/***************************************************************************************************
 * Copyright (c) 2003, 2004 IBM Corporation and others. All rights reserved. This program and the
 * accompanying materials are made available under the terms of the Eclipse Public License v1.0
 * which accompanies this distribution, and is available at
 * http://www.eclipse.org/legal/epl-v10.html
 * 
 * Contributors: IBM Corporation - initial API and implementation
 **************************************************************************************************/
package org.eclipse.wst.common.emfworkbench.integration;


import java.io.IOException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Set;

import org.eclipse.core.resources.IFile;
import org.eclipse.core.resources.IProject;
import org.eclipse.core.resources.IWorkspaceRunnable;
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.emf.common.command.BasicCommandStack;
import org.eclipse.emf.common.command.CommandStack;
import org.eclipse.emf.common.command.CommandStackListener;
import org.eclipse.emf.common.notify.Notification;
import org.eclipse.emf.common.notify.impl.AdapterImpl;
import org.eclipse.emf.common.util.EList;
import org.eclipse.emf.common.util.URI;
import org.eclipse.emf.ecore.EObject;
import org.eclipse.emf.ecore.resource.Resource;
import org.eclipse.emf.ecore.resource.ResourceSet;
import org.eclipse.wst.common.emf.utilities.ExtendedEcoreUtil;
import org.eclipse.wst.common.emfworkbench.EMFWorkbenchContext;
import org.eclipse.wst.common.emfworkbench.WorkbenchResourceHelper;
import org.eclipse.wst.common.framework.ISaveHandler;
import org.eclipse.wst.common.framework.SaveFailedException;
import org.eclipse.wst.common.framework.SaveHandlerHeadless;
import org.eclipse.wst.common.framework.SaveHandlerRegister;
import org.eclipse.wst.common.framework.enablement.nonui.IWFTWrappedException;
import org.eclipse.wst.common.framework.operation.IOperationHandler;
import org.eclipse.wst.common.internal.emf.resource.CompatibilityXMIResource;
import org.eclipse.wst.common.internal.emf.resource.ReferencedResource;
import org.eclipse.wst.common.internal.emf.resource.TranslatorResource;
import org.eclipse.wst.common.internal.emf.utilities.PleaseMigrateYourCodeError;
import org.eclipse.wst.common.internal.emfworkbench.edit.ClientAccessRegistry;
import org.eclipse.wst.common.internal.emfworkbench.edit.EditModelRegistry;
import org.eclipse.wst.common.internal.emfworkbench.edit.EditModelResource;
import org.eclipse.wst.common.internal.emfworkbench.validateedit.ResourceStateInputProvider;
import org.eclipse.wst.common.internal.emfworkbench.validateedit.ResourceStateValidator;
import org.eclipse.wst.common.internal.emfworkbench.validateedit.ResourceStateValidatorImpl;
import org.eclipse.wst.common.internal.emfworkbench.validateedit.ResourceStateValidatorPresenter;
import org.eclipse.wst.common.internal.jdt.integration.WorkingCopyManager;
import org.eclipse.wst.common.internal.jdt.integration.WorkingCopyManagerFactory;
import org.eclispe.wst.common.framework.enablement.EnablementIdentifierEvent;
import org.eclispe.wst.common.framework.enablement.IEnablementIdentifier;
import org.eclispe.wst.common.framework.enablement.IEnablementIdentifierListener;

import com.ibm.wtp.emf.workbench.ResourceSetWorkbenchSynchronizer;
import com.ibm.wtp.emf.workbench.WorkbenchResourceHelperBase;
import com.ibm.wtp.internal.emf.workbench.nls.EMFWorkbenchResourceHandler;


public class EditModel implements CommandStackListener, ResourceStateInputProvider, ResourceStateValidator, IEnablementIdentifierListener {

	protected BasicCommandStack commandStack;
	protected List listeners;
	protected List removedListeners = new ArrayList();
	private Map params;
	private final String editModelID;
	private final boolean readOnly;
	//These are the current resource uris we need to track
	protected List knownResourceUris;
	//This is a subset of the known resource uris, which we have requested be autoloaded
	protected List preloadResourceUris;
	//This is a map of identifiers to resources that we need to listen to in order to listen for
	//updates to the edit model resources
	protected Map resourceIdentifiers;

	protected EditModelEvent dirtyModelEvent;
	protected boolean isNotifing = false;
	protected boolean disposing = false;
	protected ResourceStateValidator stateValidator;
	protected boolean accessAsReadForUnKnownURIs;
	protected ResourceAdapter resourceAdapter = new ResourceAdapter();
	protected boolean isReverting = false;
	protected List resources;
	private final ClientAccessRegistry registry = new ClientAccessRegistry();
	protected EMFWorkbenchContext emfContext = null;
	private WorkingCopyManager workingCopyManager = null;
	protected IProject project = null;

	private Reference reference;
	private List resourcesTargetedForTermination;

	protected class ResourceAdapter extends AdapterImpl {
		public void notifyChanged(Notification notification) {
			if (notification.getEventType() == Notification.SET && notification.getFeatureID(null) == Resource.RESOURCE__IS_LOADED) {
				resourceIsLoadedChanged((Resource) notification.getNotifier(), notification.getOldBooleanValue(), notification.getNewBooleanValue());
			}
		}
	}

	public EditModel(String editModelID, EMFWorkbenchContext context, boolean readOnly) {
		this.editModelID = editModelID;
		this.readOnly = readOnly;
		this.emfContext = context;
		this.project = context.getProject();
		initializeKnownResourceUris();
		processLoadedResources();
		processPreloadResources();
	}



	public EditModel(String editModelID, EMFWorkbenchContext context, boolean readOnly, boolean accessUnknownResourcesAsReadOnly) {
		this(editModelID, context, readOnly);
		this.accessAsReadForUnKnownURIs = accessUnknownResourcesAsReadOnly;
	}

	/**
	 * @return editModelID
	 */
	public String getEditModelID() {
		return editModelID;
	}

