//------------------------------------------------------------------------------
// Copyright (c) 2005, 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 implementation
//------------------------------------------------------------------------------
package org.eclipse.epf.diagram.core.services;

import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;

import org.eclipse.core.commands.ExecutionException;
import org.eclipse.core.internal.events.ResourceChangeEvent;
import org.eclipse.core.resources.IFile;
import org.eclipse.core.resources.IResource;
import org.eclipse.core.resources.IResourceChangeEvent;
import org.eclipse.core.resources.IResourceChangeListener;
import org.eclipse.core.resources.IResourceStatus;
import org.eclipse.core.resources.ResourcesPlugin;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IAdaptable;
import org.eclipse.core.runtime.IPath;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.NullProgressMonitor;
import org.eclipse.core.runtime.Path;
import org.eclipse.core.runtime.Status;
import org.eclipse.emf.common.notify.Adapter;
import org.eclipse.emf.common.notify.Notification;
import org.eclipse.emf.common.notify.impl.AdapterImpl;
import org.eclipse.emf.common.util.BasicEList;
import org.eclipse.emf.common.util.URI;
import org.eclipse.emf.common.util.UniqueEList;
import org.eclipse.emf.common.util.WrappedException;
import org.eclipse.emf.ecore.EModelElement;
import org.eclipse.emf.ecore.EObject;
import org.eclipse.emf.ecore.InternalEObject;
import org.eclipse.emf.ecore.resource.Resource;
import org.eclipse.emf.ecore.util.EcoreUtil;
import org.eclipse.emf.ecore.xmi.XMIResource;
import org.eclipse.emf.ecore.xmi.XMLHelper;
import org.eclipse.emf.edit.domain.EditingDomain;
import org.eclipse.emf.transaction.impl.InternalTransactionalEditingDomain;
import org.eclipse.emf.workspace.AbstractEMFOperation;
import org.eclipse.emf.workspace.util.WorkspaceSynchronizer;
import org.eclipse.epf.common.CommonPlugin;
import org.eclipse.epf.diagram.core.DiagramCorePlugin;
import org.eclipse.epf.diagram.core.bridge.BridgeHelper;
import org.eclipse.epf.diagram.core.providers.AccessibleDiagramModificationListener;
import org.eclipse.epf.diagram.core.services.FileSynchronizer.FileInfo;
import org.eclipse.epf.diagram.model.ActivityDetailDiagram;
import org.eclipse.epf.diagram.model.ModelFactory;
import org.eclipse.epf.diagram.model.WorkProductDependencyDiagram;
import org.eclipse.epf.diagram.model.impl.DiagramImpl;
import org.eclipse.epf.diagram.model.util.TxUtil;
import org.eclipse.epf.library.ILibraryServiceListener;
import org.eclipse.epf.library.LibraryService;
import org.eclipse.epf.library.LibraryServiceListener;
import org.eclipse.epf.library.LibraryServiceUtil;
import org.eclipse.epf.library.edit.util.IDiagramManager;
import org.eclipse.epf.library.edit.util.ProcessUtil;
import org.eclipse.epf.library.edit.util.TngUtil;
import org.eclipse.epf.library.persistence.ILibraryResource;
import org.eclipse.epf.library.persistence.internal.IFailSafeSavable;
import org.eclipse.epf.library.persistence.util.ExtendedResourceSet;
import org.eclipse.epf.persistence.FailSafePersistenceHelper;
import org.eclipse.epf.persistence.FileManager;
import org.eclipse.epf.persistence.MultiFileSaveUtil;
import org.eclipse.epf.persistence.MultiFileURIConverter;
import org.eclipse.epf.services.ILibraryPersister;
import org.eclipse.epf.uma.Activity;
import org.eclipse.epf.uma.MethodLibrary;
import org.eclipse.epf.uma.Process;
import org.eclipse.epf.uma.ProcessComponent;
import org.eclipse.epf.uma.util.UmaUtil;
import org.eclipse.gmf.runtime.common.core.util.StringStatics;
import org.eclipse.gmf.runtime.diagram.core.DiagramEditingDomainFactory;
import org.eclipse.gmf.runtime.diagram.core.preferences.PreferencesHint;
import org.eclipse.gmf.runtime.diagram.core.services.ViewService;
import org.eclipse.gmf.runtime.diagram.ui.resources.editor.ide.internal.l10n.EditorMessages;
import org.eclipse.gmf.runtime.diagram.ui.resources.editor.internal.util.DiagramIOUtil;
import org.eclipse.gmf.runtime.emf.core.internal.util.EMFCoreConstants;
import org.eclipse.gmf.runtime.emf.core.resources.GMFHelper;
import org.eclipse.gmf.runtime.emf.core.resources.GMFResource;
import org.eclipse.gmf.runtime.emf.core.resources.GMFResourceFactory;
import org.eclipse.gmf.runtime.notation.Diagram;
import org.eclipse.gmf.runtime.notation.View;
import org.eclipse.ui.PlatformUI;
import org.eclipse.uml2.uml.UMLFactory;

/**
 * @author Phong Nguyen Le
 * 
 * @since 1.2
 */
public class DiagramManager {	
	private static final boolean DEBUG = DiagramCorePlugin.getDefault().isDebugging();
	
	private static final String DIAGRAM_FILENAME_WITHOUT_EXTENSION = "diagram"; //$NON-NLS-1$
	
	private static final String DIAGRAM_FILENAME = DIAGRAM_FILENAME_WITHOUT_EXTENSION + MultiFileSaveUtil.DEFAULT_FILE_EXTENSION;

