/*******************************************************************************
 * Copyright (c) 2010, 2011 Oracle. All rights reserved.
 * This program and the accompanying materials are made available under the
 * terms of the Eclipse Public License v1.0, which accompanies this distribution
 * and is available at http://www.eclipse.org/legal/epl-v10.html.
 * 
 * Contributors:
 *     Oracle - initial API and implementation
 ******************************************************************************/
package org.eclipse.jpt.jaxb.core.internal;

import java.util.ArrayList;
import java.util.List;
import java.util.Vector;
import org.eclipse.core.resources.IFile;
import org.eclipse.core.resources.IProject;
import org.eclipse.core.resources.IResource;
import org.eclipse.core.resources.IResourceDelta;
import org.eclipse.core.resources.IResourceDeltaVisitor;
import org.eclipse.core.resources.IResourceProxy;
import org.eclipse.core.resources.IResourceProxyVisitor;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.NullProgressMonitor;
import org.eclipse.core.runtime.Status;
import org.eclipse.core.runtime.content.IContentType;
import org.eclipse.jdt.core.ElementChangedEvent;
import org.eclipse.jdt.core.ICompilationUnit;
import org.eclipse.jdt.core.IJavaElement;
import org.eclipse.jdt.core.IJavaElementDelta;
import org.eclipse.jdt.core.IJavaProject;
import org.eclipse.jdt.core.IPackageDeclaration;
import org.eclipse.jdt.core.IType;
import org.eclipse.jdt.core.JavaCore;
import org.eclipse.jdt.core.JavaModelException;
import org.eclipse.jpt.common.core.JptCommonCorePlugin;
import org.eclipse.jpt.common.core.JptResourceModel;
import org.eclipse.jpt.common.core.JptResourceModelListener;
import org.eclipse.jpt.common.core.internal.utility.PlatformTools;
import org.eclipse.jpt.common.core.resource.ResourceLocator;
import org.eclipse.jpt.common.core.resource.java.JavaResourceAbstractType;
import org.eclipse.jpt.common.core.resource.java.JavaResourceCompilationUnit;
import org.eclipse.jpt.common.core.resource.java.JavaResourceNode;
import org.eclipse.jpt.common.core.resource.java.JavaResourcePackage;
import org.eclipse.jpt.common.core.resource.java.JavaResourcePackageInfoCompilationUnit;
import org.eclipse.jpt.common.utility.Command;
import org.eclipse.jpt.common.utility.CommandExecutor;
import org.eclipse.jpt.common.utility.internal.BitTools;
import org.eclipse.jpt.common.utility.internal.NotNullFilter;
import org.eclipse.jpt.common.utility.internal.ThreadLocalCommandExecutor;
import org.eclipse.jpt.common.utility.internal.iterables.ArrayIterable;
import org.eclipse.jpt.common.utility.internal.iterables.CompositeIterable;
import org.eclipse.jpt.common.utility.internal.iterables.EmptyIterable;
import org.eclipse.jpt.common.utility.internal.iterables.FilteringIterable;
import org.eclipse.jpt.common.utility.internal.iterables.LiveCloneIterable;
import org.eclipse.jpt.common.utility.internal.iterables.SnapshotCloneIterable;
import org.eclipse.jpt.common.utility.internal.iterables.TransformationIterable;
import org.eclipse.jpt.common.utility.internal.synchronizers.CallbackSynchronousSynchronizer;
import org.eclipse.jpt.common.utility.internal.synchronizers.SynchronousSynchronizer;
import org.eclipse.jpt.common.utility.synchronizers.CallbackSynchronizer;
import org.eclipse.jpt.common.utility.synchronizers.Synchronizer;
import org.eclipse.jpt.jaxb.core.JaxbFacet;
import org.eclipse.jpt.jaxb.core.JaxbFile;
import org.eclipse.jpt.jaxb.core.JaxbProject;
import org.eclipse.jpt.jaxb.core.JptJaxbCorePlugin;
import org.eclipse.jpt.jaxb.core.SchemaLibrary;
import org.eclipse.jpt.jaxb.core.context.JaxbContextRoot;
import org.eclipse.jpt.jaxb.core.context.JaxbPackage;
import org.eclipse.jpt.jaxb.core.context.JaxbPackageInfo;
import org.eclipse.jpt.jaxb.core.context.JaxbType;
import org.eclipse.jpt.jaxb.core.context.java.JavaContextNode;
import org.eclipse.jpt.jaxb.core.internal.platform.JaxbPlatformImpl;
import org.eclipse.jpt.jaxb.core.internal.validation.DefaultValidationMessages;
import org.eclipse.jpt.jaxb.core.internal.validation.JaxbValidationMessages;
import org.eclipse.jpt.jaxb.core.libprov.JaxbLibraryProviderInstallOperationConfig;
import org.eclipse.jpt.jaxb.core.platform.JaxbPlatform;
import org.eclipse.jpt.jaxb.core.resource.jaxbindex.JaxbIndexResource;
import org.eclipse.jpt.jaxb.core.resource.jaxbprops.JaxbPropertiesResource;
import org.eclipse.jst.common.project.facet.core.libprov.ILibraryProvider;
import org.eclipse.jst.common.project.facet.core.libprov.LibraryInstallDelegate;
import org.eclipse.jst.j2ee.model.internal.validation.ValidationCancelledException;
import org.eclipse.wst.common.project.facet.core.IFacetedProject;
import org.eclipse.wst.common.project.facet.core.IProjectFacetVersion;
import org.eclipse.wst.common.project.facet.core.ProjectFacetsManager;
import org.eclipse.wst.validation.internal.provisional.core.IMessage;
import org.eclipse.wst.validation.internal.provisional.core.IReporter;

/**
 * JAXB project. Holds all the JAXB stuff.
 * 
 * The JAXB platform provides the hooks for vendor-specific stuff.
 * 
 * The JAXB files are the "resource" model (i.e. objects that correspond directly
 * to Eclipse resources; e.g. Java source code files, XML files, JAR files).
 * 
 * The root context node is the "context" model (i.e. objects that attempt to
 * model the JAXB spec, using the "resource" model as an adapter to the Eclipse
 * resources).
 */