	/**
	 * Insert the method's description here. Creation date: (9/27/2001 10:25:43 PM)
	 * 
	 * @return boolean
	 */
	protected boolean isDisposing() {
		return disposing;
	}

	public void dispose() {
		disposing = true;
		if (commandStack != null)
			commandStack.removeCommandStackListener(this);
		if (hasListeners())
			notifyListeners(new EditModelEvent(EditModelEvent.PRE_DISPOSE, this));
		if (getEmfContext() != null)
			getEmfContext().removeEditModel(this, isReadOnly());
		releasePreloadResources();
		releaseIdentifiers();

		emfContext = null;
		listeners = null;
		removedListeners = null;
		resources = null;
		disposing = false;
		project = null;
	}

	protected void releaseIdentifiers() {
		if (resourceIdentifiers == null)
			return;
		Iterator iter = resourceIdentifiers.keySet().iterator();
		IEnablementIdentifier identifier = null;
		while (iter.hasNext()) {
			identifier = (IEnablementIdentifier) iter.next();
			identifier.removeIdentifierListener(this);
		}
	}

	private ResourceSetWorkbenchSynchronizer getResourceSetSynchronizer() {
		if (emfContext == null || !emfContext.hasResourceSet())
			return null;
		return getEmfContext().getResourceSet().getSynchronizer();
	}

	protected void releasePreloadResources() {
		ResourceSetWorkbenchEditSynchronizer sync = (ResourceSetWorkbenchEditSynchronizer) getResourceSetSynchronizer();
		if (sync != null) {
			for (int i = 0; i < preloadResourceUris.size(); i++) {
				URI uri = (URI) preloadResourceUris.get(i);
				sync.disableAutoload(uri);
			}
		}
	}


	/** ** BEGIN Command Stack Manipulation *** */

	/**
	 * Return the CommandStack.
	 */
	protected BasicCommandStack createCommandStack() {
		BasicCommandStack stack = new BasicCommandStack();
		return stack;
	}

	/**
	 * This is called with the {@link CommandStack}'s state has changed.
	 */
	public void commandStackChanged(java.util.EventObject event) {
		if (dirtyModelEvent == null)
			dirtyModelEvent = new EditModelEvent(EditModelEvent.DIRTY, this);
		if (hasListeners())
			notifyListeners(dirtyModelEvent);
	}

	/**
	 * Flush the Commands from the CommandStack.
	 */
	protected void flushCommandStack() {
		getCommandStack().flush();
		getCommandStack().saveIsDone();
	}

	/**
	 * Return the CommandStack.
	 */
	public BasicCommandStack getCommandStack() {
		if (commandStack == null) {
			commandStack = createCommandStack();
			commandStack.addCommandStackListener(this);
		}
		return commandStack;
	}

	/**
	 * Returns true if there are any listeners
	 */
	public boolean hasListeners() {
		return !getListeners().isEmpty();
	}

	/** ** END Command Stack Manipulation *** */

	/** ** BEGIN Listeners *** */

	/**
	 * Add
	 * 
	 * @aListener to the list of listeners.
	 */
	public void addListener(EditModelListener aListener) {
		if (aListener != null && !getListeners().contains(aListener))
			getListeners().add(aListener);
	}

	/**
	 * Insert the method's description here. Creation date: (4/11/2001 4:42:58 PM)
	 * 
	 * @return java.util.List
	 */
	protected java.util.List getListeners() {
		if (listeners == null)
			listeners = new ArrayList();
		return listeners;
	}

	/**
	 * Notify listeners of
	 * 
	 * @anEvent.
	 */
	protected void notifyListeners(EditModelEvent anEvent) {
		if (listeners == null)
			return;
		boolean oldIsNotifying = isNotifing;
		synchronized (this) {
			isNotifing = true;
		}
		try {
			List list = getListeners();
			for (int i = 0; i < list.size(); i++) {
				EditModelListener listener = (EditModelListener) list.get(i);
				if (!removedListeners.contains(listener))
					listener.editModelChanged(anEvent);
			}
		} finally {
			synchronized (this) {
				isNotifing = oldIsNotifying;
				if (!isNotifing && removedListeners != null && !removedListeners.isEmpty()) {
					listeners.removeAll(removedListeners);
					removedListeners.clear();
				}
			}
		}
	}

	/**
	 * Remove
	 * 
	 * @aListener from the list of listeners.
	 */
	public synchronized boolean removeListener(EditModelListener aListener) {
		if (aListener != null) {
			if (isNotifing)
				return removedListeners.add(aListener);
			return getListeners().remove(aListener);
		}
		return false;
	}

	/** ** END Listeners *** */

	protected void makeFileEditable(IFile aFile) {
		if (aFile == null)
			return;
		aFile.setReadOnly(false);
	}

	/**
	 * @return java.util.List of IFile; any read-only files that will be touched if this edit model
	 *         saves
	 */
	public List getReadOnlyAffectedFiles() {
		Iterator affected = getAffectedFiles().iterator();
		List result = new ArrayList();
		while (affected.hasNext()) {
			IFile aFile = (IFile) affected.next();
			if (aFile.isReadOnly())
				result.add(aFile);
		}
		return result;
	}

	/** ** BEGIN Save Handlers *** */

	protected ISaveHandler getSaveHandler() {
		return SaveHandlerRegister.getSaveHandler();
	}

	/**
	 * Default is to do nothing. This method is called if a saveIfNecessary or
	 * saveIfNecessaryWithPrompt determines not to save. This provides subclasses with an
	 * opportunity to do some other action.
	 */
	protected void handleSaveIfNecessaryDidNotSave(IProgressMonitor monitor) {
	}

	/**
	 * This will force all of the referenced Resources to be saved.
	 */
	public void save(Object accessorKey) {
		save(null, accessorKey);
	}

	/**
	 * This will force all of the referenced Resources to be saved.
	 */
	public void save(IProgressMonitor monitor) throws PleaseMigrateYourCodeError {

	}