	private static final Map<Process, DiagramManager> processToDiagramManagerMap = new HashMap<Process, DiagramManager>();
	
	private static ILibraryServiceListener libSvcListener;
	
	private static final FileSynchronizer fileSynchronizer = new FileSynchronizer() {
		@Override
		protected Collection<IFile> handleChangedFiles(Collection<IFile> changedFiles) {
			try {
				Collection<DiagramManager> mgrs = getDiagramManagers();
				if(!mgrs.isEmpty()) {
					Collection<IFile> handledFiles = new ArrayList<IFile>();
					for (DiagramManager mgr : mgrs) {
						Resource resource = mgr.getResource(false);
						if(resource != null && resource.isLoaded()) {
							IFile file = WorkspaceSynchronizer.getFile(mgr.getResource());
							if(changedFiles.contains(file)) {
								try {									
									mgr.reload();
									handledFiles.add(file);
								} catch (IOException e) {
									CommonPlugin.getDefault().getLogger().logError(e);
									if(DEBUG) {
										e.printStackTrace();
									}
								}
							}
						}
					}
					return handledFiles;
				}
			}
			catch(CoreException e) {
				handleCoreException(e, e.getMessage());
			}
			return Collections.emptyList();
		}
		
		@Override
		protected Map<IFile, IPath> handleMovedFiles(Map<IFile, IPath> movedFileToNewPathMap) {
			for (Map.Entry<IFile, IPath> entry : movedFileToNewPathMap.entrySet()) {
				IFile iFile = entry.getKey();
				if(DIAGRAM_FILENAME.equals(iFile.getName())) {
					synchronized (processToDiagramManagerMap) {
						DiagramManager mgr = getDiagramManager(iFile);
						if(mgr != null) {
							mgr.updateResourceURI();
						}
					}
				}
			}
			return super.handleMovedFiles(movedFileToNewPathMap);
		}
		
		@Override
		protected Collection handleDeletedFiles(Collection<IFile> deletedFiles) {
			// TODO Auto-generated method stub
			return super.handleDeletedFiles(deletedFiles);
		}
	};

	public static final String ADD_kind = "ADD"; //$NON-NLS-1$

	public static final String AD_kind = "AD"; //$NON-NLS-1$

	public static final String WPD_kind = "WPDD"; //$NON-NLS-1$	
	
	private static DiagramManager getDiagramManager(IFile iFile) {
		for (Iterator iterator = processToDiagramManagerMap.values().iterator(); iterator
		.hasNext();) {
			DiagramManager mgr = (DiagramManager) iterator.next();
			if(mgr.resource != null && iFile.equals(WorkspaceSynchronizer.getFile(mgr.resource))) {
				return mgr;
			}
		}
		return null;
	}
	
	public static void disposeDiagramManagers(MethodLibrary library) {
		synchronized(processToDiagramManagerMap) {
			for (Iterator<Map.Entry<Process, DiagramManager>> iterator = processToDiagramManagerMap.entrySet().iterator(); iterator.hasNext();) {
				Map.Entry<Process, DiagramManager> entry = iterator.next();
				if(UmaUtil.getMethodLibrary(entry.getKey()) == library) {
					entry.getValue().doDispose();
					iterator.remove();
				}
			}
		}
	}
	
	private static synchronized void setupLibraryServiceListener() {
		if(libSvcListener == null) {
			libSvcListener = new LibraryServiceListener() {
				
				@Override
				public void libraryClosed(MethodLibrary library) {
					disposeDiagramManagers(library);
				}
				
				@Override
				public void libraryReopened(MethodLibrary library) {
					disposeDiagramManagers(library);
				}
			};
			LibraryService.getInstance().addListener(libSvcListener);
		}
	}
	
	/**
	 * Gets a instance of DiagramManager for the specified process. Caller must
	 * release the returned DiagramManager instance when it's no longer needed
	 * using {@link #removeConsumer(Object)}.
	 * 
	 * @param process
	 * @return
	 */
	public static final DiagramManager getInstance(Process process, Object consumer) {
		if(DEBUG) {
			if(process.eIsProxy()) {
				System.err.println("Process is a proxy: " + process); //$NON-NLS-1$
			}
		}
		assert process != null && consumer != null && !process.eIsProxy();
		setupLibraryServiceListener();
		DiagramManager mgr = (DiagramManager) processToDiagramManagerMap.get(process);
		if(mgr != null && mgr.isDisposed()) {
			processToDiagramManagerMap.remove(process);
			mgr = null;
		}
		if(mgr == null) {
			synchronized(processToDiagramManagerMap) {
				mgr = (DiagramManager) processToDiagramManagerMap.get(process);
				if(mgr == null) {
					mgr = new DiagramManager(process);
					processToDiagramManagerMap.put(process, mgr);
					if(!fileSynchronizer.fIsInstalled) {
						fileSynchronizer.install();
					}
				}
			}			
		}
		mgr.addConsumer(consumer);
		return mgr;
	}
	
	/**
	 * Checks if an diagram manager for the given process already exists.
	 * 
	 * @param process
	 * @return
	 */
	public static final boolean hasDiagramManager(Process process) {
		return processToDiagramManagerMap.containsKey(process);
	}
	
	public static boolean disposeDiagramManager(Process process) {
		synchronized (processToDiagramManagerMap) {
			DiagramManager mgr = processToDiagramManagerMap.get(process);
			if(mgr != null) {
				mgr.doDispose();
				processToDiagramManagerMap.remove(process);
				return true;
			}
			return false;
		}
	}
	
