//------------------------------------------------------------------------------
// 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.FileNotFoundException;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Set;

import org.eclipse.core.resources.IResource;
import org.eclipse.core.runtime.IPath;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.Path;
import org.eclipse.core.runtime.Status;
import org.eclipse.emf.common.CommonPlugin;
import org.eclipse.emf.common.notify.Notification;
import org.eclipse.emf.common.notify.impl.NotificationImpl;
import org.eclipse.emf.common.util.AbstractTreeIterator;
import org.eclipse.emf.common.util.URI;
import org.eclipse.emf.common.util.UniqueEList;
import org.eclipse.emf.common.util.WrappedException;
import org.eclipse.emf.ecore.EAttribute;
import org.eclipse.emf.ecore.EClass;
import org.eclipse.emf.ecore.EClassifier;
import org.eclipse.emf.ecore.EObject;
import org.eclipse.emf.ecore.EReference;
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.URIConverter;
import org.eclipse.emf.ecore.resource.impl.ResourceSetImpl;
import org.eclipse.emf.ecore.util.EcoreUtil;
import org.eclipse.emf.ecore.util.InternalEList;
import org.eclipse.emf.ecore.xmi.XMLResource;
import org.eclipse.emf.ecore.xmi.impl.XMLInfoImpl;
import org.eclipse.emf.ecore.xmi.impl.XMLMapImpl;
import org.eclipse.emf.ecore.xmi.impl.XMLResourceImpl;
import org.eclipse.epf.common.utils.FileUtil;
import org.eclipse.epf.library.persistence.ILibraryResourceSet;
import org.eclipse.epf.library.persistence.LibraryResourceException;
import org.eclipse.epf.persistence.refresh.IRefreshEvent;
import org.eclipse.epf.persistence.refresh.IRefreshListener;
import org.eclipse.epf.persistence.refresh.RefreshJob;
import org.eclipse.epf.persistence.refresh.internal.RefreshEvent;
import org.eclipse.epf.persistence.util.PersistenceResources;
import org.eclipse.epf.persistence.util.PersistenceUtil;
import org.eclipse.epf.persistence.util.UnresolvedProxyMarkerManager;
import org.eclipse.epf.resourcemanager.ResourceDescriptor;
import org.eclipse.epf.resourcemanager.ResourceManager;
import org.eclipse.epf.services.ILibraryPersister;
import org.eclipse.epf.services.Services;
import org.eclipse.epf.uma.Activity;
import org.eclipse.epf.uma.BreakdownElement;
import org.eclipse.epf.uma.Descriptor;
import org.eclipse.epf.uma.Diagram;
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.Process;
import org.eclipse.epf.uma.ProcessComponent;
import org.eclipse.epf.uma.ProcessElement;
import org.eclipse.epf.uma.ProcessPackage;
import org.eclipse.epf.uma.RoleDescriptor;
import org.eclipse.epf.uma.SemanticModelBridge;
import org.eclipse.epf.uma.TeamProfile;
import org.eclipse.epf.uma.UMASemanticModelBridge;
import org.eclipse.epf.uma.UmaFactory;
import org.eclipse.epf.uma.UmaPackage;
import org.eclipse.epf.uma.WorkOrder;
import org.eclipse.epf.uma.WorkProductDescriptor;
import org.eclipse.epf.uma.ecore.IProxyResolutionListener;
import org.eclipse.epf.uma.ecore.IUmaResourceSet;
import org.eclipse.epf.uma.ecore.ResolveException;
import org.eclipse.epf.uma.ecore.impl.MultiResourceEObject;
import org.eclipse.epf.uma.ecore.util.EventTypes;
import org.eclipse.epf.uma.ecore.util.OppositeFeature;
import org.eclipse.epf.uma.util.AssociationHelper;
import org.eclipse.epf.uma.util.ContentDescriptionFactory;
import org.eclipse.epf.uma.util.UmaUtil;
import org.eclipse.osgi.util.NLS;

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

/**
 * @author Phong Nguyen Le
 * @since 1.0
 */
