/*******************************************************************************
 * Copyright (c) 2010, 2013 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.jaxb.core.internal;

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.IResourceChangeEvent;
import org.eclipse.core.resources.IResourceChangeListener;
import org.eclipse.core.resources.IResourceDelta;
import org.eclipse.core.resources.IResourceProxy;
import org.eclipse.core.resources.IResourceProxyVisitor;
import org.eclipse.core.resources.IWorkspace;
import org.eclipse.core.resources.IncrementalProjectBuilder;
import org.eclipse.core.resources.ResourcesPlugin;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.jobs.IJobManager;
import org.eclipse.core.runtime.jobs.ILock;
import org.eclipse.core.runtime.jobs.Job;
import org.eclipse.jdt.core.ElementChangedEvent;
import org.eclipse.jdt.core.IElementChangedListener;
import org.eclipse.jdt.core.JavaCore;
import org.eclipse.jpt.common.core.JptCommonCoreMessages;
import org.eclipse.jpt.common.core.internal.utility.ProjectTools;
import org.eclipse.jpt.common.core.utility.command.JobCommand;
import org.eclipse.jpt.common.utility.command.Command;
import org.eclipse.jpt.common.utility.command.StatefulCommandContext;
import org.eclipse.jpt.common.utility.internal.ObjectTools;
import org.eclipse.jpt.common.utility.internal.command.AsynchronousExtendedCommandContext;
import org.eclipse.jpt.common.utility.internal.command.SimpleStatefulExtendedCommandContext;
import org.eclipse.jpt.common.utility.internal.exception.ExceptionHandlerAdapter;
import org.eclipse.jpt.common.utility.internal.iterable.IterableTools;
import org.eclipse.jpt.common.utility.internal.model.AbstractModel;
import org.eclipse.jpt.common.utility.internal.reference.SynchronizedBoolean;
import org.eclipse.jpt.jaxb.core.JaxbFile;
import org.eclipse.jpt.jaxb.core.JaxbPreferences;
import org.eclipse.jpt.jaxb.core.JaxbProject;
import org.eclipse.jpt.jaxb.core.JaxbProjectManager;
import org.eclipse.jpt.jaxb.core.JaxbWorkspace;
import org.eclipse.jpt.jaxb.core.JptJaxbCoreMessages;
import org.eclipse.jpt.jaxb.core.internal.plugin.JptJaxbCorePlugin;
import org.eclipse.jpt.jaxb.core.internal.utility.CallbackJobSynchronizer;
import org.eclipse.jpt.jaxb.core.internal.utility.JobSynchronizer;
import org.eclipse.jpt.jaxb.core.platform.JaxbPlatformConfig;
import org.eclipse.jpt.jaxb.core.platform.JaxbPlatformDefinition;
import org.eclipse.jpt.jaxb.core.platform.JaxbPlatformManager;
import org.eclipse.jpt.jaxb.core.utility.CallbackSynchronizer;
import org.eclipse.jpt.jaxb.core.utility.Synchronizer;
import org.eclipse.osgi.util.NLS;
import org.eclipse.wst.common.project.facet.core.FacetedProjectFramework;
import org.eclipse.wst.common.project.facet.core.IProjectFacetVersion;
import org.eclipse.wst.common.project.facet.core.ProjectFacetsManager;
import org.eclipse.wst.common.project.facet.core.events.IFacetedProjectEvent;
import org.eclipse.wst.common.project.facet.core.events.IFacetedProjectListener;
import org.eclipse.wst.common.project.facet.core.events.IProjectFacetActionEvent;
import org.osgi.framework.BundleContext;

/**
 * The JAXB project manager maintains a list of all JAXB projects in the workspace.
 * It keeps the list (and the state of the JAXB projects themselves)
 * synchronized with the workspace by listening for various
 * changes:<ul>
 * <li>Resource
 * <li>Java
 * <li>Faceted Project
 * </ul>
 * We use an Eclipse {@link ILock lock} to synchronize access to the JAXB
 * projects when dealing with these events. In an effort to reduce deadlocks,
 * the simple Resource and Java change events are dispatched to a background
 * thread, allowing us to handle the events outside of the workspace lock held
 * during resource and Java change notifications.
 * <p>
 * Events that trigger either the adding or removing of a JAXB project (e.g.
 * {@link IResourceChangeEvent#POST_CHANGE}) are handled "synchronously"
 * by allowing the background thread to handle any outstanding events before
 * updating the list of JAXB projects and returning execution to the event
 * source.
 * <p>
 * Various things that cause us to add or remove a JAXB project:<ul>
 * <li>The {@link JptJaxbCorePlugin} will "lazily" instantiate and {@link #start() start}
 *     a JAXB project manager as appropriate. This will trigger the manager
 *     to find and add all pre-existing JAXB projects.
 * 
 * <li>Project created and facet installed<p>
 *     {@link IResourceChangeEvent#POST_CHANGE}
 * <li>Project facet uninstalled<p>
 *     {@link IFacetedProjectEvent.Type#PRE_UNINSTALL}
 * 
 * <li>Project opened<p>
 *     {@link IResourceChangeEvent#POST_CHANGE}
 *     -> {@link IResource#FILE}
 *     -> {@link IResourceDelta#ADDED} facet settings file
 *     (<code>/.settings/org.eclipse.wst.common.project.facet.core.xml</code>)
 * <li>Project closed<p>
 *     {@link IResourceChangeEvent#POST_CHANGE}
 *     -> {@link IResource#FILE}
 *     -> {@link IResourceDelta#REMOVED} facet settings file
 * 
 * <li>Pre-existing project imported from directory or archive (created and opened)<p>
 *     {@link IResourceChangeEvent#POST_CHANGE}
 *     -> {@link IResource#FILE}
 *     -> {@link IResourceDelta#ADDED} facet settings file
 * <li>Project renamed<p>
 *     {@link IResourceChangeEvent#POST_CHANGE}
 *     -> {@link IResource#FILE}
 *     -> {@link IResourceDelta#REMOVED} facet settings file of old project
 *     -> {@link IResourceDelta#ADDED} facet settings file of new project
 * <li>Project deleted<p>
 *     {@link IResourceChangeEvent#POST_CHANGE}
 *     -> {@link IResource#FILE}
 *     -> {@link IResourceDelta#REMOVED} facet settings file
 * 
 * <li>Project facet installed by editing the facets settings file directly<p>
 *     {@link IResourceChangeEvent#POST_CHANGE}
 *     -> {@link IResource#FILE}
 *     -> {@link IResourceDelta#CHANGED} facet settings file
 * <li>Project facet uninstalled by editing the facets settings file directly<p>
 *     {@link IResourceChangeEvent#POST_CHANGE}
 *     -> {@link IResource#FILE}
 *     -> {@link IResourceDelta#CHANGED} facet settings file
 * </ul>
 */