	@SuppressWarnings("unchecked")
	public static Collection<DiagramManager> getDiagramManagers() {
		ArrayList<DiagramManager> mgrs;
		synchronized(processToDiagramManagerMap) {
			mgrs = new ArrayList<DiagramManager>(processToDiagramManagerMap.values());
		}
		return mgrs.isEmpty() ? Collections.EMPTY_LIST : mgrs;
	}
	
	private class GMFResourceEx extends GMFResource implements IFailSafeSavable {

		private FailSafePersistenceHelper failSafePersistenceHelper;

		public GMFResourceEx(URI uri) {
			super(uri);
		}
		
		@Override
		protected XMLHelper createXMLHelper() {					
			return new GMFHelper(this) {
				
				protected URI getHREF(Resource otherResource, EObject obj) {
					if(otherResource instanceof ILibraryResource) {
						return ((ILibraryResource)otherResource).getProxyURI(obj);
					}
					return super.getHREF(otherResource, obj);
				}
				
			};
		}
		
		public void updateInfo() {
			IFile file = WorkspaceSynchronizer.getFile(this);
			if(DiagramManager.this.resourceIsNew) {
				DiagramManager.this.resourceIsNew = false;
				fileSynchronizer.monitor(file);
			}
			fileSynchronizer.updateModificationStamp(file);
			try {
				file.refreshLocal(IResource.DEPTH_ZERO, null);
			} catch (CoreException e) {
				CommonPlugin.getDefault().getLogger().logError(e);
			}
		}
		
		@Override
		public void save(Map options) throws IOException {
			super.save(options);
			if(!hasTempURI()) {
				updateInfo();
			}
		}
		
		private Adapter superCreateModificationAdapter() {
			return super.createModificationTrackingAdapter();
		}
		
		@Override
		protected Adapter createModificationTrackingAdapter() {
			return new AdapterImpl() {
				private Adapter delegate = superCreateModificationAdapter();
				
				@Override
				public void notifyChanged(Notification msg) {
					delegate.notifyChanged(msg);
					notifyDiagramChangeListeners(msg);
				}
			};
		}
		
		/**
		 * Don't notify DiagramModificationListener about resource modification event but rather
		 * let {@link #notifyDiagramChangeListeners(Notification) handle it.
		 */
		@Override
		public void eNotify(Notification notification) {
			if(isLoaded() && notification.getNotifier() instanceof Resource 
					&& notification.getFeatureID(Resource.class) == Resource.RESOURCE__IS_MODIFIED
					&& notification.getEventType() == Notification.SET) {
				if (eAdapters != null && eDeliver())
				{
					int size = eAdapters.size();
					if (size > 0)
					{
						Adapter [] adapters = (Adapter [])eAdapters.data();
						for (int i = 0; i < size; ++i)
						{
							Adapter adapter = adapters[i];
							if(!(adapter instanceof AccessibleDiagramModificationListener)) {
								adapter.notifyChanged(notification);
							}
						}
					}
				}
			}
			else {
				super.eNotify(notification);
			}
		}

		protected void notifyDiagramChangeListeners(Notification msg) {
			BasicEList<Adapter> eAdapters = eBasicAdapters();
			if (eAdapters != null && eDeliver())
			{
				int size = eAdapters.size();
				if (size > 0)
				{
					Adapter [] adapters = (Adapter [])eAdapters.data();
					for (int i = 0; i < size; ++i)
					{
						Adapter adapter = adapters[i];
						if(adapter instanceof AccessibleDiagramModificationListener) {
							adapter.notifyChanged(msg);
						}
					}
				}
			}
		}
		
		private FailSafePersistenceHelper getFailSafePersistenceHelper() {
			if(failSafePersistenceHelper == null) {
				// id format: <process_guid>diagram
				String id = DiagramManager.this.process.getGuid() + DIAGRAM_FILENAME_WITHOUT_EXTENSION;
				failSafePersistenceHelper = new FailSafePersistenceHelper(this, id);
				failSafePersistenceHelper.setCommitEmptyResource(true);
			}
			return failSafePersistenceHelper;
		}

		public void commit() {
			getFailSafePersistenceHelper().commit();
		}

		public void deleteBackup() {
			getFailSafePersistenceHelper().deleteBackup();
		}

		public boolean hasTempURI() {
			return getFailSafePersistenceHelper().hasTempURI();
		}

		public boolean restore() {
			return getFailSafePersistenceHelper().restore();
		}

		public void setTxID(String txID) {
			getFailSafePersistenceHelper().setTempURI(txID);
		}

		public void txFinished(boolean successful) {
			getFailSafePersistenceHelper().txFinished(successful);
			if(successful) {
				updateInfo();
			}
		}
		
		@Override
		protected void doUnload() {
			super.doUnload();
			
		    Iterator<EObject> allContents = getAllProperContents(unloadingContents);
		    List<EObject> list = new ArrayList<EObject>();
			while (allContents.hasNext()) {
				list.add(allContents.next());
			}
			for (EObject object : list) {
				EcoreUtil.remove(object);
			}
		}
		
	}
	
	private class GMFExtendedResourceSet extends ExtendedResourceSet {
		@Override
		protected int getURIType(URI uri) {
			if(MultiFileURIConverter.SCHEME.equals(uri.scheme())) {
				return URI_TYPE_EXTERNAL;
			}
			if(DIAGRAM_FILENAME.equals(uri.lastSegment())) {
				return URI_TYPE_LOCAL;
			}
			return URI_TYPE_EXTERNAL;
 		}
		