	/**
	 * Subclasses may override {@link #primSave}
	 */
	public final void save(IProgressMonitor monitor, Object accessorKey) {
		assertPermissionToSave(accessorKey);
		getSaveHandler().access();
		try {
			IWorkspaceRunnable runnable = new IWorkspaceRunnable() {
				public void run(IProgressMonitor aMonitor) {
					primSave(aMonitor);
				}
			};
			runSaveOperation(runnable, monitor);
		} catch (SaveFailedException ex) {
			getSaveHandler().handleSaveFailed(ex, monitor);
		} finally {
			getSaveHandler().release();
		}
	}

	/**
	 * Save only resources that need to be saved (i.e., no other references).
	 */
	public void saveIfNecessary(Object accessorKey) {
		saveIfNecessary(null, accessorKey);
	}

	/**
	 * Save only resources that need to be saved (i.e., no other references).
	 */
	public void saveIfNecessary(IProgressMonitor monitor, Object accessorKey) {
		if (shouldSave())
			save(monitor, accessorKey);
		else
			handleSaveIfNecessaryDidNotSave(monitor);
	}

	/**
	 * Save only if necessary. If typically a save would not occur because this edit model is
	 * shared, the user will be prompted using the
	 * 
	 * @operationHandler. If the prompt returns true (the user wants to save) the entire edit model
	 *                    will be saved.
	 */
	public void saveIfNecessaryWithPrompt(IOperationHandler operationHandler, Object accessorKey) {
		saveIfNecessaryWithPrompt(null, operationHandler, accessorKey);
	}

	/**
	 * Save only if necessary. If typically a save would not occur because this edit model is
	 * shared, the user will be prompted using the
	 * 
	 * @operationHandler. If the prompt returns true (the user wants to save) the entire edit model
	 *                    will be saved. You may pass in a boolean <code>wasDirty</code> to
	 *                    indicate whether this edit model was dirty prior to making any changes and
	 *                    calling this method. {@link EditModel#isDirty()}
	 */
	public void saveIfNecessaryWithPrompt(IOperationHandler operationHandler, boolean wasDirty, Object accessorKey) {
		saveIfNecessaryWithPrompt(null, operationHandler, wasDirty, accessorKey);
	}

	/**
	 * Save only if necessary. If typically a save would not occur because this edit model is
	 * shared, the user will be prompted using the
	 * 
	 * @operationHandler. If the prompt returns true (the user wants to save) the entire edit model
	 *                    will be saved.
	 */
	public void saveIfNecessaryWithPrompt(IProgressMonitor monitor, IOperationHandler operationHandler, Object accessorKey) {
		saveIfNecessaryWithPrompt(monitor, operationHandler, true, accessorKey);
	}

	/**
	 * Save only if necessary. If typically a save would not occur because this edit model is
	 * shared, the user will be prompted using the
	 * 
	 * @operationHandler. If the prompt returns true (the user wants to save) the entire edit model
	 *                    will be saved. You may pass in a boolean <code>wasDirty</code> to
	 *                    indicate whether this edit model was dirty prior to making any changes and
	 *                    calling this method. {@link EditModel#isDirty()}
	 */
	public void saveIfNecessaryWithPrompt(IProgressMonitor monitor, IOperationHandler operationHandler, boolean wasDirty, Object accessorKey) {

		if (shouldSave(operationHandler, wasDirty))
			save(monitor, accessorKey);
		else
			handleSaveIfNecessaryDidNotSave(monitor);
	}

	protected void assertPermissionToSave(Object accessorKey) {
		if (registry != null)
			registry.assertAccess(accessorKey);
	}

	private void runSaveOperation(IWorkspaceRunnable runnable, IProgressMonitor monitor) throws SaveFailedException {
		try {
			ResourcesPlugin.getWorkspace().run(runnable, monitor);
		} catch (CoreException e) {
			throw new SaveFailedException(e);
		}
	}

	/**
	 * Should the resources be saved.
	 */
	protected boolean shouldSave(IOperationHandler operationHandler, boolean wasDirty) {
		return !wasDirty ? shouldSave() : shouldSave(operationHandler);
	}

	/**
	 * Return true if the uri for
	 * 
	 * @aResource is one of the known resource uris.
	 */
	public boolean isInterrestedInResource(Resource aResource) {
		return isInterrestedInResourceUri(aResource.getURI());
	}

	protected boolean isInterrestedInResourceUri(URI resURI) {
		URI uri;
		List uriStrings = getKnownResourceUris();
		for (int i = 0; i < uriStrings.size(); i++) {
			uri = (URI) uriStrings.get(i);
			if (ExtendedEcoreUtil.endsWith(resURI, uri))
				return true;
		}
		return false;
	}


	/**
	 * Subclasses should override and add URIs (type URI) of known resources. You must add resources
	 * that have references to other known resources first so they will be released first.
	 */
	protected void initializeKnownResourceUris() {
		knownResourceUris = new ArrayList();
		preloadResourceUris = new ArrayList();
		EditModelResource res = null;
		Collection editModelResources = EditModelRegistry.INSTANCE.getEditModelResources(getEditModelID());
		Iterator iter = editModelResources.iterator();
		while (iter.hasNext()) {
			res = (EditModelResource) iter.next();
			addEditModelResource(res);
		}

	}

	private void addEditModelResource(EditModelResource res) {
		boolean enabled = false;
		if (res.isCore()) {
			enabled = true;
		} else {
			IEnablementIdentifier identifier = res.getEnablementIdentifier(getProject());
			registerInterest(identifier, res);
			enabled = identifier.isEnabled();
		}
		if (enabled) {
			URI uri = res.getURI();
			knownResourceUris.add(uri);
			if (res.isAutoLoad()) {
				ResourceSetWorkbenchEditSynchronizer sync = (ResourceSetWorkbenchEditSynchronizer) getEmfContext().getResourceSet().getSynchronizer();
				sync.enableAutoload(uri);
				preloadResourceUris.add(uri);
			}
		}
	}

