/*******************************************************************************
 * Copyright (c) 2003, 2007 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.internal.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.IWorkspace;
import org.eclipse.core.resources.IWorkspaceRunnable;
import org.eclipse.core.resources.ResourcesPlugin;
import org.eclipse.core.runtime.Assert;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.ISafeRunnable;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.ListenerList;
import org.eclipse.core.runtime.SafeRunner;
import org.eclipse.core.runtime.Status;
import org.eclipse.emf.common.command.BasicCommandStack;
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.jem.internal.util.emf.workbench.nls.EMFWorkbenchResourceHandler;
import org.eclipse.jem.util.emf.workbench.ResourceSetWorkbenchSynchronizer;
import org.eclipse.jem.util.emf.workbench.WorkbenchResourceHelperBase;
import org.eclipse.wst.common.frameworks.internal.ISaveHandler;
import org.eclipse.wst.common.frameworks.internal.SaveFailedException;
import org.eclipse.wst.common.frameworks.internal.SaveHandlerHeadless;
import org.eclipse.wst.common.frameworks.internal.SaveHandlerRegister;
import org.eclipse.wst.common.frameworks.internal.enablement.EnablementIdentifierEvent;
import org.eclipse.wst.common.frameworks.internal.enablement.IEnablementIdentifier;
import org.eclipse.wst.common.frameworks.internal.enablement.IEnablementIdentifierListener;
import org.eclipse.wst.common.frameworks.internal.enablement.nonui.IWFTWrappedException;
import org.eclipse.wst.common.frameworks.internal.operations.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.ExtendedEcoreUtil;
import org.eclipse.wst.common.internal.emf.utilities.PleaseMigrateYourCodeError;
import org.eclipse.wst.common.internal.emfworkbench.EMFWorkbenchContext;
import org.eclipse.wst.common.internal.emfworkbench.WorkbenchResourceHelper;
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.edit.ReadOnlyClientAccessRegistry;
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.emfworkbench.integration.EMFWorkbenchEditPlugin;


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

	protected BasicCommandStack commandStack;
	protected final ListenerList listeners = new ListenerList();

	private Map params;
	private final String editModelID;
	private final boolean readOnly;
	// These are the current resource uris we need to track
	protected List knownResourceUris;
	// These are the current resource extensions to track
	protected List knownResourceExtensions;
	// 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;
	private boolean disposed = false;
	protected ResourceStateValidator stateValidator;
	protected boolean accessAsReadForUnKnownURIs;
	protected ResourceAdapter resourceAdapter = new ResourceAdapter();
	protected boolean isReverting = false;
	protected List resources;
	private ClientAccessRegistry registry;
	protected EMFWorkbenchContext emfContext = null;
	protected IProject project = null;

	private Reference reference;
	private List resourcesTargetedForTermination;

	protected class ResourceAdapter extends AdapterImpl {
		@Override
		public void notifyChanged(Notification notification) {
			if (!isDisposing() && 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) {
		if (context == null)
			throw new IllegalStateException("EMF context can't be null"); //$NON-NLS-1$
		this.editModelID = editModelID;
		this.readOnly = readOnly;
		if (readOnly)
			this.registry = new ReadOnlyClientAccessRegistry();
		else
			this.registry = new ClientAccessRegistry();
		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;
	}

	public boolean isDisposing() {
		return disposing;
	}

	
	/**
	 * Subclasses should not override this method. This method will be made
	 * final in the next release. Subclasses should override doDispose() as
	 * necessary to dispose any additional artifacts.
	 */
	public void dispose() {
		try {
			if (disposing || disposed)
				return;
			disposing = true;
		
			if (hasListeners())
				notifyListeners(new EditModelEvent(EditModelEvent.PRE_DISPOSE, this));
			
			releaseResources();

			if (commandStack != null)
				commandStack.removeCommandStackListener(this);
			if (getEmfContext() != null)
				getEmfContext().removeEditModel(this, isReadOnly());
			releasePreloadResources();
			releaseIdentifiers();
			doDispose();
		} catch (RuntimeException re) {
			EMFWorkbenchEditPlugin.logError(re);
		} finally {
			emfContext = null;
			resources = null;
			project = null;
			disposed = true;
			disposing = false;
		}
	}

	/**
	 * Subclasses should override as necessary
	 */
	protected void doDispose() {
	}

	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);
			}
			for (int i = 0; i < knownResourceExtensions.size(); i++) {
				String ext = (String) knownResourceExtensions.get(i);
				sync.disableAutoload(ext);
			}
		}
	}


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

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

	/**
	 * This is called with the {@linkorg.eclipse.emf.common.command.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 !listeners.isEmpty();
	}

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

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

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

	/**
	 * Notify listeners of
	 * 
	 * @anEvent.
	 */
	protected void notifyListeners(final EditModelEvent anEvent) {
		
		NotifyRunner notifier = new NotifyRunner(anEvent); 
		
		Object[] notifyList = listeners.getListeners(); 
		for (int i = 0; i < notifyList.length; i++) {
			notifier.setListener( (EditModelListener) notifyList[i] );
			SafeRunner.run(notifier);
		}
	}

	/**
	 * Remove
	 * 
	 * @aListener from the list of listeners.
	 */
	public boolean removeListener(EditModelListener aListener) {
		listeners.remove(aListener);
		return true;
	}

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

	protected void makeFileEditable(IFile aFile) {
		if (aFile == null)
			return;
		aFile.getResourceAttributes().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) {
		// do nothing
	}

	/**
	 * 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 {
		// save
	}

	/**
	 * 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);
		} catch (Exception ex) {
			EMFWorkbenchEditPlugin.logError(ex);
		} 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);
	}

	protected void runSaveOperation(IWorkspaceRunnable runnable, IProgressMonitor monitor) throws SaveFailedException {
		try {
			ResourcesPlugin.getWorkspace().run(runnable, ResourcesPlugin.getWorkspace().getRoot(), IWorkspace.AVOID_UPDATE, 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.getInstance().getEditModelResources(getEditModelID());
		Iterator iter = editModelResources.iterator();
		while (iter.hasNext()) {
			res = (EditModelResource) iter.next();
			addEditModelResource(res);
		}
		Collection resourceExtensions = EditModelRegistry.getInstance().getEditModelExtensions(getEditModelID());
		/* bug 170690 - initialize knownResourceExtensions if necessary, and change reference from iter to it */
		if (knownResourceExtensions == null)
		{
			knownResourceExtensions = new ArrayList();
		}
		if (!resourceExtensions.isEmpty())
		{
			knownResourceExtensions.addAll(resourceExtensions);
			Iterator it = resourceExtensions.iterator();
			ResourceSetWorkbenchEditSynchronizer sync = (ResourceSetWorkbenchEditSynchronizer) getEmfContext().getResourceSet().getSynchronizer();
			while (it.hasNext()) {
				sync.enableAutoload(it.next().toString());
			}
		}
	}

	private void addEditModelResource(EditModelResource res) {
		boolean enabled = false;
		try {
			if (res.isCore()) {
				enabled = true;
			} else {
				IEnablementIdentifier identifier = res.getEnablementIdentifier(getProject());
				registerInterest(identifier, res);
				enabled = identifier.isEnabled();
			}
		} catch (RuntimeException re) {
			EMFWorkbenchEditPlugin.logWarning(re);
		}
		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) {
		// do nothing
	}

	/**
	 * @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 {
		if (presenter == null)
			return Status.OK_STATUS;
		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 && !disposing && 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.
	 */
	// TODO The following method will only use the last segment when looking for a resource.
	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) {
				// Ignore
			}
		}
		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 aSomeResources) {
		List someResources = new ArrayList(aSomeResources);
		int size = someResources.size();
		Resource res;
		boolean processed = false;
		for (int i = 0; i < size; i++) {
			res = (Resource) someResources.get(i);
			if ((res != null) && (isInterrestedInResource(res))) {
				processResource(res);
				processed = true;
			}
		}
		return processed;
	}

	public EMFWorkbenchContext getEmfContext() {
		if (isDisposed())
			throw new IllegalStateException("Edit Model already disposed"); //$NON-NLS-1$
		if (emfContext == null)
			throw new IllegalStateException("EMF context is null"); //$NON-NLS-1$
		return emfContext;
	}

	public boolean isDisposed() {
		return disposed;
	}



	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) {

		registry.release(accessorKey);

		if (!isDisposing()) {
			boolean shouldDispose = false;
			shouldDispose = registry.size() == 0;
			if (shouldDispose) {
				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;
	}

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

	public 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) {
		EMFWorkbenchEditPlugin.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) {
					// Ignore
				}
			}
		}
	}

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

	@Override
	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()
		 */
		@Override
		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()
		 */
		@Override
		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 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.frameworks.internal.enablement.IEnablementIdentifierListener#identifierChanged(org.eclipse.wst.common.frameworks.internal.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;
	}
	
	public class NotifyRunner implements ISafeRunnable { 
		
		private final EditModelEvent event;
		private EditModelListener listener;
		
		public NotifyRunner(EditModelEvent event) {
			Assert.isNotNull(event);
			this.event = event;
		}
		
		
		public void setListener(EditModelListener listener) {
			this.listener = listener;
		}

		public void handleException(Throwable exception) { 
			EMFWorkbenchEditPlugin.getDefault().getLog().log(new Status(IStatus.ERROR, EMFWorkbenchEditPlugin.ID, 0, exception.getMessage(), exception));
			
		}

		public void run() throws Exception {
			if(listener != null)
				listener.editModelChanged(event); 
		}
		
	}
}