		@SuppressWarnings("unchecked")
		@Override
		public Resource createResource(URI uri) {
			XMIResource resource = new GMFResourceEx(uri);

			resource.getDefaultLoadOptions().putAll(GMFResourceFactory.getDefaultLoadOptions());
			resource.getDefaultSaveOptions().putAll(GMFResourceFactory.getDefaultSaveOptions());

			if (!resource.getEncoding().equals(EMFCoreConstants.XMI_ENCODING))
				resource.setEncoding(EMFCoreConstants.XMI_ENCODING);

			getResources().add(resource);
			
			return resource;
		}
		
	}

	/**
	 * Reference count to this diagram manager
	 */
	private Process process;
	
	private Resource resource;
	
	private InternalTransactionalEditingDomain editingDomain;

	private IProgressMonitor monitor;

	private boolean resourceIsNew;
	
	private List<IResourceChangeListener> resourceChangeListeners = new UniqueEList<IResourceChangeListener>();

	private ExtendedResourceSet resourceSet;

	private HashMap<Activity, Map<String, Diagram>> activityToSavedDiagramMap; 
	
	protected UniqueEList<Object> consumers = new UniqueEList<Object>();
	
	private DiagramManager(Process process) {
		this.process = process;
	}
	
	public Process getProcess() {
		return process;
	}
	
	public void addResourceChangeListener(IResourceChangeListener listener) {
		if(!resourceChangeListeners.contains(listener)) {
			resourceChangeListeners.add(listener);
		}
	}
	
	public void removeResourceChangeListener(IResourceChangeListener listener) {
		resourceChangeListeners.remove(listener);
	}
	
	public synchronized boolean addConsumer(Object consumer) {
		return consumers.add(consumer);
	}
	
	/**
	 * Removes the given consumer from the consumer list of this diagram manager. Unload
	 * this diagram manager if it does not have any more consumer after this call. 
	 */
	public synchronized boolean removeConsumer(Object consumer) {
		boolean ret = consumers.remove(consumer);
		if(ret && consumers.isEmpty()) {
			synchronized(processToDiagramManagerMap) {
				processToDiagramManagerMap.remove(process);
				if(processToDiagramManagerMap.isEmpty()) {
					fileSynchronizer.uninstall();
				}
			}
			doDispose();
		}
		return ret;
	}
	
	public boolean isNewResource() {
		return resourceIsNew;
	}
	
	public void setResourceIsNew(boolean resourceIsNew) {
		this.resourceIsNew = resourceIsNew;
	}
	
	public InternalTransactionalEditingDomain getEditingDomain() {
		if (editingDomain == null && !isDisposed()) {
			editingDomain = createEditingDomain();
			resourceSet = (ExtendedResourceSet) editingDomain.getResourceSet();
		}
		return editingDomain;
	}
	
	private InternalTransactionalEditingDomain createEditingDomain() {
		GMFExtendedResourceSet resourceSet = new GMFExtendedResourceSet();
		resourceSet.add(process.eResource().getResourceSet());
		return (InternalTransactionalEditingDomain) DiagramEditingDomainFactory.getInstance()
				.createEditingDomain(resourceSet);
	}
	
	private void doDispose() {
		if(resource != null) {
			IFile file = WorkspaceSynchronizer.getFile(resource);
			if(file != null) {
				fileSynchronizer.unmonitor(file);				
			}
			resource = null;
		}

		resourceChangeListeners.clear();
		
		if(editingDomain != null) {
			resourceSet.dispose();
			resourceSet = null;

			editingDomain.dispose();
			editingDomain = null;			
		}	
		
		consumers.clear();
		
		if(activityToSavedDiagramMap != null) {
			activityToSavedDiagramMap.clear();
		}
		
		process = null;
	}
	
	public void dispose() {
		synchronized (processToDiagramManagerMap) {
			processToDiagramManagerMap.remove(process);
		}
		doDispose();
	}
	
	public boolean isDisposed() {
		return process == null;
	}
	
	/**
	 * Gets diagrams of the given type for the specified activity
	 * <code>act</code>
	 * 
	 * @param act
	 * @param type
	 *            must be one of the following constants:
	 *            {@link IDiagramManager#ACTIVITY_DIAGRAM},
	 *            {@link IDiagramManager#ACTIVITY_DETAIL_DIAGRAM},
	 *            {@link IDiagramManager#WORK_PRODUCT_DEPENDENCY_DIAGRAM}
	 * @return
	 * @throws CoreException
	 */
	public List<Diagram> getDiagrams(Activity act, int type) throws CoreException {
		checkActivity(act);
		Resource resource = getResource(false);
		if(resource != null) {
			ArrayList<Diagram> diagrams = new ArrayList<Diagram>();
			for (EObject o : resource.getContents()) {
				if(o instanceof Diagram) {
					Diagram diagram = (Diagram) o;
					String typeStr = getDiagramTypeString(type);
					if(typeStr.equals(diagram.getType()) && isDiagramOf(diagram, act)) {
						EObject model = diagram.getElement();
						if(model instanceof DiagramImpl) {
							// disable creation of UMA graphical data
							//
							((DiagramImpl)model).setGraphicalDataRequired(false);
						}
						diagrams.add(diagram);
					}
				}
			}
			if(!diagrams.isEmpty()) {
				return diagrams;
			}
		}
		return Collections.emptyList();
	}
	
	private static void markInherited(Diagram diagram) {
		List<?> children = diagram.getChildren();
		int size = children.size();		
		for (int i = 0; i < size; i++) {
			View view = (View) children.get(i);
			BridgeHelper.markInherited(view);
		}
		for (Object edge : diagram.getEdges()) {
			BridgeHelper.markInherited((View) edge);
		}
	}
	