	/**
	 * @param res
	 */
	private void registerInterest(IEnablementIdentifier identifier, EditModelResource res) {
		getEditModelResources(identifier).add(res);
	}

	private List getEditModelResources(IEnablementIdentifier identifier) {
		if (resourceIdentifiers == null)
			resourceIdentifiers = new HashMap();
		List tResources = (List) resourceIdentifiers.get(identifier);
		if (tResources == null) {
			tResources = new ArrayList(3);
			resourceIdentifiers.put(identifier, tResources);
			identifier.addIdentifierListener(this);
		}
		return tResources;
	}



	public java.util.List getKnownResourceUris() {
		if (knownResourceUris == null)
			initializeKnownResourceUris();

		return knownResourceUris;
	}

	public boolean isShared() {
		return registry.size() > 1;
	}

	/**
	 * @see ResourceStateInputProvider#cacheNonResourceValidateState(List)
	 */
	public void cacheNonResourceValidateState(List roNonResourceFiles) {
	}

	/**
	 * @see ResourceStateInputProvider#getNonResourceFiles()
	 */
	public List getNonResourceFiles() {
		return null;
	}

	/**
	 * @see ResourceStateInputProvider#getNonResourceInconsistentFiles()
	 */
	public List getNonResourceInconsistentFiles() {
		return null;
	}

	/**
	 * Gets the stateValidator.
	 * 
	 * @return Returns a ResourceStateValidator
	 */
	public ResourceStateValidator getStateValidator() {
		if (stateValidator == null)
			stateValidator = createStateValidator();
		return stateValidator;
	}

	/**
	 * Method createStateValidator.
	 * 
	 * @return ResourceStateValidator
	 */
	private ResourceStateValidator createStateValidator() {
		return new ResourceStateValidatorImpl(this);
	}

	/**
	 * @see ResourceStateValidator#checkActivation(ResourceStateValidatorPresenter)
	 */
	public void checkActivation(ResourceStateValidatorPresenter presenter) throws CoreException {
		getStateValidator().checkActivation(presenter);
	}

	/**
	 * @see ResourceStateValidator#lostActivation(ResourceStateValidatorPresenter)
	 */
	public void lostActivation(ResourceStateValidatorPresenter presenter) throws CoreException {
		getStateValidator().lostActivation(presenter);
	}

	/**
	 * @see ResourceStateValidator#validateState(ResourceStateValidatorPresenter)
	 */
	public IStatus validateState(ResourceStateValidatorPresenter presenter) throws CoreException {
		return getStateValidator().validateState(presenter);
	}

	/**
	 * @see ResourceStateValidator#checkSave(ResourceStateValidatorPresenter)
	 */
	public boolean checkSave(ResourceStateValidatorPresenter presenter) throws CoreException {
		return getStateValidator().checkSave(presenter);
	}

	/**
	 * @see ResourceStateValidator#checkReadOnly()
	 */
	public boolean checkReadOnly() {
		return getStateValidator().checkReadOnly();
	}

	/**
	 * Return the ResourceSet from the Nature.
	 * 
	 * @return org.eclipse.emf.ecore.resource.ResourceSet
	 */
	public ResourceSet getResourceSet() {
		ResourceSet resourceSet = null;
		if (getEmfContext() != null)
			resourceSet = getEmfContext().getResourceSet();
		return resourceSet;
	}

	protected void resourceIsLoadedChanged(Resource aResource, boolean oldValue, boolean newValue) {
		if (!isReverting && hasListeners()) {
			int eventCode = newValue ? EditModelEvent.LOADED_RESOURCE : EditModelEvent.UNLOADED_RESOURCE;
			EditModelEvent evt = new EditModelEvent(eventCode, this);
			evt.addResource(aResource);
			notifyListeners(evt);
		}
	}

	public Resource getResource(URI aUri) {
		Resource res = getAndLoadLocalResource(aUri);
		if (res == null)
			res = WorkbenchResourceHelper.getOrCreateResource(aUri, getResourceSet());
		if (res != null)
			processResource(res);
		return res;
	}

	protected void processResource(Resource aResource) {
		if (aResource != null && !getResources().contains(aResource)) {
			if (aResource instanceof ReferencedResource) {
				access((ReferencedResource) aResource);
				//We need a better way to pass this through the save options instead.
				//We also need to make this dynamic based on the project target
				((ReferencedResource) aResource).setFormat(CompatibilityXMIResource.FORMAT_MOF5);
			} else if (aResource instanceof CompatibilityXMIResource) {
				((CompatibilityXMIResource) aResource).setFormat(CompatibilityXMIResource.FORMAT_MOF5);
			}

			addResource(aResource);
		}
	}

	protected void addResource(Resource aResource) {
		getResources().add(aResource);
		aResource.eAdapters().add(resourceAdapter);
	}

	/**
	 * Return a Resource for
	 * 
	 * @aUri.
	 */
	protected Resource getResource(List tResources, URI aUri) {
		Resource resource;
		for (int i = 0; i < tResources.size(); i++) {
			resource = (Resource) tResources.get(i);
			if (ExtendedEcoreUtil.endsWith(resource.getURI(), aUri))
				return resource;
		}
		return null;
	}

	public Resource createResource(URI uri) {
		Resource resource = getExistingOrCreateResource(uri);
		processResource(resource);
		return resource;
	}

	/**
	 * Get a cached Resource, either local or in the ResourceSet, before creating a Resource. This
	 * api handles the case that the Resource may be created during a demand load that failed.
	 */
	public Resource getExistingOrCreateResource(URI uri) {
		Resource res = getAndLoadLocalResource(uri);
		if (res == null)
			res = WorkbenchResourceHelperBase.getExistingOrCreateResource(uri, getResourceSet());
		return res;
	}

