/******************************************************************************
 * 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 API and implementation 
 ****************************************************************************/

package org.eclipse.epf.diagramming.base.persistence;

import java.io.ByteArrayInputStream;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.lang.reflect.InvocationTargetException;
import java.util.ArrayList;
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.commands.operations.OperationHistoryFactory;
import org.eclipse.core.resources.IFile;
import org.eclipse.core.resources.IProject;
import org.eclipse.core.resources.IResource;
import org.eclipse.core.resources.IStorage;
import org.eclipse.core.resources.IWorkspaceRoot;
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.core.runtime.SubProgressMonitor;
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.xmi.FeatureNotFoundException;
import org.eclipse.emf.ecore.xmi.PackageNotFoundException;
import org.eclipse.emf.ecore.xmi.XMLResource;
import org.eclipse.emf.transaction.Transaction;
import org.eclipse.emf.transaction.TransactionalEditingDomain;
import org.eclipse.emf.transaction.impl.InternalTransaction;
import org.eclipse.emf.transaction.impl.InternalTransactionalEditingDomain;
import org.eclipse.epf.diagram.core.part.DiagramEditorInput;
import org.eclipse.epf.diagram.core.part.DiagramFileEditorInputProxy;
import org.eclipse.epf.diagramming.EPFDiagramPlugin;
import org.eclipse.epf.diagramming.base.commands.CreateDiagramCommand;
import org.eclipse.epf.diagramming.base.util.DiagramEditorUtil;
import org.eclipse.epf.diagramming.base.util.UmaUmlUtil;
import org.eclipse.epf.diagramming.part.EPFDiagramEditorPlugin;
import org.eclipse.epf.library.LibraryService;
import org.eclipse.epf.library.edit.util.TngUtil;
import org.eclipse.epf.persistence.MethodLibraryPersister;
import org.eclipse.epf.persistence.MultiFileSaveUtil;
import org.eclipse.epf.uma.BreakdownElement;
import org.eclipse.epf.uma.CapabilityPattern;
import org.eclipse.epf.uma.DeliveryProcess;
import org.eclipse.epf.uma.MethodElement;
import org.eclipse.epf.uma.MethodPlugin;
import org.eclipse.epf.uma.Process;
import org.eclipse.epf.uma.util.UmaUtil;
import org.eclipse.gmf.runtime.common.core.command.CommandResult;
import org.eclipse.gmf.runtime.common.core.util.Log;
import org.eclipse.gmf.runtime.diagram.core.services.ViewService;
import org.eclipse.gmf.runtime.diagram.ui.resources.editor.util.DiagramFileCreator;
import org.eclipse.gmf.runtime.emf.commands.core.command.AbstractTransactionalCommand;
import org.eclipse.gmf.runtime.emf.core.resources.GMFResourceFactory;
import org.eclipse.gmf.runtime.notation.Diagram;
import org.eclipse.gmf.runtime.notation.util.NotationExtendedMetaData;
import org.eclipse.jface.operation.IRunnableContext;
import org.eclipse.jface.operation.IRunnableWithProgress;
import org.eclipse.swt.widgets.Shell;
import org.eclipse.ui.IEditorInput;
import org.eclipse.uml2.uml.Activity;
import org.eclipse.uml2.uml.NamedElement;
import org.eclipse.uml2.uml.UMLFactory;

/**
 * Re-used {DiagramIOUtil} code and modify according for EPF and UML
 * Bridge. Persister helps in handling multi resource manipulation. 
 *  
 * @author Shashidhar Kannoori
 * @since 1.2
 */

public class DiagramPersister {
	private static final Map TX_OPTIONS = new HashMap();	
    static {
        TX_OPTIONS.put(Transaction.OPTION_NO_UNDO, Boolean.TRUE);
        TX_OPTIONS.put(Transaction.OPTION_NO_NOTIFICATIONS, Boolean.TRUE);
        TX_OPTIONS.put(Transaction.OPTION_NO_TRIGGERS, Boolean.TRUE);
    }
	
    private static final Resource.Factory resourceFactory = new GMFResourceFactory();
    
	// localized labels
	private static String UNABLE_TO_LOAD_DIAGRAM = "Unable to load diagram";

	private static String NO_DIAGRAM_IN_RESOURCE = "No diagram resource";

	private static interface ILoader {
		public Resource load(TransactionalEditingDomain domain, Map loadOptions, IProgressMonitor monitor) throws IOException, CoreException;
	}
	