//TODO Still need to look at faceted project listener for facet uninstall
public class InternalJaxbProjectManager
		extends AbstractModel
		implements JaxbProjectManager {
	
	/**
	 * The JAXB workspace the JAXB project manager corresponds to.
	 */
	private final JaxbWorkspace jaxbWorkspace;

	/**
	 * All the JAXB projects in the workspace.
	 */
	private final Vector<JaxbProject> jaxbProjects = new Vector<JaxbProject>();

	/**
	 * Synchronize access to the JAXB projects.
	 */
	/* private */ final ILock lock = this.getJobManager().newLock();

	/**
	 * Determine how Resource and Java change events are
	 * handled (i.e. synchronously or asynchronously).
	 */
	private volatile StatefulCommandContext eventHandler =
			new AsynchronousExtendedCommandContext(
					JptCommonCoreMessages.DALI_EVENT_HANDLER_THREAD_NAME,
					new LocalExceptionHandler()
				);

	/* CU private */ class LocalExceptionHandler
	extends ExceptionHandlerAdapter
	{
		@Override
		public void handleException(Throwable t) {
			JptJaxbCorePlugin.instance().logError(t);
		}
	}

	/**
	 * Listen for<ul>
	 * <li>changes to projects and files
	 * <li>clean builds
	 * </ul>
	 */
	private final IResourceChangeListener resourceChangeListener = new ResourceChangeListener();

	/**
	 * The types of resource change events that interest
	 * {@link #resourceChangeListener}.
	 */
	private static final int RESOURCE_CHANGE_EVENT_TYPES =
			IResourceChangeEvent.POST_CHANGE |
			IResourceChangeEvent.POST_BUILD;

	/**
	 * Listen for changes to this file to determine when the JAXB facet is
	 * added to or removed from a "faceted" project.
	 */
	private static final String FACETED_PROJECT_FRAMEWORK_SETTINGS_FILE_NAME = FacetedProjectFramework.PLUGIN_ID + ".xml"; //$NON-NLS-1$

	/**
	 * Listen for the JAXB facet being added to or removed from a "faceted" project.
	 */
	private final IFacetedProjectListener facetedProjectListener = new FacetedProjectListener();

	/**
	 * The types of faceted project events that interest
	 * {@link #facetedProjectListener}.
	 */
	private static final IFacetedProjectEvent.Type[] FACETED_PROJECT_EVENT_TYPES = new IFacetedProjectEvent.Type[] {
			IFacetedProjectEvent.Type.PRE_UNINSTALL
		};

	/**
	 * Listen for Java changes (unless the Dali UI is active).
	 * @see #javaElementChangeListenerIsActive()
	 */
	private final JavaElementChangeListener javaElementChangeListener = new JavaElementChangeListener();

	/**
	 * The types of resource change events that interest
	 * {@link #javaElementChangeListener}.
	 */
	private static final int JAVA_CHANGE_EVENT_TYPES =
			ElementChangedEvent.POST_CHANGE |
			ElementChangedEvent.POST_RECONCILE;


	// ********** constructor **********

	/**
	 * Internal: called by {@link InternalJaxbWorkspace}.
	 */
	InternalJaxbProjectManager(JaxbWorkspace jaxbWorkspace) {
		super();
		this.jaxbWorkspace = jaxbWorkspace;
	}


	// ********** plug-in controlled life-cycle **********

	/**
	 * Internal: called by the {@link InternalJaxbWorkspace JAXB workspace}
	 * constructor.
	 */
	void start() {
		try {
			this.lock.acquire();
			this.start_();
		} finally {
			this.lock.release();
		}
	}

	private void start_() {
		debug("*** JAXB project manager START ***"); //$NON-NLS-1$
		try {
			this.buildJaxbProjects();
			this.eventHandler.start();
			this.getWorkspace().addResourceChangeListener(this.resourceChangeListener, RESOURCE_CHANGE_EVENT_TYPES);
			FacetedProjectFramework.addListener(this.facetedProjectListener, FACETED_PROJECT_EVENT_TYPES);
			JavaCore.addElementChangedListener(this.javaElementChangeListener, JAVA_CHANGE_EVENT_TYPES);
		} catch (RuntimeException ex) {
			JptJaxbCorePlugin.instance().logError(ex);
			this.stop_();
		}
	}

	/**
	 * Side-effect: {@link #jaxbProjects} populated.
	 */
	private void buildJaxbProjects() {
		try {
			this.buildJaxbProjects_();
		} catch (CoreException ex) {
			// if we have a problem, leave the currently built JAXB projects in
			// place and keep executing (should be OK...)
			JptJaxbCorePlugin.instance().logError(ex);
		}
	}

	private void buildJaxbProjects_() throws CoreException {
		this.getWorkspace().getRoot().accept(new ResourceProxyVisitor(), IResource.NONE);
	}

	/**
	 * Internal: called by {@link JptJaxbCorePlugin Dali plug-in}.
	 */
	void stop() {
		try {
			this.lock.acquire();
			this.stop_();
		} finally {
			this.lock.release();
		}
	}

	private void stop_() {
		debug("*** JAXB project manager STOP ***"); //$NON-NLS-1$
		JavaCore.removeElementChangedListener(this.javaElementChangeListener);
		FacetedProjectFramework.removeListener(this.facetedProjectListener);
		this.getWorkspace().removeResourceChangeListener(this.resourceChangeListener);
		try {
			this.eventHandler.stop();
		} catch (InterruptedException ex) {
			Thread.currentThread().interrupt();
		}
		this.clearJaxbProjects();
	}

	private void clearJaxbProjects() {
		// clone to prevent concurrent modification exceptions
		for (JaxbProject jaxbProject : this.getJaxbProjects_()) {
			this.removeJaxbProject(jaxbProject);
		}
	}


	// ********** JaxbProjectManager implementation **********

	public Iterable<JaxbProject> getJaxbProjects() {
		try {
			this.lock.acquire();
			return this.getJaxbProjects_();
		} finally {
			this.lock.release();
		}
	}

	private Iterable<JaxbProject> getJaxbProjects_() {
		return IterableTools.cloneLive(this.jaxbProjects);
	}

	public int getJaxbProjectsSize() {
		return this.jaxbProjects.size();
	}

	public JaxbProject getJaxbProject(IProject project) {
		try {
			this.lock.acquire();
			return this.getJaxbProject_(project);
		} finally {
			this.lock.release();
		}
	}

	private JaxbProject getJaxbProject_(IProject project) {
		for (JaxbProject jaxbProject : this.jaxbProjects) {
			if (jaxbProject.getProject().equals(project)) {
				return jaxbProject;
			}
		}
		return null;
	}

	public JaxbFile getJaxbFile(IFile file) {
		JaxbProject jaxbProject = this.getJaxbProject(file.getProject());
		return (jaxbProject == null) ? null : jaxbProject.getJaxbFile(file);
	}

	public void rebuildJaxbProject(IProject project) {
		try {
			this.lock.acquire();
			this.rebuildJaxbProject_(project);
		} finally {
			this.lock.release();
		}
	}

	/**
	 * assumption: the JAXB project holder exists
	 */
	private void rebuildJaxbProject_(IProject project) {
		this.removeJaxbProject(this.getJaxbProject_(project));
		this.addJaxbProject(project);
	}

	public boolean javaElementChangeListenerIsActive() {
		return this.javaElementChangeListener.isActive();
	}

	public void setJavaElementChangeListenerIsActive(boolean javaElementChangeListenerIsActive) {
		this.javaElementChangeListener.setActive(javaElementChangeListenerIsActive);
	}

	public IWorkspace getWorkspace() {
		return ResourcesPlugin.getWorkspace();
	}

	public IJobManager getJobManager() {
		return Job.getJobManager();
	}


	// ********** adding/removing JAXB projects **********

	/* private */ void addJaxbProject(IProject project) {
		this.addJaxbProject(this.buildJaxbProject(project));
	}

	private void addJaxbProject(JaxbProject jaxbProject) {
		// figure out exactly when JAXB projects are added
		dumpStackTrace("add: ", jaxbProject); //$NON-NLS-1$
		// the JAXB project will be null if we have any problems building it...
		// (e.g. if we have problems getting the JAXB platform)
		if (jaxbProject != null) {
			this.addItemToCollection(jaxbProject, this.jaxbProjects, JAXB_PROJECTS_COLLECTION);
		}
	}

	/**
	 * return null if we have any problems...
	 */
	private JaxbProject buildJaxbProject(IProject project) {
		return this.buildJaxbProject(this.buildJaxbProjectConfig(project));
	}

	/**
	 * return null if we have any problems...
	 */
	private JaxbProject buildJaxbProject(JaxbProject.Config config) {
		JaxbPlatformDefinition platformDefinition = config.getPlatformDefinition();
		if (platformDefinition == null) {
			return null;
		}
		JaxbProject jaxbProject = this.buildJaxbProject(platformDefinition, config);
		if (jaxbProject == null) {
			return null;
		}
		jaxbProject.setContextModelSynchronizer(buildJobContextModelSynchronizer(jaxbProject));
		jaxbProject.setUpdateSynchronizer(buildJobUpdateSynchronizer(jaxbProject));
		return jaxbProject;
	}
	
	/**
	 * return null if we have any problems...
	 */
	private JaxbProject buildJaxbProject(JaxbPlatformDefinition platformDefinition, JaxbProject.Config config) {
		try {
			return platformDefinition.getFactory().buildJaxbProject(config);
		}
		catch (RuntimeException ex) {
			JptJaxbCorePlugin.instance().logError(ex);
			return null;
		}
	}
	
	private JaxbProject.Config buildJaxbProjectConfig(IProject project) {
		SimpleJaxbProjectConfig config = new SimpleJaxbProjectConfig();
		config.setProject(project);
		config.setPlatformDefinition(this.getJaxbPlatformDefinition(project));
		return config;
	}

	private JaxbPlatformDefinition getJaxbPlatformDefinition(IProject project) {
		JaxbPlatformManager mgr = this.jaxbWorkspace.getJaxbPlatformManager();
		String jaxbPlatformID = JaxbPreferences.getJaxbPlatformID(project);
		if (jaxbPlatformID != null) {
			return mgr.getJaxbPlatformDefinition(jaxbPlatformID);
		}
		// the ID taken from the JAXB preferences can be null if the JAXB facet is
		// added by editing the facet metadata file directly and there are no
		// pre-existing Dali project preferences in the project .settings directory
		jaxbPlatformID = this.getDefaultJaxbPlatformID(project);
		// it's unlikely the default ID will be null...
		return (jaxbPlatformID == null) ? null : mgr.getJaxbPlatformDefinition(jaxbPlatformID);
	}
	
	/**
	 * Return the default JAXB platform ID for the specified project.
	 * This will be determined by the current default JAXB platform for the
	 * project's JAXB facet version.
	 */
	private String getDefaultJaxbPlatformID(IProject project) {
		IProjectFacetVersion jaxbFacetVersion = this.getJaxbFacetVersion(project);
		if (jaxbFacetVersion == null) {
			return null;
		}
		JaxbPlatformConfig config = this.jaxbWorkspace.getJaxbPlatformManager().getDefaultJaxbPlatformConfig(jaxbFacetVersion);
		return (config == null) ? null : config.getId();
	}

	private IProjectFacetVersion getJaxbFacetVersion(IProject project) {
		try {
			return ProjectFacetsManager.create(project).getProjectFacetVersion(JaxbProject.FACET);
		} catch (CoreException ex) {
			JptJaxbCorePlugin.instance().logError(ex);
			return null;
		}
	}

	private Synchronizer buildJobContextModelSynchronizer(JaxbProject jaxbProject) {
		return new JobSynchronizer(
				buildContextModelJobName(jaxbProject),
				buildContextModelJobCommand(jaxbProject),
				jaxbProject.getProject());
	}
	
	private String buildContextModelJobName(JaxbProject jaxbProject) {
		return NLS.bind(JptJaxbCoreMessages.CONTEXT_MODEL_SYNC_JOB_NAME, jaxbProject.getName());
	}
	
	private JobCommand buildContextModelJobCommand(final JaxbProject jaxbProject) {
		return new JobCommand() {
			public IStatus execute(IProgressMonitor monitor) {
				return jaxbProject.synchronizeContextModel(monitor);
			}
		};
	}
	
	private CallbackSynchronizer buildJobUpdateSynchronizer(JaxbProject jaxbProject) {
		return new CallbackJobSynchronizer(
				buildUpdateJobName(jaxbProject),
				buildUpdateJobCommand(jaxbProject),
				jaxbProject.getProject());
	}
	
	private String buildUpdateJobName(JaxbProject jaxbProject) {
		return NLS.bind(JptJaxbCoreMessages.UPDATE_JOB_NAME, jaxbProject.getName());
	}
	
	private JobCommand buildUpdateJobCommand(final JaxbProject jaxbProject) {
		return new JobCommand() {
			public IStatus execute(IProgressMonitor monitor) {
				return jaxbProject.update(monitor);
			}
		};
	}
	
	/* private */ void removeJaxbProject(JaxbProject jaxbProject) {
		// figure out exactly when JAXB projects are removed
		dumpStackTrace("remove: ", jaxbProject); //$NON-NLS-1$
		this.removeItemFromCollection(jaxbProject, this.jaxbProjects, JAXB_PROJECTS_COLLECTION);
		jaxbProject.dispose();
	}


	// ********** Project POST_CHANGE **********

	/* private */ void projectChanged(IResourceDelta delta) {
		this.eventHandler.execute(this.buildProjectChangedCommand(delta));
	}

	private Command buildProjectChangedCommand(final IResourceDelta delta) {
		return new EventHandlerCommand("Project POST_CHANGE Command") { //$NON-NLS-1$
			@Override
			void execute_() {
				InternalJaxbProjectManager.this.projectChanged_(delta);
			}
		};
	}

	/**
	 * Forward the specified resource delta to all our JAXB projects;
	 * they will each determine whether the event is significant.
	 */
	/* private */ void projectChanged_(IResourceDelta delta) {
		for (JaxbProject jaxbProject : this.jaxbProjects) {
			jaxbProject.projectChanged(delta);
		}
	}


	// ********** Project POST_BUILD (CLEAN_BUILD) **********

	/* private */ void projectPostCleanBuild(IProject project) {
		this.executeAfterEventsHandled(this.buildProjectPostCleanBuildCommand(project));
	}

	private Command buildProjectPostCleanBuildCommand(final IProject project) {
		return new EventHandlerCommand("Project POST_BUILD (CLEAN_BUILD) Command") { //$NON-NLS-1$
			@Override
			void execute_() {
				InternalJaxbProjectManager.this.projectPostCleanBuild_(project);
			}
		};
	}

	/* private */ void projectPostCleanBuild_(IProject project) {
		JaxbProject jaxbProject = this.getJaxbProject_(project);
		if (jaxbProject != null) {
			this.removeJaxbProject(jaxbProject);
			this.addJaxbProject(project);
		}
	}


	// ********** File POST_CHANGE **********

	/**
	 * The Faceted Project settings file has changed in some fashion, check
	 * whether the JAXB facet has been added to or removed from the specified
	 * project.
	 */
	/* private */ void checkForJaxbFacetTransition(IProject project) {
		JaxbProject jaxbProject = this.getJaxbProject_(project);

		if (ProjectTools.hasFacet(project, JaxbProject.FACET_ID)) {
			if (jaxbProject == null) {  // JAXB facet added
				this.executeAfterEventsHandled(this.buildAddJaxbProjectCommand(project));
			}
		} else {
			if (jaxbProject != null) {  // JAXB facet removed
				this.executeAfterEventsHandled(this.buildRemoveJaxbProjectCommand(jaxbProject));
			}
		}
	}

	private Command buildAddJaxbProjectCommand(final IProject project) {
		return new EventHandlerCommand("Add JAXB Project Command") { //$NON-NLS-1$
			@Override
			void execute_() {
				InternalJaxbProjectManager.this.addJaxbProject(project);
			}
		};
	}

	private Command buildRemoveJaxbProjectCommand(final JaxbProject jaxbProject) {
		return new EventHandlerCommand("Remove JAXB Project Command") { //$NON-NLS-1$
			@Override
			void execute_() {
				InternalJaxbProjectManager.this.removeJaxbProject(jaxbProject);
			}
		};
	}

	// ********** FacetedProject PRE_UNINSTALL **********

	/* private */ void jaxbFacetedProjectPreUninstall(IProjectFacetActionEvent event) {
		IProject project = event.getProject().getProject();
		this.executeAfterEventsHandled(this.buildJaxbFacetedProjectPreUninstallCommand(project));
	}

	private Command buildJaxbFacetedProjectPreUninstallCommand(final IProject project) {
		return new EventHandlerCommand("Faceted Project PRE_UNINSTALL Command") { //$NON-NLS-1$
			@Override
			void execute_() {
				InternalJaxbProjectManager.this.jaxbFacetedProjectPreUninstall_(project);
			}
		};
	}

	/* private */ void jaxbFacetedProjectPreUninstall_(IProject project) {
		// assume(?) this is the first event to indicate we need to remove the JAXB project from the JAXB project manager
		this.removeJaxbProject(this.getJaxbProject_(project));
	}


	// ********** Java element changed **********

	/* private */ void javaElementChanged(ElementChangedEvent event) {
		this.eventHandler.execute(this.buildJavaElementChangedCommand(event));
	}

	private Command buildJavaElementChangedCommand(final ElementChangedEvent event) {
		return new EventHandlerCommand("Java element changed Command") { //$NON-NLS-1$
			@Override
			void execute_() {
				InternalJaxbProjectManager.this.javaElementChanged_(event);
			}
		};
	}

	/**
	 * Forward the Java element changed event to all the JAXB projects
	 * because the event could affect multiple projects.
	 */
	/* private */ void javaElementChanged_(ElementChangedEvent event) {
		for (JaxbProject jaxbProject : this.jaxbProjects) {
			jaxbProject.javaElementChanged(event);
		}
	}


	// ********** miscellaneous **********

	public JaxbWorkspace getJaxbWorkspace() {
		return this.jaxbWorkspace;
	}

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


	// ********** event handler **********

	/**
	 * If the event handler is executing asynchronously:<br>
	 * Allow all the commands currently on the command context's queue to execute.
	 * Once they have executed, suspend the command context and process the
	 * specified command (on <em>this</em> thread, <em>not</em> the command
	 * context thread). Once the specified command is finished, allow the
	 * command context to resume processing its command queue.
	 * <p>
	 * If the event handler is executing synchronously:<br>
	 * All the events have already been handled synchronously, so we simply
	 * execute the specified command [sorta] directly.
	 */
	private void executeAfterEventsHandled(Command command) {
		SynchronizedBoolean flag = new SynchronizedBoolean(false);
		this.eventHandler.execute(new PauseCommand(flag));
		try {
			flag.waitUntilTrue();
		} catch (InterruptedException ex) {
			// ignore - not sure why this thread would be interrupted
		}
		try {
			command.execute();
		} finally {
			flag.setFalse();
		}
	}

	/**
	 * If this "pause" command is executing (asynchronously) on a different
	 * thread than the JAXB project manager:<ol>
	 * <li>it will set the flag to <code>true</code>, allowing the JAXB project
	 * manager to resume executing on its own thread
	 * <li>then it will suspend its command context until the JAXB project
	 * manager sets the flag back to <code>false</code>.
	 * </ol>
	 * If this "pause" command is executing (synchronously) on the same thread
	 * as the JAXB project manager, it will simply set the flag to
	 * <code>true</code> and return.
	 */
	private static class PauseCommand
		implements Command
	{
		private final Thread producerThread;
		private final SynchronizedBoolean flag;

		PauseCommand(SynchronizedBoolean flag) {
			this(Thread.currentThread(), flag);
		}

		PauseCommand(Thread producerThread, SynchronizedBoolean flag) {
			super();
			this.producerThread = producerThread;
			this.flag = flag;
		}

		public void execute() {
			this.flag.setTrue();
			if (Thread.currentThread() != this.producerThread) {
				try {
					this.flag.waitUntilFalse();
				} catch (InterruptedException ex) {
					// ignore - the command context will check for interruptions
				}
			}
		}
	}

	/**
	 * This method is called (via reflection) when the test plug-in is loaded.
	 * @see JptJaxbCoreTestsPlugin#start(BundleContext)
	 */
	public void handleEventsSynchronously() throws InterruptedException {
		try {
			this.lock.acquire();
			this.handleEventsSynchronously_();
		} finally {
			this.lock.release();
		}
	}

	private void handleEventsSynchronously_() throws InterruptedException {
		this.eventHandler.stop();
		this.eventHandler = new SimpleStatefulExtendedCommandContext();
		this.eventHandler.start();
	}


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

	/**
	 * Visit the workspace resource tree, adding a JAXB project to the
	 * JAXB project manager for each open Eclipse project that has a JAXB facet.
	 */
	private class ResourceProxyVisitor implements IResourceProxyVisitor {
		ResourceProxyVisitor() {
			super();
		}

		public boolean visit(IResourceProxy resourceProxy) {
			switch (resourceProxy.getType()) {
				case IResource.ROOT :
					return true;  // all projects are in the "root"
				case IResource.PROJECT :
					this.processProject(resourceProxy);
					return false;  // no nested projects
				case IResource.FOLDER :
					return false;  // ignore
				case IResource.FILE :
					return false;  // ignore
				default :
					return false;
			}
		}

		private void processProject(IResourceProxy resourceProxy) {
			if (resourceProxy.isAccessible()) {  // the project exists and is open
				IProject project = (IProject) resourceProxy.requestResource();
				if (ProjectTools.hasFacet(project, JaxbProject.FACET_ID)) {
					InternalJaxbProjectManager.this.addJaxbProject(project);
				}
			}
		}

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

	}


	// ********** event handler command **********

	/**
	 * Command that holds the JAXB project manager lock while
	 * executing.
	 */
	private abstract class EventHandlerCommand
		implements Command
	{
		private final String name;

		EventHandlerCommand(String name) {
			super();
			this.name = name;
		}

		public final void execute() {
			try {
				InternalJaxbProjectManager.this.lock.acquire();
				this.execute_();
			} catch (RuntimeException ex) {
				JptJaxbCorePlugin.instance().logError(ex);
			} finally {
				InternalJaxbProjectManager.this.lock.release();
			}
		}

		abstract void execute_();

		@Override
		public String toString() {
			return this.name;
		}
	}


	// ********** resource change listener **********

	private class ResourceChangeListener implements IResourceChangeListener {

		ResourceChangeListener() {
			super();
		}

		/**
		 * PRE_UNINSTALL is the only facet event we use for 
		 * removing JAXB projects. These are the cases where we listen for resource events.
		 * <p>
		 * Check for:<ul>
		 * <li>facet settings file added/removed/changed
		 * (<code>/.settings/org.eclipse.wst.common.project.facet.core.xml</code>)
		 * <li>file add/remove - forwarded to the individual JAXB projects
		 * <li>project clean
		 * </ul>
		 */
		public void resourceChanged(IResourceChangeEvent event) {
			switch (event.getType()) {
				case IResourceChangeEvent.POST_CHANGE :
					this.processPostChangeEvent(event);
					break;

				// workspace or project events
				case IResourceChangeEvent.PRE_REFRESH :
					break;  // ignore
				case IResourceChangeEvent.PRE_BUILD :
					break;  // ignore
				case IResourceChangeEvent.POST_BUILD :
					this.processPostBuildEvent(event);
					break;

				// project-only events
				case IResourceChangeEvent.PRE_CLOSE :  
					break;  // ignore
				case IResourceChangeEvent.PRE_DELETE :
					break;  // ignore
				default :
					break;
			}
		}

		private void processPostChangeEvent(IResourceChangeEvent event) {
			debug("Resource POST_CHANGE"); //$NON-NLS-1$
			this.processPostChangeDelta(event.getDelta());
		}

		private void processPostChangeDelta(IResourceDelta delta) {
			IResource resource = delta.getResource();
			switch (resource.getType()) {
				case IResource.ROOT :
					this.processPostChangeRootDelta(delta);
					break;
				case IResource.PROJECT :
					this.processPostChangeProjectDelta(delta);
					break;
				case IResource.FOLDER :
					this.processPostChangeFolderDelta((IFolder) resource, delta);
					break;
				case IResource.FILE :
					this.processPostChangeFileDelta((IFile) resource, delta);
					break;
				default :
					break;
			}
		}

		// ***** POST_CHANGE ROOT
		private void processPostChangeRootDelta(IResourceDelta delta) {
			this.processPostChangeDeltaChildren(delta);
		}

		// ***** POST_CHANGE PROJECT
		/**
		 * Process the project first for the Opening project case.
		 * The JAXB project will not be built until the children are processed
		 * and we see that the facet metadata file is added.
		 * Otherwise the JAXB project would be built and then we would process
		 * the ADDED deltas for all the files in the project.
		 */
		private void processPostChangeProjectDelta(IResourceDelta delta) {
			InternalJaxbProjectManager.this.projectChanged(delta);
			this.processPostChangeDeltaChildren(delta);
		}

		// ***** POST_CHANGE FOLDER
		private void processPostChangeFolderDelta(IFolder folder, IResourceDelta delta) {
			if (folder.getName().equals(".settings")) { //$NON-NLS-1$
				this.processPostChangeDeltaChildren(delta);
			}
		}

		// ***** POST_CHANGE FILE
		private void processPostChangeFileDelta(IFile file, IResourceDelta delta) {
			if (file.getName().equals(FACETED_PROJECT_FRAMEWORK_SETTINGS_FILE_NAME)) {
				this.checkForFacetFileChanges(file, delta);
			}
		}
		
		private void checkForFacetFileChanges(IFile file, IResourceDelta delta) {
			switch (delta.getKind()) {
				case IResourceDelta.ADDED :
				case IResourceDelta.REMOVED :
				case IResourceDelta.CHANGED : 
					InternalJaxbProjectManager.this.checkForJaxbFacetTransition(file.getProject());
					break;
				case IResourceDelta.ADDED_PHANTOM :
					break;  // ignore
				case IResourceDelta.REMOVED_PHANTOM :
					break;  // ignore
				default :
					break;
			}
		}

		private void processPostChangeDeltaChildren(IResourceDelta delta) {
			for (IResourceDelta child : delta.getAffectedChildren()) {
				this.processPostChangeDelta(child);  // recurse
			}
		}

		/**
		 * A post build event has occurred.
		 * Check for whether the build was a "clean" build and trigger project update.
		 */
		// ***** POST_BUILD
		private void processPostBuildEvent(IResourceChangeEvent event) {
			debug("Resource POST_BUILD: ", event.getResource()); //$NON-NLS-1$
			if (event.getBuildKind() == IncrementalProjectBuilder.CLEAN_BUILD) {
				this.processPostCleanBuildDelta(event.getDelta());
			}
		}

		private void processPostCleanBuildDelta(IResourceDelta delta) {
			IResource resource = delta.getResource();
			switch (resource.getType()) {
				case IResource.ROOT :
					this.processPostCleanBuildDeltaChildren(delta);
					break;
				case IResource.PROJECT :
					this.processProjectPostCleanBuild((IProject) resource);
					break;
				case IResource.FOLDER :
					break;  // ignore
				case IResource.FILE :
					break;  // ignore
				default :
					break;
			}
		}

		private void processPostCleanBuildDeltaChildren(IResourceDelta delta) {
			for (IResourceDelta child : delta.getAffectedChildren()) {
				this.processPostCleanBuildDelta(child);  // recurse
			}
		}

		private void processProjectPostCleanBuild(IProject project) {
			debug("\tProject CLEAN: ", project.getName()); //$NON-NLS-1$
			InternalJaxbProjectManager.this.projectPostCleanBuild(project);
		}

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

	}


	// ********** faceted project listener **********

	/**
	 * Forward the Faceted project change event back to the JAXB project manager.
	 */
	private class FacetedProjectListener implements IFacetedProjectListener {

		FacetedProjectListener() {
			super();
		}

		/**
		 * Check for:<ul>
		 * <li>un-install of JAXB facet
		 * </ul>
		 */
		public void handleEvent(IFacetedProjectEvent event) {
			switch (event.getType()) {
				case PRE_UNINSTALL :
					this.processPreUninstallEvent((IProjectFacetActionEvent) event);
					break;
				default :
					break;
			}
		}

		private void processPreUninstallEvent(IProjectFacetActionEvent event) {
			debug("Facet PRE_UNINSTALL: ", event.getProjectFacet()); //$NON-NLS-1$
			if (event.getProjectFacet().equals(JaxbProject.FACET)) {
				InternalJaxbProjectManager.this.jaxbFacetedProjectPreUninstall(event);
			}
		}

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

	}


	// ********** Java element change listener **********

	/**
	 * Forward the Java element change event back to the JAXB project manager.
	 */
	private class JavaElementChangeListener implements IElementChangedListener {
		/**
		 * A flag to activate/deactivate the listener
		 * so we can ignore Java events whenever Dali is manipulating the Java
		 * source code via the Dali model. We do this because the 0.5 sec delay
		 * between the Java source being changed and the corresponding event
		 * being fired causes us no end of pain.
		 */
		private volatile boolean active = true;

		JavaElementChangeListener() {
			super();
		}

		public void elementChanged(ElementChangedEvent event) {
			if (this.active) {
				InternalJaxbProjectManager.this.javaElementChanged(event);
			}
		}

		void setActive(boolean active) {
			this.active = active;
		}

		boolean isActive() {
			return this.active;
		}

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

	}


	// ********** DEBUG **********

	// @see JaxbProjectManagerTests#testDEBUG()
	private static final boolean DEBUG = false;

	/**
	 * trigger #toString() call and string concatenation only if DEBUG is true
	 */
	/* private */ static void debug(String message, Object object) {
		if (DEBUG) {
			debug_(message + object);
		}
	}

	/* private */ static void debug(String message) {
		if (DEBUG) {
			debug_(message);
		}
	}

	private static void debug_(String message) {
		System.out.println(Thread.currentThread().getName() + ": " + message); //$NON-NLS-1$
	}

	/* private */ static void dumpStackTrace() {
		dumpStackTrace(null);
	}

	/* private */ static void dumpStackTrace(String message, Object object) {
		if (DEBUG) {
			dumpStackTrace_(message + object);
		}
	}

	/* private */ static void dumpStackTrace(String message) {
		if (DEBUG) {
			dumpStackTrace_(message);
		}
	}

	private static void dumpStackTrace_(String message) {
		// lock System.out so the stack elements are printed out contiguously
		synchronized (System.out) {
			if (message != null) {
				debug_(message);
			}
			StackTraceElement[] stackTrace = Thread.currentThread().getStackTrace();
			// skip the first 3 elements - those are this method and 2 methods in Thread
			for (int i = 3; i < stackTrace.length; i++) {
				StackTraceElement element = stackTrace[i];
				if (element.getMethodName().equals("invoke0")) { //$NON-NLS-1$
					break;  // skip all elements outside of the JUnit test
				}
				System.out.println("\t" + element); //$NON-NLS-1$
			}
		}
	}

}