	/**
	 * Return a Resource for
	 * 
	 * @aUri.
	 */
	protected Resource getAndLoadLocalResource(URI aUri) {
		Resource resource = getLocalResource(aUri);
		if (null != resource && !resource.isLoaded()) {
			try {
				resource.load(Collections.EMPTY_MAP); //reload it
			} catch (IOException e) {
			}
		}
		return resource;
	}

	/**
	 * Return a Resource for
	 * 
	 * @aUri.
	 */
	protected Resource getLocalResource(URI aUri) {
		return getResource(getResources(), aUri);
	}

	/*
	 * Return true if this is a ReadOnly EditModel or if we should only access unknown URIs as
	 * ReadOnly.
	 */
	protected boolean shouldAccessForRead(ReferencedResource aResource) {
		return isReadOnly() || (accessAsReadForUnKnownURIs && !isInterrestedInResource(aResource));
	}

	/**
	 * Save only resources that need to be saved (i.e., no other references).
	 */
	public void resourceChanged(EditModelEvent anEvent) {
		int code = anEvent.getEventCode();
		switch (code) {
			case EditModelEvent.REMOVED_RESOURCE : {
				if (!isReverting && hasResourceReference(anEvent.getChangedResources()))
					removeResources(anEvent.getChangedResources());
				else
					return;
				break;
			}
			case EditModelEvent.ADDED_RESOURCE :
				if (!processResourcesIfInterrested(anEvent.getChangedResources()))
					return;
		}
		if (hasListeners()) {
			anEvent.setEditModel(this);
			notifyListeners(anEvent);
		}
	}

	/**
	 * Return true if aResource is referenced by me.
	 */
	protected boolean hasResourceReference(Resource aResource) {
		if (aResource != null)
			return getResources().contains(aResource);
		return false;
	}

	/**
	 * Return true if any Resource in the list of
	 * 
	 * @resources is referenced by me.
	 */
	protected boolean hasResourceReference(List tResources) {
		for (int i = 0; i < tResources.size(); i++) {
			if (hasResourceReference((Resource) tResources.get(i)))
				return true;
		}
		return false;
	}

	/**
	 * Remove reference to the Resource objects in
	 * 
	 * @aList. This should be called when one or more Resource objects are removed from the
	 *         ResourceSet without the reference count going to zero.
	 */
	protected void removeResources(List aList) {
		Resource res;
		for (int i = 0; i < aList.size(); i++) {
			res = (Resource) aList.get(i);
			if (removeResource(res) && res instanceof ReferencedResource)
				removedResource((ReferencedResource) res);
		}
	}

	private final void removedResource(ReferencedResource referencedResource) {
		if (!isReadOnly() && referencedResource.wasReverted()) {
			isReverting = true;
			try {
				reverted(referencedResource);
			} finally {
				isReverting = false;
			}
		}
	}

	protected boolean removeResource(URI uri) {
		Resource res = getLocalResource(uri);
		return removeResource(res);
	}

	/**
	 * Remove reference to the aResource.
	 */
	protected boolean removeResource(Resource aResource) {
		if (aResource != null) {
			aResource.eAdapters().remove(resourceAdapter);
			return getResources().remove(aResource);
		}
		return false;
	}

	/**
	 * Subclasses should override to post process a removed ReferencedResource.
	 * 
	 * @see J2EEEditModel#revertAllResources()
	 */
	protected void reverted(ReferencedResource revertedResource) {
		revertAllResources();
	}

	protected void revertAllResources() {
		List someResources = getSortedResources();
		for (int i = 0; i < someResources.size(); i++)
			((Resource) someResources.get(i)).unload();
		getResources().removeAll(someResources);
		for (int i = 0; i < someResources.size(); i++)
			((Resource) someResources.get(i)).eAdapters().remove(resourceAdapter);
	}

	/**
	 * group the resources by XMI first, then XML
	 */
	protected List getSortedResources() {

		List theResources = getResources();
		int size = theResources.size();
		if (size == 0)
			return Collections.EMPTY_LIST;
		Resource[] sorted = new Resource[size];
		int xmlInsertPos = size - 1;
		int xmiInsertPos = 0;
		Resource res = null;
		for (int i = 0; i < size; i++) {
			res = (Resource) theResources.get(i);
			if (res instanceof TranslatorResource)
				sorted[xmlInsertPos--] = res;
			else
				sorted[xmiInsertPos++] = res;
		}

		return Arrays.asList(sorted);
	}

	/**
	 * Process Resources that we are interrested in.
	 */
	protected boolean processResourcesIfInterrested(List someResources) {
		int size = someResources.size();
		Resource res;
		boolean processed = false;
		for (int i = 0; i < size; i++) {
			res = (Resource) someResources.get(i);
			if (isInterrestedInResource(res)) {
				processResource(res);
				processed = true;
			}
		}
		return processed;
	}

	public EMFWorkbenchContext getEmfContext() {
		return emfContext;
	}

	public IProject getProject() {
		return project;
	}

	/**
	 * This method should only be called by the EMFWorkbenchContext.
	 */
	public void access(Object accessorKey) {
		registry.access(accessorKey);
	}

	/**
	 * Access
	 * 
	 * @aResource for read or write.
	 */
	protected void access(ReferencedResource aResource) {
		if (shouldAccessForRead(aResource))
			aResource.accessForRead();
		else
			aResource.accessForWrite();
	}

	/**
	 * This method should be called from each client when they are finished working with the
	 * EditModel.
	 */
	public void releaseAccess(Object accessorKey) {

		if (!isShared())
			releaseResources();

		registry.release(accessorKey);

		if (!isDisposing() && registry.size() == 0) {
			dispose();
		}
	}

	/**
	 * Release each of the referenced resources.
	 */
	protected void release(Resource aResource) {

		removeResource(aResource);
		if (aResource != null && aResource instanceof ReferencedResource)
			release((ReferencedResource) aResource);
	}

	/**
	 * Release each of the referenced resources.
	 */
	protected void release(ReferencedResource aResource) {
		if (isReadOnly())
			aResource.releaseFromRead();
		else
			aResource.releaseFromWrite();

	}

