/***************************************************************************************************
 * Copyright (c) 2003, 2005 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.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.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.jem.util.logger.proxy.Logger;
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;


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 {
		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) {
			Logger.getLogger().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 {@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 !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) {
			ex.printStackTrace();
		} 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, getProject(), 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());
		if (resourceExtensions.isEmpty()) {
			knownResourceExtensions = Collections.EMPTY_LIST;
		} else {
			knownResourceExtensions.addAll(resourceExtensions);
			Iterator it = resourceExtensions.iterator();
			ResourceSetWorkbenchEditSynchronizer sync = (ResourceSetWorkbenchEditSynchronizer) getEmfContext().getResourceSet().getSynchronizer();
			while (it.hasNext()) {
				String extension = (String) iter.next();
				sync.enableAutoload(extension);
			}
		}
	}

	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) {
			Logger.getLogger().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 someResources) {
		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) {
		org.eclipse.jem.util.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) {
					// 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;
	}

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