//------------------------------------------------------------------------------
// Copyright (c) 2005, 2006 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.persistence;

import java.io.File;
import java.io.FileFilter;
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.runtime.IStatus;
import org.eclipse.emf.common.CommonPlugin;
import org.eclipse.emf.common.util.AbstractTreeIterator;
import org.eclipse.emf.common.util.BasicEList;
import org.eclipse.emf.common.util.URI;
import org.eclipse.emf.ecore.EClass;
import org.eclipse.emf.ecore.EObject;
import org.eclipse.emf.ecore.EStructuralFeature;
import org.eclipse.emf.ecore.InternalEObject;
import org.eclipse.emf.ecore.resource.Resource;
import org.eclipse.emf.ecore.resource.ResourceSet;
import org.eclipse.emf.ecore.util.EcoreUtil;
import org.eclipse.emf.ecore.util.InternalEList;
import org.eclipse.emf.ecore.xmi.impl.XMIResourceImpl;
import org.eclipse.epf.common.utils.StrUtil;
import org.eclipse.epf.library.persistence.ILibraryResourceSet;
import org.eclipse.epf.library.persistence.LibraryResourceException;
import org.eclipse.epf.persistence.refresh.RefreshJob;
import org.eclipse.epf.persistence.util.PersistenceResources;
import org.eclipse.epf.persistence.util.PersistenceUtil;
import org.eclipse.epf.resourcemanager.ResourceDescriptor;
import org.eclipse.epf.resourcemanager.ResourceManager;
import org.eclipse.epf.resourcemanager.ResourcemanagerFactory;
import org.eclipse.epf.services.ILibraryPersister;
import org.eclipse.epf.uma.BreakdownElementDescription;
import org.eclipse.epf.uma.CapabilityPattern;
import org.eclipse.epf.uma.ContentDescription;
import org.eclipse.epf.uma.DeliveryProcess;
import org.eclipse.epf.uma.MethodConfiguration;
import org.eclipse.epf.uma.MethodElement;
import org.eclipse.epf.uma.MethodLibrary;
import org.eclipse.epf.uma.MethodPlugin;
import org.eclipse.epf.uma.MethodUnit;
import org.eclipse.epf.uma.ProcessComponent;
import org.eclipse.epf.uma.ecore.impl.MultiResourceEObject;
import org.eclipse.epf.uma.util.UmaUtil;
import org.eclipse.osgi.util.NLS;

import com.ibm.icu.text.SimpleDateFormat;
import com.ibm.icu.util.Calendar;

/**
 * Utility class with static routines for XMI persistence
 * 
 * @author Phong Nguyen Le
 * @author Jinhua Xi
 * @since 1.0
 */
public final class MultiFileSaveUtil {

	public static final String DEFAULT_MODEL_FILENAME = "model.xmi"; //$NON-NLS-1$

	public static final String DEFAULT_CONTENT_FILENAME = "content.xmi"; //$NON-NLS-1$

	public static final String DEFAULT_LIBRARY_MODEL_FILENAME = "library.xmi"; //$NON-NLS-1$
	
	public static final String DEFAULT_PLUGIN_EXPORT_FILENAME = "export.xmi"; //$NON-NLS-1$

	public static final String DEFAULT_PLUGIN_MODEL_FILENAME = "plugin.xmi"; //$NON-NLS-1$

	public static final String DEFAULT_FILE_EXTENSION = ".xmi"; //$NON-NLS-1$

	public static final String LIBRARY_FILE_EXTENSION = "uma"; //$NON-NLS-1$

	public static final String CAPABILITY_PATTERN_PATH = "capabilitypatterns"; //$NON-NLS-1$

	public static final String DELIVERY_PROCESS_PATH = "deliveryprocesses"; //$NON-NLS-1$

	public static final String PROCESS_CONTRIBUTION_PATH = "processcontributions"; //$NON-NLS-1$

	public static final String METHOD_CONFIGURATION_FOLDER_NAME = "configurations"; //$NON-NLS-1$

	public static final boolean DEBUG = PersistencePlugin.getDefault()
			.isDebugging();

	static final boolean PROFILE = false;

	private static final SimpleDateFormat dateFormatter = new SimpleDateFormat(
			"yyMMddHHmmss.S"); //$NON-NLS-1$

	public static boolean isValidFileName(String name) {
		if (name == null)
			return false;
		if (name.indexOf('/') != -1 || name.indexOf('\\') != -1
				|| name.indexOf(':') != -1 || name.indexOf('*') != -1
				|| name.indexOf('?') != -1 || name.indexOf('"') != -1
				|| name.indexOf('<') != -1 || name.indexOf('>') != -1
				|| name.indexOf('|') != -1)
			return false;
		return true;
	}

	public static String getPath(MethodElement e) {
		StringBuffer strBuff = new StringBuffer(String.valueOf(e.getName()));
		for (e = (MethodElement) ((EObject) e).eContainer(); e != null; e = (MethodElement) ((EObject) e)
				.eContainer()) {
			strBuff.insert(0, String.valueOf(e.getName()) + " > "); //$NON-NLS-1$
		}
		return strBuff.toString();
	}

	public static String createDirName(MethodElement obj) {
		String name = ((MethodElement) obj).getName();
		if (isValidFileName(name))
			return name;
		throw new MultiFileIOException(NLS.bind(
				PersistenceResources.invalidNameError_msg, name), obj);
	}

	public static EObject resolve(EObject proxy) {
		if (!(proxy instanceof InternalEObject))
			return proxy;
		InternalEObject obj = (InternalEObject) proxy;
		if (obj.eProxyURI() == null)
			return proxy;
		XMIResourceImpl res = new XMIResourceImpl(obj.eProxyURI());
		try {
			res.load(null);
			return PersistenceUtil.getMethodElement(res);
		} catch (IOException e) {
			e.printStackTrace();
		}
		return proxy;
	}

	static Resource save(EObject o, URI uri, Map options) {
		ResourceSet resourceSet = o.eResource().getResourceSet();
		MultiFileXMIResourceImpl resource = save(resourceSet, o, uri, options);

		if (options == null) {
			options = ((MultiFileResourceSetImpl) resourceSet)
					.getDefaultSaveOptions();
		}
		String str = (String) options
				.get(MultiFileXMISaveImpl.REFRESH_NEW_RESOURCE);
		if (str != null && Boolean.valueOf(str).booleanValue()) {
			// notify RefreshJob the this resource is saved so it will not be
			// reloaded after refreshing it
			//
			RefreshJob.getInstance().resourceSaved(resource);

			// refresh the newly created resource so it is in synch with the
			// workspace
			//
			FileManager.getInstance().refresh(resource);
		}

		return resource;
	}

	public static boolean canSaveTogether(Map options, Object obj) {
		Set saveTogetherClasses = (Set) options
				.get(MultiFileXMISaveImpl.SAVE_TOGETHER_CLASS_SET);
		if (saveTogetherClasses == null)
			return false;
		for (Iterator iter = saveTogetherClasses.iterator(); iter.hasNext();) {
			EClass eCls = (EClass) iter.next();
			if (eCls.isInstance(obj))
				return true;
		}
		return false;
	}