	/**
	 * Release each of the referenced resources.
	 */
	protected void releaseResources() {
		List tResources = getSortedResources();
		Resource resource;
		for (int i = 0; i < tResources.size(); i++) {
			resource = (Resource) tResources.get(i);
			release(resource);
		}
	}

	public void deleteResource(Resource aResource) {
		if (aResource == null || resources == null || !getResources().contains(aResource))
			return;
		getResourcesTargetedForTermination().add(aResource);

	}

	/**
	 * @return
	 */
	protected List getResourcesTargetedForTermination() {
		if (resourcesTargetedForTermination == null)
			resourcesTargetedForTermination = new ArrayList(5);
		return resourcesTargetedForTermination;
	}



	/**
	 * Remove my reference to aResource, remove it from the ResourceSet, and delete its file from
	 * the Workbench. This only happens if there is currently a reference to
	 * 
	 * @aResource.
	 */
	public void primDeleteResource(Resource aResource) {
		if (primFlushResource(aResource)) {
			try {
				getEmfContext().deleteResource(aResource);
			} catch (CoreException e) {
				//what should we do here?
			}
			if (hasListeners()) {
				EditModelEvent event = new EditModelEvent(EditModelEvent.REMOVED_RESOURCE, this);
				event.addResource(aResource);
				notifyListeners(event);
			}
		}
	}

	/**
	 * Remove my reference to aResource and remove it from the ResourceSet.
	 */
	public void flushResource(Resource aResource) {
		if (primFlushResource(aResource)) {
			if (hasListeners()) {
				EditModelEvent event = new EditModelEvent(EditModelEvent.REMOVED_RESOURCE, this);
				event.addResource(aResource);
				notifyListeners(event);
			}
		}
	}

	public Set getAffectedFiles() {
		Set aSet = new HashSet();
		List mofResources = getResources();
		for (int i = 0; i < mofResources.size(); i++) {
			Resource aResource = (Resource) mofResources.get(i);
			IFile output = WorkbenchResourceHelper.getFile(aResource);
			if (output != null)
				aSet.add(output);
		}
		return aSet;
	}

	protected List resetKnownResourceUris() {

		initializeKnownResourceUris();

		return knownResourceUris;
	}

	/**
	 * Insert the method's description here. Creation date: (4/11/2001 4:14:26 PM)
	 * 
	 * @return java.util.List
	 */
	public List getResources() {
		if (resources == null)
			resources = new ArrayList(5);
		return resources;
	}

	protected String[] getResourceURIs() {
		return getResourceURIs(false);
	}

	protected String[] getResourceURIs(boolean onlyDirty) {
		List list = getResources();
		int dirtyCount = 0;
		String[] uris = new String[list.size()];
		Resource res;
		for (int i = 0; i < list.size(); i++) {
			res = (Resource) list.get(i);
			if (!onlyDirty)
				uris[i] = res.getURI().toString();
			else if (res.isModified()) {
				uris[i] = res.getURI().toString();
				dirtyCount++;
			}
		}
		if (onlyDirty && dirtyCount > 0) {
			String[] dirty = new String[dirtyCount];
			int j = 0;
			for (int i = 0; i < uris.length; i++) {
				if (uris[i] != null) {
					dirty[j] = uris[i];
					j++;
				}
			}
			uris = dirty;
		}
		return uris;
	}

	/**
	 * Returns the first element in the extent of the resource; logs an error and returns null if
	 * the extent is empty
	 */
	public static EObject getRoot(Resource aResource) {
		EList extent = aResource.getContents();
		if (extent.size() < 1)
			return null;
		return (EObject) extent.get(0);
	}

	/**
	 * Handle the failure of
	 * 
	 * @aResource.
	 */
	protected void handleSaveFailed(Resource aResource, Exception e) {
		aResource.setModified(true);
		if (isFailedWriteFileFailure(e) && shouldSaveReadOnly(aResource))
			saveResource(aResource);
		else
			primHandleSaveFailed(aResource, e);
	}

	/**
	 * Return whether any of my resources has been modified.
	 */
	protected boolean isAnyResourceDirty() {
		List list = getResources();
		for (int i = 0; i < list.size(); i++) {
			if (((Resource) list.get(i)).isModified())
				return true;
		}
		return false;
	}

	/**
	 * Return whether a save is needed on the CommandStack
	 */
	public boolean isDirty() {
		return isAnyResourceDirty();
	}

	protected boolean isFailedWriteFileFailure(Exception ex) {
		return SaveHandlerHeadless.isFailedWriteFileFailure(ex);
	}

	/**
	 * Return true if you can only read the resources and not write.
	 */
	public boolean isReadOnly() {
		return readOnly;
	}

	protected boolean isReadOnlyFailure(Exception ex) {
		return false;
	}

	public boolean hasReadOnlyResource() {
		try {
			List list = getResources();
			int size = list.size();
			Resource res = null;
			IFile file;
			for (int i = 0; i < size; i++) {
				res = (Resource) list.get(i);
				file = WorkbenchResourceHelper.getFile(res);
				if (file != null && file.isReadOnly())
					return true;
			}
		} catch (NullPointerException e) {
			System.out.println(e);
		}
		return false;
	}

	/**
	 * @deprecated use createResource(URI) instead
	 */
	public Resource makeResource(String aUri) {
		return createResource(URI.createURI(aUri));
	}

	/**
	 * Return whether any of my resources has a reference count of one and it has been modified.
	 */
	public boolean needsToSave() {
		return !isShared() && isDirty();
	}

	/**
	 * Remove my reference to aResource and remove it from the ResourceSet. Return true if aResource
	 * was removed.
	 */
	protected boolean primFlushResource(Resource aResource) {
		if (aResource != null && hasResourceReference(aResource)) {
			removeResource(aResource);
			removeResourceSetResource(aResource);
			return true;
		}
		return false;
	}

