/*******************************************************************************
 * Copyright (c) 2006, 2016 Oracle. All rights reserved.
 * This program and the accompanying materials are made available under the
 * terms of the Eclipse Public License 2.0, which accompanies this distribution
 * and is available at https://www.eclipse.org/legal/epl-2.0/.
 * 
 * Contributors:
 *     Oracle - initial API and implementation
 ******************************************************************************/
package org.eclipse.jpt.jpa.core.internal;

import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.Hashtable;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.Vector;
import org.eclipse.core.resources.IFile;
import org.eclipse.core.resources.IFolder;
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.resources.WorkspaceJob;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IPath;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.Status;
import org.eclipse.core.runtime.content.IContentType;
import org.eclipse.core.runtime.jobs.ISchedulingRule;
import org.eclipse.core.runtime.jobs.Job;
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.IPackageFragmentRoot;
import org.eclipse.jdt.core.IType;
import org.eclipse.jdt.core.JavaCore;
import org.eclipse.jdt.core.JavaModelException;
import org.eclipse.jdt.core.dom.CompilationUnit;
import org.eclipse.jpt.common.core.ContentTypeReference;
import org.eclipse.jpt.common.core.JptResourceModel;
import org.eclipse.jpt.common.core.JptResourceModelListener;
import org.eclipse.jpt.common.core.internal.resource.java.binary.BinaryTypeCache;
import org.eclipse.jpt.common.core.internal.resource.java.source.SourceTypeCompilationUnit;
import org.eclipse.jpt.common.core.internal.utility.PackageFragmentRootTools;
import org.eclipse.jpt.common.core.internal.utility.ValidationMessageTools;
import org.eclipse.jpt.common.core.internal.utility.command.NotifyingRepeatingJobCommandWrapper;
import org.eclipse.jpt.common.core.internal.utility.command.RepeatingJobCommandWrapper;
import org.eclipse.jpt.common.core.resource.ProjectResourceLocator;
import org.eclipse.jpt.common.core.resource.java.JavaResourceAbstractType;
import org.eclipse.jpt.common.core.resource.java.JavaResourceAnnotatedElement;
import org.eclipse.jpt.common.core.resource.java.JavaResourceCompilationUnit;
import org.eclipse.jpt.common.core.resource.java.JavaResourceModel;
import org.eclipse.jpt.common.core.resource.java.JavaResourcePackage;
import org.eclipse.jpt.common.core.resource.java.JavaResourcePackageFragmentRoot;
import org.eclipse.jpt.common.core.resource.java.JavaResourcePackageInfoCompilationUnit;
import org.eclipse.jpt.common.core.resource.java.JavaResourceTypeCache;
import org.eclipse.jpt.common.core.resource.xml.JptXmlResource;
import org.eclipse.jpt.common.core.utility.command.JobCommand;
import org.eclipse.jpt.common.core.utility.command.JobCommandContext;
import org.eclipse.jpt.common.core.utility.command.NotifyingRepeatingJobCommand;
import org.eclipse.jpt.common.core.utility.command.RepeatingJobCommand;
import org.eclipse.jpt.common.utility.internal.BitTools;
import org.eclipse.jpt.common.utility.internal.ObjectTools;
import org.eclipse.jpt.common.utility.internal.StringTools;
import org.eclipse.jpt.common.utility.internal.iterable.EmptyIterable;
import org.eclipse.jpt.common.utility.internal.iterable.IterableTools;
import org.eclipse.jpt.common.utility.internal.transformer.TransformerAdapter;
import org.eclipse.jpt.common.utility.transformer.Transformer;
import org.eclipse.jpt.jpa.core.JpaDataSource;
import org.eclipse.jpt.jpa.core.JpaFile;
import org.eclipse.jpt.jpa.core.JpaModel;
import org.eclipse.jpt.jpa.core.JpaPlatform;
import org.eclipse.jpt.jpa.core.JpaPreferences;
import org.eclipse.jpt.jpa.core.JpaProject;
import org.eclipse.jpt.jpa.core.JptJpaCoreMessages;
import org.eclipse.jpt.jpa.core.context.JpaContextRoot;
import org.eclipse.jpt.jpa.core.context.java.JavaManagedTypeDefinition;
import org.eclipse.jpt.jpa.core.context.java.JavaTypeMappingDefinition;
import org.eclipse.jpt.jpa.core.internal.plugin.JptJpaCorePlugin;
import org.eclipse.jpt.jpa.core.jpa2.JpaMetamodelSynchronizer2_0;
import org.eclipse.jpt.jpa.core.jpa2.JpaProject2_0;
import org.eclipse.jpt.jpa.core.jpa2.context.JpaContextRoot2_0;
import org.eclipse.jpt.jpa.core.jpa2_1.JpaProject2_1;
import org.eclipse.jpt.jpa.core.libprov.JpaLibraryProviderInstallOperationConfig;
import org.eclipse.jpt.jpa.core.resource.ResourceMappingFile;
import org.eclipse.jpt.jpa.core.resource.orm.XmlEntityMappings;
import org.eclipse.jpt.jpa.core.resource.persistence.XmlPersistence;
import org.eclipse.jpt.jpa.core.validation.JptJpaCoreValidationMessages;
import org.eclipse.jpt.jpa.db.Catalog;
import org.eclipse.jpt.jpa.db.ConnectionProfile;
import org.eclipse.jpt.jpa.db.Database;
import org.eclipse.jpt.jpa.db.Schema;
import org.eclipse.jpt.jpa.db.SchemaContainer;
import org.eclipse.jst.common.project.facet.core.libprov.ILibraryProvider;
import org.eclipse.jst.common.project.facet.core.libprov.LibraryProviderFramework;
import org.eclipse.jst.j2ee.model.internal.validation.ValidationCancelledException;
import org.eclipse.osgi.util.NLS;
import org.eclipse.wst.common.internal.emfworkbench.WorkbenchResourceHelper;
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;

/**
 * JPA project. Holds all the JPA stuff.
 * <p>
 * The JPA platform provides the hooks for vendor-specific stuff.
 * <p>
 * The JPA files are the "resource" model (i.e. objects that correspond directly
 * to Eclipse resources; e.g. Java source code files, XML files, JAR files).
 * <p>
 * The root context node is the "context" model (i.e. objects that attempt to
 * model the JPA spec, using the "resource" model as an adapter to the Eclipse
 * resources).
 * <p>
 * The data source is an adapter to the DTP meta-data model.
 */