	/**
	 * Adds the given object to the given resource while still preserving
	 * object's container reference.
	 * 
	 * @param resource
	 * @param o
	 */
	private static void addTo(Resource resource, MultiResourceEObject o) {
		BasicEList contents = ((BasicEList) resource.getContents());
		if (contents.isEmpty()) {
			// this will flag resource as loaded
			//
			contents.clear();

			contents.setData(1, new Object[] { o });
		} else {
			Object[] data = contents.toArray();
			Object[] newData = new Object[data.length + 1];
			System.arraycopy(data, 0, newData, 0, data.length);
			newData[data.length] = o;
			contents.setData(newData.length, newData);
		}
		o.eSetResource((Resource.Internal) resource);
	}

	/**
	 * Saves a new contained EObject in its own new resource.
	 * 
	 * @param o
	 * @param uri
	 * @param options
	 */
	private static MultiFileXMIResourceImpl save(ResourceSet resourceSet,
			EObject o, URI uri, Map options) {
		return save(resourceSet, o, uri, options, true);
	}
	
	static MultiFileXMIResourceImpl save(ResourceSet resourceSet,
			EObject o, URI uri, Map options, boolean registerWithResourceManager) {
		// Detach the object from container resource
		//
		MultiResourceEObject mrEObj = (MultiResourceEObject) o;
		MultiFileXMIResourceImpl currentResource = (MultiFileXMIResourceImpl) o
				.eResource();

		if (currentResource != null) {
			currentResource.detached(o);
		}

		List newResourceDescriptors = null;
		Set modifiedResources = (Set) options
				.get(MultiFileXMISaveImpl.MODIFIED_RESOURCE_SET);

		MultiFileXMIResourceImpl res = null;
		if (canSaveTogether(options, o)) {
			MultiFileResourceSetImpl mfResourceSet = ((MultiFileResourceSetImpl) resourceSet);

			// if the uri has a temporary URI, use it instead to locate the
			// resource that is in process of saving
			//
			URI tempURI = (URI) mfResourceSet.getURIToTempURIMap().get(uri);
			if (tempURI != null) {
				uri = tempURI;
			}

			res = (MultiFileXMIResourceImpl) mfResourceSet.getResource(uri);
			if (res != null) {
				if (!res.getContents().contains(o)) {
					if (res.getFinalURI() == res.getURI()) {
						if (MultiFileXMISaveImpl.checkModifyRequired(options)) {
							// not a temp file of fail-safe persistence
							// transaction
							// check for writeable
							//
							MultiFileSaveUtil.checkModify(res);
						}
					}

					addTo(res, mrEObj);

					ResourceDescriptor desc = null;
					try {
						if(registerWithResourceManager) {
							// register this new object with ResourceManager
							//
							ResourceManager resMgr = getResourceManagerFor(o,
									modifiedResources);
							desc = registerWithResourceManager(resMgr, o, res
									.getFinalURI());
							if (desc != null && modifiedResources != null) {
								modifiedResources.add(resMgr.eResource());
							}
						}

						res.setModified(true);
						mfResourceSet.save(res, options, false);

						res.attachedAll(o);
					} catch (Exception e) {
						// rollback
						//

						// remove this object from the resource
						res.getContents().remove(mrEObj);
						mrEObj.eSetResource((Resource.Internal) null);

						// remove the created ResourceDescriptor
						if (desc != null) {
							EcoreUtil.remove(desc);
						}

						// re-attach to container resource
						if (currentResource != null) {
							currentResource.attached(o);
						}

						throw new MultiFileIOException(e.getMessage());
					}
				}
				return res;
			}
		}

		res = (MultiFileXMIResourceImpl) resourceSet.createResource(uri);
		addTo(res, mrEObj);
		if(mrEObj instanceof MethodPlugin) {
			addResourceManager(res);
		}

		Map objToContainerMap = null;
		try {
			if(registerWithResourceManager) {
				newResourceDescriptors = registerWithResourceManager(res,
					modifiedResources);
			}

			// back up the container references and set content object's
			// container to null
			//
			objToContainerMap = removeContainers(res);

			res.save(options);

			res.attachedAll(o);
		} catch (Exception e) {
			CommonPlugin.INSTANCE.log(e);

			// rollback
			//

			// remove the failed reousrce from the resource set
			resourceSet.getResources().remove(res);
			mrEObj.eSetResource((Resource.Internal) null);

			// remove the created ResourceDescriptors
			if(newResourceDescriptors != null && !newResourceDescriptors.isEmpty()) {
				for (Iterator iter = newResourceDescriptors.iterator(); iter
				.hasNext();) {
					EcoreUtil.remove((EObject) iter.next());
				}
			}

			// re-attach to container resource
			if (currentResource != null) {
				currentResource.attached(o);
			}

			throw new MultiFileIOException(e.getMessage());
		} finally {
			// restore the container references for the content objects
			//
			restoreContainers(res, objToContainerMap);
		}

		if(registerWithResourceManager) {
			ResourceManager resMgr = addNewResourceManager(res);
			if (resMgr == null) {
				if (o instanceof MethodPlugin) {
					// create new ResourceManager for new MethodPlugin
					//
					resMgr = getResourceManagerFor(o, modifiedResources);
				}
			} else if (modifiedResources != null) {
				modifiedResources.add(resMgr.eContainer().eResource());
			}
		}

		res.updateTimeStamps();

		return res;
	}

	private static Map removeContainers(Resource resource) {
		int size = resource.getContents().size();
		Map objToContainerMap = new HashMap();
		for (int i = 0; i < size; i++) {
			MultiResourceEObject multiResEObj = (MultiResourceEObject) resource
					.getContents().get(i);
			InternalEObject container = (InternalEObject) multiResEObj
					.eContainer();
			if (container != null) {
				objToContainerMap.put(multiResEObj, container);
				multiResEObj.eBasicSetContainer(null, multiResEObj
						.eContainerFeatureID());
			}
		}
		return objToContainerMap;
	}

	/**
	 * Gets the containers of objects in resource's contents
	 * 
	 * @param resource
	 * @return map of object to container entries
	 */
	static Map getContainers(Resource resource) {
		int size = resource.getContents().size();
		Map objToContainerMap = new HashMap();
		for (int i = 0; i < size; i++) {
			MultiResourceEObject multiResEObj = (MultiResourceEObject) resource
					.getContents().get(i);
			InternalEObject container = (InternalEObject) multiResEObj
					.eContainer();
			if (container != null) {
				objToContainerMap.put(multiResEObj, container);
			}
		}
		return objToContainerMap;

	}