	private static String getDiagramTypeString(int diagramType) {
		switch(diagramType) {
		case IDiagramManager.ACTIVITY_DETAIL_DIAGRAM:
			return ADD_kind;
		case IDiagramManager.ACTIVITY_DIAGRAM:
			return AD_kind;
		case IDiagramManager.WORK_PRODUCT_DEPENDENCY_DIAGRAM:
			return WPD_kind;
		}
		return null;
	}
	
	public static int getDiagramType(String typeStr) {
		if(AD_kind.equals(typeStr)) {
			return IDiagramManager.ACTIVITY_DIAGRAM;			
		}
		else if(ADD_kind.equals(typeStr)) {
			return IDiagramManager.ACTIVITY_DETAIL_DIAGRAM;			
		}
		else if(WPD_kind.equals(typeStr)) {
			return IDiagramManager.WORK_PRODUCT_DEPENDENCY_DIAGRAM;
		}
		return -1;
	}
	
	/**
	 * Associates a new diagram with the given activity
	 * 
	 * @param diagram
	 * @param type
	 * @param activity
	 * @throws CoreException 
	 */
	public void associate(Diagram newDiagram, int type, Activity activity) throws CoreException {
		switch(type) {
		case IDiagramManager.ACTIVITY_DIAGRAM:
			associateAD(newDiagram, activity);
			return;
		case IDiagramManager.ACTIVITY_DETAIL_DIAGRAM:
			associateADD(newDiagram, activity);
			return;
		case IDiagramManager.WORK_PRODUCT_DEPENDENCY_DIAGRAM:
			associateWPD(newDiagram, activity);	
		}
	}
	
	private void associateWPD(Diagram copy, Activity activity) throws CoreException {
		// TODO - consolidate one method with ADD.
		if(copy.getElement() instanceof WorkProductDependencyDiagram) {
			((WorkProductDependencyDiagram)copy.getElement()).setLinkedElement(activity);
			((DiagramImpl)copy.getElement()).setGraphicalDataRequired(false);
		}
		getResource().getContents().add(copy.getElement());
		getResource().getContents().add(copy);	
	}

	private void associateAD(Diagram copy, Activity act) throws CoreException {
		if(copy.getElement() instanceof EModelElement) {
			BridgeHelper.associate((EModelElement) copy.getElement(), act);
		}
		getResource().getContents().add(copy.getElement());
		getResource().getContents().add(copy);
	}
	
	private void associateADD(Diagram copy, Activity activity) throws CoreException {
		if(copy.getElement() instanceof ActivityDetailDiagram) {
			((ActivityDetailDiagram)copy.getElement()).setLinkedElement(activity);
			((DiagramImpl)copy.getElement()).setGraphicalDataRequired(false);
		}
		getResource().getContents().add(copy.getElement());
		getResource().getContents().add(copy);		
	}
	
	private Diagram copyDiagram(Diagram diagram, Activity targetActivity) {
		Diagram copy = DiagramHelper.copyDiagram(getEditingDomain(), diagram);
		DiagramHelper.reassociate(targetActivity, copy);
		return copy;
	}

	public Diagram createDiagram(final Activity act, final int type, final PreferencesHint hint) throws CoreException {
		checkActivity(act);
		// check if this activity contributes/extends other activity and try
		// copy
		// the existing diagram from the base
		//
		if (ProcessUtil.isExtendingOrLocallyContributing(act)) {
			Activity baseAct = (Activity) act.getVariabilityBasedOnElement();
			DiagramManager mgr = DiagramManager.getInstance(TngUtil.getOwningProcess(baseAct), this);
			try {
				List baseDiagrams = mgr.getDiagrams(baseAct, type);
				if(!baseDiagrams.isEmpty()) {
					Diagram baseDiagram = (Diagram) baseDiagrams.get(0);
					if (baseDiagram != null) {
						final Diagram copy = copyDiagram(baseDiagram, act);
						TxUtil.runInTransaction(getEditingDomain(), new Runnable() {

							public void run() {
								markInherited(copy);
								try {
									associate(copy, type, act);
								} catch (CoreException e) {
									throw new WrappedException(e);
								}
							}
							
						});
						return copy;
					}
				}
			} catch(Exception e){
				CommonPlugin.getDefault().getLogger().logError("Error in retrieving base diagram: ", e); //$NON-NLS-1$
			}
			finally {
				if(mgr != null) {
					mgr.removeConsumer(this);
				}
			}
		}
				
		
		final Diagram[] resultHolder = new Diagram[1];
		try {
			TxUtil.runInTransaction(getEditingDomain(), new Runnable() {

				public void run() {
					try {
						resultHolder[0] = doCreateDiagram(act, type, hint);
					} catch (CoreException e) {
						throw new WrappedException(e);
					}
				}
				
			});
		} catch (Exception e) {
			DiagramCorePlugin.getDefault().getLogger().logError(e);
			if(DEBUG) {
				e.printStackTrace();
			}
		}
		return resultHolder[0];
	}
	
	private Diagram doCreateDiagram(Activity act, int type, PreferencesHint hint) throws CoreException {
		switch(type) {
		case IDiagramManager.ACTIVITY_DIAGRAM:
			return createAD(act, hint);
		case IDiagramManager.ACTIVITY_DETAIL_DIAGRAM:
			return createADD(act, hint);
		case IDiagramManager.WORK_PRODUCT_DEPENDENCY_DIAGRAM:
			return createWPDD(act, hint);
		}
		return null;
	}