	/**
	 * Handle the failure of
	 * 
	 * @aResource.
	 */
	protected void primHandleSaveFailed(Resource aResource, Exception e) {
		com.ibm.wtp.common.logger.proxy.Logger.getLogger().logError(e);
		Exception nested = null;
		if (e instanceof IWFTWrappedException)
			nested = ((IWFTWrappedException) e).getNestedException();
		else
			nested = e;

		throw new SaveFailedException(EMFWorkbenchResourceHandler.getString("An_error_occurred_while_sa_ERROR_"), nested); //$NON-NLS-1$ = "An error occurred while saving."
	}

	/**
	 * Prompt for a save.
	 */
	protected boolean promptToSave(IOperationHandler operationHandler) {
		if (operationHandler == null)
			return false;
		return operationHandler.canContinue(EMFWorkbenchResourceHandler.getString("The_following_resources_ne_UI_"), getResourceURIs(true)); //$NON-NLS-1$ = "The following resources need to be saved but are currently shared, do you want to save now?"
	}

	/**
	 * This will force all of the referenced Resources to be saved.
	 */
	public void primSave(IProgressMonitor monitor) {
		if (isReadOnly())
			return; //do nothing
		deleteResourcesIfNecessary();
		Resource resource;
		if (getResources().isEmpty())
			return; //nothing to save
		List localResources = getSortedResources();
		for (int i = 0; i < localResources.size(); i++) {
			resource = (Resource) localResources.get(i);
			saveResource(resource);
		}
		getCommandStack().saveIsDone();
		if (hasListeners()) {
			EditModelEvent event = new EditModelEvent(EditModelEvent.SAVE, this);
			notifyListeners(event);
		}
	}

	/**
	 *  
	 */
	protected void deleteResourcesIfNecessary() {
		if (resourcesTargetedForTermination == null || resourcesTargetedForTermination.size() == 0)
			return;
		Resource deadres = null;
		for (int i = 0; i < getResourcesTargetedForTermination().size(); i++) {
			deadres = (Resource) getResourcesTargetedForTermination().get(i);
			primDeleteResource(deadres);

			getResources().remove(deadres);
			getResourcesTargetedForTermination().remove(deadres);
		}
	}



	/**
	 * Save
	 * 
	 * @aResource.
	 */
	protected void primSaveResource(Resource aResource) throws Exception {
		if (aResource.isModified())
			aResource.save(Collections.EMPTY_MAP);
	}

	/**
	 * Process resources that have already been loaded.
	 */
	protected void processLoadedResources() {
		List loaded = getResourceSet().getResources();
		if (!loaded.isEmpty())
			processResourcesIfInterrested(loaded);
	}

	private void processPreloadResources() {
		for (int i = 0; i < preloadResourceUris.size(); i++) {
			URI uri = (URI) preloadResourceUris.get(i);
			getResource(uri);
		}
	}

	/**
	 * Remove aResource from my ResourceSet. Return true if aResource was removed.
	 */
	protected boolean removeResourceSetResource(Resource aResource) {
		aResource.eSetDeliver(false);
		aResource.unload();
		aResource.eSetDeliver(true);
		return getResourceSet().getResources().remove(aResource);
	}

	protected void saveResource(Resource resource) {
		try {
			primSaveResource(resource);
		} catch (Exception e) {
			handleSaveFailed(resource, e);
		}
	}

	/**
	 * Should the resources be saved.
	 */
	protected boolean shouldSave() {
		return !isReadOnly() && !isShared();
	}

	/**
	 * Should the resources be saved.
	 */
	protected boolean shouldSave(IOperationHandler operationHandler) {
		return shouldSave() || promptToSave(operationHandler);
	}

	protected boolean shouldSaveReadOnly(Resource aResource) {
		IFile aFile = WorkbenchResourceHelper.getFile(aResource);
		if (aFile == null || !aFile.isReadOnly())
			return false;

		return getSaveHandler().shouldContinueAndMakeFileEditable(aFile);
	}

	/**
	 * Force all of the known resource URIs to be loaded if they are not already.
	 */
	public void forceLoadKnownResources() {
		List uris = getKnownResourceUris();
		URI uri = null;
		for (int i = 0; i < uris.size(); i++) {
			uri = (URI) uris.get(i);
			getResource(uri);
		}
	}

	/**
	 * This method should be called when you want to extend this edit model to handle a resource
	 * with a URI equal to <code>aRelativeURI</code>.
	 */
	public void manageExtensionResourceURI(String aRelativeURI) {
		if (aRelativeURI != null && aRelativeURI.length() > 0) {
			URI uri = URI.createURI(aRelativeURI);
			if (!isInterrestedInResourceUri(uri)) {
				getKnownResourceUris().add(uri);
				//Process the resource if it is already loaded.
				try {
					Resource res = getEmfContext().getResource(uri);
					if (res != null)
						processResource(res);
				} catch (Exception e) {
				}
			}
		}
	}

	/**
	 * Get a cached Resource or try to load the Resource prior to creating a Resource. This api
	 * handles the case that the Resource may be created during the load.
	 */
	public Resource getOrCreateResource(URI uri) {
		return getResource(uri);
	}

	/**
	 * @return boolean
	 */
	public boolean isAccessAsReadForUnKnownURIs() {
		return accessAsReadForUnKnownURIs;
	}

	/**
	 * Use this api to indicate that you want all unknown Resources to be accessed for ReadOnly.
	 * 
	 * @param b
	 */
	public void setAccessAsReadForUnKnownURIs(boolean b) {
		accessAsReadForUnKnownURIs = b;
	}

	/**
	 * Returns the working copy remembered for the compilation unit.
	 * 
	 * @param input
	 *            ICompilationUnit
	 * @return the working copy of the compilation unit, or <code>null</code> if there is no
	 *         remembered working copy for this compilation unit
	 */
	public org.eclipse.jdt.core.ICompilationUnit getWorkingCopy(org.eclipse.jdt.core.ICompilationUnit cu, boolean forNewCU) throws org.eclipse.core.runtime.CoreException {
		if (isReadOnly())
			return null;
		return getWorkingCopyManager().getWorkingCopy(cu, forNewCU);
	}