	/**
	 * Restores the containers of the objects in resource's contents that
	 * previously saved in a map returned from getContainers(Resource resource)
	 * or removeContainers(Resource resource)
	 * 
	 * @param resource
	 * @param objToContainerMap
	 * @see #getContainers(Resource)
	 * @see #removeContainers(Resource)
	 */
	private static void restoreContainers(Resource resource,
			Map objToContainerMap) {
		int size = resource.getContents().size();
		for (int i = 0; i < size; i++) {
			MultiResourceEObject multiResEObj = (MultiResourceEObject) resource
					.getContents().get(i);
			InternalEObject container = (InternalEObject) objToContainerMap
					.get(multiResEObj);
			if (container != null) {
				multiResEObj.eBasicSetContainer(container, multiResEObj
						.eContainerFeatureID());
			}
		}
	}

	public static void checkModify(Resource resource) {
		checkModify(Collections.singleton(resource));
	}

	static void doCheckModify(Collection<Resource> resources) {
		ArrayList<String> pathList = new ArrayList<String>();
		for (Iterator iter = resources.iterator(); iter.hasNext();) {
			Resource resource = (Resource) iter.next();
			// skip checking on resource that is currently being saved to a temporary
			// file
			//
			if(resource instanceof MultiFileXMIResourceImpl && ((MultiFileXMIResourceImpl)resource).hasTempURI()) {
				continue;
			}
			pathList.add(FileManager.toFileString(resource.getURI()));
		}
		if(!pathList.isEmpty()) {
			String[] paths = new String[pathList.size()];
			pathList.toArray(paths);
			IStatus status = FileManager.getInstance().checkModify(paths,
					PersistencePlugin.getDefault().getContext()/*MsgBox.getDefaultShell()*/);
			if (!status.isOK()) {
				String msg = UmaUtil.getMessage(status);
				if (msg == null) {
					msg = NLS.bind(PersistenceResources.modifyFileError_msg, Arrays
							.asList(paths));
				}
				throw new MultiFileIOException(msg);
			}
		}
	}
	
	public static void checkModify(Collection<Resource> resources) {
		Map<ILibraryResourceSet, Collection<Resource>> libResourceSetToResourcesMap = new HashMap<ILibraryResourceSet, Collection<Resource>>();
		Collection<Resource> otherResources = new ArrayList<Resource>();
		for (Iterator iter = resources.iterator(); iter.hasNext();) {
			Resource resource = (Resource) iter.next();
			ResourceSet resourceSet = resource.getResourceSet();
			if(resourceSet instanceof ILibraryResourceSet) {
				Collection<Resource> collection = libResourceSetToResourcesMap.get(resourceSet);
				if(collection == null) {
					collection = new ArrayList<Resource>();
					libResourceSetToResourcesMap.put((ILibraryResourceSet) resourceSet, collection);					
				}
				collection.add(resource);
			}
			else {
				otherResources.add(resource);
			}
		}
		if(!libResourceSetToResourcesMap.isEmpty()) {
			for (Iterator<Map.Entry<ILibraryResourceSet, Collection<Resource>>> iter = libResourceSetToResourcesMap.entrySet().iterator(); iter.hasNext();) {
				Map.Entry<ILibraryResourceSet, Collection<Resource>> entry = iter.next();
				ILibraryResourceSet resourceSet = entry.getKey();			
				Resource[] resourceArray = new Resource[entry.getValue().size()];
				entry.getValue().toArray(resourceArray);
				try {
					resourceSet.checkModify(resourceArray, PersistencePlugin.getDefault().getContext()/*MsgBox.getDefaultShell()*/);
				} catch (LibraryResourceException e) {
					throw new MultiFileIOException(e.getMessage());
				}
			}
		}
		if(!otherResources.isEmpty()) {
			doCheckModify(otherResources);
		}
	}
	
	public static void checkOutOfSynch(Collection<Resource> resources, Map saveOptions) {
		Collection<Resource> resourcesToCheckOutOfSynch;
		Collection<Resource> overwritableResources = (Collection<Resource>) saveOptions.get(
				ILibraryPersister.FailSafeMethodLibraryPersister.OPTIONS_OVERWRITABLE_RESOURCES);				
		if(overwritableResources != null && !overwritableResources.isEmpty()) {
			resourcesToCheckOutOfSynch = new ArrayList<Resource>(resources);
			resourcesToCheckOutOfSynch.removeAll(overwritableResources);
		}
		else {
			resourcesToCheckOutOfSynch = resources;
		}
		if(!resourcesToCheckOutOfSynch.isEmpty()) {
			checkOutOfSynch(resourcesToCheckOutOfSynch);
		}
	}

	private static void checkOutOfSynch(Collection resources) {
		// check for out-of-synch
		//
		for (Iterator iter = resources.iterator(); iter.hasNext();) {
			MultiFileXMIResourceImpl res = (MultiFileXMIResourceImpl) iter
					.next();
			if(res.isLoaded() && !res.hasTempURI()) {
				File file = new File(res.getURI().toFileString());
				if(file.exists()) {
//					long lastModified = file.lastModified();
//					if (res.getFileLastModified() != lastModified && !same(lastModified, res.getFileLastModified())) {
//						String msg = NLS.bind(
//								PersistenceResources.resourceOutOfSynch_msg, res
//								.getURI().toFileString());
//						throw new MultiFileIOException(msg);
//					}
					
					if(!res.isSynchronized()) {
						String msg = NLS.bind(
								PersistenceResources.resourceOutOfSynch_msg,
								res.getURI().toFileString());
						throw new MultiFileIOException(msg);						
					}
				}
			}
		}
	}

	/**
	 * Saves the existing own resource of a contained EObject. Adds resources
	 * that have been modifed after this call to the MODIFIED_RESOURCE_SET of
	 * the save options.
	 * 
	 * @param resource
	 * @param options
	 * @return true if the given resource has been saved successfully, false otherwise
	 */
	public static boolean save(Resource resource, Map options) {
		if (resource.getContents().isEmpty())
			return false;

		Set modifiedResources = (Set) options
				.get(MultiFileXMISaveImpl.MODIFIED_RESOURCE_SET);

		// should not change resource location automatically without letting
		// user know about it
		//
		// adjustLocation(resource, modifiedResources);

		// back up the container references and set content object's container
		// to null
		//
		Map objToContainerMap = removeContainers(resource);
		try {
			resource.save(options);
		} catch (IOException e) {
			e.printStackTrace();
			throw new MultiFileIOException(e.getMessage());
		} finally {
			// restore the container references for the content objects
			//
			restoreContainers(resource, objToContainerMap);
		}

		ResourceManager resMgr = addNewResourceManager(resource);
		if (resMgr != null && modifiedResources != null) {
			modifiedResources.add(resMgr.eContainer().eResource());
		}
		
		return true;
	}