	private Diagram createWPDD(Activity act, PreferencesHint hint)
			throws CoreException {
		// ProcessPackage model = (ProcessPackage) act.eContainer();
		WorkProductDependencyDiagram model = ModelFactory.eINSTANCE
				.createWorkProductDependencyDiagram();
		if (model instanceof DiagramImpl) {
			// disable creation of UMA graphical data
			//
			((DiagramImpl) model).setGraphicalDataRequired(false);
		}
		model.setNew(true);
		Diagram diagram = ViewService
				.createDiagram(
						model,
						getDiagramTypeString(IDiagramManager.WORK_PRODUCT_DEPENDENCY_DIAGRAM),
						hint);
		if (diagram != null) {
			diagram.setName(act.getName());
			model.setLinkedElement(act);
			getResource().getContents().add(model);
			getResource().getContents().add(diagram);

			// add ResourceDomainLink to the method library resource set
			//
			// EcoreUtil.getAdapter(getResource().getResourceSet().eAdapters(),
			// ResourceDo)
		}
		return diagram;
	}

	private Diagram createADD(Activity act, PreferencesHint hint)
			throws CoreException {
		ActivityDetailDiagram model = ModelFactory.eINSTANCE
				.createActivityDetailDiagram();
		if (model instanceof DiagramImpl) {
			// disable creation of UMA graphical data
			//
			((DiagramImpl) model).setGraphicalDataRequired(false);
		}
		model.setNew(true);
		Diagram diagram = ViewService.createDiagram(model,
				getDiagramTypeString(IDiagramManager.ACTIVITY_DETAIL_DIAGRAM),
				hint);
		if (diagram != null) {
			model.setLinkedElement(act);
			diagram.setName(act.getName());
			getResource().getContents().add(model);
			getResource().getContents().add(diagram);
		}
		return diagram;
	}

	private Diagram createAD(Activity act, PreferencesHint hint) throws CoreException {
		org.eclipse.uml2.uml.Activity model = UMLFactory.eINSTANCE
				.createActivity();
		Diagram diagram = ViewService.createDiagram(model,
				getDiagramTypeString(IDiagramManager.ACTIVITY_DIAGRAM), hint);
		if (diagram != null) {
			BridgeHelper.associate(model, act);
			diagram.setName(act.getName());
			model.setName(act.getName());
			getResource().getContents().add(model);
			getResource().getContents().add(diagram);
		}
		return diagram;
	}

	private IProgressMonitor getMonitor() {
		if(monitor == null) {
			monitor = new NullProgressMonitor();
		}
		return monitor;
	}
	
	public static String getDiagramFilePath(Process process) {
		try {
			ProcessComponent procComp = (ProcessComponent) process.eContainer();
			if(procComp == null) {
				return null;
			}
			if(UmaUtil.hasDirectResource(procComp)) {
				// existing process
				//
				return new File(new File(FileManager.toFileString(process.eResource().getURI())).getParentFile(), DIAGRAM_FILENAME).getCanonicalPath();
			}
			else {
				// new process that has not been saved yet
				//
				URI uri = MultiFileSaveUtil.createURI(procComp, procComp.eResource().getResourceSet());
				return new File(new File(uri.toFileString()).getParentFile(),
								DIAGRAM_FILENAME).getCanonicalPath();
			}
		} catch (IOException e) {
			e.printStackTrace();
			return null;
		}		
	}
	
	public void reload() throws IOException {
		if(resource == null) {
			return;
		}
		resource.unload();
		resource.load(Collections.EMPTY_MAP);
		IFile file = WorkspaceSynchronizer.getFile(resource);
		fileSynchronizer.updateModificationStamp(file);
		notifyReloaded();
	}
	
	public Resource getResource() throws CoreException {
		if(resource == null) {
			resource = getResource(true);
		}
		return resource;
	}	
	
	private static URI createDiagramResourceURI(String path) {
		IFile diagramFile = ResourcesPlugin.getWorkspace().getRoot().getFileForLocation(new Path(path));
		return URI.createPlatformResourceURI(diagramFile
				.getFullPath().toString());
	}
	
	private static Resource loadDiagramResource(IFile fFile,
			EditingDomain domain, Map loadOptions, IProgressMonitor monitor)
			throws CoreException, IOException {
		fFile.refreshLocal(IResource.DEPTH_ZERO, monitor);
		URI uri = URI.createPlatformResourceURI(fFile.getFullPath()
            .toString(), true);
		
		Resource resource = domain.getResourceSet().getResource(uri, false);
		
		if (resource == null) {
			resource = domain.getResourceSet().createResource(uri);
		}
		
		if (!resource.isLoaded()) {
			Map loadingOptions = new HashMap(GMFResourceFactory.getDefaultLoadOptions());
			
            // propogate passed in options to the defaults
            Iterator iter = loadOptions.keySet().iterator();
            while (iter.hasNext()) {
                Object key = iter.next();
                loadingOptions.put(key, loadOptions.get(key));
            }
            
            try {
            	resource.load(loadingOptions);
            } catch (IOException e) {
            	resource.unload();
            	throw e;
            }
		}
					
		return resource;

	}
	