public class MultiFileResourceSetImpl extends ResourceSetImpl implements
		IProxyResolutionListener, IUmaResourceSet, ILibraryResourceSet {
	public static final String SKIP_RETRY_PROXY_RESOLUTION = "SKIP_RETRY_PROXY_RESOLUTION"; //$NON-NLS-1$

	private static final String[] DEFAULT_DELIVERY_PROCESS_PATH = { "DeliveryProcesses" }; //$NON-NLS-1$

	private static final String[] DEFAULT_CAPABILITY_PATTERN_PATH = {
			"Content", "CapabilityPatterns" }; //$NON-NLS-1$ //$NON-NLS-2$

	private static final String[] DEFAULT_PROCESS_CONTRIBUTION_PATH = { "ProcessContributions" }; //$NON-NLS-1$		

	public static final String[][] PROCESS_PACKAGE_PATHS = {
			DEFAULT_DELIVERY_PROCESS_PATH, DEFAULT_CAPABILITY_PATTERN_PATH,
			DEFAULT_PROCESS_CONTRIBUTION_PATH };

	public static boolean REPORT_ERROR = true;

	static final Map<Object, Object> DEFAULT_SAVE_OPTIONS = new HashMap<Object, Object>();

	static final Set DEFAULT_SAVE_SEPARATELY_CLASS_SET = new HashSet();

	static {
		DEFAULT_SAVE_SEPARATELY_CLASS_SET.add(UmaPackage.eINSTANCE
				.getMethodPlugin());
		DEFAULT_SAVE_SEPARATELY_CLASS_SET.add(UmaPackage.eINSTANCE
				.getProcessComponent());
		DEFAULT_SAVE_SEPARATELY_CLASS_SET.add(UmaPackage.eINSTANCE
				.getContentDescription());
		// eClasses.add(ResourcemanagerPackage.eINSTANCE.getResourceManager());
		DEFAULT_SAVE_SEPARATELY_CLASS_SET.add(UmaPackage.eINSTANCE
				.getMethodConfiguration());

		XMLResource.XMLMap xmlMap = createSaveXMLMap();

		HashSet saveTogether = new HashSet();
		saveTogether.add(UmaPackage.eINSTANCE.getBreakdownElementDescription());

		DEFAULT_SAVE_OPTIONS.put(
				MultiFileXMISaveImpl.SAVE_SEPARATELY_CLASS_SET,
				DEFAULT_SAVE_SEPARATELY_CLASS_SET);
		DEFAULT_SAVE_OPTIONS.put(MultiFileXMISaveImpl.SAVE_ALL, "false"); //$NON-NLS-1$
		DEFAULT_SAVE_OPTIONS.put(MultiFileXMISaveImpl.SAVE_TOGETHER_CLASS_SET,
				saveTogether);
		DEFAULT_SAVE_OPTIONS.put(MultiFileXMISaveImpl.REFRESH_NEW_RESOURCE,
				"true"); //$NON-NLS-1$
		DEFAULT_SAVE_OPTIONS.put(MultiFileXMISaveImpl.CHECK_MODIFY, "true"); //$NON-NLS-1$
		DEFAULT_SAVE_OPTIONS.put(XMLResource.OPTION_ENCODING, "UTF-8"); //$NON-NLS-1$
		DEFAULT_SAVE_OPTIONS.put(XMLResource.OPTION_PROCESS_DANGLING_HREF,
				XMLResource.OPTION_PROCESS_DANGLING_HREF_DISCARD);
		DEFAULT_SAVE_OPTIONS.put(XMLResource.OPTION_XML_MAP, xmlMap);
		DEFAULT_SAVE_OPTIONS.put(XMLResource.OPTION_CONFIGURATION_CACHE, Boolean.TRUE);

		AssociationHelper.init();
	}

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

	private HashMap<Object, Object> defaultSaveOptions;

	private HashMap<String, EObject> guidToMethodElementMap;

	private boolean loading;

	private boolean loadingResourceManagerTree;

	private Map URIToTempURIMap;

	private UnresolvedProxyMarkerManager markerMananger;

	private UniqueEList<IRefreshListener> refreshListeners;

	protected IURIProvider uriProvider;

	private Path configFolderPath;

	private Path libFolderPath;

	private static XMLResource.XMLMap createLoadXMLMap() {
		XMLResource.XMLMap xmlMap = new XMLMapImpl();
		Set excludedAttributes = new HashSet();
		excludedAttributes.add(UmaPackage.eINSTANCE.getMethodElement_Guid());
		excludedAttributes.add(UmaPackage.eINSTANCE.getNamedElement_Name());

		for (Iterator iter = UmaPackage.eINSTANCE.getEClassifiers().iterator(); iter
				.hasNext();) {
			EClassifier eClassifier = (EClassifier) iter.next();
			if (eClassifier instanceof EClass) {
				EClass eClass = (EClass) eClassifier;

				for (Iterator iterator = eClass.getEAttributes().iterator(); iterator
						.hasNext();) {
					EAttribute attrib = (EAttribute) iterator.next();
					if (!excludedAttributes.contains(attrib)) {
						XMLResource.XMLInfo xmlInfo = new XMLInfoImpl();
						xmlInfo.setName(attrib.getName());
						xmlInfo
								.setXMLRepresentation(XMLResource.XMLInfo.ELEMENT);
						xmlMap.add(attrib, xmlInfo);
					}
				}
			}
		}

		return xmlMap;
	}

	private static boolean saveAttributeAsElement(EClass eClass,
			Collection selectedEClasses) {
		for (Iterator iter = selectedEClasses.iterator(); iter.hasNext();) {
			EClass base = (EClass) iter.next();
			if (base.isSuperTypeOf(eClass)) {
				return true;
			}
		}
		return false;
	}

	private static XMLResource.XMLMap createSaveXMLMap() {
		XMLResource.XMLMap xmlMap = new XMLMapImpl();
		Set excludedAttributes = new HashSet();
		excludedAttributes.add(UmaPackage.eINSTANCE.getMethodElement_Guid());
		excludedAttributes.add(UmaPackage.eINSTANCE.getNamedElement_Name());

		// select only ContentDescription and Section
		Set selectedEClasses = new HashSet();
		selectedEClasses.add(UmaPackage.eINSTANCE.getContentDescription());
		selectedEClasses.add(UmaPackage.eINSTANCE.getSection());

		for (Iterator iter = UmaPackage.eINSTANCE.getEClassifiers().iterator(); iter
				.hasNext();) {
			EClassifier eClassifier = (EClassifier) iter.next();
			if (eClassifier instanceof EClass) {
				EClass eClass = (EClass) eClassifier;

				if (saveAttributeAsElement(eClass, selectedEClasses)) {
					for (Iterator iterator = eClass.getEAttributes().iterator(); iterator
							.hasNext();) {
						EAttribute attrib = (EAttribute) iterator.next();
						if (!excludedAttributes.contains(attrib)) {
							XMLResource.XMLInfo xmlInfo = new XMLInfoImpl();
							xmlInfo.setName(attrib.getName());
							xmlInfo
									.setXMLRepresentation(XMLResource.XMLInfo.ELEMENT);
							xmlMap.add(attrib, xmlInfo);
						}
					}
				}
			}
		}

		return xmlMap;
	}

	public MultiFileResourceSetImpl() {
		super();
		setURIResourceMap(new HashMap<URI, Resource>());
		markerMananger = new UnresolvedProxyMarkerManager(this);
	}

	public MultiFileResourceSetImpl(boolean reportError) {
		this();
		markerMananger.setEnabled(reportError);
	}

	public UnresolvedProxyMarkerManager getUnresolvedProxyMarkerManager() {
		return markerMananger;		
	}
	
	public IURIProvider getURIProvider() {
		if(uriProvider == null) {
			uriProvider = new FilePathProvider();
		}
		return uriProvider;
	}
	
	private void handleResourceChange(IResource wsRes) {
		System.out
				.println("MultiFileResourceSetImpl.handleResourceChange(): " + wsRes.toString()); //$NON-NLS-1$

		MultiFileXMIResourceImpl resource = (MultiFileXMIResourceImpl) getResource(
				URI.createFileURI(wsRes.getLocation().toString()), false);
		if (resource != null) {
			try {
				ArrayList proxies = new ArrayList();
				resource.reload(proxies);

				// notify MAKE_PROXY event for all proxies
				//
				Notification msg = new NotificationImpl(EventTypes.MAKE_PROXY,
						false, true);
				for (Iterator iter = proxies.iterator(); iter.hasNext();) {
					EObject o = (EObject) iter.next();
					o.eNotify(msg);
				}

			} catch (IOException e) {
				CommonPlugin.INSTANCE.log(e);
			}
		}

	}

	public Map<Object, Object> getLoadOptions() {
		Map<Object, Object> options = super.getLoadOptions();
		options.put(XMLResource.OPTION_ENCODING, "UTF-8"); //$NON-NLS-1$
		options.put(XMLResource.OPTION_XML_MAP, createLoadXMLMap());
		return options;
	}

	public Map<Object, Object> getDefaultSaveOptions() {
		if (defaultSaveOptions == null) {
			defaultSaveOptions = new HashMap<Object, Object>();
			defaultSaveOptions.putAll(DEFAULT_SAVE_OPTIONS);
		}

		return defaultSaveOptions;
	}

	private Resource getMethodLibraryResource() {
		if (getResources().isEmpty())
			return null;
		return (Resource) getResources().get(0);
	}

	public MethodLibrary getMethodLibrary() {
		Resource resource = getMethodLibraryResource();
		return resource == null ? null : (MethodLibrary) PersistenceUtil
				.getMethodElement(resource);
	}

	protected ResourceManager getRootResourceManager() {
		Resource resource = getMethodLibraryResource();
		return resource == null ? null : MultiFileSaveUtil
				.getResourceManager(resource);
	}

	/**
	 * @see org.eclipse.emf.ecore.resource.impl.ResourceSetImpl#getURIConverter()
	 */
	public URIConverter getURIConverter() {
		if (uriConverter == null) {
			uriConverter = new MultiFileURIConverter(this);
		}
		return uriConverter;
	}

	/**
	 * @param uri
	 * @return null if the resource with the given URI could not be found
	 */
	public Resource getResource(URI uri) {
		if (getURIConverter().normalize(uri) == null)
			return null;
		Resource res = null;
		try {
			res = super.getResource(uri, false);
			if (res == null) {
				Map map = getURIResourceMap();
				res = createResource(uri);

				try {
					demandLoadHelper(res);
				} catch (RuntimeException e) {
					// remove the resource from resource set if it could not be
					// loaded
					//
					getResources().remove(res);
					throw e;
				}

				if (map != null) {
					map.put(uri, res);
				}
			}
		} catch (WrappedException e) {
			if (e.exception() instanceof FileNotFoundException) {
				return null;
			}
			throw e;
		}
		return res;
	}
	
	/* (non-Javadoc)
	 * @see org.eclipse.emf.ecore.resource.impl.ResourceSetImpl#demandLoad(org.eclipse.emf.ecore.resource.Resource)
	 */
	protected void demandLoad(Resource resource) throws IOException {
		super.demandLoad(resource);

		// refresh workspace resource of this resource to make them synchronized
		//
		boolean ret = FileManager.getInstance().refresh(resource);
		if(MultiFileSaveUtil.DEBUG) {
			if(!ret) {
				System.err.println("MultiFileResourceSetImpl.demandLoad(): could not refresh resource " + resource); //$NON-NLS-1$
			}
		}
	}
	
	/**
	 * Resolves container of the MethodElement in the given resource.
	 * 
	 * @param res
	 */
	public void resolveContainer(Resource res) {
		MethodLibrary lib = getMethodLibrary();
		if(loading && lib == null) {
			return;
		}
		for (Iterator iterator = res.getContents().iterator(); iterator.hasNext();) {
			Object element = (Object) iterator.next();
			if(element instanceof MethodElement) {
				MethodElement e = (MethodElement) element;
				if(e != lib && e.eContainer() == null) {
					// the method element might have been loaded before its container accessed it
					//
					ResourceDescriptor resDesc = MultiFileSaveUtil.getResourceDescriptor(res);
					if(resDesc != null) {
						Resource containerResource = resDesc.eResource();
						if(containerResource instanceof XMLResourceImpl) {
							Object proxy = ((XMLResourceImpl)containerResource).getIDToEObjectMap().get(e.getGuid());
							if(proxy instanceof EObject) {
								EObject proxyEObject = ((EObject)proxy); 
								EReference ref = proxyEObject.eContainmentFeature();
								EObject container = proxyEObject.eContainer();
								if(container != null) {
									if (ref.isMany()) {
										List values = (List) container.eGet(ref);
										for (Iterator iter = values.iterator(); iter.hasNext(); iter
										.next())
											;
									} else {
										container.eGet(ref);
									}
									resolveContainer(containerResource);
								}
							}
						}
					}
				}
			}			
		}
	}
	
	private Set<URI> errorUriSet;
	private void handleLoadResourceException(URI uri, RuntimeException e) {
		if (errorUriSet == null) {
			errorUriSet = new HashSet<URI>();
		}
		if (errorUriSet.contains(uri)) {
			return;
		}
		errorUriSet.add(uri);
		String msg = null;
		if (e.getMessage() != null) {
			msg = NLS.bind(
					PersistenceResources.loadResourceErrorWithReason_msg,
					(new Object[] { uri, e.getMessage() }));
		}
		else {
			msg = NLS.bind(PersistenceResources.loadResourceError_msg, uri);
			PersistencePlugin.getDefault().getLogger().logError(e);
		}
		handleException(msg);
		throw e;

	}

	/**
	 * @see org.eclipse.emf.ecore.resource.impl.ResourceSetImpl#getResource(org.eclipse.emf.common.util.URI,
	 *      boolean)
	 */
	public Resource getResource(URI uri, boolean loadOnDemand) {
		if (getURIConverter().normalize(uri) == null)
			return null;
		Resource res = null;
		try {
			res = super.getResource(uri, loadOnDemand);
		} catch (RuntimeException e) {
			// Somehow the resource list of the resource set has null value that
			// will cause NullPointerException in the following call. Remove the null resource and retry here.
			// TODO: need to find out the cause of this and fix it.
			if(e instanceof NullPointerException) {
				boolean hasNull = false;
				for (Iterator<Resource> iterator = getResources().iterator(); iterator
						.hasNext();) {
					Resource resource = iterator.next();
					if(resource == null) {
						iterator.remove();
						hasNull = true;
					}
				}
				if(hasNull) {
					try {
						return super.getResource(uri, loadOnDemand);
					} catch(RuntimeException re) {
						handleLoadResourceException(uri, re);
					}
				}
			}
			
			handleLoadResourceException(uri, e);
		}
		return res;
	}

	public void addRefreshListener(IRefreshListener listener) {
		if (refreshListeners == null) {
			refreshListeners = new UniqueEList<IRefreshListener>();
		}
		refreshListeners.add(listener);
	}

	public void removeRefreshListenter(IRefreshListener listener) {
		if (refreshListeners != null) {
			refreshListeners.remove(listener);
		}
	}
	
	public void notifyRefreshListeners(IRefreshEvent event) {
		if(refreshListeners != null && !refreshListeners.isEmpty()) {
			for (IRefreshListener listener : refreshListeners) {
				try {
					listener.notifyRefreshed(event);
				} catch (Exception e) {
					PersistencePlugin.getDefault().getLogger().logError(e);
				}
			}
		}
	}

	/**
	 * Reloads the given resources
	 * 
	 * @param resources
	 * @return resources that had been reloaded
	 */
	public synchronized Collection reloadResources(Collection resources) {		
		// save the ResourceDescriptor for the resources to create URI for their
		// proxies after unload
		//
		for (Iterator iter = resources.iterator(); iter.hasNext();) {
			MultiFileXMIResourceImpl resource = (MultiFileXMIResourceImpl) iter
					.next();
			
			if(MultiFileSaveUtil.DEBUG) {
				System.out
						.println("MultiFileResourceSetImpl.reloadResources(): resource=" + resource + ", element=" + PersistenceUtil.getMethodElement(resource)); //$NON-NLS-1$ //$NON-NLS-2$
			}
			
			ResourceDescriptor resDesc = MultiFileSaveUtil
					.getResourceDescriptor(resource);
			if (resDesc != null) {
				resource.setResourceDescriptor(resDesc);
			}
		}

		ArrayList reloadedResources = new ArrayList();
		HashSet proxies = new HashSet();
		ArrayList resourceList = new ArrayList(resources);

		Resource libResource = getMethodLibraryResource();
		boolean reloadAllConfigs = false;
		if (resourceList.remove(libResource)) {
			// MethodLibrary resource is to reload, it must be reloaded first
			//			
			MultiFileXMIResourceImpl resource = (MultiFileXMIResourceImpl) libResource;

			// clear markers for this resource
			//
			markerMananger.clearMarkers(resource);

			try {
				if (resource.reload(proxies)) {
					reloadedResources.add(resource);

					// reset the resource manager reference in URIConverter of
					// this resource set
					// since the resource manager is reloaded
					//
					MultiFileURIConverter uriConverter = (MultiFileURIConverter) getURIConverter();
					uriConverter.resMgr = null;
					
					reloadAllConfigs = true;
				}
			} catch (IOException e) {
				CommonPlugin.INSTANCE.log(e);
			}

		}
		// reload the resources
		//
		for (Iterator iter = resourceList.iterator(); iter.hasNext();) {
			MultiFileXMIResourceImpl resource = (MultiFileXMIResourceImpl) iter
					.next();

			// clear markers for this resource
			//
			markerMananger.clearMarkers(resource);

			try {
				if (resource.reload(proxies)) {
					reloadedResources.add(resource);
				}
			} catch (IOException e) {
				CommonPlugin.INSTANCE.log(e);
			}
		}

		if (!reloadedResources.isEmpty()) {
			// reinitialize the resource set
			//
			initialize(reloadAllConfigs);

			// notify the listeners
			//
			if (refreshListeners != null) {
				IRefreshEvent event = new RefreshEvent(reloadedResources,
						proxies);
				for (Iterator iter = new ArrayList(refreshListeners).iterator(); iter
						.hasNext();) {
					IRefreshListener listener = (IRefreshListener) iter.next();
					listener.notifyRefreshed(event);
				}
			}
		}

		return reloadedResources;
	}

	public void initialize(boolean loadConfigurations) {
		// load the ResourceManager tree and opposite features
		//
		loadResourceManagerTree();

		setContainersOfLoadedElements();
		
		if(loadConfigurations) {
			loadConfigurations();
		}

		loadOppositeFeatures();

		// reset the resource manager reference in URIConverter of this resource
		// set
		//
		MultiFileURIConverter uriConverter = (MultiFileURIConverter) getURIConverter();
		uriConverter.resMgr = null;
	}
	
	private void setContainersOfLoadedElements() {
		ResourceManager resMgr = getRootResourceManager();
		Iterator iterator = new AbstractTreeIterator(resMgr, false) {

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

			protected Iterator getChildren(Object object) {
				ResourceManager resMgr = (ResourceManager) object;
				Collection GUIDs = new HashSet();
				List subMgrs = new ArrayList(resMgr.getSubManagers());
				for (Iterator iter = subMgrs.iterator(); iter.hasNext();) {
					try {
						InternalEObject subMgr = (InternalEObject) iter
								.next();
						if (subMgr != null && !subMgr.eIsProxy()) {
							MethodElement e = PersistenceUtil
									.getMethodElement(subMgr.eResource());
							GUIDs.add(e.getGuid());
						}
					} catch (RuntimeException e) {
						throw e;
					}
				}
				Resource resource = resMgr.eResource();
				if(resource != null) {
					MethodElement parent = PersistenceUtil
							.getMethodElement(resource);

					// resolve the proxy of this element in the parent
					//
					MultiFileSaveUtil.resolveProxies(GUIDs, parent);
				}

				return resMgr.getSubManagers().iterator();
			}

		};
		for (; iterator.hasNext(); iterator.next())
			;
	}

	/**
	 * Checks if the given workspace resource represents a library resource
	 * 
	 * @param wsResource
	 * @return
	 */
	public boolean isLibraryResource(IResource wsResource) {
		return libFolderPath != null && libFolderPath.isPrefixOf(wsResource.getLocation());
	}
	
	/**
	 * Checks if the given workspace resource is a new resource that can be loaded 
	 * using {@link #loadNewResources(Collection)}
	 *  
	 * @return
	 */
	public boolean isNewResourceToLoad(IResource wsResource) {
		IPath loc = wsResource.getLocation();
		return (loc != null && configFolderPath != null 
				&& MultiFileSaveUtil.DEFAULT_FILE_EXTENSION.equalsIgnoreCase("." + loc.getFileExtension()) //$NON-NLS-1$
				&& configFolderPath.isPrefixOf(loc)
				&& !FileManager.getInstance().isTeamPrivate(loc.toString()));

	}
	
	/**
	 * Loads new resources specified by the given collection of {@link IResource work space resources}
	 * into this resource set
	 * TODO: merge this code to {@link #getResource(URI, boolean)}
	 * @param wsResources collection of {@link IResource} objects
	 */
	public void loadNewResources(Collection<IResource> wsResources) {
		ArrayList newConfigFiles = new ArrayList();
		for (Iterator iter = wsResources.iterator(); iter.hasNext();) {
			Object wsResource = (Object) iter.next();
			if(wsResource instanceof IResource) {
				IResource wsRes = (IResource) wsResource;
				IPath loc = wsRes.getLocation();
				String configFile;
				if(loc != null && configFolderPath != null 
						&& MultiFileSaveUtil.DEFAULT_FILE_EXTENSION.equalsIgnoreCase("." + loc.getFileExtension()) //$NON-NLS-1$
						&& configFolderPath.isPrefixOf(loc)
						&& !FileManager.getInstance().isTeamPrivate(configFile = loc.toString())) {
					newConfigFiles.add(configFile);
				}
			}
		}
		
		// load new configurations
		//
		for (Iterator iter = newConfigFiles.iterator(); iter.hasNext();) {
			String configFile = (String) iter.next();
			loadConfiguration(new File(configFile));
		}
	}

	/**
	 * Special handling for MethodConfiguration since MethodLibrary will no
	 * longer keeps the references to MethodConfigurations and their files. Any
	 * XMI file under folder ./configurations and its subfolders will be treated
	 * as a configuration file. They will be loaded and added to MethodLibrary
	 * as its configurations.
	 * @return TODO
	 */
	protected Collection<Resource> loadConfigurations() {
		MethodLibrary lib = getMethodLibrary();
		File configDir = new File(new File(lib.eResource().getURI()
				.toFileString()).getParent(),
				MultiFileSaveUtil.METHOD_CONFIGURATION_FOLDER_NAME);
		return loadConfigurations(configDir);
	}
	
	/**
	 * Loads method configurations from the specified directory.
	 * 
	 * @param configDir
	 * @return TODO
	 */
	protected Collection<Resource> loadConfigurations(File configDir) {
		ArrayList<Resource> resources = new ArrayList<Resource>();
		Iterator dirIter = MultiFileSaveUtil.listConfigFiles(configDir);
		HashSet<File> configFiles = new HashSet<File>();
		while (dirIter.hasNext()) {
			File configFile = (File) dirIter.next();
			if(configFile.isFile()) {
				configFiles.add(configFile);
			}
		}
		MethodLibrary lib = getMethodLibrary();
		for (Iterator iter = lib.getPredefinedConfigurations().iterator(); iter
				.hasNext();) {
			MethodConfiguration config = (MethodConfiguration) iter.next();
			File file = new File(config.eResource().getURI().toFileString());
			if (configFiles.contains(file)) {
				configFiles.remove(file);
			}
		}

		for (Iterator iter = configFiles.iterator(); iter.hasNext();) {
			File file = (File) iter.next();
			Resource resource = loadConfiguration(file);
			if(resource != null) {
				resources.add(resource);
			}
		}
		return resources;
	}

	protected Resource loadConfiguration(File configFile) {
		try {
			MethodLibrary lib = getMethodLibrary();
			URI uri = URI.createFileURI(configFile.getCanonicalPath());
			Resource resource = super.getResource(uri, true);
			if (resource != null) {
				MethodElement e = PersistenceUtil
						.getMethodElement(resource);
				if (e instanceof MethodConfiguration) {
					if(PersistenceUtil.hasDuplicateGUID(e, lib.getPredefinedConfigurations())) {
						PersistencePlugin.getDefault().getLogger().logError(
								NLS.bind(PersistenceResources.loadConfiguration_couldNotLoad_logMsg, configFile));
					}
					else {
						lib.getPredefinedConfigurations().add((MethodConfiguration) e);
						return resource;
					}
				} else {
					PersistencePlugin.getDefault().getLogger().logError(
							NLS.bind(PersistenceResources.loadConfiguration_notConfigFile_logMsg, configFile)
							);
				}
				resource.unload();
				getResources().remove(resource);
			}
		} catch (Exception e) {
			PersistencePlugin.getDefault().getLogger().logError(e);
		}
		return null;
	}

	/**
	 * @param string
	 */
	protected void handleException(Object err) {
		if (err instanceof Throwable) {
			PersistencePlugin.getDefault().getLogger().logError((Exception)err);
		} else {
			PersistencePlugin.getDefault().getLogger().logError(err.toString());
		}
		if(MultiFileSaveUtil.DEBUG) {
			if (err instanceof Throwable) {
				((Exception) err).printStackTrace();
			} else {
				System.err.println(err.toString());
			}
		}
	}

	public void reset() {
		if (uriConverter instanceof MultiFileURIConverter) {
			((MultiFileURIConverter) uriConverter).dispose();
		}
		errorUriSet = null;
		uriConverter = null;
		boolean notify = eDeliver();
		boolean reportError = REPORT_ERROR;
		boolean refresh = RefreshJob.getInstance().isEnabled();
		boolean oldMarkerManagerEnabled = markerMananger.isEnabled();

		try {
			if(RefreshJob.getInstance().getResourceSet() == this) {
				RefreshJob.getInstance().setEnabled(false);
				RefreshJob.getInstance().reset();
			}
			eSetDeliver(false);
			REPORT_ERROR = false;
			markerMananger.setEnabled(false);
			markerMananger.clearAll();

			for (Iterator iter = new ArrayList(getResources()).iterator(); iter
					.hasNext();) {
				Resource resource = (Resource) iter.next();
				try {
					resource.unload();
				} catch (Exception e) {
					// System.err.println("Error unloading resource: " +
					// resource.getURI());
					// e.printStackTrace();
				}
			}

			clearErrors();
		} finally {
			eSetDeliver(notify);
			REPORT_ERROR = reportError;
			markerMananger.setEnabled(oldMarkerManagerEnabled);
			if(RefreshJob.getInstance().getResourceSet() == this) {
				RefreshJob.getInstance().setEnabled(refresh);
			}
		}

		if (guidToMethodElementMap != null) {
			guidToMethodElementMap.clear();
		}

		getResources().clear();

		if (URIToTempURIMap != null) {
			URIToTempURIMap.clear();
		}
		
		Map<URI, Resource> map = getURIResourceMap();
		if (map != null) {
			map.clear();
		}

		MultiFileXMIResourceImpl.clearDetachedEObjectToIDMap();
	}

	private void clearErrors() {
		// clear all markers
		markerMananger.clearAll();
	}

	public MethodLibrary loadLibrary(String path) throws Exception {
		long begin = System.currentTimeMillis();

		reset();

		long afterReset = System.currentTimeMillis();
		
		if (MultiFileSaveUtil.DEBUG) {
			System.out.println("Reset time: " + (afterReset - begin)); //$NON-NLS-1$
		}

		MethodLibrary lib = loadLibraryWithoutReset(path);

		if (MultiFileSaveUtil.DEBUG) {
			System.out
					.println("Load time: " + (System.currentTimeMillis() - begin)); //$NON-NLS-1$
		}

		if (MultiFileSaveUtil.DEBUG) {
			// check if any resource is marked as modified after loading
			//
			System.err.println("Modified resources after loading:"); //$NON-NLS-1$
			for (Iterator iter = getResources().iterator(); iter.hasNext();) {
				Resource resource = (Resource) iter.next();
				if (resource.isModified()) {
					System.err.println("  " + resource.getURI()); //$NON-NLS-1$
				}
			}
		}

		return lib;
	}
	
	protected Resource loadLibraryResource(String path) {
		URI uri = URI.createFileURI(path);
		Resource res = super.getResource(uri, true);
		if (!res.getErrors().isEmpty()) {
			StringBuffer strBuf = new StringBuffer();
			strBuf.append(PersistenceResources.loadLibraryError_msg);
			for (Iterator<?> iter = res.getErrors().iterator(); iter.hasNext();) {
				Resource.Diagnostic error = (Resource.Diagnostic) iter
						.next();
				strBuf.append(NLS.bind(
						PersistenceResources.loadLibraryError_details,
						(new Object[] { String.valueOf(error.getLine()),
								String.valueOf(error.getColumn()),
								error.getMessage() })));
			}
			String msg = strBuf.toString();
			CommonPlugin.INSTANCE.log(msg);
			if(MultiFileSaveUtil.DEBUG) {
				System.err.println(msg);
			}
		}
		return res;
	}

	public MethodLibrary loadLibraryWithoutReset(String path) throws Exception {
		loading = true;

		// no refresh during load
		//
		boolean b = RefreshJob.getInstance().isEnabled();
		if(RefreshJob.getInstance().getResourceSet() == this) {
			RefreshJob.getInstance().setEnabled(false);
			RefreshJob.getInstance().reset();
		}
		
		// defer adding markers during load
		//
		boolean autoScheduled = markerMananger.isAutoScheduled();
		markerMananger.setAutoScheduled(false);
		try {		
			File libFile = new File(path);
			configFolderPath = new Path(new File(libFile.getParentFile(),
					MultiFileSaveUtil.METHOD_CONFIGURATION_FOLDER_NAME).getCanonicalPath());
			libFolderPath = new Path(libFile.getParentFile().getCanonicalPath());
			Resource res = loadLibraryResource(libFile.getCanonicalPath()); 
			try {
				initialize(true);
				
				// Set modified flag of library resource to false in case it had been modified during initialization
				//
				if(res != null) {
					res.setModified(false);
				}
				
				return getMethodLibrary();
			} catch (Exception e) {
				PersistencePlugin.getDefault().getLogger().logError(e);
				throw new Exception(NLS.bind(
						PersistenceResources.invalidLibraryFileError_msg, path));
			}
		} finally {
			if(RefreshJob.getInstance().getResourceSet() == this) {
				RefreshJob.getInstance().setEnabled(b);
			}
					
			markerMananger.setAutoScheduled(autoScheduled);
			markerMananger.start();
			
			loading = false;
		}
	}

	/**
	 * Loads opposite features for all loaded objects
	 */
	private void loadOppositeFeatures() {
		ArrayList oppositeFeatures = new ArrayList();
		for (Iterator iter = AssociationHelper.getPredefinedOppositeFeatures()
				.iterator(); iter.hasNext();) {
			OppositeFeature oppositeFeature = (OppositeFeature) iter.next();
			if (oppositeFeature.resolveOwner()) {
				oppositeFeatures.add(oppositeFeature);
			}
		}
		loadOppositeFeatures(oppositeFeatures);
	}

	/**
	 * Loads ResourceManager tree of the open library and connect any loaded
	 * MethodUnit to the library tree as well.
	 */
	private void loadResourceManagerTree() {
		long begin = 0;
		
		if(MultiFileSaveUtil.DEBUG) {
			begin = System.currentTimeMillis();
		}

		// disable logging unresolved proxies during loading resource manager
		// tree
		//
		boolean oldMarkerManagerEnabled = markerMananger.isEnabled();
		markerMananger.setEnabled(false);

		MultiFileURIConverter uriConverter = (MultiFileURIConverter) getURIConverter();
		try {
			// this prevents uriConverter from loading resources while
			// normalizing URI
			//
			uriConverter.setResolveProxy(false);

			ResourceManager resMgr = getRootResourceManager();
			Iterator<?> iterator = new AbstractTreeIterator<Object>(resMgr, false) {

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

				protected Iterator<?> getChildren(Object object) {
					ResourceManager resMgr = (ResourceManager) object;
					return resMgr.getSubManagers().iterator();
				}

			};
			loadingResourceManagerTree = true;
			for (; iterator.hasNext(); iterator.next())
				;
		} finally {
			markerMananger.setEnabled(oldMarkerManagerEnabled);
			uriConverter.setResolveProxy(true);
			loadingResourceManagerTree = false;

			// Reporting of unnormalized URIs was disabled while loading
			// resource manager tree. Now we need
			// to go thru all the loaded objects to find proxies with
			// unnormalized URIs and report them
			//
			try {
				for (Iterator<?> iter = new ArrayList<Object>(getGuidToMethodElementMap().values())
						.iterator(); iter.hasNext();) {
					InternalEObject o = (InternalEObject) iter.next();
					if (o.eIsProxy() && o.eContainer() != null) {
						URI uri = o.eProxyURI();
						URI normalizedURI = getURIConverter().normalize(uri);
						if (normalizedURI == null) {
							// this call will log error about unresolved proxy
							//
							((InternalEObject) o.eContainer()).eResolveProxy(o);
						}
					}
				}
			}
			catch(Exception e) {
				PersistencePlugin.getDefault().getLogger().logError(e);
			}
			
			if(MultiFileSaveUtil.DEBUG) {
				System.out
						.println("MultiFileResourceSetImpl.loadResourceManagerTree(): " + (System.currentTimeMillis() - begin)); //$NON-NLS-1$
			}
		}
	}

	protected ResourceManager getResourceManager() {
		return ((MultiFileURIConverter) getURIConverter()).getResourceManager();
	}

	protected EObject findEObjectInUnloadedResources(String id) {
		return findEObjectInUnloadedResources(getResourceManager(), id);
	}

	private EObject findEObjectInUnloadedResources(ResourceManager resMgr,
			String id) {
		for (Iterator iter = resMgr.getResourceDescriptors().iterator(); iter
				.hasNext();) {
			ResourceDescriptor desc = (ResourceDescriptor) iter.next();
			Resource resource = super.getResource(desc.getResolvedURI(), false);
			if (resource == null || !resource.isLoaded()) {
				try {
					resource = super.getResource(desc.getResolvedURI(), true);
				} catch (Exception e) {
					//
				}
				if (resource != null) {
					EObject eObject = resource.getEObject(id);
					if (eObject != null) {
						return eObject;
					}
				}
			}
		}
		for (Iterator iter = resMgr.getSubManagers().iterator(); iter.hasNext();) {
			EObject eObject = findEObjectInUnloadedResources(
					(ResourceManager) iter.next(), id);
			if (eObject != null)
				return eObject;
		}
		return null;
	}

	/**
	 * Gets object with the given id
	 */
	public EObject getEObject(String id) {
		// first, try to get the object from the cache guidToMethodElement
		//
		EObject eObject = (EObject) getGuidToMethodElementMap().get(id);
		if (eObject != null)
			return eObject;

		URI uri = MultiFileURIConverter.createURI(id).appendFragment(id);
		URI normalized = getURIConverter().normalize(uri);
		if (normalized == null) {
			// the object with the given id might not have direct resource,
			// hence, it does not have
			// its own ResourceDescriptor in ResourceManager tree.
			// go thru all unloaded resources, load them, and try to find the
			// object with the given id.
			//
			eObject = findEObjectInUnloadedResources(id);
			if (eObject == null && REPORT_ERROR) {
				handleException(NLS.bind(
						PersistenceResources.objNotFoundError_msg, id));
			}
			return eObject;
		}

		try {
			return getEObject(uri, true);
		} catch (RuntimeException e) {
			return null;
		}
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see org.eclipse.emf.ecore.resource.ResourceSet#getEObject(org.eclipse.emf.common.util.URI,
	 *      boolean)
	 */
	public EObject getEObject(URI uri, boolean loadOnDemand) {
		return getEObject(null, uri, loadOnDemand);
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see org.eclipse.emf.ecore.resource.ResourceSet#createResource(org.eclipse.emf.common.util.URI)
	 */
	public Resource createResource(URI uri) {
		Resource result = doCreateResource(uri);
		result.setTrackingModification(true);
		getResources().add(result);
		return result;
	}
	
	/*
	 * Javadoc copied from interface.
	 */
	public Resource createResource(URI uri, String contentType) {
		return createResource(uri);
	}
	
	protected Resource doCreateResource(URI uri) {
		return new MultiFileXMIResourceImpl(uri);
	}

	private static boolean backupRequired(Map options) {
		Boolean backup = (Boolean) options
				.get(MultiFileXMISaveImpl.BACK_UP_BEFORE_SAVE);
		return backup != null && backup.booleanValue();
	}

	private void backup(Resource res) {
		try {
			if (res.getContents().isEmpty())
				return;
			Object object = res.getContents().get(0);
			if (!(object instanceof MethodLibrary
					|| object instanceof ResourceManager || object instanceof MethodPlugin))
				return;

			MethodLibrary library = getMethodLibrary();
			String backupDir = new File(library.eResource().getURI()
					.toFileString()).getParent()
					+ File.separator + ".bak"; //$NON-NLS-1$
			SimpleDateFormat dateFormatter = new SimpleDateFormat(
					"yyMMddHHmmss.S"); //$NON-NLS-1$
			if (res == library.eResource()) {
				DateFormat.getInstance().format(
						Calendar.getInstance().getTime());
				File backupFile = new File(backupDir,
						MultiFileSaveUtil.DEFAULT_LIBRARY_MODEL_FILENAME
								+ '_'
								+ dateFormatter.format(Calendar.getInstance()
										.getTime()));
				if (!backupFile.getParentFile().exists()) {
					backupFile.getParentFile().mkdirs();
				}
				FileUtil.moveFile(new File(res.getURI().toFileString()), backupFile);
			} else {
				String relativePath = res.getURI().deresolve(
						library.eResource().getURI()).toFileString();
				File backupFile = new File(backupDir, relativePath
						+ '_'
						+ dateFormatter
								.format(Calendar.getInstance().getTime()));
				if (!backupFile.getParentFile().exists()) {
					backupFile.getParentFile().mkdirs();
				}
				FileUtil.moveFile(new File(res.getURI().toFileString()), backupFile);
			}
		} catch (Exception e) {
			handleException(e);
			handleException(NLS.bind(PersistenceResources.backupError_msg, res));
		}
	}

	void removeURIMappings(EObject eObj, Set modifiedResources) {
		ResourceManager resMgr = MultiFileSaveUtil.getResourceManager(eObj
				.eResource());
		if (resMgr != null && resMgr.eContainer() != null) {
			EcoreUtil.remove(resMgr);
		}
		resMgr = getRootResourceManager();
		if(resMgr != null) {
			ResourceDescriptor desc = MultiFileSaveUtil.findResourceDescriptor(
					resMgr, MultiFileSaveUtil.getGuid(eObj),
					null, true);
			if (desc != null) {
				if (modifiedResources != null && desc.eResource() != null) {
					modifiedResources.add(desc.eResource());
				}
				EcoreUtil.remove(desc);
			}
		}
	}

	protected void cleanUp(Resource removedResource) throws IOException {
		cleanUp(removedResource, null);
	}

	// protected void cleanUp(EObject obj, Set modifiedResources) {
	// try {
	// // remove all the URI mappings
	// //
	// removeURIMappings(obj, modifiedResources);
	// }
	// finally {
	// Resource resource = obj.eResource();
	// if(resource != null && resource.getContents().contains(obj)) {
	// resource.unload();
	// getResources().remove(resource);
	// }
	// }
	// }

	void cleanUp(Resource removedResource, Set modifiedResources)
			throws IOException {
		try {
			//
			if (removedResource.getContents().isEmpty()) {
				removedResource.unload();
				try {
					removedResource.load(null);
				} catch (FileNotFoundException e) {
					// the file might already be deleted, moved or never
					// creared.
					//
					return;
				}
			}

			EObject obj = PersistenceUtil.getMethodElement(removedResource);

			// if(obj == null) return;
			// boolean cleanFolder;
			// if(obj instanceof MethodPlugin) {
			// cleanFolder = true;
			// }
			// else {
			// cleanFolder = false;
			// }

			// MultiFileURIConverter umaUriConverter =
			// ((MultiFileURIConverter)getURIConverter());
			// umaUriConverter.getResourceManager().removeResourceDescriptor(removedResource.getURI(),
			// cleanFolder);

			// remove all the URI mappings
			//
			removeURIMappings(obj, modifiedResources);

			// if(obj instanceof ProcessPackage) {
			// cleanUpResourceDescriptors((ProcessPackage)obj);
			// }

			removedResource.unload();
		} finally {
			getResources().remove(removedResource);
			URI oldURI = ((MultiFileXMIResourceImpl) removedResource)
					.getOldURI();
			if (oldURI != null) {
				getURIToTempURIMap().remove(oldURI);
			}
		}
	}

	private void cleanUp(ProcessPackage procPkg) {
		// remove ContentDescription of all ProcessElements in this
		// ProcessPackage
		//
		removeContentDescriptions(procPkg);

		EcoreUtil.remove(procPkg);
	}

	/**
	 * @param procPkg
	 */
	private void removeContentDescriptions(ProcessPackage procPkg) {
		for (Iterator iter = procPkg.getProcessElements().iterator(); iter
				.hasNext();) {
			ProcessElement element = (ProcessElement) iter.next();
			if (ContentDescriptionFactory.hasPresentation(element)
					&& element.getPresentation().eResource() != null) {
				removePresentation(element);
			}
		}

		for (Iterator iter = procPkg.getChildPackages().iterator(); iter
				.hasNext();) {
			Object pkg = iter.next();
			if (pkg instanceof ProcessPackage) {
				removeContentDescriptions((ProcessPackage) pkg);
			}
		}
	}

	/**
	 * @param element
	 */
	private void removePresentation(ProcessElement element) {
		Resource resource = element.getPresentation().eResource();
		resource.getContents().remove(element.getPresentation());
	}

	private boolean save(Collection resources, Map options, boolean prepareSave)
			throws Exception {
		if (options == null) {
			options = getDefaultSaveOptions();
		}

		Set modifiedResources = new HashSet();
		options.put(MultiFileXMISaveImpl.MODIFIED_RESOURCE_SET,
				modifiedResources);
		try {
			for (Iterator iter = resources.iterator(); iter.hasNext();) {
				Resource res = (Resource) iter.next();
				save(res, options, prepareSave);
			}
			saveModifiedResources(options);
			return true;
		} finally {
			options.remove(MultiFileXMISaveImpl.MODIFIED_RESOURCE_SET);
		}
	}

	boolean save(Resource res, Map options, boolean prepareSave)
			throws Exception {
		Set modifiedResources = (Set) options
				.get(MultiFileXMISaveImpl.MODIFIED_RESOURCE_SET);
		TxRecord txRecord = (TxRecord) options
				.get(MultiFileXMISaveImpl.TX_RECORD);
		List resourcesToCommit = txRecord != null ? txRecord
				.getResourcesToCommit() : null;

		try {
			MethodElement eObj = PersistenceUtil.getMethodElement(res);
			if (eObj != null) {
				if (prepareSave) {
					if (eObj instanceof ProcessComponent) {
						ProcessComponent procComp = (ProcessComponent) eObj;
						Resource content = procComp.getProcess() != null
								&& ContentDescriptionFactory
										.hasPresentation(procComp.getProcess()) ? procComp
								.getProcess().getPresentation().eResource()
								: null;
						boolean alreadyModified = content != null
								&& content.isModified();
						prepareSave(procComp);
						if (content != null && content.isModified()
								&& !alreadyModified) {
							// content is modified as result of prepareSave(),
							// it needs to be saved after model is saved
							//
							modifiedResources.add(content);
						}
					}
					else if (eObj instanceof MethodPlugin) {
						MultiFileSaveUtil.addResourceManager(res);
					}
				}
				if (res.isModified()) {
					// System.out.println("----> Start saving " + res);
					boolean backupRequired = backupRequired(options);
					if (backupRequired) {
						// back up resource before saving
						//
						backup(res);
					}

					if (resourcesToCommit != null) {
						((MultiFileXMIResourceImpl) res).setTempURI(txRecord
								.getTxID());
						resourcesToCommit.add(res);
					}

					MultiFileSaveUtil.save(res, options);

					// System.out.println("<---- Saved resource: " + res);

					return true;
				}
			}
		} catch (Exception exception) {
			handleException(exception);
			throw exception;
		}

		return false;
	}

	/**
	 * Save a resource of this resource set with the given save options
	 * 
	 * @param res
	 * @param options
	 * @return <code>true</code> if there is at least a resource has been saved in this call
	 * @throws Exception
	 */
	public boolean save(Resource res, Map options) throws Exception {
//		// clear all error markers for this resource
//		//
//		markerMananger.clearMarkers(res);

		if (res == null || res.getContents().isEmpty())
			return false;

		if (options == null) {
			options = getDefaultSaveOptions();
		}

		Set modifiedResources = new HashSet();
		options.put(MultiFileXMISaveImpl.MODIFIED_RESOURCE_SET,
				modifiedResources);
		boolean notFailSafe = options.get(MultiFileXMISaveImpl.TX_RECORD) == null;
		try {
			Collection savedResources = null;
			if(notFailSafe) {
				savedResources = new ArrayList();
			}
			boolean ret = save(res, options, true);
			if(ret && notFailSafe) {
				savedResources.add(res);
			}
			Collection collection = saveModifiedResources(options);
			if(!collection.isEmpty()) {
				ret = true;
				if(notFailSafe) {
					savedResources.addAll(collection);
				}
			}
			
			if(notFailSafe && ret) {
				// update resource cached timestamps
				//
				for (Iterator iter = savedResources.iterator(); iter.hasNext();) {
					Object resource = iter.next();
					if(resource instanceof MultiFileXMIResourceImpl) {
						((MultiFileXMIResourceImpl)resource).updateTimeStamps();
					}
				}								
			}
			
			return ret;
		} finally {
			options.remove(MultiFileXMISaveImpl.MODIFIED_RESOURCE_SET);
		}
	}

	/**
	 * Saves only the modified resources in this resource set.
	 * 
	 * @param options
	 */
	public void save(Map options) throws LibraryResourceException {
		try {
			save(options, false, true);
		} catch (Exception e) {
			if(e instanceof RuntimeException) {
				throw (RuntimeException)e;
			}
			throw new LibraryResourceException(e);
		}
	}

	/**
	 * 
	 * @param options
	 * @return resources that had been saved by this call
	 * @throws LibraryResourceException 
	 */
	Collection saveModifiedResources(Map options) throws LibraryResourceException {
		Set modifiedResources = (Set) options
				.get(MultiFileXMISaveImpl.MODIFIED_RESOURCE_SET);
		TxRecord txRecord = (TxRecord) options
				.get(MultiFileXMISaveImpl.TX_RECORD);
		List resourcesToCommit = txRecord != null ? txRecord
				.getResourcesToCommit() : null;
		if (modifiedResources == null)
			return Collections.EMPTY_LIST;
		boolean backupRequired = backupRequired(options);
		boolean checkModify = MultiFileXMISaveImpl.checkModifyRequired(options);
		Collection savedResources = new ArrayList();
		while (!modifiedResources.isEmpty()) {
			List<Resource> resourcesToSave = new ArrayList<Resource>(modifiedResources);
			
			modifiedResources.clear();
			if (checkModify) {
				checkModify(resourcesToSave);
				if(resourcesToCommit != null) {
					// check for out-of-synch only in fail-safe saving for now
					//
					MultiFileSaveUtil.checkOutOfSynch(resourcesToSave, options);
				}
			}
			for(Iterator iter = resourcesToSave.iterator(); iter.hasNext();) {
				Resource resource = (Resource) iter.next();
				// if(resource.isModified()) {
				if (backupRequired) {
					// back up resource before saving
					//
					backup(resource);
				}

				if (resourcesToCommit != null) {
					((MultiFileXMIResourceImpl) resource).setTempURI(txRecord
							.getTxID());
					resourcesToCommit.add(resource);
				}

				if(MultiFileSaveUtil.save(resource, options)) {
					savedResources.add(resource);
				}
				// }
			}
		}
		return savedResources;
	}

	/**
	 * 
	 * @param options
	 * @param saveAll
	 *            if true, force saving all the resources even if they are not
	 *            modified.
	 * @throws Exception
	 */
	public void save(Map options, boolean saveAll) throws Exception {
		save(options, saveAll, false);
	}
	
	protected void save(Map options, boolean saveAll, boolean failSafe)
			throws Exception {
		if (options == null) {
			options = new HashMap(getDefaultSaveOptions());
		}

		MethodLibrary library = getMethodLibrary();
		MultiFileSaveUtil.setGuid(library);

		prepareSave(library);

		// do clean-up this resource set before saving
		//
		cleanUp();

		MultiFileURIConverter umaUriConverter = ((MultiFileURIConverter) getURIConverter());
		umaUriConverter.setLibraryURIs(library);

		Set modifiedResources = new HashSet();
		options.put(MultiFileXMISaveImpl.MODIFIED_RESOURCE_SET,
				modifiedResources);
		MethodLibraryPersister.FailSafePersister persister = null;
		if (failSafe) {
			persister = MethodLibraryPersister.INSTANCE
					.getFailSafePersister(options);
			options = persister.getSaveOptions();
		}
		try {
			List list = getResources();
			int size = list.size();
			// System.out.println("Start saving " + size + " loaded resources: "
			// + list);
			// System.out.println();
			boolean backupRequired = backupRequired(options);
			List saveResources = new ArrayList();
			List moveResources = new ArrayList();
			for (int i = 0; i < size; i++) {
				Resource res = (Resource) list.get(i);

				 if (res.isModified() && 
						 MultiFileSaveUtil.adjustLocationRequired((MultiFileXMIResourceImpl) res)) {
					 moveResources.add(res);
				 }

				MethodElement eObj = PersistenceUtil.getMethodElement(res);
				if (eObj != null && eObj instanceof MethodElement) {
					if (saveAll || res.isModified()) {
//						// System.out.println("----> Start saving " + res);
//						if (failSafe) {
//							saveResources.add(res);
//						} else {
//							if (backupRequired) {
//								// back up resource before saving
//								//
//								backup(res);
//							}
//
//							if(MultiFileSaveUtil.save(res, options)) {
//								savedResources.add(res);
//								if(res instanceof MultiFileXMIResourceImpl) {
//									((MultiFileXMIResourceImpl)res).updateTimeStamps();
//								}
//							}
//						}
//						// System.out.println("<---- Saved resource: " + res);
						
						saveResources.add(res);
					}
				}
			}

			if(!saveResources.isEmpty()) {
				Resource libResource = getMethodLibraryResource();
				if(!saveResources.contains(libResource) && PersistenceUtil.checkToolVersion(libResource) != 0) {
					saveResources.add(libResource);
				}
				if(MultiFileXMISaveImpl.checkModifyRequired(options)) {
					checkModify(saveResources);
				}
				if (failSafe) {
					try {
						save(saveResources, options, false);
						persister.commit();
						persister.adjustLocation(moveResources);
					} catch (Exception e) {
						persister.rollback();
						throw e;
					}
				} else {
					for (Iterator iter = saveResources.iterator(); iter
							.hasNext();) {
						Resource resource = (Resource) iter.next();
						if(MultiFileSaveUtil.save(resource, options)) {
							if(resource instanceof MultiFileXMIResourceImpl) {
								((MultiFileXMIResourceImpl)resource).updateTimeStamps();
							}
						}
					}
					for (Iterator iter = moveResources.iterator(); iter.hasNext();) {
						Resource resource = (Resource) iter.next();
						MultiFileSaveUtil.adjustLocation(resource,
								modifiedResources);
					}
					Collection saved = saveModifiedResources(options);
					if (saved != null) {
						for (Iterator iter = saved.iterator(); iter.hasNext();) {
							Resource resource = (Resource) iter.next();
							if(resource instanceof MultiFileXMIResourceImpl) {
								((MultiFileXMIResourceImpl)resource).updateTimeStamps();
							}
						}
					}
				}
			}
		} catch (Exception exception) {
			handleException(exception);
			throw exception;
		} finally {
			options.remove(MultiFileXMISaveImpl.MODIFIED_RESOURCE_SET);
		}
	}

	/**
	 * Saves the open library under a new location
	 * 
	 * @param newLocation
	 *            directory to save the open library to
	 * @param if
	 *            true, regenerateGUID regenerate GUID for all MethodElements in
	 *            the open library
	 */
	public void saveAs(String newLocation, boolean regenerateGUID,
			IProgressMonitor monitor) throws Exception {
		MethodLibrary lib = getMethodLibrary();
		if (lib == null)
			return;

		// load all the resources in memory
		//
		if (monitor != null)
			monitor.setTaskName(PersistenceResources.loadResourcesTask_name);
		for (Iterator iter = lib.eAllContents(); iter.hasNext();) {
			EObject element = (EObject) iter.next();
			if (regenerateGUID && element instanceof MethodElement) {
				((MethodElement) element).setGuid(UmaUtil.generateGUID());
			}
			for (Iterator iterator = element.eCrossReferences().iterator(); iterator
					.hasNext();) {
				iterator.next();
			}
		}

		// change URI of all loaded resources for new location
		//
		URI oldDir = URI.createFileURI(new File(lib.eResource().getURI()
				.toFileString()).getParent()
				+ File.separator);
		URI newDir = URI.createFileURI(newLocation + File.separator);
		for (Iterator iter = getResources().iterator(); iter.hasNext();) {
			Resource resource = (Resource) iter.next();
			resource.setURI(resource.getURI().replacePrefix(oldDir, newDir));
		}

		// clear the ResourceManager
		//
		ResourceManager resMgr = ((MultiFileURIConverter) getURIConverter())
				.getResourceManager();
		if (resMgr != null) {
			resMgr.getResourceDescriptors().clear();
		}

		if (monitor != null)
			monitor.setTaskName(PersistenceResources.saveLibraryTask_name);
		save(null, true);
	}
	
	protected boolean unloadWithoutRemove(MultiFileXMIResourceImpl resource) {
		MethodElement e = PersistenceUtil.getMethodElement(resource);
		resource.unloadWithoutRemove();
		if(e instanceof MethodConfiguration) {
			MethodLibrary lib = getMethodLibrary();
			if(lib != null) {
				lib.getPredefinedConfigurations().remove(e);
			}
		}
		return true;
	}

	/**
	 * @throws IOException
	 * 
	 */
	private void cleanUp() throws IOException {
		MethodLibrary library = getMethodLibrary();
		List removedResources = new ArrayList();

		List list = getResources();
		int size = list.size();
		for (int i = 0; i < size; i++) {
			Resource res = (Resource) list.get(i);
			boolean remove = false;
			if (res.getContents().isEmpty()) {
				System.out
						.println("MultiFileResourceSetImpl.cleanUp(): empty resource: " + res); //$NON-NLS-1$
				remove = true;
			} else {
				MethodElement eObj = PersistenceUtil.getMethodElement(res);
				if (eObj == null
						|| (eObj != library && eObj.eContainer() == null)) {
					if (eObj == null) {
						System.out
								.println("MultiFileResourceSetImpl.cleanUp(): resource without any MethodElement: " + res); //$NON-NLS-1$
						remove = true;
					}
					// some resources might be loaded directly, not thru its
					// container. Therefore, we cannot assume
					// that a object without a container in a loaded resource is
					// a removed object.
					//
					else if (eObj != library && eObj.eContainer() == null) {
						System.out
								.println("MultiFileResourceSetImpl.cleanUp(): resource without a container: " + res); //$NON-NLS-1$
					}
				}
			}
			if (remove) {
				// This is a removed object. Add its path to the list for
				// removing its files later.
				//
				removedResources.add(res);
			}
		}

		// do clean-up
		//
		System.out
				.println("MultiFileResourceSetImpl.cleanUp(): removed resources: " + removedResources); //$NON-NLS-1$

		for (Iterator iter = removedResources.iterator(); iter.hasNext();) {
			Resource res = (Resource) iter.next();

			try {
				// remove ResourceDescriptor of the removed resource
				//
				cleanUp(res);
			} catch (Exception e) {
				handleException(e);
			}
		}

		// getResources().removeAll(removedResources);
	}
	
	/**
	 * Prepares the library for saving
	 */
	private void prepareSave(MethodLibrary library) {
		// check if the library already has a ResourceManager
		// if not, create ResourceManager for it
		//
		MultiFileXMIResourceImpl resource = (MultiFileXMIResourceImpl) library
				.eResource();
		ResourceManager libResMgr = MultiFileSaveUtil.addResourceManager(resource);
		if(libResMgr != null) {
			MultiFileSaveUtil.registerWithResourceManager(libResMgr, library,
					resource.getFinalURI());
		}

		List models = library.getMethodPlugins();
		int size = models.size();
		for (int i = 0; i < size; i++) {
			prepareSave((MethodPlugin) models.get(i));
		}

		for (int i = 0; i < size; i++) {
			cleanUp((MethodPlugin) models.get(i));
		}
	}

	private static void cleanUp(MethodPlugin plugin) {
		for (int i = 0; i < PROCESS_PACKAGE_PATHS.length; i++) {
			ProcessPackage pkg = (ProcessPackage) UmaUtil.findMethodPackage(
					plugin, PROCESS_PACKAGE_PATHS[i]);
			if (pkg != null) {
				cleanUpProcesses(pkg);
			}
		}
	}

	private void prepareSave(MethodPlugin model) {
		for (int i = 0; i < PROCESS_PACKAGE_PATHS.length; i++) {
			ProcessPackage pkg = (ProcessPackage) UmaUtil.findMethodPackage(
					model, PROCESS_PACKAGE_PATHS[i]);
			if (pkg != null) {
				prepareSave(pkg);
			}
		}
	}

	/**
	 * Removes process packages of unused activities.
	 * 
	 * @param pkg
	 */
	private static void cleanUpProcesses(ProcessPackage pkg) {
		List list = pkg.getChildPackages();
		int size = list.size();
		for (int i = 0; i < size; i++) {
			Object obj = list.get(i);
			if (obj instanceof ProcessComponent) {
				ProcessComponent procComp = (ProcessComponent) obj;
				List packages = new ArrayList();
				for (Iterator iter = procComp.getChildPackages().iterator(); iter
						.hasNext();) {
					Object element = (Object) iter.next();
					if (element instanceof ProcessPackage) {
						getRemovedPackages((ProcessPackage) element, packages);
					}
				}
				for (Iterator iterator = packages.iterator(); iterator
						.hasNext();) {
					EcoreUtil.remove((EObject) iterator.next());
				}
			}
		}
	}

	private static void getRemovedPackages(ProcessPackage pkg,
			List removedPackages) {
		// find activity
		//
		Activity act = getActivity(pkg);

		if (act == null || getParent(act) == null) {
			// Invalid process package. It does not contain any activity.
			// Add it to the list of packages to be removed.
			//
			removedPackages.add(pkg);
		} else {
			for (Iterator iter = pkg.getChildPackages().iterator(); iter
					.hasNext();) {
				Object element = (Object) iter.next();
				if (element instanceof ProcessPackage) {
					getRemovedPackages((ProcessPackage) element,
							removedPackages);
				}
			}
		}
	}

	private static Activity getActivity(ProcessPackage pkg) {
		// find activity
		//
		Activity act = null;
		for (Iterator iter = pkg.getProcessElements().iterator(); iter
				.hasNext();) {
			Object element = iter.next();
			if (element instanceof Activity) {
				act = (Activity) element;
				break;
			}
		}
		return act;
	}

	private static Object getParent(BreakdownElement e) {
		// ItemProviderAdapter adapter = (ItemProviderAdapter)
		// TngUtil.getAdapter(e, IBSItemProvider.class);
		// return adapter == null ? null : adapter.getParent(e);

		return UmaUtil.getParentActivity(e);
	}

	/**
	 * Creates process package for those activities that still don't belong to
	 * any process package.
	 */
	private void prepareSave(ProcessPackage pkg) {
		List list = pkg.getChildPackages();
		int size = list.size();
		for (int i = 0; i < size; i++) {
			Object obj = list.get(i);
			if (obj instanceof ProcessComponent) {
				prepareSave((ProcessComponent) obj);
			}
		}
	}

	private void prepareSave(ProcessComponent procComp) {
		Process proc = procComp.getProcess();
		if (proc != null) {
			// associateAllAdapters(proc);
			prepareSave(proc);

			cleanUpDanglingDescriptors(procComp);

			List danglingPkgs = new ArrayList();
			for (Iterator iter = new ArrayList(procComp.getChildPackages())
					.iterator(); iter.hasNext();) {
				Object element = (Object) iter.next();
				if (element instanceof ProcessPackage) {
					ProcessPackage pkg = (ProcessPackage) element;
					reorganize(pkg, danglingPkgs);
				}
			}

			// clean up dangling ProcessPackages
			//
			for (Iterator iter = danglingPkgs.iterator(); iter.hasNext();) {
				cleanUp((ProcessPackage) iter.next());
			}

		}
	}

	// /**
	// * @param activity
	// */
	// private static void associateAllAdapters(Activity activity) {
	// AdapterFactory adapterFactory =
	// TngAdapterFactory.INSTANCE.getWBS_ComposedAdapterFactory();
	// ItemProviderAdapter adapter = (ItemProviderAdapter)
	// adapterFactory.adapt(activity, ITreeItemContentProvider.class);
	// for (Iterator iter = adapter.getChildren(activity).iterator();
	// iter.hasNext();) {
	// Object element = iter.next();
	// if(element instanceof Activity) {
	// associateAllAdapters((Activity) element);
	// }
	// }
	// }

	/**
	 * @param activity
	 */
	private static void prepareSave(Activity activity) {
		ProcessPackage parentPkg = (ProcessPackage) activity.eContainer();
		List elements = activity.getBreakdownElements();

		// add new descriptors and other non-activity breakdown elements of the
		// activity to its process package
		//
		for (Iterator iter = elements.iterator(); iter.hasNext();) {
			EObject element = (EObject) iter.next();
			if (!(element instanceof Activity) && element.eContainer() == null) {
				parentPkg.getProcessElements().add((ProcessElement) element);
			}
		}

		// add new WorkOrder objects or remove unused WorkOrder objects of this
		// activity
		//
		for (WorkOrder workOrder : activity.getLinkToPredecessor()) {
			if (workOrder.eContainer() == null) {
				if (workOrder.getPred() != null
						&& getParent(workOrder.getPred()) != null) {
					parentPkg.getProcessElements().add(workOrder);
				}
			} else {
				if (workOrder.getPred() == null
						|| getParent(workOrder.getPred()) == null) {
					if (MultiFileSaveUtil.DEBUG) {
						System.err.println("Invalid WorkOrder: " + workOrder); //$NON-NLS-1$
					}
					parentPkg.getProcessElements().remove(workOrder);
				}
			}
		}

		// removed unused diagrams
		//
		for (Iterator iter = parentPkg.getDiagrams().iterator(); iter.hasNext();) {
			Diagram diagram = (Diagram) iter.next();
			SemanticModelBridge bridge = diagram.getSemanticModel();
			if (bridge instanceof UMASemanticModelBridge) {
				MethodElement element = ((UMASemanticModelBridge) bridge)
						.getElement();
				if (element instanceof Activity
						&& (!(element instanceof Process) && getParent((Activity) element) == null)) {
					iter.remove();
				}
			}
		}

		int size = elements.size();
		for (int i = 0; i < size; i++) {
			Object e = elements.get(i);
			if (e instanceof Activity) {
				Activity act = (Activity) e;
				if (act.eContainer() == null) {
					ProcessPackage pkg = UmaFactory.eINSTANCE
							.createProcessPackage();
					pkg.setName(act.getName());
					pkg.getProcessElements().add(act);
					List descriptors = new ArrayList();
					for (int j = 0; j < act.getBreakdownElements().size(); j++) {
						Object obj = act.getBreakdownElements().get(j);
						if (obj instanceof Descriptor) {
							descriptors.add(obj);
						}
					}
					pkg.getProcessElements().addAll(descriptors);

					parentPkg.getChildPackages().add(pkg);
					// System.out.println("Process package created for activity:
					// '" + act.getName() + "'");
				}
				prepareSave(act);
			}
		}
	}

	private static void cleanUpDanglingDescriptors(ProcessPackage pkg) {
		for (Iterator iter = pkg.getProcessElements().iterator(); iter
				.hasNext();) {
			Object element = iter.next();
			if (element instanceof BreakdownElement
					&& ((BreakdownElement) element).getSuperActivities() == null) {
				boolean remove = false;
				if (element instanceof RoleDescriptor) {
					if (AssociationHelper.getTeamProfiles(
							(RoleDescriptor) element).isEmpty()) {
						remove = true;
					}
				} else if (element instanceof WorkProductDescriptor) {
					if (AssociationHelper.getDeliverableDescriptors(
							(WorkProductDescriptor) element).isEmpty()) {
						remove = true;
					}
				} else if (element instanceof TeamProfile) {
					if (((TeamProfile) element).getSuperTeam() == null) {
						remove = true;
					}
				} else {
					remove = true;
				}

				if (remove) {
					iter.remove();
				}
			}
		}
	}

	/**
	 * Moves the process packages to the right location in the tree if needed.
	 * 
	 * @param pkg
	 * @param danglingPkgs
	 */
	private void reorganize(ProcessPackage pkg, List danglingPkgs) {
		Activity act = getActivity(pkg);
		if (act == null)
			return;

		// make sure the package has the same name as the activity's name
		//
		if (!pkg.getName().equals(act.getName())) {
			pkg.setName(act.getName());
		}

		// check if the container of pkg is actually holding the parent activity
		// of act
		//
		EObject parentAct = (EObject) getParent(act);

		if (parentAct == null) {
			// cleanUpResourceDescriptors(pkg);
			// cleanUp(pkg);
			// return;
			danglingPkgs.add(pkg);
		} else if (parentAct != getActivity((ProcessPackage) pkg.eContainer())) {
			// move the package to the right location, under the process package
			// of parentAct
			//
			ProcessPackage parentPkg = (ProcessPackage) parentAct.eContainer();
			parentPkg.getChildPackages().add(pkg);
		}

		if (parentAct != null) {
			cleanUpDanglingDescriptors(pkg);
		}

		for (Iterator iter = pkg.getChildPackages().iterator(); iter.hasNext();) {
			Object element = (Object) iter.next();
			if (element instanceof ProcessPackage) {
				reorganize((ProcessPackage) element, danglingPkgs);
			}
		}
	}

	public Map<String, EObject> getGuidToMethodElementMap() {
		if (guidToMethodElementMap == null) {
			guidToMethodElementMap = new HashMap<String, EObject>();
		}
		return guidToMethodElementMap;
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see org.eclipse.emf.common.notify.impl.BasicNotifierImpl#eNotify(org.eclipse.emf.common.notify.Notification)
	 */
	public void eNotify(Notification notification) {
		try {
			super.eNotify(notification);
		} catch (RuntimeException e) {
			CommonPlugin.INSTANCE
					.log("ERROR notifying changes: resourceSet=" + this + ", notification=" + notification); //$NON-NLS-1$ //$NON-NLS-2$
			CommonPlugin.INSTANCE.log(e);
			e.printStackTrace();
		}
	}

	public void addMarker(Exception e) {
		try {
			// insert problem marker
			//
			markerMananger.notifyException(e);
		} catch (RuntimeException ex) {
			CommonPlugin.INSTANCE.log(ex);
			if (MultiFileSaveUtil.DEBUG) {
				ex.printStackTrace();
			}
		}
	}

	public void setLoading(boolean b) {
		loading = b;
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see org.eclipse.epf.uma.ecore.IExceptionCollector#collect(java.lang.Exception)
	 */
	public void notifyException(Exception e) {
		if (loadingResourceManagerTree) {
			if (e instanceof ResolveException) {
				if (((ResolveException) e).exception() instanceof MultiFileIOException) {
					return;
				}
			}
		}
		try {
			addMarker(e);
		} catch (Exception ex) {
			//
		}
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see org.eclipse.epf.uma.ecore.IProxyResolutionListener#proxyResolved(java.lang.Object,
	 *      java.lang.Object)
	 */
	public void proxyResolved(Object proxy, Object resolved) {
		if(resolved instanceof MethodElement) {
			String guid = MultiFileSaveUtil.getGuid(resolved);
			if (guid != null) {
				getGuidToMethodElementMap().put(guid, (EObject) resolved);
			}
		}
		markerMananger.proxyResolved(proxy, resolved);
	}

	protected EObject getEObjectByGUID(String guid) {
		return (EObject) getGuidToMethodElementMap().get(guid);
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see org.eclipse.epf.uma.ecore.IUmaResourceSet#getEObject(org.eclipse.emf.ecore.EObject,
	 *      org.eclipse.emf.common.util.URI, boolean)
	 */
	public EObject getEObject(EObject resolver, URI uri, boolean loadOnDemand) {
		// long start;
		// if(MultiFileSaveUtil.PROFILE) {
		// start = System.currentTimeMillis();
		// }

		URI normalized = ((MultiFileURIConverter) getURIConverter()).normalize(
				uri, resolver);
		if (normalized == null) {
			// work-around to look up for object by its GUID in case it had been
			// moved to other resource
			//
			String guid = uri.fragment();
			EObject eObject = getEObjectByGUID(guid);
			if (eObject != null) {
				return eObject;
			}

			String msg = NLS.bind(PersistenceResources.normalizeURIError_msg,
					uri);
			throw new UnnormalizedURIException(uri, msg);
		}
		Resource resource = getResource(normalized.trimFragment(), loadOnDemand);
		if (resource != null) {
			String fragment = normalized.fragment();
			if (fragment == null || fragment.length() == 0) {
				return PersistenceUtil.getMethodElement(resource);
			}
			EObject eObject = resource.getEObject(fragment);
			if (eObject == null && !fragment.equals(uri.authority())) {
				// work-around to look up for object by its GUID in case it had
				// been moved
				//
				return getEObjectByGUID(fragment);
			}
			return eObject;
		} else {
			return null;
		}

		// if(MultiFileSaveUtil.PROFILE) {
		//			
		// }
	}
	
	private ArrayList copyCollectionToList(Collection c) {
		int max = 5;
		for (int i = 0; i < max; i++) {	//Try up to max times for any concurrent exception
			try {
				return new ArrayList(c);				
			} catch (Exception e) {
				if (i == max - 1) {
					CommonPlugin.INSTANCE.log(e);
				} else {
					try {
						Thread.sleep(1000);
					} catch (Exception ee) {						
					}
				}
			}
		}
		return new ArrayList();
	}

	// /**
	// * @return Returns the exceptions.
	// */
	// public List getExceptions() {
	// return exceptions;
	// }

	public void loadOppositeFeatures(List oppositeFeatures) {
		int max = oppositeFeatures.size() - 1;
		if (max < 0) {
			return;
		}
		ArrayList elements = copyCollectionToList(getGuidToMethodElementMap().values());
		HashSet loadedElements = new HashSet();
		while (!elements.isEmpty()) {
			for (Iterator iter = elements.iterator(); iter.hasNext();) {
				Object obj = iter.next();
				if (obj instanceof MethodElement) {
					MethodElement element = (MethodElement) obj;
					for (int i = max; i > -1; i--) {
						EStructuralFeature eFeature = ((OppositeFeature) oppositeFeatures
								.get(i)).getTargetFeature();
						if (eFeature.getContainerClass().isInstance(element)) {
							if (eFeature.isMany()) {
								InternalEList list = (InternalEList) element
										.eGet(eFeature);
								if (!list.isEmpty()) {
									for (Iterator iterator = list.iterator(); iterator
											.hasNext();) {
										iterator.next();
									}
								}
							} else {
								element.eGet(eFeature);
							}
						}
					}
				}
			}

			// gets the newly loaded elements to load their opposite features
			//
			loadedElements.addAll(elements);
			elements = copyCollectionToList(getGuidToMethodElementMap().values());
			elements.removeAll(loadedElements);
		}
	}

	public void loadOppositeFeatures(List oppositeFeatures, Set deletedGUIDs) {
		int max = oppositeFeatures.size() - 1;
		if (max < 0) {
			return;
		}
		ArrayList elements = copyCollectionToList(getGuidToMethodElementMap().values());
		HashSet loadedElements = new HashSet();
		while (!elements.isEmpty()) {
			for (Iterator iter = elements.iterator(); iter.hasNext();) {
				Object obj = iter.next();
				if (obj instanceof MethodElement) {
					MethodElement element = (MethodElement) obj;
					MultiResourceEObject mrEObject = ((MultiResourceEObject) element);
					for (int i = max; i > -1; i--) {
						OppositeFeature oppositeFeature = ((OppositeFeature) oppositeFeatures
								.get(i));
						EStructuralFeature eFeature = oppositeFeature.getTargetFeature();
						if (eFeature.getContainerClass().isInstance(element)) {
							if (eFeature.isMany()) {
								InternalEList list = (InternalEList) element
										.eGet(eFeature);
								if (!list.isEmpty()) {
									boolean resolve = false;
									check_resolve: for (Iterator iterator = list
											.basicIterator(); iterator
											.hasNext();) {
										InternalEObject e = (InternalEObject) iterator
												.next();
										if (e.eIsProxy()) {
											String guid = e.eProxyURI()
													.fragment();
											if (deletedGUIDs.contains(guid)) {
												resolve = true;
												break check_resolve;
											}
										}
									}
									if (resolve) {
										Collection<Object> deletedElements = new HashSet<Object>();
										for (Iterator iterator = list
												.iterator(); iterator.hasNext();) {
											Object o = iterator.next();
											if(o instanceof MethodElement && deletedGUIDs.contains(((MethodElement) o).getGuid())) {
												deletedElements.add(o);
											}
										}
										for (Object e : deletedElements) {
											if(oppositeFeature.isMany()) {
												mrEObject.oppositeAdd(oppositeFeature, e);
											}
											else {
												mrEObject.getOppositeFeatureMap().put(oppositeFeature, e);
											}
										}										
									}
								}
							} else {
								Object value = element.eGet(eFeature, false);
								if (value instanceof InternalEObject) {
									InternalEObject e = (InternalEObject) value;
									if (e.eIsProxy()) {
										String guid = e.eProxyURI().fragment();
										if (deletedGUIDs.contains(guid)) {
											Object o = element.eGet(eFeature);
											if(oppositeFeature.isMany()) {
												mrEObject.oppositeAdd(oppositeFeature, o);
											}
											else {
												mrEObject.getOppositeFeatureMap().put(oppositeFeature, o);
											}
										}
									}
								}
							}
						}
					}
				}
			}
			// gets the newly loaded elements to load their opposite features
			//
			loadedElements.addAll(elements);
			elements = copyCollectionToList(getGuidToMethodElementMap().values());
			elements.removeAll(loadedElements);
		}
	}

	public boolean hasUnresolvedProxy() {
		return markerMananger.hasUnresolvedProxy();
	}

	protected Map getURIToTempURIMap() {
		if (URIToTempURIMap == null) {
			URIToTempURIMap = new HashMap();
		}

		return URIToTempURIMap;
	}

	public UnresolvedProxyMarkerManager getMarkerMananger() {
		return markerMananger;
	}
	
	private void checkModify(Collection<Resource> resources) throws LibraryResourceException {
		if(!resources.isEmpty()) {
			Resource[] resourceArray = new Resource[resources.size()];
			resources.toArray(resourceArray);
			checkModify(resourceArray, PersistencePlugin.getDefault().getContext()/*MsgBox.getDefaultShell()*/);
		}
	}

	/* (non-Javadoc)
	 * @see org.eclipse.epf.library.persistence.ILibraryResourceSet#checkModify(org.eclipse.epf.library.persistence.ILibraryResource[], java.lang.Object)
	 */
	public void checkModify(Resource[] resources, Object context) throws LibraryResourceException {		
		MultiFileSaveUtil.doCheckModify(Arrays.asList(resources));
	}

	/* (non-Javadoc)
	 * @see org.eclipse.epf.library.persistence.ILibraryResourceSet#checkModify(java.util.Collection<EObject>, java.lang.Object)
	 */
	public IStatus checkModify(Collection<EObject> eObjects, Object context) {
		HashSet pathSet = new HashSet();
		for (Iterator iter = eObjects.iterator(); iter.hasNext();) {
			EObject o = (EObject) iter.next();
			Resource resource = o.eResource();
			if(resource != null && resource.getResourceSet() == this) {
				MultiFileXMIResourceImpl mfResource = (MultiFileXMIResourceImpl) resource;
				if(!mfResource.hasTempURI()) {
					String path = mfResource.getURI().toFileString();
					pathSet.add(path);
				}
			}
		}
		if(pathSet.isEmpty()) {
			return Status.OK_STATUS;
		}
		String[] paths = new String[pathSet.size()];
		pathSet.toArray(paths);
		return FileManager.getInstance().checkModify(paths, context);
	}

	/* (non-Javadoc)
	 * @see org.eclipse.epf.library.persistence.ILibraryResourceSet#getPersister()
	 */
	public ILibraryPersister getPersister() {
		return MethodLibraryPersister.INSTANCE;
	}

	/* (non-Javadoc)
	 * @see org.eclipse.epf.library.persistence.ILibraryResourceSet#unload(org.eclipse.emf.ecore.resource.Resource, java.util.Map)
	 */
	public boolean unload(Resource resource, Map options) {
		if(resource instanceof MultiFileXMIResourceImpl) {
			return unloadWithoutRemove((MultiFileXMIResourceImpl) resource);
		}
		return false;
	}

	/* (non-Javadoc)
	 * @see org.eclipse.epf.library.persistence.ILibraryResourceSet#unload()
	 */
	public void unload() {
		reset();
	}

	/* (non-Javadoc)
	 * @see org.eclipse.epf.library.persistence.ILibraryResourceSet#getFirstMethodLibrary()
	 */
	public MethodLibrary getFirstMethodLibrary() {
		return getMethodLibrary();
	}

	/* (non-Javadoc)
	 * @see org.eclipse.epf.library.persistence.ILibraryResourceSet#getMethodLibraries()
	 */
	public List getMethodLibraries() {
		MethodLibrary lib = getMethodLibrary();
		if(lib == null) {
			return Collections.EMPTY_LIST;
		}
		return Collections.singletonList(lib);
	}

	/* (non-Javadoc)
	 * @see org.eclipse.epf.library.persistence.ILibraryResourceSet#loadMethodLibraries(org.eclipse.emf.common.util.URI, java.util.Map)
	 */
	public void loadMethodLibraries(URI uri, Map<?, ?> parameters) throws LibraryResourceException {
		try {
			loadLibrary(uri.toFileString());
		} catch (Exception e) {
			if(e instanceof RuntimeException) {
				throw (RuntimeException)e;
			}
			throw new LibraryResourceException(e);
		}

	}

	/* (non-Javadoc)
	 * @see org.eclipse.epf.library.persistence.ILibraryResourceSet#getPersistenceType()
	 */
	public String getPersistenceType() {
		return Services.XMI_PERSISTENCE_TYPE;
	}

	/* (non-Javadoc)
	 * @see org.eclipse.epf.library.persistence.ILibraryResourceSet#unload(org.eclipse.emf.ecore.EObject)
	 */
	public boolean unload(EObject object) {
		Resource resource = object.eResource();
		if(resource instanceof MultiFileXMIResourceImpl) {
			((MultiFileXMIResourceImpl)resource).unloaded((InternalEObject) object);
			return true;
		}		
		return false;
	}

	/* (non-Javadoc)
	 * @see org.eclipse.epf.library.persistence.ILibraryResourceSet#reloadObjects(java.util.Collection)
	 */
	public Collection reloadObjects(Collection objects) {
		// TODO Auto-generated method stub
		return null;
	}

	public Resource getResource(IResource wsRes) {
		IPath path = wsRes.getLocation();
		return path != null ? PersistenceUtil.getResource(path, this) : null;
	}

//	public Collection<Resource> getContainedResources(IResource wsRes) {
//		return Collections.EMPTY_LIST;		
//	}
	
	public Collection<Resource> loadNewResources() {
		return loadConfigurations();
	}
	
	public void handleLibraryMoved(String newFolder) {
		PersistenceUtil.replaceURIPrefix(new ArrayList<Resource>(getResources()), libFolderPath.toOSString(), newFolder);
		
		// clear cached resolved URI in all ResourceDescriptors
		//
		clearCachedResolvedURIs();
	}
	
	protected void clearCachedResolvedURIs() {
		ResourceManager resMgr = getRootResourceManager();
		Iterator iterator = new AbstractTreeIterator(resMgr, true) {
			private static final long serialVersionUID = 1L;

			protected Iterator getChildren(Object object) {
				ResourceManager resMgr = (ResourceManager) object;
				return resMgr.getSubManagers().iterator();
			}

		};
		while (iterator.hasNext()) {
			ResourceManager mgr = (ResourceManager) iterator.next();
			for(ResourceDescriptor resDesc : mgr.getResourceDescriptors()) {
				resDesc.clearResolvedURI();
			}
		}
	}
	
	public boolean hasOwnFolder(Object e) {
		return MultiFileSaveUtil.hasOwnFolder(e);
	}	
	
}