	/**
	 * 
	 * @param resource
	 * @return ResourceManager that is just added to the resource manager tree
	 *         or null.
	 */
	private static ResourceManager addNewResourceManager(Resource resource) {
		ResourceManager resMgr = getResourceManager(resource);
		MethodElement e = PersistenceUtil.getMethodElement(resource);
		EObject container = e.eContainer();
		if (resMgr != null && container != null && resMgr.eContainer() == null) {
			// new ResourceManager is added to the resource
			//
			ResourceManager parentResMgr = getResourceManager(container
					.eResource());

			// check if resMgr is already a sub manager of parentResMgr before
			// adding it
			//
			if (!parentResMgr.getSubManagers().contains(resMgr)) {
				parentResMgr.getSubManagers().add(resMgr);				
				registerWithResourceManager(parentResMgr, e, MultiFileSaveUtil.getFinalURI(resource));
				return resMgr;
			}

			// registerWithResourceManager(parentResMgr, resMgr,
			// resMgr.eResource().getURI().appendFragment(resMgr.getGuid()));
			// return resMgr;
		}
		return null;
	}

	private static String toFileString(EObject eObj) {
		return eObj.eResource().getResourceSet().getURIConverter().normalize(
				eObj.eResource().getURI()).toFileString();
	}

	static boolean hasOwnFolder(Object e) {
		return e instanceof MethodPlugin || e instanceof ProcessComponent;
	}

	static boolean hasOwnResource(Object obj, Collection saveSeparatelyClassSet) {
		if (obj instanceof MethodUnit)
			return true;
		if (saveSeparatelyClassSet == null)
			return false;
		for (Iterator iter = saveSeparatelyClassSet.iterator(); iter.hasNext();) {
			EClass eCls = (EClass) iter.next();
			if (eCls.isInstance(obj))
				return true;
		}
		return false;
	}

	static URI createFileURI(MethodElement e) {
		if (e.eContainer() == null)
			return ((MultiFileXMIResourceImpl) e.eResource()).getFinalURI();

		// Handle ProcessComponent specially. ProcessComponent objects are
		// stored as following in the method library:
		// <Method Library>
		// |_ <Method Plugin>
		// |_processes
		// |_capability_patterns
		// |_delivery_processes
		// |_process_contributions
		//
		if (e instanceof ProcessComponent) {
			MethodPlugin plugin = UmaUtil.getMethodPlugin(e);
			if(plugin == null) {
				return null;
			}
			Resource resource = plugin.eResource();
			if (resource == null) {
			}
			String pluginDir = null;
			if(resource != null) {
				pluginDir = new File(getFinalURI(resource).toFileString()).getParent();
			}
			else {
				MethodLibrary lib = (MethodLibrary) plugin.eContainer();
				if (lib != null) {
					String libDir = new File(((MultiFileXMIResourceImpl) lib
							.eResource()).getFinalURI().toFileString()).getParent();
					pluginDir = libDir + File.separator + plugin.getName();
				}
			}
			if(pluginDir == null) {
				// plugin is already deleted
				//
				return null;
			}

			String relativeDir;
			org.eclipse.epf.uma.Process proc = ((ProcessComponent) e)
					.getProcess();
			if (proc instanceof CapabilityPattern) {
				relativeDir = CAPABILITY_PATTERN_PATH;
			} else if (proc instanceof DeliveryProcess) {
				relativeDir = DELIVERY_PROCESS_PATH;
			} else {
				relativeDir = ""; //$NON-NLS-1$
			}

			String path = pluginDir + File.separator + relativeDir
					+ File.separator + e.getName() + File.separator
					+ DEFAULT_MODEL_FILENAME;
			return URI.createFileURI(path);
		} else if (e instanceof BreakdownElementDescription) {
			String dir = null;
			try {
				dir = new File(((MultiFileXMIResourceImpl) UmaUtil
						.getProcessComponent(e).eResource()).getFinalURI()
						.toFileString()).getParent();
			} catch (RuntimeException ex) {
				throw ex;
			}
			return URI.createFileURI(dir + File.separator
					+ DEFAULT_CONTENT_FILENAME);
		} else if (e instanceof ContentDescription) {
			URI uri;
			ContentDescription content = (ContentDescription) e;
			String path = MethodLibraryPersister.getCorrectPath(content);
			if (path == null) {
				String dir = ((MultiFileXMIResourceImpl) e.eResource())
						.getFinalURI().trimSegments(1).toFileString()
						+ File.separator;
				path = MethodLibraryPersister.getNextAvailableFileName(dir,
						content);
			}
			uri = URI.createFileURI(path);
			return uri;
		} else if (e instanceof MethodConfiguration) {			
			String dir = new StringBuffer(((MultiFileXMIResourceImpl) e
					.eContainer().eResource()).getFinalURI().trimSegments(1)
					.toFileString()).append(File.separator).append(
					METHOD_CONFIGURATION_FOLDER_NAME).append(File.separator)
					.toString();
			String path = MethodLibraryPersister.getNextAvailableFileName(dir,
					StrUtil.makeValidFileName(e.getName()),
					(MultiResourceEObject) e);
			return URI.createFileURI(path);
		}

		StringBuffer path = new StringBuffer();
		EObject lastContainer = null;
		for (MethodElement obj = (MethodElement) e.eContainer(); obj != null; obj = (MethodElement) obj
				.eContainer()) {
			lastContainer = obj;
			if (obj instanceof MethodLibrary) {
				path.insert(0, new File(((MultiFileXMIResourceImpl) obj
						.eResource()).getFinalURI().toFileString())
						.getParentFile().getAbsolutePath());
				break;
			} else {
				path.insert(0, obj.getName()).insert(0, File.separatorChar);
			}
		}
		if (lastContainer == null) {
			return e.eResource() != null ? ((MultiFileXMIResourceImpl) e
					.eResource()).getFinalURI() : null;
		}
		if (!(lastContainer instanceof MethodLibrary)) {
			path.insert(0, new File(toFileString(lastContainer))
					.getParentFile().getParentFile().getAbsolutePath());
		}

		String modelFileName;
		if (e instanceof MethodPlugin) {
			modelFileName = DEFAULT_PLUGIN_MODEL_FILENAME;
		} else {
			modelFileName = MultiFileSaveUtil.DEFAULT_MODEL_FILENAME;
		}
		URI uri = URI.createFileURI(path.toString() + File.separator
				+ MultiFileSaveUtil.createDirName(e) + File.separator
				+ modelFileName);
		return uri;
	}

	public static void delete(File file) {
		File[] files = file.listFiles();
		if (files != null) {
			for (int i = 0; i < files.length; i++) {
				delete(files[i]);
			}
		}
		file.delete();
	}

	/**
	 * 
	 * @param e
	 * @param uri
	 * @param modifiedResources
	 *            output of resources that have been changed after this call.
	 */
	static void setURIMapping(EObject e, URI uri, Set modifiedResources) {
		MultiFileURIConverter uriConverter = (MultiFileURIConverter) e
				.eResource().getResourceSet().getURIConverter();
		uriConverter.setURIMapping(e, uri, modifiedResources);
	}

	/**
	 * 
	 * @param resource
	 * @param modifiedResources
	 *            output of resources that have been changed after this call
	 */
	static void updateURIMappings(MultiFileXMIResourceImpl resource,
			Set modifiedResources) {
		updateURIMappings(resource, modifiedResources, true);
	}