	private Resource getResource(boolean create) throws CoreException {
		if(resource == null) {
			String path = getDiagramFilePath(process);	
			if(path != null) {
				IResource wsRes = FileManager.getResourceForLocation(path);
				if(wsRes instanceof IFile) {
					IFile file = (IFile) wsRes;
					try {						
						Diagram diagram = DiagramIOUtil.load(getEditingDomain(), file, true, getMonitor());					
						resource = diagram.eResource();
					}
					catch(CoreException e) {
						// handled exception that is thrown if resource does not have any diagram
						//
						if(org.eclipse.gmf.runtime.diagram.ui.resources.editor.internal.l10n.EditorMessages.Diagram_NO_DIAGRAM_IN_RESOURCE
								.equals(e.getMessage())) {
							try {
								resource = loadDiagramResource(file, getEditingDomain(), Collections.EMPTY_MAP, getMonitor());
							} catch (IOException e1) {
								if(DEBUG) {
									DiagramCorePlugin.getDefault().getLogger().logError(e);
								}
								throw new CoreException(new Status(IStatus.ERROR, DiagramCorePlugin.PLUGIN_ID, e1.getMessage(), e1));
							}
						}
						else {
							throw e;
						}
					}
					fileSynchronizer.monitor(file);
				}
				else if(create) {
					resource = getEditingDomain().getResourceSet().createResource(
							createDiagramResourceURI(path));
					resourceIsNew = true;
					
					try {
						TxUtil.runInTransaction(getEditingDomain(), new Runnable() {

							public void run() {
								resource.getContents().clear();
							}
							
						});
					} catch (Exception e) {
						DiagramCorePlugin.getDefault().getLogger().logError(e);
					}
				}
			}
		}
		else if(!resource.isLoaded()) {
			try {
				resource.load(Collections.EMPTY_MAP);
				notifyReloaded();
			} catch (IOException e) {
				CommonPlugin.getDefault().getLogger().logError(e);
				if(DEBUG) {
					e.printStackTrace();
				}
			}
		}
		return resource;
	}

	private void notifyReloaded() {
		for (Iterator iter = resourceChangeListeners.iterator(); iter.hasNext();) {
			IResourceChangeListener listener = (IResourceChangeListener) iter.next();
			try {
				listener.resourceChanged(new ResourceChangeEvent(this, IResourceChangeEvent.POST_CHANGE, 0, null));
			}
			catch(Exception e) {
				CommonPlugin.getDefault().getLogger().logError(e);
				if(DEBUG) {
					e.printStackTrace();
				}
			}
		}
	}

	private void checkActivity(Activity act) {		
		Process proc = TngUtil.getOwningProcess(act);
		if(proc != process) {
			throw new IllegalArgumentException("The specified activity does not belong to the process of this diagram manager."); //$NON-NLS-1$
		}
	}	
	
	private static boolean isDiagramOf(Diagram diagram, Activity act) {
		if(AD_kind.equals(diagram.getType())) {
			return BridgeHelper.getMethodElementFromAnnotation((EModelElement) diagram.getElement(), act.eResource().getResourceSet()) == act;
		}
		else if(ADD_kind.equals(diagram.getType())) {
			EObject model = diagram.getElement();
			return model instanceof ActivityDetailDiagram && ((ActivityDetailDiagram)model).getLinkedElement() == act;
		}
		else if(WPD_kind.equals(diagram.getType())) {
			EObject model = diagram.getElement();
			return model instanceof WorkProductDependencyDiagram && ((WorkProductDependencyDiagram)model).getLinkedElement() == act;
		}
		return false;
	}
	
	/**
	 * Checks whether the given resource has been changed on the
	 * local file system by comparing the actual time stamp with the
	 * cached one. If the resource has been changed, a <code>CoreException</code>
	 * is thrown.
	 *
	 * @param cachedModificationStamp the cached modification stamp
	 * @param resource the resource to check
	 * @throws org.eclipse.core.runtime.CoreException if resource has been changed on the file system
	 */
	public static void checkSynchronizationState(Resource resource) throws CoreException {
		if(!isSynchronized(resource)) {
			Status status= new Status(IStatus.ERROR, PlatformUI.PLUGIN_ID, IResourceStatus.OUT_OF_SYNC_LOCAL, EditorMessages.FileDocumentProvider_error_out_of_sync, null);
			throw new CoreException(status);
		}
	}
	
	public static boolean isSynchronized(Resource resource) {
		IFile file = WorkspaceSynchronizer.getFile(resource);
		if(file != null) {
			// don't refresh to prevent resource from automatically reloaded
			//
//			file.refreshLocal(IResource.DEPTH_ZERO, monitor);
			FileInfo info = fileSynchronizer.getFileInfo(file);
			if(info != null) {
				return info.fModificationStamp == FileSynchronizer.computeModificationStamp(file);
			}
		}
		return true;
	}
	
	private Map<Activity, Map<String, Diagram>> getActivityToSavedDiagramsMap() {
		if(activityToSavedDiagramMap == null) {
			activityToSavedDiagramMap = new HashMap<Activity, Map<String, Diagram>>();
		}
		return activityToSavedDiagramMap;
	}
	
	private Diagram getDiagramBackup(Activity act, String type) {
		if(activityToSavedDiagramMap != null) {
			Map<String, Diagram> typeToDiagamMap = activityToSavedDiagramMap.get(act);
			if(typeToDiagamMap != null) {
				return (Diagram) typeToDiagamMap.get(type);
			}
		}
		return null;
	}
	
