/*******************************************************************************
 * 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.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.java.JavaResourceAbstractType;
import org.eclipse.jpt.jaxb.core.resource.java.JavaResourceAbstractType.Kind;
import org.eclipse.jpt.jaxb.core.resource.java.JavaResourceCompilationUnit;
import org.eclipse.jpt.jaxb.core.resource.java.JavaResourceNode;
import org.eclipse.jpt.jaxb.core.resource.java.JavaResourcePackage;
import org.eclipse.jpt.jaxb.core.resource.java.JavaResourcePackageInfoCompilationUnit;
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, 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);
		// 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();
		}
	}
}