public abstract class AbstractJpaProject
	extends AbstractJpaModel<JpaModel>
	implements JpaProject2_1
{
	/**
	 * The JPA project manager.
	 */
	protected final Manager manager;

	/**
	 * The Eclipse project corresponding to the JPA project.
	 */
	protected final IProject project;

	protected final ProjectResourceLocator projectResourceLocator;

	/**
	 * The vendor-specific JPA platform that builds the JPA project
	 * and all its contents.
	 */
	protected final JpaPlatform jpaPlatform;

	/**
	 * key - IFile associated with the JpaFile.
	 * value - the JpaFile
	 * The JPA files associated with the JPA project:
	 *     persistence.xml
	 *     orm.xml
	 *     java
	 */
	protected final Hashtable<IFile, JpaFile> jpaFiles = new Hashtable<>();

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

	/**
	 * The "external" Java resource types (binary). Populated upon demand.
	 */
	protected final JavaResourceTypeCache externalJavaResourceTypeCache;

	/**
	 * 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 JPA project.
	 */
	protected final JpaContextRoot contextRoot;

	/**
	 * A repeating command that keeps the JPA project's context model
	 * synchronized with its resource model, either synchronously or
	 * asynchronously (or not at all), depending on the JPA project manager.
	 */
	protected volatile RepeatingJobCommand synchronizeContextModelCommand;
	protected volatile boolean synchronizingContextModel = false;

	/**
	 * A pluggable synchronizer that "updates" the JPA project, either
	 * synchronously or asynchronously (or not at all), depending on the JPA
	 * project manager.
	 */
	protected volatile NotifyingRepeatingJobCommand updateCommand;
	protected final NotifyingRepeatingJobCommand.Listener updateCommandListener;

	/**
	 * The data source that wraps the DTP model.
	 */
	// TODO move to persistence unit... :-(
	protected final JpaDataSource dataSource;

	/**
	 * A catalog name used to override the connection's default catalog.
	 */
	protected volatile String userOverrideDefaultCatalog;

	/**
	 * A schema name used to override the connection's default schema.
	 */
	protected volatile String userOverrideDefaultSchema;

	/**
	 * Flag indicating whether the project should "discover" annotated
	 * classes automatically, as opposed to requiring the classes to be
	 * listed in <code>persistence.xml</code>. Stored as a preference.
	 * @see #setDiscoversAnnotatedClasses(boolean)
	 */
	protected volatile boolean discoversAnnotatedClasses;

	/**
	 * The name of the Java project source folder that holds the generated
	 * metamodel. If the name is <code>null</code> the metamodel is not
	 * generated.
	 */
	protected volatile String metamodelSourceFolderName;


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

	protected AbstractJpaProject(JpaProject.Config config, IProgressMonitor monitor) {
		super(null);  // JPA project is the root of the containment tree
		if ((config.getJpaProjectManager() == null) || (config.getProject() == null) || (config.getJpaPlatform() == null)) {
			throw new NullPointerException();
		}
		this.manager = config.getJpaProjectManager();
		this.project = config.getProject();
		this.projectResourceLocator = this.buildProjectResourceLocator();
		this.synchronizeContextModelCommand = this.buildSynchronizeContextModelCommand();
		this.updateCommand = this.buildTempUpdateCommand(monitor);  // temporary command
		this.jpaPlatform = config.getJpaPlatform();
		this.dataSource = this.getJpaFactory().buildJpaDataSource(this, config.getConnectionProfileName());
		this.userOverrideDefaultCatalog = config.getUserOverrideDefaultCatalog();
		this.userOverrideDefaultSchema = config.getUserOverrideDefaultSchema();
		this.discoversAnnotatedClasses = config.discoverAnnotatedClasses();

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

		this.externalJavaResourceTypeCache = this.buildExternalJavaResourceTypeCache();

		if (this.isJpa2_0Compatible()) {
			this.metamodelSourceFolderName = ((JpaProject2_0.Config) config).getMetamodelSourceFolderName();
			if (this.metamodelSoureFolderNameIsInvalid()) {
				this.metamodelSourceFolderName = null;
			}
		}

		this.contextRoot = this.buildContextRoot();

		this.updateCommandListener = this.buildUpdateCommandListener();
		this.initializeContextModel();

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

	@Override
	protected boolean requiresParent() {
		return false;
	}

	@Override
	public IResource getResource() {
		return this.project;
	}

	protected ProjectResourceLocator buildProjectResourceLocator() {
		return this.project.getAdapter(ProjectResourceLocator.class);
	}

	protected JavaResourceTypeCache buildExternalJavaResourceTypeCache() {
		return new BinaryTypeCache(this.jpaPlatform.getAnnotationProvider());
	}

	protected JpaContextRoot buildContextRoot() {
		return this.getJpaFactory().buildContextRoot(this);
	}

	/**
	 * Execute a synchronous <em>sync</em> and <em>update</em> before returning
	 * from the constructor.
	 */
	protected void initializeContextModel() {
		// there *shouldn't* be any changes to the resource model yet...
		this.synchronizeContextModelCommand.start();

		// perform a synchronous update...
		this.updateCommand.start();
		this.update();
		try {
			this.updateCommand.stop();
		} catch (InterruptedException ex) {
			// the initial update is synchronous, so this shouldn't happen...
			// but let our thread know it was interrupted during a wait
			Thread.currentThread().interrupt();
		}

		// ...then delegate further updates to the JPA project manager
		this.updateCommand = this.buildUpdateCommand();
		this.updateCommand.addListener(this.updateCommandListener);
		this.updateCommand.start();
	}


	// ********** initial resource proxy visitor **********

	protected InitialResourceProxyVisitor buildInitialResourceProxyVisitor() {
		return new InitialResourceProxyVisitor();
	}

	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 :
					AbstractJpaProject.this.addJpaFileMaybe_((IFile) resource.requestResource());
					return false;  // no children
				default :
					return false;  // no children
			}
		}
		@Override
		public String toString() {
			return ObjectTools.toString(this, AbstractJpaProject.this);
		}
	}


	// ********** misc **********

	/**
	 * 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 JpaProject getJpaProject() {
		return this;
	}

	public Manager getManager() {
		return this.manager;
	}

	public String getName() {
		return this.project.getName();
	}

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

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

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

	@Override
	public JpaPlatform getJpaPlatform() {
		return this.jpaPlatform;
	}

	@SuppressWarnings("unchecked")
	protected Iterable<JavaResourceCompilationUnit> getCombinedJavaResourceCompilationUnits() {
		return IterableTools.concatenate(
					this.getInternalJavaResourceCompilationUnits(),
					this.getExternalJavaResourceCompilationUnits()
				);
	}


	// ********** database **********

	@Override
	public JpaDataSource getDataSource() {
		return this.dataSource;
	}

	public ConnectionProfile getConnectionProfile() {
		return this.dataSource.getConnectionProfile();
	}

	/**
	 * If we don't have a catalog (i.e. we don't even have a <em>default</em>
	 * catalog), then the database probably does not support catalogs.
	 */
	public Catalog getDefaultDbCatalog() {
		String catalog = this.getDefaultCatalog();
		return (catalog == null) ? null : this.resolveDbCatalog(catalog);
	}

	public String getDefaultCatalog() {
		String catalog = this.getUserOverrideDefaultCatalog();
		return (catalog != null) ? catalog : this.getDatabaseDefaultCatalog();
	}

	protected String getDatabaseDefaultCatalog() {
		Database db = this.getDatabase();
		return (db == null ) ? null : db.getDefaultCatalogIdentifier();
	}

	/**
	 * If we don't have a catalog (i.e. we don't even have a <em>default</em> catalog),
	 * then the database probably does not support catalogs; and we need to
	 * get the schema directly from the database.
	 */
	public SchemaContainer getDefaultDbSchemaContainer() {
		String catalog = this.getDefaultCatalog();
		return (catalog != null) ? this.resolveDbCatalog(catalog) : this.getDatabase();
	}

	public Schema getDefaultDbSchema() {
		SchemaContainer sc = this.getDefaultDbSchemaContainer();
		return (sc == null) ? null : sc.getSchemaForIdentifier(this.getDefaultSchema());
	}

	public String getDefaultSchema() {
		String schema = this.getUserOverrideDefaultSchema();
		if (schema != null) {
			return schema;
		}

		String catalog = this.getDefaultCatalog();
		if (catalog == null) {
			// if there is no default catalog (either user-override or database-determined),
			// the database probably does not support catalogs;
			// return the database's default schema
			return this.getDatabaseDefaultSchema();
		}

		Catalog dbCatalog = this.resolveDbCatalog(catalog);
		if (dbCatalog != null) {
			return dbCatalog.getDefaultSchemaIdentifier();
		}

		// if we could not find a catalog on the database that matches the default
		// catalog name, return the database's default schema(?) - hmmm
		return this.getDatabaseDefaultSchema();
	}

	protected String getDatabaseDefaultSchema() {
		Database db = this.getDatabase();
		return (db == null ) ? null : db.getDefaultSchemaIdentifier();
	}


	// ********** user override default catalog **********

	public String getUserOverrideDefaultCatalog() {
		return this.userOverrideDefaultCatalog;
	}

	public void setUserOverrideDefaultCatalog(String catalog) {
		String old = this.userOverrideDefaultCatalog;
		this.userOverrideDefaultCatalog = catalog;
		if (this.firePropertyChanged(USER_OVERRIDE_DEFAULT_CATALOG_PROPERTY, old, catalog)) {
			JpaPreferences.setUserOverrideDefaultCatalog(this.project, catalog);
		}
	}


	// ********** user override default schema **********

	public String getUserOverrideDefaultSchema() {
		return this.userOverrideDefaultSchema;
	}

	public void setUserOverrideDefaultSchema(String schema) {
		String old = this.userOverrideDefaultSchema;
		this.userOverrideDefaultSchema = schema;
		if (this.firePropertyChanged(USER_OVERRIDE_DEFAULT_SCHEMA_PROPERTY, old, schema)) {
			JpaPreferences.setUserOverrideDefaultSchema(this.project, schema);
		}
	}


	// ********** discover annotated classes **********

	public boolean discoversAnnotatedClasses() {
		return this.discoversAnnotatedClasses;
	}

	public void setDiscoversAnnotatedClasses(boolean discoversAnnotatedClasses) {
		boolean old = this.discoversAnnotatedClasses;
		this.discoversAnnotatedClasses = discoversAnnotatedClasses;
		JpaPreferences.setDiscoverAnnotatedClasses(this.project, discoversAnnotatedClasses);
		this.firePropertyChanged(DISCOVERS_ANNOTATED_CLASSES_PROPERTY, old, discoversAnnotatedClasses);
	}


	// ********** JPA files **********

	public Iterable<JpaFile> getJpaFiles() {
		return IterableTools.cloneLive(this.jpaFiles.values());  // read-only
	}

	public int getJpaFilesSize() {
		return this.jpaFiles.size();
	}

	protected Iterable<JpaFile> getJpaFiles(final IContentType contentType) {
		return IterableTools.filter(
				this.getJpaFiles(),
				new ContentTypeReference.ContentTypeIsKindOf(contentType)
			);
	}

	@Override
	public JpaFile getJpaFile(IFile file) {
		return file == null ? null : this.jpaFiles.get(file);
	}

	/**
	 * Add a JPA file for the specified file, if appropriate.
	 * Return true if a JPA File was created and added, false otherwise
	 */
	protected boolean addJpaFileMaybe(IFile file) {
		JpaFile jpaFile = this.addJpaFileMaybe_(file);
		if (jpaFile != null) {
			this.fireItemAdded(JPA_FILES_COLLECTION, jpaFile);
			return true;
		}
		return false;
	}

	/**
	 * Add a JPA file for the specified file, if appropriate, without firing
	 * an event; useful during construction.
	 * Return the new JPA file, null if it was not created.
	 */
	protected JpaFile addJpaFileMaybe_(IFile file) {
		if (this.fileIsJavaRelated(file)) {
			if ( ! this.getJavaProject().isOnClasspath(file)) {
				return null;  // java-related files must be on the Java classpath
			}
		}
		else if ( ! this.fileResourceLocationIsValid(file)) {
			return null;
		}

		JpaFile jpaFile = this.buildJpaFile(file);
		if (jpaFile == null) {
			return null;
		}
		jpaFile.getResourceModel().addResourceModelListener(this.resourceModelListener);
		this.jpaFiles.put(file, jpaFile);
		return jpaFile;
	}

	/**
	 * <code>.java</code> or <code>.jar</code>
	 */
	protected boolean fileIsJavaRelated(IFile file) {
		IContentType contentType = getContentType(file);
		return (contentType != null) && this.contentTypeIsJavaRelated(contentType);
	}

	/**
	 * pre-condition: content type is not <code>null</code>
	 */
	protected boolean contentTypeIsJavaRelated(IContentType contentType) {
		return contentType.isKindOf(JavaResourceCompilationUnit.CONTENT_TYPE) ||
				contentType.isKindOf(JavaResourcePackageFragmentRoot.JAR_CONTENT_TYPE);
	}

	protected boolean fileResourceLocationIsValid(IFile file) {
		return this.projectResourceLocator.locationIsValid(file.getParent());
	}

	/**
	 * Log any developer exceptions and don't build a JPA file rather
	 * than completely failing to build the JPA Project.
	 */
	protected JpaFile buildJpaFile(IFile file) {
		try {
			return this.getJpaPlatform().buildJpaFile(this, file);
		} catch (Exception ex) {
			JptJpaCorePlugin.instance().logError(ex, "Error building JPA file: " + file.getFullPath()); //$NON-NLS-1$
			return null;
		}
	}

	/**
	 * Remove the JPA file corresponding to the specified IFile, if it exists.
	 * Return true if a JPA File was removed, false otherwise
	 */
	protected boolean removeJpaFile(IFile file) {
		JpaFile jpaFile = this.getJpaFile(file);
		if (jpaFile != null) {  // a JpaFile is not added for every IFile
			this.removeJpaFile(jpaFile);
			return true;
		}
		return false;
	}

	/**
	 * Stop listening to the JPA file and remove it.
	 */
	protected void removeJpaFile(JpaFile jpaFile) {
		jpaFile.getResourceModel().removeResourceModelListener(this.resourceModelListener);
		if (this.jpaFiles.remove(jpaFile.getFile()) == null) {
			throw new IllegalArgumentException(jpaFile.toString());
		}
		this.fireItemRemoved(JPA_FILES_COLLECTION, jpaFile);
	}


	// ********** external Java resource types (source or binary) **********

	protected JavaResourceAbstractType buildExternalJavaResourceType(String typeName) {
		IType jdtType = this.findType(typeName);
		return (jdtType == null) ? null : this.buildExternalJavaResourceType(jdtType);
	}

	/**
	 * If the Java project has a class named <code>Foo</code> in the default package,
	 * {@link IJavaProject#findType(String)} will return the {@link IType}
	 * corresponding to <code>Foo</code> if the named passed to it is <code>".Foo"</code>.
	 * This is not what we are expecting! So we had to put in a check for any
	 * type name beginning with <code>'.'</code>.
	 * See JDT bug 377710.
	 */
	protected IType findType(String typeName) {
		try {
			return typeName.startsWith(".") ? null : this.getJavaProject().findType(typeName); //$NON-NLS-1$
		} catch (JavaModelException ex) {
			return null;  // ignore exception? resource exception was probably already logged by JDT
		}
	}

	protected JavaResourceAbstractType buildExternalJavaResourceType(IType jdtType) {
		return jdtType.isBinary() ?
				this.buildBinaryExternalJavaResourceType(jdtType) :
				this.buildSourceExternalJavaResourceType(jdtType);
	}

	protected JavaResourceAbstractType buildBinaryExternalJavaResourceType(IType jdtType) {
		return this.externalJavaResourceTypeCache.addType(jdtType);
	}

	protected JavaResourceAbstractType buildSourceExternalJavaResourceType(IType jdtType) {
		JavaResourceCompilationUnit jrcu = this.getExternalJavaResourceCompilationUnit(jdtType.getCompilationUnit());
		String jdtTypeName = jdtType.getFullyQualifiedName('.');  // JDT member type names use '$'
		for (JavaResourceAbstractType jrat : jrcu.getTypes()) {
			if (jrat.getTypeBinding().getQualifiedName().equals(jdtTypeName)) {
				return jrat;
			}
		}
		// 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 JavaResourceTypeCache getExternalJavaResourceTypeCache() {
		return this.externalJavaResourceTypeCache;
	}


	// ********** external Java resource compilation units (source) **********

	public Iterable<JavaResourceCompilationUnit> getExternalJavaResourceCompilationUnits() {
		return IterableTools.cloneLive(this.externalJavaResourceCompilationUnits);  // read-only
	}

	public int getExternalJavaResourceCompilationUnitsSize() {
		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.manager.getModifySharedDocumentCommandContext()
				);
	}

	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 JpaContextRoot getContextRoot() {
		return this.contextRoot;
	}


	// ********** utility **********

	public IFile getPlatformFile(IPath runtimePath) {
		return this.projectResourceLocator.getPlatformFile(runtimePath);
	}


	// ********** XML files **********

	public JptXmlResource getPersistenceXmlResource() {
		return (JptXmlResource) this.getResourceModel(
				XmlPersistence.DEFAULT_RUNTIME_PATH,
				XmlPersistence.CONTENT_TYPE
			);
	}

	public JptXmlResource getDefaultOrmXmlResource() {
		return this.getMappingFileXmlResource(XmlEntityMappings.DEFAULT_RUNTIME_PATH);
	}

	public JptXmlResource getMappingFileXmlResource(IPath runtimePath) {
		return (JptXmlResource) this.getResourceModel(runtimePath, ResourceMappingFile.Root.CONTENT_TYPE);
	}

	/**
	 * 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 JptResourceModel getResourceModel(IPath runtimePath, IContentType contentType) {
		IFile file = this.getPlatformFile(runtimePath);
		return ((file != null) && 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 JptResourceModel getResourceModel(IFile file, IContentType contentType) {
		JpaFile jpaFile = this.getJpaFile(file);
		return (jpaFile == null) ? null : jpaFile.getResourceModel(contentType);
	}


	// ********** annotated Java source classes **********

	/**
	 * Return only those valid annotated Java resource types that are
	 * directly part of the JPA project, ignoring those in JARs referenced in
	 * <code>persistence.xml</code>.
	 * @see JavaResourceAbstractType#isAnnotated()
	 */
	public Iterable<JavaResourceAbstractType> getAnnotatedJavaSourceTypes() {
		// i.e. the type has a valid JPA type annotation
		return IterableTools.filter(this.getInternalSourceJavaResourceTypes(), JavaResourceAnnotatedElement.IS_ANNOTATED);
	}

	/**
	 * Return only the types of those valid <em>managed</em> (i.e. annotated with
	 * <code>@Entity</code>, <code>@Embeddable</code>, <code>@Converter</code>etc.) 
	 * Java resource types that are directly part of the JPA project, ignoring
	 * those in JARs referenced in <code>persistence.xml</code>.
	 */
	public Iterable<JavaResourceAbstractType> getPotentialJavaSourceTypes() {
		return getInternalPotentialSourceJavaResourceTypes();
	}

	/**
	 * Return only those valid <em>managed</em> (i.e. annotated with
	 * <code>@Entity</code>, <code>@Embeddable</code>, <code>@Converter</code>etc.) Java resource
	 * types that are directly part of the JPA project, ignoring
	 * those in JARs referenced in <code>persistence.xml</code>.
	 */
	protected Iterable<JavaResourceAbstractType> getInternalPotentialSourceJavaResourceTypes() {
		Iterable<String> annotationNames = this.getManagedTypeAnnotationNames();
		return IterableTools.filter(
				this.getAnnotatedJavaSourceTypes(),
				new JavaResourceAnnotatedElement.IsAnnotatedWithAnyOf(annotationNames)
			);
	}

	public Iterable<String> getTypeMappingAnnotationNames() {
		return IterableTools.transform(this.getJpaPlatform().getJavaTypeMappingDefinitions(), JavaTypeMappingDefinition.ANNOTATION_NAME_TRANSFORMER);
	}

	public Iterable<String> getManagedTypeAnnotationNames() {
		return IterableTools.concatenate(
				IterableTools.transform(
					this.getJpaPlatform().getJavaManagedTypeDefinitions(), 
					new JavaManagedTypeDefinition.AnnotationNamesTransformer(this.getJpaProject())));		
	}

	/**
	 * Return only those Java resource persistent types that are directly
	 * part of the JPA project, ignoring those in JARs referenced in
	 * <code>persistence.xml</code>
	 */
	protected Iterable<JavaResourceAbstractType> getInternalSourceJavaResourceTypes() {
		// get *all* the types in each compilation unit
		return IterableTools.children(this.getInternalJavaResourceCompilationUnits(), JavaResourceModel.Root.TYPES_TRANSFORMER);
	}

	/**
	 * Return the JPA project's resource compilation units.
	 */
	protected Iterable<JavaResourceCompilationUnit> getInternalJavaResourceCompilationUnits() {
		return IterableTools.downCast(IterableTools.transform(this.getJavaSourceJpaFiles(), JpaFile.RESOURCE_MODEL_TRANSFORMER));
	}

	/**
	 * Return the JPA project's JPA files with Java source <em>content</em>.
	 */
	protected Iterable<JpaFile> getJavaSourceJpaFiles() {
		return this.getJpaFiles(JavaResourceCompilationUnit.CONTENT_TYPE);
	}


	// ********** Java resource persistent type look-up **********

	public JavaResourceAbstractType getJavaResourceType(String typeName) {
		for (JavaResourceAbstractType jraType : this.getJavaResourceTypes()) {
			if (jraType.getTypeBinding().getQualifiedName().equals(typeName)) {
				return jraType;
			}
		}
		// if we don't have a type already, try to build new one from the project classpath
		return this.buildExternalJavaResourceType(typeName);
	}

	public JavaResourceAbstractType getJavaResourceType(String typeName, JavaResourceAnnotatedElement.AstNodeType astNodeType) {
		JavaResourceAbstractType resourceType = this.getJavaResourceType(typeName);
		if ((resourceType == null) || (resourceType.getAstNodeType() != astNodeType)) {
			return null;
		}
		return resourceType;
	}


	/**
	 * return *all* the Java resource persistent types, including those in JARs referenced in
	 * persistence.xml
	 */
	protected Iterable<JavaResourceAbstractType> getJavaResourceTypes() {
		return IterableTools.children(this.getJavaResourceModelRoots(), JavaResourceModel.Root.TYPES_TRANSFORMER);
	}

	@SuppressWarnings("unchecked")
	protected Iterable<JavaResourceModel.Root> getJavaResourceModelRoots() {
		return IterableTools.concatenate(
					this.getInternalJavaResourceCompilationUnits(),
					this.getInternalJavaResourcePackageFragmentRoots(),
					this.getExternalJavaResourceCompilationUnits(),
					Collections.singleton(this.externalJavaResourceTypeCache)
				);
	}


	// ********** Java resource persistent package look-up **********

	public JavaResourcePackage getJavaResourcePackage(String packageName) {
		for (JavaResourcePackage jrp : this.getJavaResourcePackages()) {
			String name = jrp.getName();
			// name can be null if package name is wrong(?)
			if ((name != null) && name.equals(packageName)) {
				return jrp;
			}
		}
		return null;
	}

	public Iterable<JavaResourcePackage> getJavaResourcePackages(){
		return IterableTools.removeNulls(IterableTools.transform(this.getPackageInfoSourceJpaFiles(), JPA_FILE_JAVA_RESOURCE_PACKAGE_TRANSFORMER));
	}

	protected static final Transformer<JpaFile, JavaResourcePackage> JPA_FILE_JAVA_RESOURCE_PACKAGE_TRANSFORMER = new JpaFileJavaResourcePackageTransformer();
	public static class JpaFileJavaResourcePackageTransformer
		extends TransformerAdapter<JpaFile, JavaResourcePackage>
	{
		@Override
		public JavaResourcePackage transform(JpaFile jpaFile) {
			return ((JavaResourcePackageInfoCompilationUnit) jpaFile.getResourceModel()).getPackage();
		}
	}

	/**
	 * return JPA files with package-info source "content"
	 */
	protected Iterable<JpaFile> getPackageInfoSourceJpaFiles() {
		return this.getJpaFiles(JavaResourceCompilationUnit.PACKAGE_INFO_CONTENT_TYPE);
	}


	// ********** JARs **********

	// TODO
	public JavaResourcePackageFragmentRoot getJavaResourcePackageFragmentRoot(String jarFileName) {
//		return this.getJarResourcePackageFragmentRoot(this.convertToPlatformFile(jarFileName));
		return this.getJavaResourcePackageFragmentRoot(this.project.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 IterableTools.downCast(IterableTools.transform(this.getJarJpaFiles(), JpaFile.RESOURCE_MODEL_TRANSFORMER));
	}

	/**
	 * return JPA files with JAR "content"
	 */
	public Iterable<JpaFile> getJarJpaFiles() {
		return this.getJpaFiles(JavaResourcePackageFragmentRoot.JAR_CONTENT_TYPE);
	}


	// ********** metamodel **********

	public Iterable<JavaResourceAbstractType> getGeneratedMetamodelTopLevelTypes() {
		if (this.metamodelSourceFolderName == null) {
			return EmptyIterable.instance();
		}
		IPackageFragmentRoot genSourceFolder = this.getMetamodelPackageFragmentRoot();
		return IterableTools.filter(
				this.getInternalSourceJavaResourceTypes(),
				new JpaMetamodelSynchronizer2_0.MetamodelTools.IsGeneratedMetamodelTopLevelType(genSourceFolder)
			);
	}

	public JavaResourceAbstractType getGeneratedMetamodelTopLevelType(IFile file) {
		JavaResourceCompilationUnit jrcu = this.getJavaResourceCompilationUnit(file);
		if (jrcu == null) {
			return null;  // hmmm...
		}
		JavaResourceAbstractType primaryType = jrcu.getPrimaryType();
		if (primaryType == null) {
			return null;  // no types in the file
		}
		return JpaMetamodelSynchronizer2_0.MetamodelTools.isGeneratedMetamodelTopLevelType(primaryType) ? primaryType : null;
	}

	protected JavaResourceCompilationUnit getJavaResourceCompilationUnit(IFile file) {
		return (JavaResourceCompilationUnit) this.getResourceModel(file, JavaResourceCompilationUnit.CONTENT_TYPE);
	}

	public String getMetamodelSourceFolderName() {
		return this.metamodelSourceFolderName;
	}

	public void setMetamodelSourceFolderName(String folderName) {
		if (this.setMetamodelSourceFolderName_(folderName)) {
			JpaPreferences.setMetamodelSourceFolderName(this.project, folderName);
			if (folderName == null) {
				this.disposeMetamodel();
			} else {
				this.initializeMetamodel();
			}
		}
	}

	protected boolean setMetamodelSourceFolderName_(String folderName) {
		String old = this.metamodelSourceFolderName;
		this.metamodelSourceFolderName = folderName;
		return this.firePropertyChanged(METAMODEL_SOURCE_FOLDER_NAME_PROPERTY, old, folderName);
	}

	protected void initializeMetamodel() {
		((JpaContextRoot2_0) this.contextRoot).initializeMetamodel();
	}

	/**
	 * Synchronize the metamodel for 2.0-compatible JPA projects.
	 */
	protected void synchronizeMetamodel() {
		if (this.isJpa2_0Compatible()) {
			if (this.metamodelSourceFolderName != null) {
				this.scheduleSynchronizeMetamodelJob();
			}
		}
	}

	/**
	 * We dispatch a job even when the JPA project manager is "synchronous"
	 * because we will synchronously execute an update when we receive a
	 * resource change event that is fired when a file is changed; and we
	 * cannot modify another file in response to a file change because the
	 * rules are incompatible. For example, if the <code>persistence.xml</code>
	 * file changes, we will receive a resource change event while the
	 * <code>persistence.xml</code> file is locked. We will not be able to
	 * lock and modify the necessary metamodel source files under this lock.
	 */
	protected void scheduleSynchronizeMetamodelJob() {
		this.buildSynchronizeMetamodelJob().schedule();
	}

	protected Job buildSynchronizeMetamodelJob() {
		Job job = this.buildSynchronizeMetamodelJob_();
		// lock the project so we are synchronized with the JPA project manager
		job.setRule(this.project);
		return job;
	}

	protected Job buildSynchronizeMetamodelJob_() {
		return new SynchronizeMetamodelJob(this.buildSynchronizeMetamodelJobName());
	}

	protected String buildSynchronizeMetamodelJobName() {
		return NLS.bind(JptJpaCoreMessages.METAMODEL_SYNC_JOB_NAME, this.getName());
	}

	/**
	 * Use a {@link WorkspaceJob} to
	 * suppress the resource change events until we are finished synchronizing
	 * the metamodel.
	 */
	protected class SynchronizeMetamodelJob
		extends WorkspaceJob
	{
		protected SynchronizeMetamodelJob(String name) {
			super(name);
		}
		@Override
		public IStatus runInWorkspace(IProgressMonitor monitor) throws CoreException {
			return AbstractJpaProject.this.synchronizeMetamodel_(monitor);
		}
		@Override
		public String toString() {
			return ObjectTools.toString(this, AbstractJpaProject.this);
		}
	}

	/**
	 * Called by the {@link SynchronizeMetamodelJob#runInWorkspace(IProgressMonitor)}.
	 */
	protected IStatus synchronizeMetamodel_(IProgressMonitor monitor) {
		return ((JpaContextRoot2_0) this.contextRoot).synchronizeMetamodel(monitor);
	}

	protected void disposeMetamodel() {
		((JpaContextRoot2_0) this.contextRoot).disposeMetamodel();
	}

	public IPackageFragmentRoot getMetamodelPackageFragmentRoot() {
		return this.getJavaProject().getPackageFragmentRoot(this.getMetaModelSourceFolder());
	}

	protected IFolder getMetaModelSourceFolder() {
		return this.project.getFolder(this.metamodelSourceFolderName);
	}

	/**
	 * If the metamodel source folder is no longer a Java project source
	 * folder, clear it out.
	 */
	protected void checkMetamodelSourceFolderName() {
		if (this.metamodelSoureFolderNameIsInvalid()) {
			this.setMetamodelSourceFolderName(null);
		}
	}

	protected boolean metamodelSoureFolderNameIsInvalid() {
		return ! this.metamodelSourceFolderNameIsValid();
	}

	protected boolean metamodelSourceFolderNameIsValid() {
		return IterableTools.contains(this.getJavaSourceFolderNames(), this.metamodelSourceFolderName);
	}


	// ********** Java source folder names **********

	public Iterable<String> getJavaSourceFolderNames() {
		try {
			return this.getJavaSourceFolderNames_();
		} catch (JavaModelException ex) {
			JptJpaCorePlugin.instance().logError(ex);
			return EmptyIterable.instance();
		}
	}

	protected Iterable<String> getJavaSourceFolderNames_() throws JavaModelException {
		return IterableTools.transform(this.getJavaSourceFolders(), PACKAGE_FRAGMENT_ROOT_PATH_TRANSFORMER);
	}

	protected static final Transformer<IPackageFragmentRoot, String> PACKAGE_FRAGMENT_ROOT_PATH_TRANSFORMER = new PackageFragmentRootPathTransformer();
	public static class PackageFragmentRootPathTransformer
		extends TransformerAdapter<IPackageFragmentRoot, String>
	{
		@Override
		public String transform(IPackageFragmentRoot pfr) {
			try {
				return this.transform_(pfr);
			} catch (JavaModelException ex) {
				return "Error: " + pfr.getPath(); //$NON-NLS-1$
			}
		}
		protected String transform_(IPackageFragmentRoot pfr) throws JavaModelException {
			return pfr.getUnderlyingResource().getProjectRelativePath().toString();
		}
	}

	protected Iterable<IPackageFragmentRoot> getJavaSourceFolders() throws JavaModelException {
		return IterableTools.filter(
				this.getPackageFragmentRoots(),
				PackageFragmentRootTools.IS_SOURCE_FOLDER
			);
	}

	protected Iterable<IPackageFragmentRoot> getPackageFragmentRoots() throws JavaModelException {
		return IterableTools.iterable(this.getJavaProject().getPackageFragmentRoots());
	}


	// ********** 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)}.
	 * 
	 * <br> <b>
	 * This code has been copied and modified in InternalJpaProjectManager, so make sure
	 * to make changes in both locations.
	 * </b>
	 * @see InternalJpaProjectManager#javaElementChanged(ElementChangedEvent)
	 */
	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 static 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 (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.checkMetamodelSourceFolderName();
			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 (JpaFile jpaFile : this.getJpaFiles()) {
			if (this.jpaFileIsDead(jpaFile)) {
				this.removeJpaFile(jpaFile);
			}
		}
	}

	protected boolean jpaFileIsDead(JpaFile jpaFile) {
		return ! this.jpaFileIsAlive(jpaFile);
	}

	/**
	 * 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 jpaFileIsAlive(JpaFile jpaFile) {
		IFile file = jpaFile.getFile();
		if ( ! file.exists()) {
			return false;
		}
		if (this.fileIsJavaRelated(file)) {
			return this.getJavaProject().isOnClasspath(file);
		}
		return this.fileResourceLocationIsValid(file);
	}

	/**
	 * pre-condition:
	 * delta.getElement().getElementType() == IJavaElement.JAVA_PROJECT
	 */
	protected static boolean classpathHasChanged(IJavaElementDelta delta) {
		return 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 (classpathEntryHasBeenAdded(delta)) {
			// TODO bug 277218
		} else if (classpathEntryHasBeenRemoved(delta)) {  // should be mutually-exclusive w/added (?)
			// TODO bug 277218
		}
	}

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

	/**
	 * pre-condition:
	 * delta.getElement().getElementType() == IJavaElement.PACKAGE_FRAGMENT_ROOT
	 */
	protected static boolean classpathEntryHasBeenRemoved(IJavaElementDelta delta) {
		return 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 (javaCompilationUnitDeltaIsRelevant(delta)) {
			ICompilationUnit compilationUnit = (ICompilationUnit) delta.getElement();
			for (JavaResourceCompilationUnit jrcu : this.getCombinedJavaResourceCompilationUnits()) {
				if (jrcu.getCompilationUnit().equals(compilationUnit)) {
					CompilationUnit astRoot = delta.getCompilationUnitAST(); //this will be null for POST_CHANGE jdt events
					//I don't think we can guarantee hasResolvedBindings() is true, so check for this and don't pass it in if false.
					if (astRoot != null && astRoot.getAST().hasResolvedBindings()) { 

						jrcu.synchronizeWithJavaSource(astRoot);
					}
					else {
						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 static boolean javaCompilationUnitDeltaIsRelevant(IJavaElementDelta delta) {
		// ignore Java notification for ADDED or REMOVED;
		// these are handled via resource notification
		if (delta.getKind() != IJavaElementDelta.CHANGED) {
			return false;
		}

		// 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 when the compilation unit's resource is deleted;
		// because the AST parser will log an exception for the missing file. 
		// IJavaElementDelta.F_PRIMARY_RESOURCE is the only flag set when refactor
		// renaming a type directly in the java editor when the file is modified..
		// IJavaElementDelta.F_AST_AFFECTED is the only flag set when I refactor
		// rename a type directly in the java editor and the file is *not* modified.
		if (BitTools.onlyFlagIsSet(delta.getFlags(), IJavaElementDelta.F_PRIMARY_RESOURCE)
			|| BitTools.onlyFlagIsSet(delta.getFlags(), IJavaElementDelta.F_AST_AFFECTED)) {
			ICompilationUnit compilationUnit = (ICompilationUnit) delta.getElement();
			if ( !compilationUnitResourceExists(compilationUnit)) {
				return false;
			}
		}

		return true;
	}


	protected static boolean compilationUnitResourceExists(ICompilationUnit compilationUnit) {
		try {
			return compilationUnit.getCorrespondingResource().exists();
		} catch (JavaModelException ex) {
			return false;
		}
	}


	// ********** validation **********

	public Iterable<IMessage> getValidationMessages(IReporter reporter) {
		ArrayList<IMessage> messages = new ArrayList<>();
		this.validate(messages, reporter);
		return messages;
	}

	// TODO about the only use for the reporter is to check for cancellation;
	// we should check for cancellation...
	protected void validate(List<IMessage> messages, IReporter reporter) {
		if (reporter.isCancelled()) {
			throw new ValidationCancelledException();
		}
		this.validateLibraryProvider(messages);
		this.validateConnection(messages);
		this.contextRoot.validate(messages, reporter);
	}

	protected void validateLibraryProvider(List<IMessage> messages) {
		try {
			this.validateLibraryProvider_(messages);
		} catch (CoreException ex) {
			JptJpaCorePlugin.instance().logError(ex);
		}
	}

	protected void validateLibraryProvider_(List<IMessage> messages) throws CoreException {
		Map<String, Object> enablementVariables = new HashMap<>();
		enablementVariables.put(JpaLibraryProviderInstallOperationConfig.JPA_PLATFORM_ENABLEMENT_EXP, this.getJpaPlatform().getId());
		enablementVariables.put(JpaLibraryProviderInstallOperationConfig.JPA_PLATFORM_DESCRIPTION_ENABLEMENT_EXP, this.getJpaPlatform().getConfig());

		ILibraryProvider libraryProvider = LibraryProviderFramework.getCurrentProvider(this.project, JpaProject.FACET);
		IFacetedProject facetedProject = ProjectFacetsManager.create(this.project);
		IProjectFacetVersion facetVersion = facetedProject.getInstalledVersion(JpaProject.FACET);
		if ( ! libraryProvider.isEnabledFor(facetedProject, facetVersion, enablementVariables)) {
			messages.add(
				ValidationMessageTools.buildValidationMessage(
					this.getResource(),
					JptJpaCoreValidationMessages.PROJECT_INVALID_LIBRARY_PROVIDER
				)
			);
		}
	}

	protected void validateConnection(List<IMessage> messages) {
		String cpName = this.dataSource.getConnectionProfileName();
		if (StringTools.isBlank(cpName)) {
			messages.add(
				ValidationMessageTools.buildValidationMessage(
					this.getResource(),
					JptJpaCoreValidationMessages.PROJECT_NO_CONNECTION
				)
			);
			return;
		}
		ConnectionProfile cp = this.dataSource.getConnectionProfile();
		if (cp == null) {
			messages.add(
				ValidationMessageTools.buildValidationMessage(
					this.getResource(),
					JptJpaCoreValidationMessages.PROJECT_INVALID_CONNECTION,
					cpName
				)
			);
			return;
		}
		if (cp.isInactive()) {
			messages.add(
				ValidationMessageTools.buildValidationMessage(
					this.getResource(),
					JptJpaCoreValidationMessages.PROJECT_INACTIVE_CONNECTION,
					cpName
				)
			);
		}
	}


	// ********** dispose **********

	public void dispose() {
		this.stopCommand(this.synchronizeContextModelCommand);
		this.stopCommand(this.updateCommand);
		this.updateCommand.removeListener(this.updateCommandListener);
		this.dataSource.dispose();
		// the XML resources are held indefinitely by the WTP translator framework,
		// so we better remove our listener or the JPA project will not be GCed
		for (JpaFile jpaFile : this.getJpaFiles()) {
			jpaFile.getResourceModel().removeResourceModelListener(this.resourceModelListener);
		}
	}

	protected void stopCommand(RepeatingJobCommand command) {
		try {
			command.stop();
		} catch (InterruptedException ex) {
			// allow the dispose to complete;
			// but let our thread know it was interrupted during a wait
			Thread.currentThread().interrupt();
		}
	}


	// ********** resource model listener **********

	protected JptResourceModelListener buildResourceModelListener() {
		return new ResourceModelListener();
	}

	protected class ResourceModelListener
		implements JptResourceModelListener
	{
		protected ResourceModelListener() {
			super();
		}
		public void resourceModelChanged(JptResourceModel jpaResourceModel) {
//			String msg = Thread.currentThread() + " resource model change: " + jpaResourceModel;
//			System.out.println(msg);
//			new Exception(msg).printStackTrace(System.out);
			AbstractJpaProject.this.synchronizeContextModel(jpaResourceModel);
		}

		public void resourceModelReverted(JptResourceModel jpaResourceModel) {
			IFile file = WorkbenchResourceHelper.getFile((JptXmlResource)jpaResourceModel);
			AbstractJpaProject.this.removeJpaFile(file);
			AbstractJpaProject.this.addJpaFileMaybe(file);
		}

		public void resourceModelUnloaded(JptResourceModel jpaResourceModel) {
			IFile file = WorkbenchResourceHelper.getFile((JptXmlResource)jpaResourceModel);
			AbstractJpaProject.this.removeJpaFile(file);
			if (file.exists()) { //false if file delete caused the unload event
				//go ahead and re-add the JPA file here, otherwise a resource change event
				//will cause it to be added.
				AbstractJpaProject.this.addJpaFileMaybe(file);
			}
		}

		@Override
		public String toString() {
			return ObjectTools.toString(this, AbstractJpaProject.this);
		}
	}

	/**
	 * Called from {@link ResourceModelListener#resourceModelChanged(JptResourceModel)}.
	 */
	// TODO pass down the resource model (for a possible optimization?)
	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.project)) {
			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 InternalResourceDeltaVisitor();
	}

	protected class InternalResourceDeltaVisitor
		extends ResourceDeltaVisitor
	{
		protected InternalResourceDeltaVisitor() {
			super();
		}
		@Override
		public boolean fileChangeIsSignificant(IFile file, int deltaKind) {
			return AbstractJpaProject.this.synchronizeJpaFiles(file, deltaKind);
		}
		@Override
		public String toString() {
			return ObjectTools.toString(this, AbstractJpaProject.this);
		}
	}

	/**
	 * Internal resource delta visitor callback.
	 * Return true if a JpaFile was either added or removed.
	 */
	protected boolean synchronizeJpaFiles(IFile file, int deltaKind) {
		switch (deltaKind) {
			case IResourceDelta.ADDED :
				return this.addJpaFileMaybe(file);
			case IResourceDelta.REMOVED :
				return this.removeJpaFile(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) {
		JpaFile jpaFile = this.getJpaFile(file);
		if (jpaFile == null) {
			// the file might have changed its content to something significant to Dali
			return this.addJpaFileMaybe(file);
		}

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

		// the content type changed, we need to remove the old JPA file and build a new one
		// (e.g. the schema of an orm.xml file changed from JPA to EclipseLink)
		this.removeJpaFile(jpaFile);
		this.addJpaFileMaybe(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 ExternalResourceDeltaVisitor();
	}

	protected class ExternalResourceDeltaVisitor
		extends ResourceDeltaVisitor
	{
		protected ExternalResourceDeltaVisitor() {
			super();
		}
		@Override
		public boolean fileChangeIsSignificant(IFile file, int deltaKind) {
			return AbstractJpaProject.this.synchronizeExternalFiles(file, deltaKind);
		}
		@Override
		public String toString() {
			return ObjectTools.toString(this, AbstractJpaProject.this);
		}
	}

	/**
	 * 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 = getContentType(file);
		if (contentType == null) {
			return false;
		}
		if (contentType.equals(JavaResourceCompilationUnit.CONTENT_TYPE)) {
			return true;
		}
		if (contentType.equals(JavaResourcePackageFragmentRoot.JAR_CONTENT_TYPE)) {
			return true;
		}
		return false;
	}

	protected boolean externalFileRemoved(IFile file) {
		IContentType contentType = getContentType(file);
		if (contentType == null) {
			return false;
		}
		if (contentType.equals(JavaResourceCompilationUnit.CONTENT_TYPE)) {
			return this.removeExternalJavaResourceCompilationUnit(file);
		}
		if (contentType.equals(JavaResourcePackageFragmentRoot.JAR_CONTENT_TYPE)) {
			return this.externalJavaResourceTypeCache.removeTypes(file);
		}
		return false;
	}

	protected IContentType getContentType(IFile file) {
		return this.getJpaPlatform().getContentType(file);
	}

	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;
		}

		@Override
		public String toString() {
			return ObjectTools.toString(this, AbstractJpaProject.this);
		}
	}


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

	protected RepeatingJobCommand buildSynchronizeContextModelCommand() {
		return new RepeatingJobCommandWrapper(
					this.buildSynchronizeContextModelJobCommand(),
					this.buildStartSynchronizeContextModelJobCommandContext(),
					JptJpaCorePlugin.instance().getExceptionHandler()
				);
	}

	protected JobCommand buildSynchronizeContextModelJobCommand() {
		return new SynchronizeContextModelJobCommand();
	}

	protected JobCommandContext buildStartSynchronizeContextModelJobCommandContext() {
		return new ManagerJobCommandContext(this.buildSynchronizeContextModelJobName());
	}

	protected String buildSynchronizeContextModelJobName() {
		return NLS.bind(JptJpaCoreMessages.CONTEXT_MODEL_SYNC_JOB_NAME, this.getName());
	}

	/**
	 * The JPA project's resource model has changed; synchronize the JPA
	 * project's context model with it. This method is typically called when the
	 * resource model state has changed when it is synchronized with its
	 * underlying Eclipse resource as the result of an Eclipse resource change
	 * event. This method can also be called when a client (e.g. a JUnit test
	 * case) has manipulated the resource model via its API (as opposed to
	 * modifying the underlying Eclipse resource directly) and needs the context
	 * model to be synchronized accordingly (since manipulating the resource
	 * model via its API will not trigger this method). Whether the context
	 * model is synchronously (or asynchronously) depends on the JPA project
	 * manager.
	 */
	public void synchronizeContextModel() {
		try {
			this.synchronizingContextModel = true;
			this.synchronizeContextModelCommand.execute(null);  // this progress monitor is ignored
		} finally {
			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 JPA project is automatically
		// discovering annotated classes); so we explicitly execute an update
		// here to discover those changes.
		// TODO change sync so it will *always* trigger an update?
		this.update();
	}

	protected class SynchronizeContextModelJobCommand
		implements JobCommand
	{
		public IStatus execute(IProgressMonitor monitor) {
			return AbstractJpaProject.this.synchronizeContextModel(monitor);
		}
		@Override
		public String toString() {
			return ObjectTools.toString(this, AbstractJpaProject.this);
		}
	}

	/**
	 * Called by the {@link SynchronizeContextModelJobCommand#execute(IProgressMonitor)}.
	 */
	protected IStatus synchronizeContextModel(IProgressMonitor monitor) {
		if (monitor.isCanceled()) {
			return Status.CANCEL_STATUS;
		}
		this.contextRoot.synchronizeWithResourceModel(monitor);
		if (monitor.isCanceled()) {
			return Status.CANCEL_STATUS;
		}
		return Status.OK_STATUS;
	}


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

	/**
	 * The first update is executed synchronously during construction.
	 * Once that is complete, we delegate to the JPA project manager.
	 */
	protected NotifyingRepeatingJobCommand buildTempUpdateCommand(IProgressMonitor monitor) {
		return new NotifyingRepeatingJobCommandWrapper(
					this.buildUpdateJobCommand(),
					this.buildTempStartUpdateJobCommandContext(monitor),
					JptJpaCorePlugin.instance().getExceptionHandler()
				);
	}

	protected JobCommandContext buildTempStartUpdateJobCommandContext(IProgressMonitor monitor) {
		return new TempUpdateJobCommandContext(monitor);
	}

	protected NotifyingRepeatingJobCommand buildUpdateCommand() {
		return new NotifyingRepeatingJobCommandWrapper(
					this.buildUpdateJobCommand(),
					this.buildStartUpdateJobCommandContext(),
					JptJpaCorePlugin.instance().getExceptionHandler()
				);
	}

	protected JobCommand buildUpdateJobCommand() {
		return new UpdateJobCommand();
	}

	protected JobCommandContext buildStartUpdateJobCommandContext() {
		return new ManagerJobCommandContext(this.buildUpdateJobName());
	}

	protected String buildUpdateJobName() {
		return NLS.bind(JptJpaCoreMessages.UPDATE_JOB_NAME, this.getName());
	}

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

	/**
	 * The JPA project's state has changed, "update" those parts of the
	 * JPA project that are dependent on other parts of the JPA project.
	 * <p>
	 * Delegate to the JPA project manager 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.
	 */
	protected void update() {
		if ( ! this.synchronizingContextModel) {
			this.updateCommand.execute(null);  // this progress monitor is ignored
		}
	}

	protected class UpdateJobCommand
		implements JobCommand
	{
		public IStatus execute(IProgressMonitor monitor) {
			return AbstractJpaProject.this.update(monitor);
		}
		@Override
		public String toString() {
			return ObjectTools.toString(this, AbstractJpaProject.this);
		}
	}

	/**
	 * Called by the {@link UpdateJobCommand#execute(IProgressMonitor)}.
	 */
	protected IStatus update(IProgressMonitor monitor) {
		if (monitor.isCanceled()) {
			return Status.CANCEL_STATUS;
		}

		this.contextRoot.update(monitor);
		if (monitor.isCanceled()) {
			return Status.CANCEL_STATUS;
		}

		this.updateRootStructureNodes(monitor);
		if (monitor.isCanceled()) {
			return Status.CANCEL_STATUS;
		}

		return Status.OK_STATUS;
	}

	protected void updateRootStructureNodes(IProgressMonitor monitor) {
		for (JpaFile jpaFile : this.getJpaFiles()) {
			if (monitor.isCanceled()) {
				return;
			}
			jpaFile.updateRootStructureNodes();
		}
	}

	// ********** update command listener **********

	protected NotifyingRepeatingJobCommand.Listener buildUpdateCommandListener() {
		return new UpdateCommandListener();
	}

	protected class UpdateCommandListener
		implements NotifyingRepeatingJobCommand.Listener
	{
		public void executionQuiesced(JobCommand command) {
			AbstractJpaProject.this.updateQuiesced();
		}
		public void executionCanceled(JobCommand command) {
			AbstractJpaProject.this.updateCanceled();
		}
		@Override
		public String toString() {
			return ObjectTools.toString(this, AbstractJpaProject.this);
		}
	}

	/**
	 * This is the callback used by the update command to notify the JPA
	 * project that the "update" has quiesced (i.e. the "update" has completed
	 * and there are no outstanding requests for further "updates").
	 * Called by {@link UpdateCommandListener#executionQuiesced(JobCommand)}.
	 */
 	protected void updateQuiesced() {
		this.synchronizeMetamodel();
	}

	/**
	 * This is the callback used by the update command to notify the JPA
	 * project that the "update" has been canceled (typically by the user).
	 * Called by {@link UpdateCommandListener#executionCanceled(JobCommand)}.
	 */
 	protected void updateCanceled() {
		// NOP
	}


	// ********** job command context **********

 	/**
	 * Delegate execution to the JPA project manager, which will determine
	 * whether commands are executed synchronously or asynchronously.
	 * 
	 * @see #buildStartSynchronizeContextModelJobCommandContext()
	 * @see #buildStartUpdateJobCommandContext()
	 */
	protected class ManagerJobCommandContext
		implements JobCommandContext
	{
		protected final String defaultJobName;
		protected ManagerJobCommandContext(String defaultJobName) {
			super();
			if (defaultJobName == null) {
				throw new NullPointerException();
			}
			this.defaultJobName = defaultJobName;
		}
		/**
		 * This should be the only method called on this context....
		 */
		public void execute(JobCommand command) {
			this.execute(command, this.defaultJobName);
		}
		public void execute(JobCommand command, String jobName) {
			AbstractJpaProject.this.manager.execute(command, jobName, AbstractJpaProject.this);
		}
		public void execute(JobCommand command, String jobName, ISchedulingRule schedulingRule) {
			// the JPA project manager will supply the scheduling rule
			this.execute(command, jobName);
		}
		@Override
		public String toString() {
			return ObjectTools.toString(this, this.defaultJobName);
		}
	}


	// ********** temp update job command context **********

 	/**
 	 * Pass through a progress monitor.
 	 * <br>
 	 * <strong>NB:</strong> One-time use only.
	 * 
	 * @see #buildTempStartUpdateJobCommandContext(IProgressMonitor)
	 */
	protected class TempUpdateJobCommandContext
		implements JobCommandContext
	{
		protected IProgressMonitor monitor;
		protected TempUpdateJobCommandContext(IProgressMonitor monitor) {
			super();
			if (monitor == null) {
				throw new NullPointerException();
			}
			this.monitor = monitor;
		}
		public void execute(JobCommand command) {
			IProgressMonitor m = null;
			synchronized (this)	 {
				if (this.monitor == null) {
					throw new NullPointerException();
				}
				m = this.monitor;
				this.monitor = null; // one-time use...
			}
			command.execute(m);
		}
		public void execute(JobCommand command, String jobName) {
			this.execute(command);
		}
		public void execute(JobCommand command, String jobName, ISchedulingRule schedulingRule) {
			this.execute(command);
		}
		@Override
		public String toString() {
			return ObjectTools.toString(this, this.monitor);
		}
	}
}