	private static class FileLoader implements ILoader {
		private IFile fFile;
		public FileLoader(IFile file) {
			//assert file != null;
			fFile = file;
		}
		
		public Resource load(TransactionalEditingDomain domain, Map loadOptions, IProgressMonitor monitor) throws IOException, CoreException {
			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;
                }
			}
			
			logResourceErrorsAndWarnings(resource);
						
			return resource;
		}
	}

	private static void logResourceErrorsAndWarnings(Resource resource) {
		for (Iterator iter = resource.getErrors().iterator(); iter.hasNext();) {
			Resource.Diagnostic diagnostic = (Resource.Diagnostic) iter.next();
			Log.error(EPFDiagramPlugin.getDefault(), 1, diagnostic.getMessage());				
		}

		for (Iterator iter = resource.getWarnings().iterator(); iter.hasNext();) {
			Resource.Diagnostic diagnostic = (Resource.Diagnostic) iter.next();
			Log.warning(EPFDiagramPlugin.getDefault(), 7, diagnostic.getMessage());				
		}
	}

	
	private static class StorageLoader implements ILoader {
		private IStorage fStorage;
		public StorageLoader(IStorage storage) {
			//assert storage != null;
			fStorage = storage;
		}
		
		public Resource load(TransactionalEditingDomain editingDomain,
				Map loadOptions, IProgressMonitor monitor)
			throws IOException, CoreException {
            String storageName = fStorage.getName();
            URI uri = URI.createPlatformResourceURI(storageName);
            Resource resource = editingDomain.getResourceSet().getResource(uri,false);
            if (resource == null) {
                resource = editingDomain.getResourceSet().createResource(uri);
            }
            if (!resource.isLoaded()) {
                resource.load(fStorage.getContents(), loadOptions);
            }
			logResourceErrorsAndWarnings(resource);
			return resource;
		}
	}
	
	static public Diagram load(final TransactionalEditingDomain domain, final IFile file, boolean bTryCompatible, IProgressMonitor monitor) throws CoreException {
		FileLoader loader = new FileLoader(file);
		return load(domain, loader, bTryCompatible, monitor);
	}
	
	static public Diagram load(final TransactionalEditingDomain domain, final IStorage storage, boolean bTryCompatible, IProgressMonitor monitor,
			IEditorInput input) throws CoreException {
		ILoader loader = null;
		if(storage instanceof IFile) {
			loader = new FileLoader((IFile)storage);
		} else {
			loader = new StorageLoader(storage);
		}
		return load(domain, loader, bTryCompatible, monitor, input);
	}
	
	static public Diagram load(final TransactionalEditingDomain domain, final IStorage storage, boolean bTryCompatible, IProgressMonitor monitor,
			MethodElement me) throws CoreException {
		ILoader loader = null;
		if(storage instanceof IFile) {
			loader = new FileLoader((IFile)storage);
		} else {
			loader = new StorageLoader(storage);
		}
		return load(domain, loader, bTryCompatible, monitor, me);
	}
	
	/**
	 * load an existing diagram file.
	 * 
	 * @param file
	 * @return
	 * @throws CoreException
	 */
	static private Diagram load(final TransactionalEditingDomain domain, final ILoader loader, boolean bTryCompatible, IProgressMonitor monitor) throws CoreException  {
		Resource notationModel = null;
		try {
			try {	
				// File exists with contents..
				notationModel = loader.load(domain, new HashMap(), monitor);
			} catch (Resource.IOWrappedException e) {
				if (bTryCompatible) {
					Throwable causeError = e.getCause();
					
					if (causeError == null) {
						causeError = e;
					}
					
					String errMsg = causeError.getLocalizedMessage();
					if (causeError instanceof Resource.IOWrappedException) {
						Exception exc = (Exception)((Resource.IOWrappedException) causeError)
							.getCause();
						if (exc != null) {
							causeError = exc;
						}
					}
					
					if ((causeError instanceof PackageNotFoundException 
							|| causeError instanceof ClassNotFoundException
							|| causeError instanceof FeatureNotFoundException)) {
						if (shouldLoadInCompatibilityMode(errMsg)) {
                            Map loadOptions = new HashMap();
            				
                            // We will place a special extended metadata in here to ensure that we can load diagrams
            				//  from older versions of our metamodel.
            				loadOptions.put(XMLResource.OPTION_EXTENDED_META_DATA, new NotationExtendedMetaData());
            				
                            loadOptions.put(XMLResource.OPTION_RECORD_UNKNOWN_FEATURE, Boolean.TRUE);
							notationModel = loader.load(domain, loadOptions, monitor);
						} else {
							// user does not want to load in compatibility mode.
							return null; 
						}
					} else {
                        throw e;
					}
				} else {
					throw e;
				}
			}
			if(notationModel == null)
				throw new RuntimeException(UNABLE_TO_LOAD_DIAGRAM);

			Iterator rootContents = notationModel.getContents().iterator();
			while(rootContents.hasNext()) {
				EObject rootElement = (EObject)rootContents.next();
				if(rootElement instanceof Diagram)
					return (Diagram)rootElement;
			}
			
			throw new RuntimeException(NO_DIAGRAM_IN_RESOURCE);
		} catch(Exception e) {
			CoreException thrownExcp = null;
			if(e instanceof CoreException) {
				thrownExcp = (CoreException)e;
            } else {
                String exceptionMessage = e.getLocalizedMessage();
                thrownExcp = new CoreException(new Status(IStatus.ERROR,
                		EPFDiagramPlugin.getPluginId(), 1,
                    exceptionMessage != null ? exceptionMessage
                        : "load(IFile, boolean)", e)); //$NON-NLS-1$
            }
			throw thrownExcp;
		}
	}

	/**
	 * load an existing diagram file.
	 * 
	 * @param file
	 * @return
	 * @throws CoreException
	 */
	static private Diagram load(final TransactionalEditingDomain domain, final ILoader loader, boolean bTryCompatible, IProgressMonitor monitor,
			IEditorInput input) throws CoreException  {
		Resource notationModel = null;
		try {
			try {	
				// File exists with contents..
				notationModel = loader.load(domain, new HashMap(), monitor);
			} catch (Resource.IOWrappedException e) {
				if (bTryCompatible) {
					Throwable causeError = e.getCause();
					
					if (causeError == null) {
						causeError = e;
					}
					
					String errMsg = causeError.getLocalizedMessage();
					if (causeError instanceof Resource.IOWrappedException) {
						Exception exc = (Exception)((Resource.IOWrappedException) causeError)
							.getCause();
						if (exc != null) {
							causeError = exc;
						}
					}
					
					if ((causeError instanceof PackageNotFoundException 
							|| causeError instanceof ClassNotFoundException
							|| causeError instanceof FeatureNotFoundException)) {
						if (shouldLoadInCompatibilityMode(errMsg)) {
                            Map loadOptions = new HashMap();
            				
                            // We will place a special extended metadata in here to ensure that we can load diagrams
            				//  from older versions of our metamodel.
            				loadOptions.put(XMLResource.OPTION_EXTENDED_META_DATA, new NotationExtendedMetaData());
            				
                            loadOptions.put(XMLResource.OPTION_RECORD_UNKNOWN_FEATURE, Boolean.TRUE);
							notationModel = loader.load(domain, loadOptions, monitor);
						} else {
							// user does not want to load in compatibility mode.
							return null; 
						}
					} else {
                        throw e;
					}
				} else {
					throw e;
				}
			}
			if(notationModel == null)
				throw new RuntimeException(UNABLE_TO_LOAD_DIAGRAM);

			//FileEditorInputProxy proxy = (FileEditorInputProxy)input;
			DiagramFileEditorInputProxy fileInput = (DiagramFileEditorInputProxy)input;
			DiagramEditorInput diagramInput = fileInput.getDiagramEditorInput();
			
			Object inputElement = diagramInput.getMethodElement();
			
			Diagram ad = null;
			Iterator rootContents = notationModel.getContents().iterator();
			find_ad:
			while(rootContents.hasNext()) {
				EObject rootElement = (EObject)rootContents.next();
				
				if(rootElement instanceof Diagram){
					Diagram diagram = (Diagram)rootElement;
					EObject diagramElement = diagram.getElement();
					//TODO: can this method handle with other types of diagram???
					if(DiagramService.AD_kind.equals(diagram.getType()) && diagramElement instanceof Activity){
						MethodElement element = UmaUmlUtil.getUmaElement((NamedElement)diagramElement);
						if(inputElement == element){
							ad = diagram;
							break find_ad;
						}
					}
				}
			}
			if(ad != null) {
				
				// diagram found, remove all other diagrams and their sematic models from the resource
				//
//				List toRemove = new ArrayList();
//				for (Iterator iter = notationModel.getContents().iterator(); iter.hasNext();) {
//					Object element = (Object) iter.next();
//					if(element != ad && element != ad.getElement()) {
//						toRemove.add(element);
//					}					
//				}
//				
//				if(!toRemove.isEmpty()) {
//					InternalTransactionalEditingDomain internalDomain = ((InternalTransactionalEditingDomain)domain);
//					InternalTransaction tx = internalDomain.getActiveTransaction();
//					if(tx == null) {
//						tx = internalDomain.startTransaction(false, Collections.EMPTY_MAP);
//					}
//					else if(!tx.isActive()) {		
//						tx.start();
//					}
//					notationModel.getContents().removeAll(toRemove);
//					
//					tx.commit();
//				}
				
//				Resource resource = domain.createResource(notationModel.getURI());
//				resource.getContents().clear();
//				resource.getContents().add(ad.getElement());
//				resource.getContents().add(ad);
				
				
				return ad;
			}
			
			//TODO: remove the dependency on DiagramEditorUtil.
			boolean ok =DiagramEditorUtil.createDiagramContent(domain,
					fileInput.getFile(), new NullProgressMonitor(), diagramInput, notationModel);
			if(ok){
				//unload(domain, diagram)
				return load(domain, loader, bTryCompatible, monitor, input);
			}
				
			
			throw new RuntimeException(NO_DIAGRAM_IN_RESOURCE);
		} catch(Exception e) {
			CoreException thrownExcp = null;
			if(e instanceof CoreException) {
				thrownExcp = (CoreException)e;
            } else {
                String exceptionMessage = e.getLocalizedMessage();
                thrownExcp = new CoreException(new Status(IStatus.ERROR,
                    EPFDiagramPlugin.getPluginId(), 1,
                    exceptionMessage != null ? exceptionMessage
                        : "load(IFile, boolean)", e)); //$NON-NLS-1$
            }
			throw thrownExcp;
		}
	}
	
	
	/**
	 * load an existing diagram file.
	 * 
	 * @param file
	 * @return
	 * @throws CoreException
	 */
	static private Diagram load(final TransactionalEditingDomain domain, final ILoader loader, boolean bTryCompatible, IProgressMonitor monitor,
			MethodElement me) throws CoreException  {
		Resource notationModel = null;
		try {
			try {	
				// File exists with contents..
				notationModel = loader.load(domain, new HashMap(), monitor);
			} catch (Resource.IOWrappedException e) {
				if (bTryCompatible) {
					Throwable causeError = e.getCause();
					
					if (causeError == null) {
						causeError = e;
					}
					
					String errMsg = causeError.getLocalizedMessage();
					if (causeError instanceof Resource.IOWrappedException) {
						Exception exc = (Exception)((Resource.IOWrappedException) causeError)
							.getCause();
						if (exc != null) {
							causeError = exc;
						}
					}
					
					if ((causeError instanceof PackageNotFoundException 
							|| causeError instanceof ClassNotFoundException
							|| causeError instanceof FeatureNotFoundException)) {
						if (shouldLoadInCompatibilityMode(errMsg)) {
                            Map loadOptions = new HashMap();
            				
                            // We will place a special extended metadata in here to ensure that we can load diagrams
            				//  from older versions of our metamodel.
            				loadOptions.put(XMLResource.OPTION_EXTENDED_META_DATA, new NotationExtendedMetaData());
            				
                            loadOptions.put(XMLResource.OPTION_RECORD_UNKNOWN_FEATURE, Boolean.TRUE);
							notationModel = loader.load(domain, loadOptions, monitor);
						} else {
							// user does not want to load in compatibility mode.
							return null; 
						}
					} else {
                        throw e;
					}
				} else {
					throw e;
				}
			}
			if(notationModel == null)
				throw new RuntimeException(UNABLE_TO_LOAD_DIAGRAM);

			Iterator rootContents = notationModel.getContents().iterator();
			while(rootContents.hasNext()) {
				EObject rootElement = (EObject)rootContents.next();
				
				if(rootElement instanceof Diagram){
					Diagram diagram = (Diagram)rootElement;
					EObject diagramElement = diagram.getElement();
					if(diagramElement instanceof Activity){
						MethodElement element = UmaUmlUtil.getUmaElement((NamedElement)diagramElement);

						if(me == element){
							return diagram;
						}
					}
				}
			}
			return null;
			
		} catch(Exception e) {
			CoreException thrownExcp = null;
			if(e instanceof CoreException) {
				thrownExcp = (CoreException)e;
            } else {
                String exceptionMessage = e.getLocalizedMessage();
                thrownExcp = new CoreException(new Status(IStatus.ERROR,
                    EPFDiagramPlugin.getPluginId(), 1,
                    exceptionMessage != null ? exceptionMessage
                        : "load(IFile, boolean)", e)); //$NON-NLS-1$
            }
			throw thrownExcp;
		}
	}
	
	
	/**
	 * 
	 * @param domain
	 * @param file
	 * @param diagram
	 * @param bKeepUnrecognizedData
	 * @param progressMonitor
	 * @throws CoreException
	 */
	
	static public void save(TransactionalEditingDomain domain, IFile file, Diagram diagram, boolean bKeepUnrecognizedData, IProgressMonitor progressMonitor) throws CoreException {
        Map options = new HashMap();
		if(bKeepUnrecognizedData)
            options.put(XMLResource.OPTION_RECORD_UNKNOWN_FEATURE, Boolean.TRUE);
        save(domain, file, diagram, progressMonitor, options);
	}
    
    static public void save(TransactionalEditingDomain domain, IFile file, Diagram diagram, IProgressMonitor progressMonitor) throws CoreException {
        Map options = new HashMap();
        save(domain, file, diagram, progressMonitor, options);
    }
    
    private static List getOtherDiagramObjects(Resource resource, String actGuid) {
		ArrayList list = new ArrayList();
		for (Iterator iter = resource.getContents().iterator(); iter.hasNext();) {
			Object element = (Object) iter.next();
			if(element instanceof Activity) {
				if(!actGuid.equals(UmaUmlUtil.getUmaGuidFromUmlElement((NamedElement) element))) {
					list.add(element);
				}
			}
			else if(element instanceof Diagram) {
				Object e = ((Diagram)element).getElement();
				if(e instanceof Activity) { 
					if(!actGuid.equals(UmaUmlUtil.getUmaGuidFromUmlElement((NamedElement) e))) {
						list.add(element);
					}						
				}
				else {
					list.add(element);
				}
			}
			else {
				list.add(element);
			}
		}
		return list;
    }
	
	static public void save(TransactionalEditingDomain domain, IFile file, Diagram diagram, IProgressMonitor progressMonitor, Map options) throws CoreException {
		Resource notationModel = ((EObject) diagram).eResource();
		String actGuid = UmaUmlUtil.getUmaGuidFromUmlElement((NamedElement) diagram.getElement());
		
		// The current resource contains only current diagram
		// So load diagram file and add other diagrams to the current resource before saving it
		//
		Resource resource = resourceFactory.createResource(URI.createPlatformResourceURI(file.getFullPath().toString()));
		try {
			Transaction tx = ((InternalTransactionalEditingDomain)domain).startTransaction(false, TX_OPTIONS);
			resource.load(Collections.EMPTY_MAP);	
			List newList = getOtherDiagramObjects(resource, actGuid);
			List oldList = getOtherDiagramObjects(notationModel, actGuid);
			notationModel.getContents().removeAll(oldList);
			notationModel.getContents().addAll(newList);
			tx.commit();
		} catch (Exception e1) {
			// TODO Auto-generated catch block
			e1.printStackTrace();
		}		
		
		String fileName = file.getFullPath().toOSString();
		notationModel.setURI(URI.createPlatformResourceURI(fileName, true));
		try {
			notationModel.save(options);
		} catch (IOException e) {
			throw new CoreException(new Status(IStatus.ERROR, EPFDiagramPlugin
				.getPluginId(), 5, e
				.getLocalizedMessage(), null));
		}

		if (progressMonitor != null)
			progressMonitor.done();
		
		logResourceErrorsAndWarnings(notationModel);
	}
	
	/**
	 * Temp method will be removed later.
	 * @param domain
	 * @param file
	 * @param diagram
	 * @param progressMonitor
	 * @param save
	 * @throws CoreException
	 */
	static public void save(TransactionalEditingDomain domain, IFile file, Diagram diagram, 
			IProgressMonitor progressMonitor, boolean save) throws CoreException {
        Map options = new HashMap();
		Resource notationModel = ((EObject) diagram).eResource();
		if(notationModel == null){
				URI uri = URI.createPlatformResourceURI(file.getFullPath()
	                .toOSString(), true);
				
				notationModel = domain.getResourceSet().getResource(uri, false);
				if (notationModel == null) {
					notationModel = domain.getResourceSet().createResource(uri);
				}
				notationModel.getContents().add(diagram.getElement());
				notationModel.getContents().add(diagram);
		}else{
			String fileName = file.getFullPath().toOSString();
			notationModel.setURI(URI.createPlatformResourceURI(fileName, true));
		}
		
		try {
			notationModel.save(options);
		} catch (IOException e) {
			throw new CoreException(new Status(IStatus.ERROR, EPFDiagramPlugin
				.getPluginId(), 5, e
				.getLocalizedMessage(), null));
		}

		if (progressMonitor != null)
			progressMonitor.done();
		
		logResourceErrorsAndWarnings(notationModel);
	}
	
	
		/**
	 * @param errMsg
	 * @return
	 */
	private static boolean shouldLoadInCompatibilityMode(String errMsg) {
		// no compatibility support at present
		return false;
	}
	
	public static void unload(TransactionalEditingDomain domain, Diagram diagram) {
		diagram.eResource().unload();
	}

	public static boolean hasUnrecognizedData(Resource resource) {
		// no compatibility support at present
		return false;
	}
	
	public static IFile getFile(IEditorInput input){
		return getFile(DiagramFileCreatorEx.default_diagram_file, input,
				DiagramFileCreatorEx.getInstance());
	}
	
	/**
	 * Check whether file exists or not.
	 * @param szFileName
	 * @param input
	 * @param diagramFileCreator
	 * @return
	 */
	public static IFile getFile(String szFileName, IEditorInput input,
			DiagramFileCreator diagramFileCreator) {

		MethodElement e = ((DiagramEditorInput) input).getMethodElement();
		Process srcProc = TngUtil.getOwningProcess((BreakdownElement) e);

		IPath containerPath = getContainerPath(e);
		String szNewFileName = szFileName;
		IPath filePath = containerPath.append(diagramFileCreator
				.appendExtensionToFileName(szNewFileName));
		File libDirs = new File(LibraryService.getInstance()
				.getCurrentMethodLibraryPath());
		String diagramPath = libDirs.getAbsolutePath() + File.separator
				+ MethodLibraryPersister.getElementPath(srcProc)
				+ File.separator + srcProc.getName() + File.separator
				+ "diagram.xmi";
		File filex = new File(diagramPath);
		if (filex.exists()) {
			return ResourcesPlugin.getWorkspace().getRoot().getFile(filePath);
		}
		return null;
	}
	/**
	 * @written
	 */
	public static IPath getContainerPath(){
		IPath path = null;
		if (path == null) {
				IWorkspaceRoot root = ResourcesPlugin.getWorkspace().getRoot();
				IProject[] projects = root.getProjects();

				path = root.getFullPath();

				for (int i = 0; i < projects.length; ++i) {
					IProject project = projects[i];

					if (project.isOpen()) {
						path = project.getFullPath();
						break;
					}
				}
		}
		return path;
	}
	
	/**
	 * 
	 * 
	 * @param proc
	 * @return
	 * @custom
	 */
	public static IPath getContainerPath(MethodElement e) {

		Process proc = TngUtil.getOwningProcess(e);
		// TODO handle the Wrapper Elements.
		
		if (proc instanceof Process) {
			MethodPlugin plugin = UmaUtil.getMethodPlugin(proc);

			String relativeDir;

			if (proc instanceof CapabilityPattern) {
				relativeDir = MultiFileSaveUtil.CAPABILITY_PATTERN_PATH;
			} else if (proc instanceof DeliveryProcess) {
				relativeDir = MultiFileSaveUtil.DELIVERY_PROCESS_PATH;
			} else {
				relativeDir = ""; //$NON-NLS-1$
			}

			IPath workspacePath = null;
			if (workspacePath == null) {
				IWorkspaceRoot root = ResourcesPlugin.getWorkspace().getRoot();
				IProject[] projects = root.getProjects();

				workspacePath = root.getFullPath();

				for (int i = 0; i < projects.length; ++i) {
					IProject project = projects[i];

					if (project.isOpen()) {
						workspacePath = project.getFullPath();
						break;
					}
				}
			}

			String libDir = workspacePath.toString();
			String pluginDir = libDir + File.separator + plugin.getName();
			String diagramDir = pluginDir + File.separator + relativeDir
					+ File.separator + proc.getName() + File.separator;
			//System.out.println("Print: " + diagramDir);
			Path path = new Path(diagramDir);
			return path;

			//	 return workspacePath;
		} else
			return null;
	} 
	
	/**
	 * Check whether file exists or not.
	 * 
	 * @param szFileName
	 * @param input
	 * @param diagramFileCreator
	 * @return
	 */
	public static IFile getFile(String szFileName, BreakdownElement e,
			DiagramFileCreator diagramFileCreator) {

		Process srcProc = TngUtil.getOwningProcess((BreakdownElement) e);

		IPath containerPath = getContainerPath(e);
		String szNewFileName = szFileName;
		IPath filePath = containerPath.append(diagramFileCreator
				.appendExtensionToFileName(szNewFileName));
		File libDirs = new File(LibraryService.getInstance()
				.getCurrentMethodLibraryPath());
		String diagramPath = libDirs.getAbsolutePath() + File.separator
				+ MethodLibraryPersister.getElementPath(srcProc)
				+ File.separator + srcProc.getName() + File.separator
				+ "diagram.xmi";
		File filex = new File(diagramPath);
		if (filex.exists()) {
			return ResourcesPlugin.getWorkspace().getRoot().getFile(filePath);
		}
		return null;
	}
	
	
	/**
	 * 
	 * 
	 * Creates a diagram file content - GMF notation Diagram and UML Activity,
	 * UMA bridge. TODO: remove the dependency on command.
	 * @deprecated
	 */
	public static boolean createDiagramContent(
			TransactionalEditingDomain editingDomain, IFile diagramFile,
			IProgressMonitor progressMonitor, IEditorInput input,
			Resource resource, String kind) {

		List affectedFiles = new ArrayList();
		affectedFiles.add(diagramFile);
		CreateDiagramCommand command = new CreateDiagramCommand(editingDomain,
				CreateDiagramCommand.COMMAND_LABEL, affectedFiles, input,
				resource, kind);
		try {
			OperationHistoryFactory.getOperationHistory().execute(command,
					new SubProgressMonitor(progressMonitor, 1), null);
		} catch (ExecutionException e) {
			EPFDiagramEditorPlugin.getInstance().logError(
					"Unable to create model and diagram", e); //$NON-NLS-1$
			return false;
		}
		return true;
	}
	
	/**
	 * 
	 */
	public static Diagram createDiagram(TransactionalEditingDomain editingDomain, 
			String diagramKind, BreakdownElement me, boolean save) {
		IFile diagramFile = getFile(DiagramFileCreatorEx.default_diagram_file, (BreakdownElement)me, 
				DiagramFileCreatorEx.getInstance());	
		
		final Resource diagramResource = editingDomain.getResourceSet()
				.createResource(URI.createPlatformResourceURI(diagramFile
						.getFullPath().toString()));
		List affectedFiles = new ArrayList();
		affectedFiles.add(diagramFile);

		final String kindParam = diagramKind;
		final MethodElement methodElement = me;
		final boolean saveDiagram = save;
		AbstractTransactionalCommand command = new AbstractTransactionalCommand(
				editingDomain, "Creating diagram and model", affectedFiles) { //$NON-NLS-1$
			Diagram diagram = null;
			protected CommandResult doExecuteWithResult(
					IProgressMonitor monitor, IAdaptable info)
					throws ExecutionException {
				Activity model = UMLFactory.eINSTANCE.createActivity();
				diagramResource.getContents().add(model);
				diagram = ViewService.createDiagram(model, kindParam,
						EPFDiagramEditorPlugin.DIAGRAM_PREFERENCES_HINT);
				if (diagram != null) {
					if(methodElement != null && methodElement instanceof org.eclipse.epf.uma.Activity){
						UmaUmlUtil.createEAnnotationForUml(model, methodElement.getGuid());
					}
					diagramResource.getContents().add(diagram);
					diagram.setName(methodElement.getName());
					diagram.setElement(model);
					model.setName(methodElement.getName());
				}
				// Enable below if we have to store the diagram immediately.
				if (saveDiagram) {
					try {
						 diagramResource.save(Collections.EMPTY_MAP);
					} catch (IOException e) {
						System.out
								.println("Unable to store model and diagram resources"
										+ e.getMessage());
					}
				}
				return CommandResult.newOKCommandResult(diagram);
			}
		};

		try {
			OperationHistoryFactory.getOperationHistory().execute(command,
					new SubProgressMonitor(new NullProgressMonitor(), 1), null);
		} catch (ExecutionException e) {
				System.out.println("Error: Unable to create model and diagram" + e.getMessage());
		}

		try {
			diagramFile.setCharset(
					"UTF-8", new SubProgressMonitor(new NullProgressMonitor(), 1)); //$NON-NLS-1$
		} catch (CoreException e) {
			System.out.println("Error: Unable to set charset for diagram file "+  e.getLocalizedMessage()); //$NON-NLS-1$
		}
		return (Diagram)command.getCommandResult().getReturnValue();
	}
	
	
	/**
	 * 
	 * @
	 */
	public static Diagram saveDiagram(TransactionalEditingDomain editingDomain, IFile diagramFile, 
			Diagram diagram, boolean save) {
		
		Resource notationModel = ((EObject) diagram).eResource();
		if(notationModel == null){
				URI uri = URI.createPlatformResourceURI(diagramFile.getFullPath()
	                .toOSString(), true);
				
				notationModel = editingDomain.getResourceSet().getResource(uri, false);
				if (notationModel == null) {
					notationModel = editingDomain.getResourceSet().createResource(uri);
				}
		}
		final Resource diagramResource = notationModel;
		List affectedFiles = new ArrayList();
		affectedFiles.add(diagramFile);
		final Diagram saveDiagram = diagram;
		AbstractTransactionalCommand command = new AbstractTransactionalCommand(
				editingDomain, "Saving diagram and model", affectedFiles) { //$NON-NLS-1$
			protected CommandResult doExecuteWithResult(
					IProgressMonitor monitor, IAdaptable info)
					throws ExecutionException {
				diagramResource.getContents().add(saveDiagram.getElement());
				diagramResource.getContents().add(saveDiagram);
				try {
					 diagramResource.save(Collections.EMPTY_MAP);
				} catch (IOException e) {
					System.out
							.println("Unable to store model and diagram resources"
									+ e.getMessage());
				}
				return CommandResult.newOKCommandResult(saveDiagram);
			}
		};

		try {
			OperationHistoryFactory.getOperationHistory().execute(command,
					new SubProgressMonitor(new NullProgressMonitor(), 1), null);
		} catch (ExecutionException e) {
				System.out.println("Error: Unable to create model and diagram" + e.getMessage());
		}

		try {
			diagramFile.setCharset(
					"UTF-8", new SubProgressMonitor(new NullProgressMonitor(), 1)); //$NON-NLS-1$
		} catch (CoreException e) {
			System.out.println("Error: Unable to set charset for diagram file "+  e.getLocalizedMessage()); //$NON-NLS-1$
		}
		return (Diagram)command.getCommandResult().getReturnValue();
	}
	
	/**
	 * Method getInitialContents. Gets the initial contents of the UML
	 * Visualizer diagram file. Currently it returns an empty byte stream.
	 *
	 * @return Byte stream that will initially populate the UML
	 *         Visualizer diagram file.
	 */
	public static InputStream getInitialContents() {
		return new ByteArrayInputStream(new byte[0]);
	}
	
	
	/**
	 * <p>
	 * This method should be called within a workspace modify operation since it creates resources.
	 * </p>
	 * @modified
	 * @return the created file resource, or <code>null</code> if the file was not created
	 */
	public static final IFile createNewDiagramFile(
			DiagramFileCreatorEx diagramFileCreator, IEditorInput input, 
			Shell shell, IProgressMonitor progressMonitor ) {
		
		MethodElement element = ((DiagramEditorInput)input).getMethodElement();
		final IPath containerPath = getContainerPath(element);
		final String diagramFileName = DiagramFileCreatorEx.default_diagram_file;
		progressMonitor.beginTask("Creating notation diagram and model file", 4); //$NON-NLS-1$
		final IProgressMonitor subProgressMonitor = new SubProgressMonitor(
				progressMonitor, 1);
		final IFile diagramFile = diagramFileCreator.createNewFile(
				containerPath, diagramFileName, 
				getInitialContents(), shell,
				new IRunnableContext() {
					public void run(boolean fork, boolean cancelable,
							IRunnableWithProgress runnable)
							throws InvocationTargetException,
							InterruptedException {
						runnable.run(subProgressMonitor);
					}
				});
		
		//createDiagramContent(diagramFile, progressMonitor, input);
		progressMonitor.done();
		return diagramFile;
	}
}

