//------------------------------------------------------------------------------
// 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.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.serviceability.MsgBox;
import org.eclipse.epf.common.utils.StrUtil;
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.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
 * @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) {
		// don't check if the resource is currently being saved to a temporary
		// file
		//
		if (resource instanceof MultiFileXMIResourceImpl
				&& ((MultiFileXMIResourceImpl) resource).hasTempURI()) {
			return;
		}
		String path = resource.getURI().toFileString();
		IStatus status = FileManager.getInstance().checkModify(path,
				MsgBox.getDefaultShell());
		if (!status.isOK()) {
			String msg = UmaUtil.getMessage(status);
			if (msg == null) {
				msg = NLS.bind(PersistenceResources.modifyFileError_msg, path);
			}
			throw new MultiFileIOException(msg);
		}
	}

	public static void checkModify(Collection resources) {
		ArrayList pathList = new ArrayList();
		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);
			IStatus status = FileManager.getInstance().checkModify(paths,
					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 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);
					}
				}
			}
		}
	}

	/**
	 * 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);
				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);
			MethodLibrary lib = (MethodLibrary) plugin.eContainer();
			String pluginDir;
			if (lib != null) {
				String libDir = new File(((MultiFileXMIResourceImpl) lib
						.eResource()).getFinalURI().toFileString()).getParent();
				pluginDir = libDir + File.separator + plugin.getName();
			} else {
				if (plugin.eResource() == null) {
					// plugin is already deleted
					//
					return null;
				}
				pluginDir = new File(((MultiFileXMIResourceImpl) plugin
						.eResource()).getFinalURI().toFileString()).getParent();
			}
			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
	 */
	public static void save(MethodElement e, Map options) {
		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.createFileURI(e);
			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 void save(ResourceSet resourceSet, MethodElement e,
			Map options) {
		URI uri = createFileURI(e);
		save(resourceSet, e, uri, options);
	}

	static void adjustLocation(Resource resource, Set modifiedResources) {
		MethodElement e = PersistenceUtil.getMethodElement(resource);
		if (e == null)
			return;
		URI newFile = createFileURI(e);
		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 = createFileURI(e);
		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 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
				// 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 = createFileURI(e);
			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;
	}
}