	public WorkingCopyManager getWorkingCopyManager() {
		if (workingCopyManager == null)
			workingCopyManager = WorkingCopyManagerFactory.newRegisteredInstance();
		return workingCopyManager;
	}

	/**
	 * Reset the working copy manager because the ejb-jar.xml was removed without disposing.
	 */
	protected void resetWorkingCopyManager() {
		if (workingCopyManager != null) {
			workingCopyManager.dispose();
			workingCopyManager = null;
		}
	}

	public String toString() {
		StringBuffer buffer = new StringBuffer(getClass().getName());
		buffer.append(": "); //$NON-NLS-1$
		if (isReadOnly())
			buffer.append(" R = "); //$NON-NLS-1$
		else
			buffer.append(" W = "); //$NON-NLS-1$
		buffer.append(getRegistry().size());
		buffer.append("[ID: \""); //$NON-NLS-1$
		buffer.append(getEditModelID());
		buffer.append("\" Known Resources: ["); //$NON-NLS-1$
		List uris = getKnownResourceUris();
		if (uris != null) {
			int i = 0;
			for (i = 0; i < (uris.size() - 1); i++)
				buffer.append(uris.get(i) + ", "); //$NON-NLS-1$
			buffer.append(uris.get(i));
			buffer.append("]"); //$NON-NLS-1$
		} else
			buffer.append("none"); //$NON-NLS-1$


		buffer.append("]"); //$NON-NLS-1$
		return buffer.toString();
	}

	public Reference getReference() {
		if (reference == null)
			reference = new Reference();
		return reference;
	}

	/**
	 * @return
	 */
	protected ClientAccessRegistry getRegistry() {
		return registry;
	}

	public class Reference {

		protected String tostring = null;

		/*
		 * (non-Javadoc)
		 * 
		 * @see java.lang.Object#toString()
		 */
		public String toString() {
			if (tostring == null) {
				StringBuffer result = new StringBuffer("EditModel.Reference ["); //$NON-NLS-1$
				result.append("{"); //$NON-NLS-1$
				result.append(getEditModelID());
				result.append("} {"); //$NON-NLS-1$
				result.append(getProject().getName());
				result.append("}]"); //$NON-NLS-1$
				tostring = result.toString();
			}
			return tostring;
		}

		/*
		 * (non-Javadoc)
		 * 
		 * @see java.lang.Object#hashCode()
		 */
		public int hashCode() {
			return toString().hashCode();
		}
	}

	/**
	 * Subclasses can override - by default this will return the first root object from the first
	 * resource referenced by the known resource URIs for this EditModel
	 * 
	 * @return an EObject or Null
	 */
	public EObject getPrimaryRootObject() {
		Resource res = getPrimaryResource();
		if (res == null || res.getContents().isEmpty())
			return null;
		return (EObject) res.getContents().get(0);
	}

	/**
	 * Subclasses can override - by default this will return the first resource referenced by the
	 * known resource URIs for this EditModel
	 * 
	 * @return
	 */
	public Resource getPrimaryResource() {
		if (knownResourceUris == null)
			getKnownResourceUris();
		if (knownResourceUris == null || knownResourceUris.isEmpty())
			return null;

		URI uri = (URI) knownResourceUris.get(0);
		return getResource(uri);
	}



	/*
	 * (non-Javadoc)
	 * 
	 * @see org.eclipse.wst.common.framework.enablement.IEnablementIdentifierListener#identifierChanged(org.eclipse.wst.common.framework.enablement.EnablementIdentifierEvent)
	 */
	public void identifierChanged(EnablementIdentifierEvent evt) {
		if (evt.hasEnabledChanged()) {
			EditModelEvent editModelEvent = new EditModelEvent(EditModelEvent.KNOWN_RESOURCES_ABOUT_TO_CHANGE, this);
			notifyListeners(editModelEvent);
			IEnablementIdentifier id = evt.getIdentifier();
			if (id.isEnabled())
				addKnownResources(id);
			else
				removeKnownResources(id);
			editModelEvent = new EditModelEvent(EditModelEvent.KNOWN_RESOURCES_CHANGED, this);
			notifyListeners(editModelEvent);
		}
	}

	private void removeKnownResources(IEnablementIdentifier id) {
		List editModelResources = getEditModelResources(id);
		EditModelResource editModelResource = null;
		ResourceSetWorkbenchEditSynchronizer sync = (ResourceSetWorkbenchEditSynchronizer) getResourceSetSynchronizer();
		for (int i = 0; i < editModelResources.size(); i++) {
			editModelResource = (EditModelResource) editModelResources.get(i);
			if (editModelResource.isAutoLoad() && sync != null) {
				sync.disableAutoload(editModelResource.getURI());
				preloadResourceUris.remove(editModelResource.getURI());
			}
			knownResourceUris.remove(editModelResource.getURI());
			removeResource(editModelResource.getURI());
		}

	}



	private void addKnownResources(IEnablementIdentifier id) {
		List editModelResources = getEditModelResources(id);
		EditModelResource editModelResource = null;
		ResourceSetWorkbenchEditSynchronizer sync = (ResourceSetWorkbenchEditSynchronizer) getResourceSetSynchronizer();
		for (int i = 0; i < editModelResources.size(); i++) {
			editModelResource = (EditModelResource) editModelResources.get(i);
			if (editModelResource.isAutoLoad() && sync != null) {
				sync.enableAutoload(editModelResource.getURI());
				preloadResourceUris.add(editModelResource.getURI());
				getResource(editModelResource.getURI());
			}
			knownResourceUris.add(editModelResource.getURI());

		}
	}


	/**
	 * @return Returns the params.
	 */
	public Map getParams() {
		return params;
	}

	/**
	 * @param params
	 *            The params to set.
	 */
	public void setParams(Map params) {
		this.params = params;
	}
}