public abstract class AbstractJaxbProject
	extends AbstractJaxbNode
	implements JaxbProject {
	
	/**
	 * The Eclipse project corresponding to the JAXB project.
	 */
	protected final IProject project;
	
	/**
	 * The vendor-specific JAXB platform that builds the JAXB project
	 * and all its contents.
	 */
	protected final JaxbPlatform jaxbPlatform;
	
	/**
	 * The library of schemas associated with this project
	 */
	protected final SchemaLibraryImpl schemaLibrary;
	
	/**
	 * The JAXB files associated with the JAXB project:
	 *     java
	 *     jaxb.index
	 *     platform-specific files
	 */
	protected final Vector<JaxbFile> jaxbFiles = new Vector<JaxbFile>();

//	/**
//	 * The "external" Java resource compilation units (source). Populated upon demand.
//	 */
//	protected final Vector<JavaResourceCompilationUnit> externalJavaResourceCompilationUnits = new Vector<JavaResourceCompilationUnit>();
//
//	/**
//	 * The "external" Java resource persistent types (binary). Populated upon demand.
//	 */
//	protected final JavaResourcePersistentTypeCache externalJavaResourcePersistentTypeCache;

	/**
	 * Resource models notify this listener when they change. A project update
	 * should occur any time a resource model changes.
	 */
	protected final JptResourceModelListener resourceModelListener;

	/**
	 * The root of the model representing the collated resources associated with 
	 * the JAXB project.
	 */
	protected final JaxbContextRoot contextRoot;

	/**
	 * A pluggable synchronizer that keeps the JAXB
	 * project's context model synchronized with its resource model, either
	 * synchronously or asynchronously (or not at all). A synchronous synchronizer
	 * is the default. For performance reasons, a UI should
	 * immediately change this to an asynchronous synchronizer. A synchronous
	 * synchronizer can be used when the project is being manipulated by a "batch"
	 * (or non-UI) client (e.g. when testing "synchronization"). A null updater
	 * can used during tests that do not care whether "synchronization" occur.
	 * Clients will need to explicitly configure the synchronizer if they require
	 * an asynchronous synchronizer.
	 */
	protected volatile Synchronizer contextModelSynchronizer;
	protected volatile boolean synchronizingContextModel = false;

	/**
	 * A pluggable synchronizer that "updates" the JAXB project, either
	 * synchronously or asynchronously (or not at all). A synchronous updater
	 * is the default, allowing a newly-constructed JAXB project to be "updated"
	 * upon return from the constructor. For performance reasons, a UI should
	 * immediately change this to an asynchronous updater. A synchronous
	 * updater can be used when the project is being manipulated by a "batch"
	 * (or non-UI) client (e.g. when testing the "update" behavior). A null
	 * updater can used during tests that do not care whether "synchronization"
	 * occur.
	 * Clients will need to explicitly configure the updater if they require
	 * an asynchronous updater.
	 */
	protected volatile CallbackSynchronizer updateSynchronizer;
	protected final CallbackSynchronizer.Listener updateSynchronizerListener;

	/**
	 * Support for modifying documents shared with the UI.
	 */
	protected final ThreadLocalCommandExecutor modifySharedDocumentCommandExecutor;


	// ********** constructor/initialization **********

	protected AbstractJaxbProject(JaxbProject.Config config) {
		super(null);  // JPA project is the root of the containment tree
		if ((config.getProject() == null) || (config.getPlatformDefinition() == null)) {
			throw new NullPointerException();
		}
		this.project = config.getProject();
		this.jaxbPlatform = new JaxbPlatformImpl(config.getPlatformDefinition());
		
		this.schemaLibrary = new SchemaLibraryImpl(this);
		
		this.modifySharedDocumentCommandExecutor = this.buildModifySharedDocumentCommandExecutor();

		this.resourceModelListener = this.buildResourceModelListener();
		// build the JPA files corresponding to the Eclipse project's files
		InitialResourceProxyVisitor visitor = this.buildInitialResourceProxyVisitor();
		visitor.visitProject(this.project);

//		this.externalJavaResourcePersistentTypeCache = this.buildExternalJavaResourcePersistentTypeCache();

		this.contextRoot = this.buildContextRoot();

		// there *shouldn't* be any changes to the resource model...
		this.setContextModelSynchronizer_(this.buildSynchronousContextModelSynchronizer());

		this.updateSynchronizerListener = this.buildUpdateSynchronizerListener();
		// "update" the project before returning
		this.setUpdateSynchronizer_(this.buildSynchronousUpdateSynchronizer());

//		// start listening to this cache once the context model has been built
//		// and all the external types are faulted in
//		this.externalJavaResourcePersistentTypeCache.addResourceModelListener(this.resourceModelListener);
	}

	@Override
	protected boolean requiresParent() {
		return false;
	}
	
	@Override
	public IResource getResource() {
		return this.project;
	}

	protected ThreadLocalCommandExecutor buildModifySharedDocumentCommandExecutor() {
		return new ThreadLocalCommandExecutor();
	}

	protected InitialResourceProxyVisitor buildInitialResourceProxyVisitor() {
		return new InitialResourceProxyVisitor();
	}
//
//	protected JavaResourcePersistentTypeCache buildExternalJavaResourcePersistentTypeCache() {
//		return new BinaryPersistentTypeCache(this.jpaPlatform.getAnnotationProvider());
//	}

	protected JaxbContextRoot buildContextRoot() {
		return this.getFactory().buildContextRoot(this);
	}

	// ***** inner class
	protected class InitialResourceProxyVisitor implements IResourceProxyVisitor {
		protected InitialResourceProxyVisitor() {
			super();
		}
		protected void visitProject(IProject p) {
			try {
				p.accept(this, IResource.NONE);
			} catch (CoreException ex) {
				// shouldn't happen - we don't throw any CoreExceptions
				throw new RuntimeException(ex);
			}
		}
		// add a JPA file for every [appropriate] file encountered by the visitor
		public boolean visit(IResourceProxy resource) {
			switch (resource.getType()) {
				case IResource.ROOT :  // shouldn't happen
					return true;  // visit children
				case IResource.PROJECT :
					return true;  // visit children
				case IResource.FOLDER :
					return true;  // visit children
				case IResource.FILE :
					AbstractJaxbProject.this.addJaxbFile_((IFile) resource.requestResource());
					return false;  // no children
				default :
					return false;  // no children
			}
		}
	}


//	// ********** miscellaneous **********
//
//	/**
//	 * Ignore changes to this collection. Adds can be ignored since they are triggered
//	 * by requests that will, themselves, trigger updates (typically during the
//	 * update of an object that calls a setter with the newly-created resource
//	 * type). Deletes will be accompanied by manual updates.
//	 */
//	@Override
//	protected void addNonUpdateAspectNamesTo(Set<String> nonUpdateAspectNames) {
//		super.addNonUpdateAspectNamesTo(nonUpdateAspectNames);
//		nonUpdateAspectNames.add(EXTERNAL_JAVA_RESOURCE_COMPILATION_UNITS_COLLECTION);
//	}


	// ********** general queries **********

	@Override
	public JaxbProject getJaxbProject() {
		return this;
	}

	public String getName() {
		return this.project.getName();
	}
	
	@Override
	public void toString(StringBuilder sb) {
		sb.append(this.getName());
	}

	public IProject getProject() {
		return this.project;
	}

	public IJavaProject getJavaProject() {
		return JavaCore.create(this.project);
	}

	@Override
	public JaxbPlatform getPlatform() {
		return this.jaxbPlatform;
	}
	
	public SchemaLibrary getSchemaLibrary() {
		return this.schemaLibrary;
	}

	@SuppressWarnings("unchecked")
	protected Iterable<JavaResourceCompilationUnit> getCombinedJavaResourceCompilationUnits() {
		return this.getInternalJavaResourceCompilationUnits();
//		return new CompositeIterable<JavaResourceCompilationUnit>(
//					this.getInternalJavaResourceCompilationUnits(),
//					this.getExternalJavaResourceCompilationUnits()
//				);
	}
	
	
	// ********** JAXB files **********

	public Iterable<JaxbFile> getJaxbFiles() {
		return new LiveCloneIterable<JaxbFile>(this.jaxbFiles);  // read-only
	}

	public int getJaxbFilesSize() {
		return this.jaxbFiles.size();
	}

	protected Iterable<JaxbFile> getJaxbFiles(final IContentType contentType) {
		return new FilteringIterable<JaxbFile>(this.getJaxbFiles()) {
			@Override
			protected boolean accept(JaxbFile jaxbFile) {
				return jaxbFile.getContentType().isKindOf(contentType);
			}
		};
	}

	@Override
	public JaxbFile getJaxbFile(IFile file) {
		for (JaxbFile jaxbFile : this.getJaxbFiles()) {
			if (jaxbFile.getFile().equals(file)) {
				return jaxbFile;
			}
		}
		return null;
	}

	/**
	 * Add a JAXB file for the specified file, if appropriate.
	 * Return true if a JAXB File was created and added, false otherwise
	 */
	protected boolean addJaxbFile(IFile file) {
		JaxbFile jaxbFile = this.addJaxbFile_(file);
		if (jaxbFile != null) {
			this.fireItemAdded(JAXB_FILES_COLLECTION, jaxbFile);
			return true;
		}
		return false;
	}
	
	/**
	 * Add a JAXB file for the specified file, if appropriate, without firing
	 * an event; useful during construction.
	 * Return the new JAXB file, null if it was not created.
	 */
	protected JaxbFile addJaxbFile_(IFile file) {
		if (isJavaFile(file)) {
			if (! getJavaProject().isOnClasspath(file)) {
				// a java (.jar or .java) file must be on the Java classpath
				return null;
			}
		}
		else if (! isInAcceptableResourceLocation(file)) {
			return null;  
		}

		JaxbFile jaxbFile = null;
		try {
			jaxbFile = this.getPlatform().buildJaxbFile(this, file);
		}
		catch (Exception e) {
			//log any developer exceptions and don't build a JaxbFile rather
			//than completely failing to build the JaxbProject
			JptJaxbCorePlugin.log(e);
		}
		if (jaxbFile == null) {
			return null;
		}
		jaxbFile.getResourceModel().addResourceModelListener(this.resourceModelListener);
		this.jaxbFiles.add(jaxbFile);
		return jaxbFile;
	}
	
	/* file is .java or .jar */
	protected boolean isJavaFile(IFile file) {
		IContentType contentType = PlatformTools.getContentType(file);
		return contentType != null 
				&& (contentType.isKindOf(JptCommonCorePlugin.JAVA_SOURCE_CONTENT_TYPE)
					|| contentType.isKindOf(JptCommonCorePlugin.JAR_CONTENT_TYPE));
	}
	
	/* (non-java resource) file is in acceptable resource location */
	protected boolean isInAcceptableResourceLocation(IFile file) {
		ResourceLocator resourceLocator = JptCommonCorePlugin.getResourceLocator(getProject());
		return resourceLocator.acceptResourceLocation(getProject(), file.getParent());
	}
	
	/**
	 * Remove the JAXB file corresponding to the specified IFile, if it exists.
	 * Return true if a JAXB File was removed, false otherwise
	 */
	protected boolean removeJaxbFile(IFile file) {
		JaxbFile jaxbFile = this.getJaxbFile(file);
		if (jaxbFile != null) {  // a JpaFile is not added for every IFile
			this.removeJaxbFile(jaxbFile);
			return true;
		}
		return false;
	}

	/**
	 * Stop listening to the JAXB file and remove it.
	 */
	protected void removeJaxbFile(JaxbFile jaxbFile) {
		jaxbFile.getResourceModel().removeResourceModelListener(this.resourceModelListener);
		if ( ! this.removeItemFromCollection(jaxbFile, this.jaxbFiles, JAXB_FILES_COLLECTION)) {
			throw new IllegalArgumentException(jaxbFile.toString());
		}
	}


//	// ********** external Java resource persistent types (source or binary) **********
//
//	protected JavaResourcePersistentType buildPersistableExternalJavaResourcePersistentType(String typeName) {
//		IType jdtType = this.findType(typeName);
//		return (jdtType == null) ? null : this.buildPersistableExternalJavaResourcePersistentType(jdtType);
//	}
//
//	protected IType findType(String typeName) {
//		try {
//			return this.getJavaProject().findType(typeName);
//		} catch (JavaModelException ex) {
//			return null;  // ignore exception?
//		}
//	}
//
//	protected JavaResourcePersistentType buildPersistableExternalJavaResourcePersistentType(IType jdtType) {
//		JavaResourcePersistentType jrpt = this.buildExternalJavaResourcePersistentType(jdtType);
//		return ((jrpt != null) && jrpt.isPersistable()) ? jrpt : null;
//	}
//
//	protected JavaResourcePersistentType buildExternalJavaResourcePersistentType(IType jdtType) {
//		return jdtType.isBinary() ?
//				this.buildBinaryExternalJavaResourcePersistentType(jdtType) :
//				this.buildSourceExternalJavaResourcePersistentType(jdtType);
//	}
//
//	protected JavaResourcePersistentType buildBinaryExternalJavaResourcePersistentType(IType jdtType) {
//		return this.externalJavaResourcePersistentTypeCache.addPersistentType(jdtType);
//	}
//
//	protected JavaResourcePersistentType buildSourceExternalJavaResourcePersistentType(IType jdtType) {
//		JavaResourceCompilationUnit jrcu = this.getExternalJavaResourceCompilationUnit(jdtType.getCompilationUnit());
//		String jdtTypeName = jdtType.getFullyQualifiedName('.');  // JDT member type names use '$'
//		for (Iterator<JavaResourcePersistentType> stream = jrcu.persistentTypes(); stream.hasNext(); ) {
//			JavaResourcePersistentType jrpt = stream.next();
//			if (jrpt.getQualifiedName().equals(jdtTypeName)) {
//				return jrpt;
//			}
//		}
//		// we can get here if the project JRE is removed;
//		// see SourceCompilationUnit#getPrimaryType(CompilationUnit)
//		// bug 225332
//		return null;
//	}
//
//
//	// ********** external Java resource persistent types (binary) **********
//
//	public JavaResourcePersistentTypeCache getExternalJavaResourcePersistentTypeCache() {
//		return this.externalJavaResourcePersistentTypeCache;
//	}
//
//
//	// ********** external Java resource compilation units (source) **********
//
//	public Iterator<JavaResourceCompilationUnit> externalJavaResourceCompilationUnits() {
//		return this.getExternalJavaResourceCompilationUnits().iterator();
//	}
//
//	protected Iterable<JavaResourceCompilationUnit> getExternalJavaResourceCompilationUnits() {
//		return new LiveCloneIterable<JavaResourceCompilationUnit>(this.externalJavaResourceCompilationUnits);  // read-only
//	}
//
//	public int externalJavaResourceCompilationUnitsSize() {
//		return this.externalJavaResourceCompilationUnits.size();
//	}
//
//	/**
//	 * Return the resource model compilation unit corresponding to the specified
//	 * JDT compilation unit. If it does not exist, build it.
//	 */
//	protected JavaResourceCompilationUnit getExternalJavaResourceCompilationUnit(ICompilationUnit jdtCompilationUnit) {
//		for (JavaResourceCompilationUnit jrcu : this.getExternalJavaResourceCompilationUnits()) {
//			if (jrcu.getCompilationUnit().equals(jdtCompilationUnit)) {
//				// we will get here if the JRCU could not build its persistent type...
//				return jrcu;
//			}
//		}
//		return this.addExternalJavaResourceCompilationUnit(jdtCompilationUnit);
//	}
//
//	/**
//	 * Add an external Java resource compilation unit.
//	 */
//	protected JavaResourceCompilationUnit addExternalJavaResourceCompilationUnit(ICompilationUnit jdtCompilationUnit) {
//		JavaResourceCompilationUnit jrcu = this.buildJavaResourceCompilationUnit(jdtCompilationUnit);
//		this.addItemToCollection(jrcu, this.externalJavaResourceCompilationUnits, EXTERNAL_JAVA_RESOURCE_COMPILATION_UNITS_COLLECTION);
//		jrcu.addResourceModelListener(this.resourceModelListener);
//		return jrcu;
//	}
//
//	protected JavaResourceCompilationUnit buildJavaResourceCompilationUnit(ICompilationUnit jdtCompilationUnit) {
//		return new SourceTypeCompilationUnit(
//					jdtCompilationUnit,
//					this.jpaPlatform.getAnnotationProvider(),
//					this.jpaPlatform.getAnnotationEditFormatter(),
//					this.modifySharedDocumentCommandExecutor
//				);
//	}
//
//	protected boolean removeExternalJavaResourceCompilationUnit(IFile file) {
//		for (JavaResourceCompilationUnit jrcu : this.getExternalJavaResourceCompilationUnits()) {
//			if (jrcu.getFile().equals(file)) {
//				this.removeExternalJavaResourceCompilationUnit(jrcu);
//				return true;
//			}
//		}
//		return false;
//	}
//
//	protected void removeExternalJavaResourceCompilationUnit(JavaResourceCompilationUnit jrcu) {
//		jrcu.removeResourceModelListener(this.resourceModelListener);
//		this.removeItemFromCollection(jrcu, this.externalJavaResourceCompilationUnits, EXTERNAL_JAVA_RESOURCE_COMPILATION_UNITS_COLLECTION);
//	}


	// ********** context model **********
	
	public JaxbContextRoot getContextRoot() {
		return this.contextRoot;
	}
	
	public Iterable<? extends JavaContextNode> getPrimaryJavaNodes(ICompilationUnit cu) {
		IFile file = getCorrespondingResource(cu);
		if (file == null) {	
			return EmptyIterable.instance();
		}
		
		IContentType contentType = PlatformTools.getContentType(file);
		if (contentType == null) {
			return EmptyIterable.instance();
		}
		
		if (contentType.isKindOf(JptCommonCorePlugin.JAVA_SOURCE_PACKAGE_INFO_CONTENT_TYPE)) {
			try {
				return new FilteringIterable<JaxbPackageInfo>(
						new TransformationIterable<IPackageDeclaration, JaxbPackageInfo>(
								new ArrayIterable<IPackageDeclaration>(cu.getPackageDeclarations())) {
							@Override
							protected JaxbPackageInfo transform(IPackageDeclaration o) {
								JaxbPackage jaxbPackage = getContextRoot().getPackage(o.getElementName());
								return (jaxbPackage != null) ? jaxbPackage.getPackageInfo() : null;
							}
						},
						NotNullFilter.<JaxbPackageInfo>instance());
			}
			catch (JavaModelException jme) {
				return EmptyIterable.instance();
			}
		}
		else if (contentType.isKindOf(JptCommonCorePlugin.JAVA_SOURCE_CONTENT_TYPE)) {
			try {
				return new FilteringIterable<JaxbType>(
						new TransformationIterable<IType, JaxbType>(
								new ArrayIterable<IType>(cu.getAllTypes())) {
							@Override
							protected JaxbType transform(IType o) {
								JaxbType jaxbType = getContextRoot().getType(o.getFullyQualifiedName('.'));
								return jaxbType;
							}
						},
						NotNullFilter.<JaxbType>instance());
			}
			catch (JavaModelException jme) {
				return EmptyIterable.instance();
			}
		}

		return EmptyIterable.instance();
	}
	
	private IFile getCorrespondingResource(ICompilationUnit cu) {
		try {
			return (IFile) cu.getCorrespondingResource();
		}
		catch (JavaModelException ex) {
			JptJaxbCorePlugin.log(ex);
			return null;
		}
	}
	
	
//	// ********** utility **********
//
//	public IFile getPlatformFile(IPath runtimePath) {
//		return JptCorePlugin.getPlatformFile(this.project, runtimePath);
//	}


//
//	/**
//	 * If the specified file exists, is significant to the JPA project, and its
//	 * content is a "kind of" the specified content type, return the JPA
//	 * resource model corresponding to the file; otherwise, return null.
//	 */
//	protected JpaResourceModel getResourceModel(IPath runtimePath, IContentType contentType) {
//		IFile file = this.getPlatformFile(runtimePath);
//		return file.exists() ? this.getResourceModel(file, contentType) :  null;
//	}
//
//	/**
//	 * If the specified file is significant to the JPA project and its content
//	 * is a "kind of" the specified content type, return the JPA resource model
//	 * corresponding to the file; otherwise, return null.
//	 */
//	protected JpaResourceModel getResourceModel(IFile file, IContentType contentType) {
//		JpaFile jpaFile = this.getJpaFile(file);
//		return (jpaFile == null) ? null : jpaFile.getResourceModel(contentType);
//	}


	// ********** annotated Java source classes **********
	
	public Iterable<JavaResourceAbstractType> getJavaSourceResourceTypes() {
		return new CompositeIterable<JavaResourceAbstractType>(this.getInternalJavaSourceResourceTypeSets());
	}
	
	public Iterable<JavaResourceAbstractType> getAnnotatedJavaSourceResourceTypes() {
		return new FilteringIterable<JavaResourceAbstractType>(getJavaSourceResourceTypes()) {
			@Override
			protected boolean accept(JavaResourceAbstractType type) {
				return type.isAnnotated();
			}
		};
	}
	
//	public Iterable<String> getAnnotatedJavaSourceClassNames() {
//		return new TransformationIterable<JavaResourceType, String>(this.getInternalAnnotatedSourceJavaResourceTypes()) {
//			@Override
//			protected String transform(JavaResourceType type) {
//				return type.getQualifiedName();
//			}
//		};
//	}
	
	/*
	 * Return the sets of {@link JavaResourceType}s that are represented by java source within this project
	 */
	protected Iterable<Iterable<JavaResourceAbstractType>> getInternalJavaSourceResourceTypeSets() {
		return new TransformationIterable<JavaResourceCompilationUnit, Iterable<JavaResourceAbstractType>>(
				this.getInternalJavaResourceCompilationUnits()) {
			@Override
			protected Iterable<JavaResourceAbstractType> transform(JavaResourceCompilationUnit compilationUnit) {
				return compilationUnit.getTypes();
			}
		};
	}
	
	protected Iterable<JavaResourceCompilationUnit> getInternalJavaResourceCompilationUnits() {
		return new TransformationIterable<JaxbFile, JavaResourceCompilationUnit>(this.getJavaSourceJaxbFiles()) {
			@Override
			protected JavaResourceCompilationUnit transform(JaxbFile jaxbFile) {
				return (JavaResourceCompilationUnit) jaxbFile.getResourceModel();
			}
		};
	}
	
	/**
	 * return JAXB files with Java source "content"
	 */
	protected Iterable<JaxbFile> getJavaSourceJaxbFiles() {
		return this.getJaxbFiles(JptCommonCorePlugin.JAVA_SOURCE_CONTENT_TYPE);
	}


	// ********** Java resource package look-up **********
	
	public Iterable<JavaResourcePackage> getJavaResourcePackages(){
		return new FilteringIterable<JavaResourcePackage>( 
				new TransformationIterable<JaxbFile, JavaResourcePackage>(this.getPackageInfoSourceJaxbFiles()) {
					@Override
					protected JavaResourcePackage transform(JaxbFile jaxbFile) {
						return ((JavaResourcePackageInfoCompilationUnit) jaxbFile.getResourceModel()).getPackage();
					}
				}) {
			
			@Override
			protected boolean accept(JavaResourcePackage resourcePackage) {
				return resourcePackage != null;
			}
		};
	}
	
	public JavaResourcePackage getJavaResourcePackage(String packageName) {
		for (JavaResourcePackage jrp : this.getJavaResourcePackages()) {
			if (jrp.getName().equals(packageName)) {
				return jrp;
			}
		}
		return null;
	}
	
	public Iterable<JavaResourcePackage> getAnnotatedJavaResourcePackages() {
		return new FilteringIterable<JavaResourcePackage>(this.getJavaResourcePackages()) {
			@Override
			protected boolean accept(JavaResourcePackage resourcePackage) {
				return resourcePackage.isAnnotated();  // i.e. the package has a valid package annotation
			}
		};
	}
	
	public JavaResourcePackage getAnnotatedJavaResourcePackage(String packageName) {
		JavaResourcePackage jrp = getJavaResourcePackage(packageName);
		return (jrp != null && jrp.isAnnotated()) ? jrp : null;
	}
	
	/**
	 * return JPA files with package-info source "content"
	 */
	protected Iterable<JaxbFile> getPackageInfoSourceJaxbFiles() {
		return this.getJaxbFiles(JptCommonCorePlugin.JAVA_SOURCE_PACKAGE_INFO_CONTENT_TYPE);
	}

	
	// ********** Java resource type look-up **********
	
	
	public JavaResourceAbstractType getJavaResourceType(String typeName) {
		for (JavaResourceAbstractType type : this.getJavaResourceTypes()) {
			if (type.getQualifiedName().equals(typeName)) {
				return type;
			}
		}
		return null;
//		// if we don't have a type already, try to build new one from the project classpath
//		return this.buildPersistableExternalJavaResourcePersistentType(typeName);
	}
	
	public JavaResourceAbstractType getJavaResourceType(String typeName, JavaResourceAbstractType.Kind kind) {
		JavaResourceAbstractType resourceType = getJavaResourceType(typeName);
		if (resourceType == null || resourceType.getKind() != kind) {
			return null;
		}
		return resourceType;
	}

	protected Iterable<JavaResourceAbstractType> getJavaResourceTypes() {
		return new CompositeIterable<JavaResourceAbstractType>(this.getJavaResourceTypeSets());
	}
	
	protected Iterable<Iterable<JavaResourceAbstractType>> getJavaResourceTypeSets() {
		return new TransformationIterable<JavaResourceNode.Root, Iterable<JavaResourceAbstractType>>(
				this.getJavaResourceNodeRoots()) {
			@Override
			protected Iterable<JavaResourceAbstractType> transform(JavaResourceNode.Root root) {
				return root.getTypes();
			}
		};
	}
	
	@SuppressWarnings("unchecked")
	protected Iterable<JavaResourceNode.Root> getJavaResourceNodeRoots() {
		return new CompositeIterable<JavaResourceNode.Root>(
					this.getInternalJavaResourceCompilationUnits()/*,
					this.getInternalJavaResourcePackageFragmentRoots(),
					this.getExternalJavaResourceCompilationUnits(),
					Collections.singleton(this.externalJavaResourcePersistentTypeCache)*/
				);
	}

	
//	// ********** JARs **********
//
//	// TODO
//	public JavaResourcePackageFragmentRoot getJavaResourcePackageFragmentRoot(String jarFileName) {
////		return this.getJarResourcePackageFragmentRoot(this.convertToPlatformFile(jarFileName));
//		return this.getJavaResourcePackageFragmentRoot(this.getProject().getFile(jarFileName));
//	}
//
//	protected JavaResourcePackageFragmentRoot getJavaResourcePackageFragmentRoot(IFile jarFile) {
//		for (JavaResourcePackageFragmentRoot pfr : this.getInternalJavaResourcePackageFragmentRoots()) {
//			if (pfr.getFile().equals(jarFile)) {
//				return pfr;
//			}
//		}
//		return null;
//	}
//
//	protected Iterable<JavaResourcePackageFragmentRoot> getInternalJavaResourcePackageFragmentRoots() {
//		return new TransformationIterable<JpaFile, JavaResourcePackageFragmentRoot>(this.getJarJpaFiles()) {
//			@Override
//			protected JavaResourcePackageFragmentRoot transform(JpaFile jpaFile) {
//				return (JavaResourcePackageFragmentRoot) jpaFile.getResourceModel();
//			}
//		};
//	}
//
//	/**
//	 * return JPA files with JAR "content"
//	 */
//	protected Iterable<JpaFile> getJarJpaFiles() {
//		return this.getJpaFiles(JptCorePlugin.JAR_CONTENT_TYPE);
//	}



//
//	// ********** Java source folder names **********
//
//	public Iterable<String> getJavaSourceFolderNames() {
//		try {
//			return this.getJavaSourceFolderNames_();
//		} catch (JavaModelException ex) {
//			JptCorePlugin.log(ex);
//			return EmptyIterable.instance();
//		}
//	}
//
//	protected Iterable<String> getJavaSourceFolderNames_() throws JavaModelException {
//		return new TransformationIterable<IPackageFragmentRoot, String>(this.getJavaSourceFolders()) {
//			@Override
//			protected String transform(IPackageFragmentRoot pfr) {
//				try {
//					return this.transform_(pfr);
//				} catch (JavaModelException ex) {
//					return "Error: " + pfr.getPath(); //$NON-NLS-1$
//				}
//			}
//			private String transform_(IPackageFragmentRoot pfr) throws JavaModelException {
//				return pfr.getUnderlyingResource().getProjectRelativePath().toString();
//			}
//		};
//	}
//
//	protected Iterable<IPackageFragmentRoot> getJavaSourceFolders() throws JavaModelException {
//		return new FilteringIterable<IPackageFragmentRoot>(
//				this.getPackageFragmentRoots(),
//				SOURCE_PACKAGE_FRAGMENT_ROOT_FILTER
//			);
//	}
//
//	protected static final Filter<IPackageFragmentRoot> SOURCE_PACKAGE_FRAGMENT_ROOT_FILTER =
//		new Filter<IPackageFragmentRoot>() {
//			public boolean accept(IPackageFragmentRoot pfr) {
//				try {
//					return this.accept_(pfr);
//				} catch (JavaModelException ex) {
//					return false;
//				}
//			}
//			private boolean accept_(IPackageFragmentRoot pfr) throws JavaModelException {
//				return pfr.exists() && (pfr.getKind() == IPackageFragmentRoot.K_SOURCE);
//			}
//		};
//
//	protected Iterable<IPackageFragmentRoot> getPackageFragmentRoots() throws JavaModelException {
//		return new ArrayIterable<IPackageFragmentRoot>(this.getJavaProject().getPackageFragmentRoots());
//	}
	
	
	// **************** jaxb.index resources **********************************
	
	public Iterable<JaxbIndexResource> getJaxbIndexResources() {
		return new TransformationIterable<JaxbFile, JaxbIndexResource>(getJaxbFiles(JptJaxbCorePlugin.JAXB_INDEX_CONTENT_TYPE)) {
			@Override
			protected JaxbIndexResource transform(JaxbFile o) {
				return (JaxbIndexResource) o.getResourceModel();
			}
		};
	}
	
	public JaxbIndexResource getJaxbIndexResource(String packageName) {
		for (JaxbIndexResource jir : getJaxbIndexResources()) {
			if (packageName.equals(jir.getPackageName())) {
				return jir;
			}
		}
		return null;
	}
	
	
	// **************** jaxb.properties resources *****************************
	
	public Iterable<JaxbPropertiesResource> getJaxbPropertiesResources() {
		return new TransformationIterable<JaxbFile, JaxbPropertiesResource>(getJaxbFiles(JptJaxbCorePlugin.JAXB_PROPERTIES_CONTENT_TYPE)) {
			@Override
			protected JaxbPropertiesResource transform(JaxbFile o) {
				return (JaxbPropertiesResource) o.getResourceModel();
			}
		};
	}
	
	public JaxbPropertiesResource getJaxbPropertiesResource(String packageName) {
		for (JaxbPropertiesResource jpr : getJaxbPropertiesResources()) {
			if (packageName.equals(jpr.getPackageName())) {
				return jpr;
			}
		}
		return null;
	}
	
	
	// ********** Java events **********

	// TODO handle changes to external projects
	public void javaElementChanged(ElementChangedEvent event) {
		this.processJavaDelta(event.getDelta());
	}

	/**
	 * We recurse back here from {@link #processJavaDeltaChildren(IJavaElementDelta)}.
	 */
	protected void processJavaDelta(IJavaElementDelta delta) {
		switch (delta.getElement().getElementType()) {
			case IJavaElement.JAVA_MODEL :
				this.processJavaModelDelta(delta);
				break;
			case IJavaElement.JAVA_PROJECT :
				this.processJavaProjectDelta(delta);
				break;
			case IJavaElement.PACKAGE_FRAGMENT_ROOT :
				this.processJavaPackageFragmentRootDelta(delta);
				break;
			case IJavaElement.PACKAGE_FRAGMENT :
				this.processJavaPackageFragmentDelta(delta);
				break;
			case IJavaElement.COMPILATION_UNIT :
				this.processJavaCompilationUnitDelta(delta);
				break;
			default :
				break; // ignore the elements inside a compilation unit
		}
	}

	protected void processJavaDeltaChildren(IJavaElementDelta delta) {
		for (IJavaElementDelta child : delta.getAffectedChildren()) {
			this.processJavaDelta(child); // recurse
		}
	}

	/**
	 * Return whether the specified Java element delta is for a
	 * {@link IJavaElementDelta#CHANGED CHANGED}
	 * (as opposed to {@link IJavaElementDelta#ADDED ADDED} or
	 * {@link IJavaElementDelta#REMOVED REMOVED}) Java element
	 * and the specified flag is set.
	 * (The delta flags are only significant if the delta
	 * {@link IJavaElementDelta#getKind() kind} is
	 * {@link IJavaElementDelta#CHANGED CHANGED}.)
	 */
	protected boolean deltaFlagIsSet(IJavaElementDelta delta, int flag) {
		return (delta.getKind() == IJavaElementDelta.CHANGED) &&
				BitTools.flagIsSet(delta.getFlags(), flag);
	}

	// ***** model
	protected void processJavaModelDelta(IJavaElementDelta delta) {
		// process the Java model's projects
		this.processJavaDeltaChildren(delta);
	}

	// ***** project
	protected void processJavaProjectDelta(IJavaElementDelta delta) {
		// process the Java project's package fragment roots
		this.processJavaDeltaChildren(delta);

		// a classpath change can have pretty far-reaching effects...
		if (this.classpathHasChanged(delta)) {
			this.rebuild((IJavaProject) delta.getElement());
		}
	}

	/**
	 * The specified Java project's classpath changed. Rebuild the JPA project
	 * as appropriate.
	 */
	protected void rebuild(IJavaProject javaProject) {
		// if the classpath has changed, we need to update everything since
		// class references could now be resolved (or not) etc.
		if (javaProject.equals(this.getJavaProject())) {
			this.removeDeadJpaFiles();
			this.synchronizeWithJavaSource(this.getInternalJavaResourceCompilationUnits());
		} else {
			// TODO see if changed project is on our classpath?
			//this.synchronizeWithJavaSource(this.getExternalJavaResourceCompilationUnits());
		}
	}

	/**
	 * Loop through all our JPA files, remove any that are no longer on the
	 * classpath.
	 */
	protected void removeDeadJpaFiles() {
		for (JaxbFile jaxbFile : this.getJaxbFiles()) {
			if (this.jaxbFileIsDead(jaxbFile)) {
				this.removeJaxbFile(jaxbFile);
			}
		}
	}

	protected boolean jaxbFileIsDead(JaxbFile jaxbFile) {
		return ! this.jaxbFileIsAlive(jaxbFile);
	}

	/**
	 * Sometimes (e.g. during tests), when a project has been deleted, we get a
	 * Java change event that indicates the Java project is CHANGED (as
	 * opposed to REMOVED, which is what typically happens). The event's delta
	 * indicates that everything in the Java project has been deleted and the
	 * classpath has changed. All entries in the classpath have been removed;
	 * but single entry for the Java project's root folder has been added. (!)
	 * This means any file in the project is on the Java project's classpath.
	 * This classpath change is what triggers us to rebuild the JPA project; so
	 * we put an extra check here to make sure the JPA file's resource file is
	 * still present.
	 * <p>
	 * This would not be a problem if Dali received the resource change event
	 * <em>before</em> JDT and simply removed the JPA project; but JDT receives
	 * the resource change event first and converts it into the problematic
	 * Java change event.... 
	 */
	protected boolean jaxbFileIsAlive(JaxbFile jaxbFile) {
		IFile file = jaxbFile.getFile();
		return this.getJavaProject().isOnClasspath(file) &&
				file.exists();
	}

	/**
	 * pre-condition:
	 * delta.getElement().getElementType() == IJavaElement.JAVA_PROJECT
	 */
	protected boolean classpathHasChanged(IJavaElementDelta delta) {
		return this.deltaFlagIsSet(delta, IJavaElementDelta.F_RESOLVED_CLASSPATH_CHANGED);
	}

	protected void synchronizeWithJavaSource(Iterable<JavaResourceCompilationUnit> javaResourceCompilationUnits) {
		for (JavaResourceCompilationUnit javaResourceCompilationUnit : javaResourceCompilationUnits) {
			javaResourceCompilationUnit.synchronizeWithJavaSource();
		}
	}


	// ***** package fragment root
	protected void processJavaPackageFragmentRootDelta(IJavaElementDelta delta) {
		// process the Java package fragment root's package fragments
		this.processJavaDeltaChildren(delta);

		if (this.classpathEntryHasBeenAdded(delta)) {
			// TODO bug 277218
		} else if (this.classpathEntryHasBeenRemoved(delta)) {  // should be mutually-exclusive w/added (?)
			// TODO bug 277218
		}
	}

	/**
	 * pre-condition:
	 * delta.getElement().getElementType() == IJavaElement.PACKAGE_FRAGMENT_ROOT
	 */
	protected boolean classpathEntryHasBeenAdded(IJavaElementDelta delta) {
		return this.deltaFlagIsSet(delta, IJavaElementDelta.F_ADDED_TO_CLASSPATH);
	}

	/**
	 * pre-condition:
	 * delta.getElement().getElementType() == IJavaElement.PACKAGE_FRAGMENT_ROOT
	 */
	protected boolean classpathEntryHasBeenRemoved(IJavaElementDelta delta) {
		return this.deltaFlagIsSet(delta, IJavaElementDelta.F_REMOVED_FROM_CLASSPATH);
	}

	// ***** package fragment
	protected void processJavaPackageFragmentDelta(IJavaElementDelta delta) {
		// process the java package fragment's compilation units
		this.processJavaDeltaChildren(delta);
	}

	// ***** compilation unit
	protected void processJavaCompilationUnitDelta(IJavaElementDelta delta) {
		if (this.javaCompilationUnitDeltaIsRelevant(delta)) {
			ICompilationUnit compilationUnit = (ICompilationUnit) delta.getElement();
			for (JavaResourceCompilationUnit jrcu : this.getCombinedJavaResourceCompilationUnits()) {
				if (jrcu.getCompilationUnit().equals(compilationUnit)) {
					jrcu.synchronizeWithJavaSource();
					// TODO ? this.resolveJavaTypes();  // might have new member types now...
					break;  // there *shouldn't* be any more...
				}
			}
		}
		// ignore the java compilation unit's children
	}

	protected boolean javaCompilationUnitDeltaIsRelevant(IJavaElementDelta delta) {
		// ignore changes to/from primary working copy - no content has changed;
		// and make sure there are no other flags set that indicate *both* a
		// change to/from primary working copy *and* content has changed
		if (BitTools.onlyFlagIsSet(delta.getFlags(), IJavaElementDelta.F_PRIMARY_WORKING_COPY)) {
			return false;
		}

		// ignore java notification for ADDED or REMOVED;
		// these are handled via resource notification
		return delta.getKind() == IJavaElementDelta.CHANGED;
	}


	// ********** validation **********
	
	public Iterable<IMessage> getValidationMessages(IReporter reporter) {
		List<IMessage> messages = new ArrayList<IMessage>();
		this.validate(messages, reporter);
		return new SnapshotCloneIterable<IMessage>(messages);
	}
	
	protected void validate(List<IMessage> messages, IReporter reporter) {
		if (reporter.isCancelled()) {
			throw new ValidationCancelledException();
		}
		
		getSchemaLibrary().refreshAllSchemas();
		
		validateLibraryProvider(messages);
		validateSchemaLibrary(messages);
		this.contextRoot.validate(messages, reporter);
	}
	
	protected void validateLibraryProvider(List<IMessage> messages) {
		try {
			IFacetedProject facetedProject = ProjectFacetsManager.create(getProject());
			IProjectFacetVersion facetVersion = facetedProject.getInstalledVersion(JaxbFacet.FACET);
			LibraryInstallDelegate lid = new LibraryInstallDelegate(facetedProject, facetVersion);
			ILibraryProvider lp = lid.getLibraryProvider();
			if (lid.getLibraryProviderOperationConfig() instanceof JaxbLibraryProviderInstallOperationConfig) {
				((JaxbLibraryProviderInstallOperationConfig) lid.getLibraryProviderOperationConfig()).setJaxbPlatform(getPlatform().getDescription());
			}
			if (! lp.isEnabledFor(facetedProject, facetVersion) || ! lid.validate().isOK()) {
				messages.add(
						DefaultValidationMessages.buildMessage(
							IMessage.HIGH_SEVERITY,
							JaxbValidationMessages.PROJECT_INVALID_LIBRARY_PROVIDER,
							this));
			}
		}
		catch (CoreException ce) {
			// fall through
			JptJaxbCorePlugin.log(ce);
		}
	}
	
	protected void validateSchemaLibrary(List<IMessage> messages) {
		this.schemaLibrary.validate(messages);
	}
	
	
	// ********** dispose **********

	public void dispose() {
		this.contextModelSynchronizer.stop();
		this.updateSynchronizer.stop();
		this.updateSynchronizer.removeListener(this.updateSynchronizerListener);
		this.schemaLibrary.dispose();
		// the XML resources are held indefinitely by the WTP translator framework,
		// so we better remove our listener or the JAXB project will not be GCed
		for (JaxbFile jaxbFile : this.getJaxbFiles()) {
			jaxbFile.getResourceModel().removeResourceModelListener(this.resourceModelListener);
		}
	}

	
	
	// ********** resource model listener **********
	
	protected JptResourceModelListener buildResourceModelListener() {
		return new DefaultResourceModelListener();
	}

	protected class DefaultResourceModelListener 
		implements JptResourceModelListener 
	{
		protected DefaultResourceModelListener() {
			super();
		}
		
		public void resourceModelChanged(JptResourceModel jpaResourceModel) {
//			String msg = Thread.currentThread() + " resource model change: " + jpaResourceModel;
//			System.out.println(msg);
//			new Exception(msg).printStackTrace(System.out);
			AbstractJaxbProject.this.synchronizeContextModel(jpaResourceModel);
		}
		
		public void resourceModelReverted(JptResourceModel jpaResourceModel) {
//			IFile file = WorkbenchResourceHelper.getFile((JpaXmlResource)jpaResourceModel);
//			AbstractJaxbProject.this.removeJaxbFile(file);
//			AbstractJaxbProject.this.addJaxbFile(file);
		}
		
		public void resourceModelUnloaded(JptResourceModel jpaResourceModel) {
//			IFile file = WorkbenchResourceHelper.getFile((JpaXmlResource)jpaResourceModel);
//			AbstractJaxbProject.this.removeJaxbFile(file);
		}
	}

	protected void synchronizeContextModel(@SuppressWarnings("unused") JptResourceModel jpaResourceModel) {
		this.synchronizeContextModel();
	}


	// ********** resource events **********

	// TODO need to do the same thing for external projects and compilation units
	public void projectChanged(IResourceDelta delta) {
		if (delta.getResource().equals(this.getProject())) {
			this.internalProjectChanged(delta);
		} else {
//			this.externalProjectChanged(delta);
		}
	}

	protected void internalProjectChanged(IResourceDelta delta) {
		ResourceDeltaVisitor resourceDeltaVisitor = this.buildInternalResourceDeltaVisitor();
		resourceDeltaVisitor.visitDelta(delta);
		// at this point, if we have added and/or removed JpaFiles, an "update" will have been triggered;
		// any changes to the resource model during the "resolve" will trigger further "updates";
		// there should be no need to "resolve" external Java types (they can't have references to
		// the internal Java types)
		if (resourceDeltaVisitor.encounteredSignificantChange()) {
			this.resolveInternalJavaTypes();
		}
	}

	protected ResourceDeltaVisitor buildInternalResourceDeltaVisitor() {
		return new ResourceDeltaVisitor() {
			@Override
			public boolean fileChangeIsSignificant(IFile file, int deltaKind) {
				return AbstractJaxbProject.this.synchronizeJaxbFiles(file, deltaKind);
			}
		};
	}

	/**
	 * Internal resource delta visitor callback.
	 * Return true if a JaxbFile was either added or removed.
	 */
	protected boolean synchronizeJaxbFiles(IFile file, int deltaKind) {
		switch (deltaKind) {
			case IResourceDelta.ADDED :
				return this.addJaxbFile(file);
			case IResourceDelta.REMOVED :
				return this.removeJaxbFile(file);
			case IResourceDelta.CHANGED :
				return this.checkForChangedFileContent(file);
			case IResourceDelta.ADDED_PHANTOM :
				break;  // ignore
			case IResourceDelta.REMOVED_PHANTOM :
				break;  // ignore
			default :
				break;  // only worried about added/removed/changed files
		}

		return false;
	}

	protected boolean checkForChangedFileContent(IFile file) {
		JaxbFile jaxbFile = this.getJaxbFile(file);
		if (jaxbFile == null) {
			// the file might have changed its content to something that we are interested in
			return this.addJaxbFile(file);
		}

		if (jaxbFile.getContentType().equals(PlatformTools.getContentType(file))) {
			// content has not changed - ignore
			return false;
		}

		// the content type changed, we need to build a new JPA file
		// (e.g. the schema of an orm.xml file changed from JPA to EclipseLink)
		this.removeJaxbFile(jaxbFile);
		this.addJaxbFile(file);
		return true;  // at the least, we have removed a JPA file
	}

	protected void resolveInternalJavaTypes() {
		for (JavaResourceCompilationUnit jrcu : this.getInternalJavaResourceCompilationUnits()) {
			jrcu.resolveTypes();
		}
	}

//	protected void externalProjectChanged(IResourceDelta delta) {
//		if (this.getJavaProject().isOnClasspath(delta.getResource())) {
//			ResourceDeltaVisitor resourceDeltaVisitor = this.buildExternalResourceDeltaVisitor();
//			resourceDeltaVisitor.visitDelta(delta);
//			// force an "update" here since adding and/or removing an external Java type
//			// will only trigger an "update" if the "resolve" causes something in the resource model to change
//			if (resourceDeltaVisitor.encounteredSignificantChange()) {
//				this.update();
//				this.resolveExternalJavaTypes();
//				this.resolveInternalJavaTypes();
//			}
//		}
//	}
//
//	protected ResourceDeltaVisitor buildExternalResourceDeltaVisitor() {
//		return new ResourceDeltaVisitor() {
//			@Override
//			public boolean fileChangeIsSignificant(IFile file, int deltaKind) {
//				return AbstractJaxbProject.this.synchronizeExternalFiles(file, deltaKind);
//			}
//		};
//	}
//
//	/**
//	 * external resource delta visitor callback
//	 * Return true if an "external" Java resource compilation unit
//	 * was added or removed.
//	 */
//	protected boolean synchronizeExternalFiles(IFile file, int deltaKind) {
//		switch (deltaKind) {
//			case IResourceDelta.ADDED :
//				return this.externalFileAdded(file);
//			case IResourceDelta.REMOVED :
//				return this.externalFileRemoved(file);
//			case IResourceDelta.CHANGED :
//				break;  // ignore
//			case IResourceDelta.ADDED_PHANTOM :
//				break;  // ignore
//			case IResourceDelta.REMOVED_PHANTOM :
//				break;  // ignore
//			default :
//				break;  // only worried about added/removed/changed files
//		}
//
//		return false;
//	}
//
//	protected boolean externalFileAdded(IFile file) {
//		IContentType contentType = PlatformTools.getContentType(file);
//		if (contentType == null) {
//			return false;
//		}
//		if (contentType.equals(JptCorePlugin.JAVA_SOURCE_CONTENT_TYPE)) {
//			return true;
//		}
//		if (contentType.equals(JptCorePlugin.JAR_CONTENT_TYPE)) {
//			return true;
//		}
//		return false;
//	}
//
//	protected boolean externalFileRemoved(IFile file) {
//		IContentType contentType = PlatformTools.getContentType(file);
//		if (contentType == null) {
//			return false;
//		}
//		if (contentType.equals(JptCorePlugin.JAVA_SOURCE_CONTENT_TYPE)) {
//			return this.removeExternalJavaResourceCompilationUnit(file);
//		}
//		if (contentType.equals(JptCorePlugin.JAR_CONTENT_TYPE)) {
//			return this.externalJavaResourcePersistentTypeCache.removePersistentTypes(file);
//		}
//		return false;
//	}
//
//	protected void resolveExternalJavaTypes() {
//		for (JavaResourceCompilationUnit jrcu : this.getExternalJavaResourceCompilationUnits()) {
//			jrcu.resolveTypes();
//		}
//	}

	// ***** resource delta visitors
	/**
	 * add or remove a JPA file for every [appropriate] file encountered by the visitor
	 */
	protected abstract class ResourceDeltaVisitor implements IResourceDeltaVisitor {
		protected boolean encounteredSignificantChange = false;
		
		protected ResourceDeltaVisitor() {
			super();
		}

		protected void visitDelta(IResourceDelta delta) {
			try {
				delta.accept(this);
			} catch (CoreException ex) {
				// shouldn't happen - we don't throw any CoreExceptions
				throw new RuntimeException(ex);
			}
		}

		public boolean visit(IResourceDelta delta) {
			IResource res = delta.getResource();
			switch (res.getType()) {
				case IResource.ROOT :
					return true;  // visit children
				case IResource.PROJECT :
					return true;  // visit children
				case IResource.FOLDER :
					return true;  // visit children
				case IResource.FILE :
					this.fileChanged((IFile) res, delta.getKind());
					return false;  // no children
				default :
					return false;  // no children (probably shouldn't get here...)
			}
		}

		protected void fileChanged(IFile file, int deltaKind) {
			if (this.fileChangeIsSignificant(file, deltaKind)) {
				this.encounteredSignificantChange = true;
			}
		}

		protected abstract boolean fileChangeIsSignificant(IFile file, int deltaKind);

		/**
		 * Return whether the visitor encountered some sort of "significant"
		 * change while traversing the IResourceDelta
		 * (e.g. a JPA file was added or removed).
		 */
		protected boolean encounteredSignificantChange() {
			return this.encounteredSignificantChange;
		}

	}


	// ********** support for modifying documents shared with the UI **********

	public void setThreadLocalModifySharedDocumentCommandExecutor(CommandExecutor commandExecutor) {
		this.modifySharedDocumentCommandExecutor.set(commandExecutor);
	}

	public CommandExecutor getModifySharedDocumentCommandExecutor() {
		return this.modifySharedDocumentCommandExecutor;
	}


	// ********** synchronize context model with resource model **********

	public Synchronizer getContextModelSynchronizer() {
		return this.contextModelSynchronizer;
	}

	public void setContextModelSynchronizer(Synchronizer synchronizer) {
		if (synchronizer == null) {
			throw new NullPointerException();
		}
		this.contextModelSynchronizer.stop();
		this.setContextModelSynchronizer_(synchronizer);
	}

	protected void setContextModelSynchronizer_(Synchronizer synchronizer) {
		this.contextModelSynchronizer = synchronizer;
		this.contextModelSynchronizer.start();
	}

	/**
	 * Delegate to the context model synchronizer so clients can configure how
	 * synchronizations occur.
	 */
	public void synchronizeContextModel() {
		this.synchronizingContextModel = true;
		this.contextModelSynchronizer.synchronize();
		this.synchronizingContextModel = false;

		// There are some changes to the resource model that will not change
		// the existing context model and trigger an update (e.g. adding an
		// @Entity annotation when the the JPA project is automatically
		// discovering annotated classes); so we explicitly execute an update
		// here to discover those changes.
		this.update();
	}

	/**
	 * Called by the context model synchronizer.
	 */
	public IStatus synchronizeContextModel(IProgressMonitor monitor) {
		this.contextRoot.synchronizeWithResourceModel();
		return Status.OK_STATUS;
	}

	public void synchronizeContextModelAndWait() {
		Synchronizer temp = this.contextModelSynchronizer;
		this.setContextModelSynchronizer(this.buildSynchronousContextModelSynchronizer());
		this.synchronizeContextModel();
		this.setContextModelSynchronizer(temp);
	}


	// ********** default context model synchronizer (synchronous) **********

	protected Synchronizer buildSynchronousContextModelSynchronizer() {
		return new SynchronousSynchronizer(this.buildSynchronousContextModelSynchronizerCommand());
	}

	protected Command buildSynchronousContextModelSynchronizerCommand() {
		return new SynchronousContextModelSynchronizerCommand();
	}

	protected class SynchronousContextModelSynchronizerCommand
		implements Command
	{
		public void execute() {
			AbstractJaxbProject.this.synchronizeContextModel(new NullProgressMonitor());
		}
	}


	// ********** project "update" **********

	public CallbackSynchronizer getUpdateSynchronizer() {
		return this.updateSynchronizer;
	}

	public void setUpdateSynchronizer(CallbackSynchronizer synchronizer) {
		if (synchronizer == null) {
			throw new NullPointerException();
		}
		this.updateSynchronizer.stop();
		this.updateSynchronizer.removeListener(this.updateSynchronizerListener);
		this.setUpdateSynchronizer_(synchronizer);
	}

	protected void setUpdateSynchronizer_(CallbackSynchronizer synchronizer) {
		this.updateSynchronizer = synchronizer;
		this.updateSynchronizer.addListener(this.updateSynchronizerListener);
		this.updateSynchronizer.start();
	}

	@Override
	public void stateChanged() {
		super.stateChanged();
		this.update();
	}

	/**
	 * The JAXB project's state has changed, "update" those parts of the
	 * JAXB project that are dependent on other parts of the JAXB project.
	 * <p>
	 * Delegate to the update synchronizer so clients can configure how
	 * updates occur.
	 * <p>
	 * Ignore any <em>updates</em> that occur while we are synchronizing
	 * the context model with the resource model because we will <em>update</em>
	 * the context model at the completion of the <em>sync</em>. This is really
	 * only useful for synchronous <em>syncs</em> and <em>updates</em>; since
	 * the job scheduling rules will prevent the <em>sync</em> and
	 * <em>update</em> jobs from running concurrently.
	 * 
	 * @see #updateAndWait()
	 */
	protected void update() {
		if ( ! this.synchronizingContextModel) {
			this.updateSynchronizer.synchronize();
		}
	}

	/**
	 * Called by the update synchronizer.
	 */
	public IStatus update(IProgressMonitor monitor) {
		this.contextRoot.update();
		return Status.OK_STATUS;
	}

	/**
	 * This is the callback used by the update synchronizer to notify the JAXB
	 * project that the "update" has quiesced (i.e. the "update" has completed
	 * and there are no outstanding requests for further "updates").
	 */
 	public void updateQuiesced() {
 		//nothing yet
	}

	public void updateAndWait() {
		CallbackSynchronizer temp = this.updateSynchronizer;
		this.setUpdateSynchronizer(this.buildSynchronousUpdateSynchronizer());
		this.update();
		this.setUpdateSynchronizer(temp);
	}


	// ********** default update synchronizer (synchronous) **********

	protected CallbackSynchronizer buildSynchronousUpdateSynchronizer() {
		return new CallbackSynchronousSynchronizer(this.buildSynchronousUpdateSynchronizerCommand());
	}

	protected Command buildSynchronousUpdateSynchronizerCommand() {
		return new SynchronousUpdateSynchronizerCommand();
	}

	protected class SynchronousUpdateSynchronizerCommand
		implements Command
	{
		public void execute() {
			AbstractJaxbProject.this.update(new NullProgressMonitor());
		}
	}


	// ********** update synchronizer listener **********

	protected CallbackSynchronizer.Listener buildUpdateSynchronizerListener() {
		return new UpdateSynchronizerListener();
	}

	protected class UpdateSynchronizerListener
		implements CallbackSynchronizer.Listener
	{
		public void synchronizationQuiesced(CallbackSynchronizer synchronizer) {
			AbstractJaxbProject.this.updateQuiesced();
		}
	}
}