	public void replaceTemporarily(final Activity act, final Diagram diagram) {
		try {
			new AbstractEMFOperation(getEditingDomain(), StringStatics.BLANK) {

				@Override
				protected IStatus doExecute(IProgressMonitor monitor, IAdaptable info) throws ExecutionException {
					try {
						List diagrams = getDiagrams(act, getDiagramType(diagram.getType()));
						if(!diagrams.isEmpty()) {
							Diagram savedDiagram = (Diagram) diagrams.get(0);
							Map<String, Diagram> typeToDiagamMap = getActivityToSavedDiagramsMap().get(act);	
							if(typeToDiagamMap == null) {
								typeToDiagamMap = new HashMap<String, Diagram>();
								getActivityToSavedDiagramsMap().put(act, typeToDiagamMap);
							}
							if(typeToDiagamMap.get(diagram.getType()) == null) {
								typeToDiagamMap.put(diagram.getType(), savedDiagram);
							}
							((InternalEObject) diagram).eSetProxyURI(null);
							for (Iterator iter = diagram.eAllContents(); iter
							.hasNext(); ((InternalEObject) iter.next()).eSetProxyURI(null));
							((InternalEObject) diagram.getElement()).eSetProxyURI(null);
							for (Iterator iter = diagram.getElement().eAllContents(); iter
							.hasNext(); ((InternalEObject) iter.next()).eSetProxyURI(null));							
							resource.getContents().set(resource.getContents().indexOf(savedDiagram), diagram);
							resource.getContents().set(resource.getContents().indexOf(savedDiagram.getElement()), diagram.getElement());				
						}
						else {
							resource.getContents().add(diagram.getElement());
							resource.getContents().add(diagram);
						}
					} catch (CoreException e) {
						CommonPlugin.getDefault().getLogger().logError(e);			
					}
					return Status.OK_STATUS;
				}
				
			}.execute(new NullProgressMonitor(), null);
		} catch (ExecutionException e1) {
			CommonPlugin.getDefault().getLogger().logError(e1);
		}
	}
	
	private Diagram getSavedDiagram(Activity act, Diagram diagram) {
		Diagram savedDiagram = getDiagramBackup(act, diagram.getType());
//		if(savedDiagram == null) {
//			// try to load diagram from file
//			//
//			IFile file = WorkspaceSynchronizer.getFile(resource);
//			if(file != null) {
//				TransactionalEditingDomain domain = createEditingDomain();
//				try {
//					Diagram d = DiagramIOUtil.load(domain, file, true, getMonitor());
//					if(d != null) {
//						int index = resource.getContents().indexOf(diagram);
//						savedDiagram = (Diagram) d.eResource().getContents().get(index);
//					}
//				} catch (CoreException e) {
//					DiagramCorePlugin.getDefault().getLogger().logError(e);
//				} finally {
//					if(domain != null) {
//						domain.dispose();
//					}
//				}
//			}
//		}
		return savedDiagram;
	}

	public synchronized boolean reverseToSaved(final Activity act, final Diagram diagram, PreferencesHint hint) {
		final Diagram savedDiagram = getSavedDiagram(act, diagram);
		try {
			new AbstractEMFOperation(getEditingDomain(), StringStatics.BLANK) {

				@Override
				protected IStatus doExecute(IProgressMonitor monitor, IAdaptable info) throws ExecutionException {
					if(savedDiagram != null) {
						// restore diagram to its backup
						//
						resource.getContents().set(resource.getContents().indexOf(diagram), savedDiagram);
						resource.getContents().set(resource.getContents().indexOf(diagram.getElement()), savedDiagram.getElement());
						removeDiagramBackup(act, diagram.getType());
					}
					else {
						// diagram is newly created, remove it from resource
						//
						resource.getContents().remove(diagram.getElement());
						resource.getContents().remove(diagram);
					}
					
					ILibraryPersister.FailSafeMethodLibraryPersister persister = LibraryServiceUtil
							.getPersisterFor(act.eResource())
							.getFailSafePersister();
					try {
						persister.save(resource);
						persister.commit();
					} catch (Exception e) {
						DiagramCorePlugin.getDefault().getLogger().logError(e);
						try {
							persister.rollback();
						}
						catch(Exception ex) {}
						throw new ExecutionException(e.getMessage(), e);
					}
					return Status.OK_STATUS;
				}
				
			}.execute(new NullProgressMonitor(), null);
			return true;
		} catch (ExecutionException e1) {
			CommonPlugin.getDefault().getLogger().logError(e1);
		}
		return false;		
	}

	/**
	 * Updates URI of diagram resource after the URI of process resource has been changed.
	 */
	public void updateResourceURI() {
		if(resource == null) {
			return;
		}
		File folder = new File(FileManager.toFileString(resource.getURI())).getParentFile();
		File procFolder = new File(process.eResource().getURI().toFileString()).getParentFile();
		if(!folder.equals(procFolder)) {
			String path = getDiagramFilePath(process);
			if(path != null && new File(path).exists()) {
				resource.setURI(createDiagramResourceURI(path));
			}
		}
	}

	public void backupDiagram(Activity activity, Diagram diagram) {
		Map<String, Diagram> typeToDiagamMap = getActivityToSavedDiagramsMap().get(activity);	
		if(typeToDiagamMap == null) {
			typeToDiagamMap = new HashMap<String, Diagram>();
			getActivityToSavedDiagramsMap().put(activity, typeToDiagamMap);
		}
		typeToDiagamMap.put(diagram.getType(), DiagramHelper.copyDiagram(getEditingDomain(), diagram));
	}

	public Diagram removeDiagramBackup(Activity act, String type) {
		if(activityToSavedDiagramMap != null) {
			Map<String, Diagram> typeToDiagamMap = activityToSavedDiagramMap.get(act);
			if(typeToDiagamMap != null) {
				return (Diagram) typeToDiagamMap.remove(type);
			}
		}
		return null;
	}
}