	/**
	 * Checks if the given resourceSet has the loaded resource with the given
	 * uri
	 * 
	 * @param resourceSet
	 * @param uri
	 * @return
	 */
	static boolean hasLoadedResource(ResourceSet resourceSet, URI uri) {
		for (Iterator iter = resourceSet.getResources().iterator(); iter
				.hasNext();) {
			Resource resource = (Resource) iter.next();
			if (resource.isLoaded() && resource.getURI().equals(uri)) {
				return true;
			}
		}
		return false;
	}

	/**
	 * Update the URIMappings with the final URI of the given resource
	 * 
	 * @param resource
	 */
	static void updateURIMappings(MultiFileXMIResourceImpl resource,
			Set modifiedResources, boolean afterMove) {
		updateURIMappings(resource, resource.getFinalURI(), modifiedResources,
				afterMove);
	}

	static void updateURIMappings(MultiFileXMIResourceImpl resource, URI uri,
			Set modifiedResources, boolean afterMove) {
		// the resource URI has been changed, reset all the cached resolved URI
		// in all offstring resource descriptors
		// of its manager, if it has one.
		//
		HashMap oldURIToResourceDescriptorMap = null;
		ResourceManager resMgr = getResourceManager(resource);
		if (resMgr != null) {
			oldURIToResourceDescriptorMap = new HashMap();
			for (Iterator iter = resMgr.eAllContents(); iter.hasNext();) {
				Object obj = iter.next();
				if (obj instanceof ResourceDescriptor) {
					ResourceDescriptor desc = ((ResourceDescriptor) obj);
					oldURIToResourceDescriptorMap.put(desc.getResolvedURI(),
							desc);
					if (afterMove) {
						desc.clearResolvedURI();
					}
				}
			}
		}

		if (!resource.getContents().isEmpty()) {
			EObject element = PersistenceUtil.getMethodElement(resource);
			// setURIMapping(element, resource.getFinalURI(),
			// modifiedResources);
			MultiFileURIConverter uriConverter = (MultiFileURIConverter) resource
					.getResourceSet().getURIConverter();
			uriConverter.setURIMapping(element, uri, modifiedResources,
					afterMove);
		}

		// for (Iterator iter = resource.getContents().iterator();
		// iter.hasNext();) {
		// EObject element = (EObject) iter.next();
		// setURIMapping(element, resource.getURI(), modifiedResources);
		// }

		if (oldURIToResourceDescriptorMap != null) {
			// go thru the list of loaded resources in resource set to update
			// the URI
			//
			for (Iterator iter = resource.getResourceSet().getResources()
					.iterator(); iter.hasNext();) {
				Resource res = (Resource) iter.next();
				ResourceDescriptor desc = (ResourceDescriptor) oldURIToResourceDescriptorMap
						.get(res.getURI());
				if (desc != null) {
					if (afterMove) {
						res.setURI(desc.getResolvedURI());
					} else if (res.isLoaded()) {
						desc.clearResolvedURI();
						res.setURI(desc.getResolvedURI());
					}
				}
			}
		}
	}

	/**
	 * @param resMgr
	 * @param o
	 * @param uri
	 */
	// private static void setUri(ResourceManager resMgr, MethodElement e, URI
	// uri) {
	// for (Iterator iter = resMgr.getResourceDescriptors().iterator();
	// iter.hasNext();) {
	// ResourceDescriptor resDesc = (ResourceDescriptor) iter.next();
	// if(resDesc.getId().equals(e.getGuid())) {
	// // change other URIs that are changed as result of this URI change
	// //
	// if(uri.fragment() == null) {
	// URI oldDir = URI.createFileURI(new
	// File(resDesc.getResolvedURI().toFileString()).getParent() +
	// File.separator);
	// URI newDir = URI.createFileURI(new File(uri.toFileString()).getParent() +
	// File.separator);
	// for (Iterator iterator = resMgr.getResourceDescriptors().iterator();
	// iterator
	// .hasNext();) {
	// ResourceDescriptor element = (ResourceDescriptor) iterator.next();
	// URI currentUri = element.getResolvedURI();
	// URI newUri = currentUri.replacePrefix(oldDir, newDir);
	// if(newUri != null) {
	// element.setResolvedURI(newUri);
	// }
	// }
	// }
	// resDesc.setResolvedURI(uri);
	// return;
	// }
	// }
	// ResourceDescriptor resDesc =
	// ResourcemanagerFactory.eINSTANCE.createResourceDescriptor();
	// resDesc.setId(e.getGuid());
	// resDesc.setResolvedURI(uri);
	// resMgr.getResourceDescriptors().add(resDesc);
	// }
	/**
	 * Gets the right ResourceManager for the given EObject, creates new
	 * ResourceManager if it does not exist yet.
	 * 
	 * @param modifiedResources
	 *            output of resources that have been changed after this call.
	 */
	static ResourceManager getResourceManagerFor(EObject eObj,
			Set modifiedResources) {
		Resource resource = eObj.eContainer() != null ? eObj.eContainer()
				.eResource() : eObj.eResource();
		ResourceManager resMgr = getResourceManager(resource);
		if (resMgr == null) {
			resMgr = ResourcemanagerFactory.eINSTANCE.createResourceManager();

			// add to beginning of the resource's contents
			//
			resource.getContents().add(0, resMgr);

			if (modifiedResources != null) {
				modifiedResources.add(resource);
			}
			EObject container = getContainerWithDirectResource((InternalEObject) eObj);
			if (container != null && container.eResource() != resource) {
				ResourceManager parentResMgr = getResourceManagerFor(container,
						modifiedResources);
				if (parentResMgr != null) {
					parentResMgr.getSubManagers().add(resMgr);
					if (modifiedResources != null) {
						modifiedResources.add(parentResMgr.eResource());
					}
				}
			}
		}

		return resMgr;

	}

	static List registerWithResourceManager(MultiFileXMIResourceImpl resource,
			Set modifiedResources) {
		ResourceManager resMgr = getResourceManagerFor(
				PersistenceUtil.getMethodElement(resource), modifiedResources);

		List resourceDescriptors = new ArrayList();
		for (Iterator iter = resource.getContents().iterator(); iter.hasNext();) {
			Object element = iter.next();
			if(element instanceof MethodElement) {
				ResourceDescriptor resDesc = registerWithResourceManager(resMgr,
						element, resource.getFinalURI());
				if (resDesc != null) {
					resourceDescriptors.add(resDesc);
				}
			}
		}
		if (!resourceDescriptors.isEmpty() && modifiedResources != null) {
			modifiedResources.add(resMgr.eResource());
		}
		return resourceDescriptors;
	}

	public static ResourceDescriptor registerWithResourceManager(
			ResourceManager resMgr, Object element, URI uri) {
		String guid = getGuid(element);
		if (resMgr.getResourceDescriptor(guid) == null) {
			return createResourceDescriptor(resMgr, guid, uri);
		} else {
			return null;
		}
	}

	// /**
	// * Creates a new ResourceDescriptor for the given MethodElement and add it
	// to the given ResourceManager
	// *
	// * @param e
	// * @return newly added ResourceDescriptor
	// */
	// private static ResourceDescriptor
	// createResourceDescriptor(ResourceManager resMgr, MethodElement e) {
	// return createResourceDescriptor(resMgr, e.getGuid(), createFileURI(e));
	// }

	/**
	 * Creates a new ResourceDescriptor with the given id and resolvedURI, then
	 * adds it to the given resMgr
	 * 
	 * @param resMgr
	 * @param id
	 * @param resolvedURI
	 * @return
	 */
	private static ResourceDescriptor createResourceDescriptor(
			ResourceManager resMgr, String id, URI resolvedURI) {
		ResourceDescriptor resDesc = ResourcemanagerFactory.eINSTANCE
				.createResourceDescriptor();
		resDesc.setId(id);
		resMgr.getResourceDescriptors().add(resDesc);
		resDesc.setResolvedURI(resolvedURI);
		return resDesc;
	}

	// static void setUri(MultiFileURIConverter uriConverter, MethodElement e,
	// URI uri) {
	// setUri(uriConverter, e, uri, false);
	// }

	// static void setUri(MultiFileURIConverter uriConverter, MethodElement e,
	// URI uri, boolean saveNow) {
	// ResourceManager resMgr = uriConverter.getResourceManager();
	// if(resMgr == null) {
	// resMgr = ResourcemanagerFactory.eINSTANCE.createResourceManager();
	// uriConverter.setResourceManager(resMgr);
	// }
	// setUri(resMgr, e, uri);
	// resMgr.eResource();
	// }

	/**
	 * @param element
	 */
	public static void setGuid(MethodElement e) {
		if (e.getGuid() == null || e.getGuid().trim().length() == 0) {
			e.setGuid(EcoreUtil.generateUUID());
		}
	}

	/**
	 * Saves the given MethodElement in its own file while still preserving the
	 * existing containment association if there is any
	 * 
	 * @param e
	 * @throws LibraryResourceException 
	 */
	public static void save(MethodElement e, Map options) throws LibraryResourceException {
		MultiFileXMIResourceImpl resource = (MultiFileXMIResourceImpl) e
				.eResource();
		MultiFileResourceSetImpl resourceSet = (MultiFileResourceSetImpl) resource
				.getResourceSet();
		if (options == null) {
			options = resourceSet.getDefaultSaveOptions();
		}
		EObject container = e.eContainer();

		Set modifiedResources = new HashSet();
		options.put(MultiFileXMISaveImpl.MODIFIED_RESOURCE_SET,
				modifiedResources);
		try {
			URI uri = MultiFileSaveUtil.createURI(e, resourceSet);
			boolean createResource = resource == null
					|| (container != null && resource == container.eResource());
			if (createResource) {
				MultiFileSaveUtil.save(e, uri, options);
			} else {
				URI oldUri = resource.getURI();
				if (!oldUri.equals(uri)) {

					// resource's location is changed.
					// move the resource, then change its URI if the resource
					// move is successful.
					//   
					if (FileManager.getInstance().move(oldUri.toFileString(),
							uri.toFileString())) {
						// MultiFileURIConverter uriConverter =
						// (MultiFileURIConverter)
						// resource.getResourceSet().getURIConverter();
						// MultiFileSaveUtil.setUri(uriConverter, e, uri);
						resource.setURI(uri);
						updateURIMappings(resource, modifiedResources);
					}
				}

				if (resource.isModified()) {
					MultiFileSaveUtil.save(resource, options);
				}
			}

			resourceSet.saveModifiedResources(options);
		} finally {

		}

	}
	
	public static URI createURI(MethodElement e, ResourceSet resourceSet) {
		URI uri = null;
		if(resourceSet instanceof MultiFileResourceSetImpl) {
			IURIProvider uriProvider = ((MultiFileResourceSetImpl)resourceSet).getURIProvider();
			if(uriProvider != null) {
				uri = uriProvider.getURI(e);
			}
		}
		if(uri == null) {
			uri = createFileURI(e);
		}
		return uri;
	}

	public static void save(ResourceSet resourceSet, MethodElement e,
			Map options) {
		URI uri = createURI(e, resourceSet);
		save(resourceSet, e, uri, options);
	}

	static void adjustLocation(Resource resource, Set modifiedResources) {
		MethodElement e = PersistenceUtil.getMethodElement(resource);
		if (e == null)
			return;
		URI newFile = createURI(e, resource.getResourceSet());
		if (newFile != null && adjustLocation(resource, newFile)) {
			resource.setURI(newFile);
			updateURIMappings((MultiFileXMIResourceImpl) resource,
					modifiedResources);
		}
	}

	static URI getNewURI(MultiFileXMIResourceImpl resource) {
		MethodElement e = PersistenceUtil.getMethodElement(resource);
		if (e == null) {
			return null;
		}
		URI newFile = createURI(e, resource.getResourceSet());
		if (newFile != null && adjustLocationRequired(resource, newFile)) {
			return newFile;
		}
		return null;
	}

	static boolean prepareAdjustLocation(MultiFileXMIResourceImpl resource,
			Set modifiedResources) {
		URI newFile = getNewURI(resource);
		if (newFile != null) {
			resource.backUpURI();
			resource.setFinalURI(newFile);
			updateURIMappings((MultiFileXMIResourceImpl) resource,
					modifiedResources, false);
			return true;
		}
		return false;
	}

	public static String getGuid(Object e) {
		if(e instanceof InternalEObject) {
			InternalEObject o = (InternalEObject) e;
			if(o.eIsProxy()) {
				URI uri = o.eProxyURI();
				if(uri != null && MultiFileURIConverter.SCHEME.equals(uri.scheme())) {
					String guid = uri.fragment();
					if(guid != null) {
						return guid;
					}
				}
			}
		}
		if (e instanceof MethodElement) {
			return ((MethodElement) e).getGuid();
		} else if (e instanceof ResourceManager) {
			return ((ResourceManager) e).getGuid();
		}
		return null;
	}

	static boolean adjustLocationRequired(MultiFileXMIResourceImpl resource,
			URI newURI) {
		File oldFile = new File(resource.getFinalURI().toFileString());
		File newFile = new File(newURI.toFileString());
		return !oldFile.equals(newFile);
	}

	/**
	 * Checks if the resource's URI has been changed and adjust the resource's
	 * location.
	 * 
	 * @param oldUri
	 * @param newUri
	 */
	static boolean adjustLocation(Resource resource, URI newUri) {
		File oldFile = new File(resource.getURI().toFileString());
		File newFile = new File(newUri.toFileString());
		if (oldFile.equals(newFile)) {
			return false;
		}
		return move(resource, oldFile, newFile);
	}

	static boolean move(Resource resource, File oldFile, File newFile) {
		boolean ret = true;
		if (oldFile.equals(newFile)) {
			return false;
		}
		Object obj = PersistenceUtil.getMethodElement(resource);
		if (hasOwnFolder(obj)) {
			String oldDir = oldFile.getParentFile().toString();
			if (!oldFile.getParentFile().equals(newFile.getParentFile())) {
				if (FileManager.getInstance().rename(oldFile.getParentFile(),
						newFile.getParentFile())) {
					if (DEBUG) {
						System.out
								.println("Directory '" + oldDir + "' is successfully moved to '" + newFile.getParentFile() + "'"); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
					}
				} else {
					ret = false;
					if (DEBUG) {
						System.out
								.println("Could not move directory '" + oldDir + "' to '" + newFile.getParentFile() + "'"); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
					}
				}
			}
			if (!oldFile.getName().equals(newFile.getName())) {
				oldFile = new File(newFile.getParentFile(), oldFile.getName());
				if (FileManager.getInstance().rename(oldFile, newFile)) {
					if (DEBUG) {
						System.out
								.println("File '" + oldFile + "' is successfully moved to '" + newFile + "'"); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
					}
				} else {
					ret = false;
					if (DEBUG) {
						System.out
								.println("Could not move file '" + oldFile + "' to '" + newFile + "'"); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
					}
				}
			}
			return ret;
		} else if (oldFile.exists()) /* if(oldFile.getParentFile().equals(newFile.getParentFile())) */{
			String oldFileStr = oldFile.toString();
			if (FileManager.getInstance().rename(oldFile, newFile)) {
				if (DEBUG) {
					System.out
							.println("File '" + oldFileStr + "' is successfully moved to '" + newFile + "'"); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
				}
				return true;
			} else {
				if (DEBUG) {
					System.out
							.println("Could not move file '" + oldFileStr + "' to '" + newFile + "'"); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
				}
			}
		}
		return false;
	}

	/**
	 * 
	 * @param resMgr
	 * @param guid
	 * @param excludedResManagers
	 *            ResourceManager that are excluded from this search
	 * @return
	 */
	public static ResourceDescriptor findResourceDescriptor(
			ResourceManager resMgr, String guid,
			Collection excludedResManagers, boolean resolveProxy) {
		try {
			ResourceDescriptor desc = resMgr.getResourceDescriptor(guid);
			if (desc != null)
				return desc;
			// TODO: (Phong) performance improvement needed to avoid loading
			// resources excessively
			//
			Iterator iter;
			if (resolveProxy) {
				iter = new ArrayList(resMgr.getSubManagers()).iterator();
			} else {
				iter = ((InternalEList) resMgr.getSubManagers())
						.basicIterator();
			}
			while (iter.hasNext()) {
				ResourceManager mgr = (ResourceManager) iter.next();
				if (mgr != null
						&& !mgr.eIsProxy()
						&& (excludedResManagers == null || !excludedResManagers
								.contains(mgr))) {
					desc = findResourceDescriptor(mgr, guid,
							excludedResManagers, resolveProxy);
					if (desc != null)
						return desc;
				}
			}
			return null;
		} catch (RuntimeException e) {
			throw e;
		}
	}

	/**
	 * 
	 * @param resMgr
	 * @return how many ResourceDescriptors are in the resMgr and its
	 *         SubManagers
	 */
	public static int getCountResourceDescriptors(ResourceManager resMgr) {
		int count = resMgr.getResourceDescriptors().size();
		for (Iterator iter = resMgr.getSubManagers().iterator(); iter.hasNext();) {
			ResourceManager mgr = (ResourceManager) iter.next();
			count += getCountResourceDescriptors(mgr);
		}
		return count;
	}

	/**
	 * Gets the resource descriptor for the given resource
	 * 
	 * @param resource
	 * @return
	 */
	public static ResourceDescriptor getResourceDescriptor(Resource resource) {
		ResourceManager containerResMgr = null;
		MethodElement me = null;
		for (Iterator iter = resource.getContents().iterator(); iter.hasNext();) {
			Object element = iter.next();
			if (element instanceof MethodLibrary) {
				ResourceManager resMgr = getResourceManager(resource);
				if (resMgr != null) {
					ResourceDescriptor desc = resMgr
							.getResourceDescriptor(((MethodElement) element)
									.getGuid());
					// hack to add missing ResourceDescriptor for library's
					// resource
					//
					if (desc == null) {
						desc = registerWithResourceManager(resMgr, element,
								((MultiFileXMIResourceImpl) resource)
										.getFinalURI());
					}
					return desc;
				}
			}
			if (me == null && element instanceof MethodElement) {
				me = (MethodElement) element;
			}
			if (containerResMgr == null && element instanceof InternalEObject) {
				EObject container = getContainerWithDirectResource((InternalEObject) element);
				if (container != null) {
					containerResMgr = getResourceManager(container.eResource());
				}
			}
			if (me != null && containerResMgr != null) {
				break;
			}
		}

		if(me != null) {
			if (containerResMgr != null) {
				return containerResMgr.getResourceDescriptor(((MethodElement) me)
						.getGuid());
			}
			else if(me.eContainer() == null) {
				// this element has been loaded before its container accessed it
				// try to find its resource descriptor using root resource manager
				//
				ResourceSet resourceSet = resource.getResourceSet();
				if(resourceSet instanceof MultiFileResourceSetImpl) {
					ResourceManager rootResMgr = ((MultiFileResourceSetImpl)resourceSet).getRootResourceManager();
					Iterator iter = new AbstractTreeIterator(rootResMgr) {

						/**
						 * Comment for <code>serialVersionUID</code>
						 */
						private static final long serialVersionUID = 1L;

						protected Iterator getChildren(Object object) {
							if(object instanceof ResourceManager) {
								ArrayList children = new ArrayList();
								ResourceManager resMgr = (ResourceManager)object; 
								children.addAll(resMgr.getResourceDescriptors());
								children.addAll(resMgr.getSubManagers());
								return children.iterator();
							}
							return Collections.EMPTY_LIST.iterator();
						}
						
					};
					URI uri = getFinalURI(resource);
					while(iter.hasNext()) {
						Object o = iter.next();
						if(o instanceof ResourceDescriptor) {
							ResourceDescriptor resDesc = (ResourceDescriptor) o;
							if(uri.equals(resDesc.getResolvedURI())) {
								return resDesc;
							}
						}
					}
				}
			}
		}
		return null;
	}

	// public static ResourceDescriptor findResourceDescriptor(MethodElement e)
	// {
	// ResourceManager resMgr = null;
	// if(e.eResource() != null) {
	// resMgr = getResourceManager(e.eResource());
	// }
	// ResourceDescriptor desc = null;
	// Collection excludedResMgrs = null;
	// if(resMgr != null) {
	// desc = findResourceDescriptor(resMgr, e.getGuid());
	// if(desc != null) return desc;
	// excludedResMgrs = Collections.singletonList(resMgr);
	// }
	//		
	// MethodLibrary lib = UmaUtil.getMethodLibrary(e);
	// resMgr = getResourceManager(lib.eResource());
	//		
	// return findResourceDescriptor(resMgr, e.getGuid(), excludedResMgrs);
	// }

	/**
	 * Gets the ResourceManager in the contents of the given resource
	 * 
	 * @param resource
	 * @return
	 */
	public static ResourceManager getResourceManager(Resource resource) {
		ResourceManager resMgr = null;
		for (Iterator iter = resource.getContents().iterator(); iter.hasNext();) {
			Object element = (Object) iter.next();
			if (element instanceof ResourceManager) {
				resMgr = (ResourceManager) element;
				break;
			}
		}

		return resMgr;
	}

	static InternalEObject getContainerWithDirectResource(InternalEObject obj) {
		if (obj.eContainer() == null)
			return null;
		InternalEObject container = (InternalEObject) ((InternalEObject) obj
				.eContainer());
		if (container.eDirectResource() != null) {
			return container;
		}
		return getContainerWithDirectResource(container);
	}

	static String getHREF(Resource resource, Object obj) {
		MethodElement owner = PersistenceUtil.getMethodElement(resource);
		return MultiFileURIConverter.createURI(owner.getGuid()).appendFragment(
				getGuid(obj)).toString();
	}

	public static String getBackupFileSuffix() {
		return "_" + dateFormatter.format(Calendar.getInstance().getTime()); //$NON-NLS-1$
	}

	/**
	 * Resolve the proxy identified by the given <code>guid</code> without
	 * loading all other proxies in <code>parent</code>
	 * 
	 * @param guid
	 * @param parent
	 * @return
	 */
	public static void resolveProxies(Collection GUIDs, EObject parent) {
		for (Iterator iterator = parent.eClass().getEAllContainments()
				.iterator(); !GUIDs.isEmpty() && iterator.hasNext();) {
			EStructuralFeature feature = (EStructuralFeature) iterator.next();
			if (feature.isMany()) {
				InternalEList list = (InternalEList) parent.eGet(feature);
				int index = 0;
				for (Iterator iter1 = list.basicIterator(); !GUIDs.isEmpty()
						&& iter1.hasNext(); index++) {
					InternalEObject child = (InternalEObject) iter1.next();
					if (child.eIsProxy()) {
						String guid = child.eProxyURI().fragment();
						if (GUIDs.contains(guid)) {
							// this will resolve the object with guid
							//
							list.get(index);
							GUIDs.remove(guid);
						}
					} else {
						resolveProxies(GUIDs, child);
					}
				}
			} else {
				InternalEObject child = (InternalEObject) parent.eGet(feature,
						false);
				if (child != null) {
					if (child.eIsProxy()) {
						String guid = child.eProxyURI().fragment();
						if (GUIDs.contains(guid)) {
							// this will resolve the object with guid
							//
							parent.eGet(feature);
							GUIDs.remove(guid);
						}
					} else {
						resolveProxies(GUIDs, child);
					}
				}
			}
		}
	}

	public static URI getFinalURI(Resource resource) {
		return resource instanceof MultiFileXMIResourceImpl ? ((MultiFileXMIResourceImpl) resource)
				.getFinalURI()
				: resource.getURI();
	}

	/**
	 * @param impl
	 * @return
	 */
	static boolean adjustLocationRequired(MultiFileXMIResourceImpl resource) {
		MethodElement e = PersistenceUtil.getMethodElement(resource);		
		if(e != null && hasOwnFolder(e)) {
			URI newURI = createURI(e, resource.getResourceSet());
			if(adjustLocationRequired(resource, newURI) && !new File(newURI.toFileString()).exists()) {
				return true;
			}
		}
		return false;
	}

	/**
	 * Checks if the specified resource is currently synchronized with its data store
	 * 
	 * @return <li> -1 don't know
	 *         <li> 0 no
	 *         <li> 1 yes
	 */
	public static int checkSynchronized(Resource resource) {
		if(resource instanceof MultiFileXMIResourceImpl) {
			return ((MultiFileXMIResourceImpl)resource).checkSynchronized();
		}
		return -1;
	}

	/**
	 * Some team providers changed the timestamp of last file modification by removing second fraction
	 * even the file was not changed. This method check the current and old time stamps for this.
	 * 
	 * @param currentTimeStamp
	 * @param lastTimeStamp
	 * @return
	 */
	public static boolean same(long currentTimeStamp, long lastTimeStamp) {
		return currentTimeStamp < lastTimeStamp && (currentTimeStamp & 7) == 0 && (lastTimeStamp - currentTimeStamp) < 1000;
	}

	/**
	 * Adds an empty resource manager for the given resource if it does not have one.
	 * 
	 * @param resource
	 * @return true if a new resource manager is added, false otherwise
	 */
	static ResourceManager addResourceManager(Resource resource) {
		ResourceManager resMgr = getResourceManager(resource);
		if (resMgr == null) {
			resMgr = ResourcemanagerFactory.eINSTANCE.createResourceManager();
			resource.getContents().add(0, resMgr);
			return resMgr;
		}
		return null;
	}
	
	static void checkFilePathLength(Collection resources) {
		List<String> pathList = new ArrayList<String>();
		for (Iterator iter = resources.iterator(); iter.hasNext();) {
			Resource resource = (Resource) iter.next();
			if(resource instanceof MultiFileXMIResourceImpl && ((MultiFileXMIResourceImpl)resource).hasTempURI()) {
				continue;
			}
			pathList.add(resource.getURI().toFileString());
		}
		
		if(!pathList.isEmpty()) {
			String[] paths = new String[pathList.size()];
			pathList.toArray(paths);

			for (int i=0; i < paths.length; i++) {
				String path = paths[i];
				if (paths[i].length() > 255) {
					String msg = NLS.bind(PersistenceResources.filePathNameTooLong_msg, Arrays
								.asList(paths));
					throw new MultiFileIOException(msg);
				}
			}
		}
	}

	/**
	 * Lists all possible configuration files in the specified directory <code>configDir</code> and its sub directories.
	 * 
	 * @param configDir
	 * @return
	 */
	public static Iterator listConfigFiles(File configDir) {
		return new AbstractTreeIterator(configDir, false) {
			/**
			 * Comment for <code>serialVersionUID</code>
			 */
			private static final long serialVersionUID = 2758436193000640907L;

			FileFilter filter = new FileFilter() {

				public boolean accept(File pathname) {
					return !FileManager.getInstance().isTeamPrivate(pathname.getAbsolutePath()) &&
							(pathname.isDirectory()
							|| pathname.getName().endsWith(
									MultiFileSaveUtil.DEFAULT_FILE_EXTENSION));
				}

			};

			protected Iterator getChildren(Object object) {
				File[] files = ((File) object).listFiles(filter);
				if (files != null && files.length > 0) {
					return Arrays.asList(files).iterator();
				}
				return Collections.EMPTY_LIST.iterator();
			}

		};
	}
	
}