//------------------------------------------------------------------------------
// Copyright (c) 2005, 2006 IBM Corporation and others.
// All rights reserved. This program and the accompanying materials
// are made available under the terms of the Eclipse Public License v1.0
// which accompanies this distribution, and is available at
// http://www.eclipse.org/legal/epl-v10.html
//
// Contributors:
// IBM Corporation - initial implementation
//------------------------------------------------------------------------------
package org.eclipse.epf.persistence;

import java.io.File;
import java.io.FileFilter;
import java.io.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.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.epf.common.serviceability.MsgBox;
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.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 {

	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 DEFAULT_SAVE_OPTIONS = new HashMap();

	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);

		AssociationHelper.init();
	}

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

	private HashMap defaultSaveOptions;

	private HashMap guidToMethodElementMap;

	private boolean loading;

	private boolean loadingResourceManagerTree;

	private Map URIToTempURIMap;

	private UnresolvedProxyMarkerManager markerMananger;

	private UniqueEList refreshListeners;

	private 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();
		markerMananger = new UnresolvedProxyMarkerManager(this);
	}

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

	public UnresolvedProxyMarkerManager getUnresolvedProxyMarkerManager() {
		return markerMananger;		
	}
	
	protected 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 getLoadOptions() {
		Map options = super.getLoadOptions();
		options.put(XMLResource.OPTION_ENCODING, "UTF-8"); //$NON-NLS-1$
		options.put(XMLResource.OPTION_XML_MAP, createLoadXMLMap());
		return options;
	}

	public Map getDefaultSaveOptions() {
		if (defaultSaveOptions == null) {
			defaultSaveOptions = new HashMap();
			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$
			}
		}
	}

	/**
	 * @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) {
			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);
			handleException(msg);
			CommonPlugin.INSTANCE.log(e);
			throw e;
		}
		return res;
	}

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

	public void removeRefreshListenter(IRefreshListener listener) {
		if (refreshListeners != null) {
			refreshListeners.remove(listener);
		}
	}

	/**
	 * 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 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.
	 */
	protected void loadConfigurations() {
		MethodLibrary lib = getMethodLibrary();
		File configDir = new File(new File(lib.eResource().getURI()
				.toFileString()).getParent(),
				MultiFileSaveUtil.METHOD_CONFIGURATION_FOLDER_NAME);
		loadConfigurations(configDir);
	}
	
	/**
	 * Loads method configurations from the specified directory.
	 * 
	 * @param configDir
	 */
	protected void loadConfigurations(File configDir) {
		Iterator dirIter = new AbstractTreeIterator(configDir, false) {
			/**
			 * Comment for <code>serialVersionUID</code>
			 */
			private static final long serialVersionUID = 2758436193000640907L;

			FileFilter filter = new FileFilter() {

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

			};

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

		};
		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();
			loadConfiguration(file);
		}
	}

	protected void 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) {
					lib.getPredefinedConfigurations().add(e);
				} else {
					// TODO: must log error into problem view
				}
			}
		} catch (Exception e) {
			// TODO: must log error into problem view
			CommonPlugin.INSTANCE.log(e);
		}
	}

	/**
	 * @param string
	 */
	protected void handleException(Object err) {
		CommonPlugin.INSTANCE.log(err);
		if (err instanceof Exception) {
			((Exception) err).printStackTrace();
		} else {
			System.err.println(err.toString());
		}
	}

	public void reset() {
		if (uriConverter instanceof MultiFileURIConverter) {
			((MultiFileURIConverter) uriConverter).dispose();
		}
		uriConverter = null;
		boolean notify = eDeliver();
		boolean reportError = REPORT_ERROR;
		boolean refresh = RefreshJob.getInstance().isEnabled();
		try {
			RefreshJob.getInstance().setEnabled(false);
			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(true);
			RefreshJob.getInstance().setEnabled(refresh);
		}

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

		getResources().clear();

		if (URIToTempURIMap != null) {
			URIToTempURIMap.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:");
			for (Iterator iter = getResources().iterator(); iter.hasNext();) {
				Resource resource = (Resource) iter.next();
				if (resource.isModified()) {
					System.err.println("  " + resource.getURI());
				}
			}
		}

		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 loading
		//
		boolean b = RefreshJob.getInstance().isEnabled();
		RefreshJob.getInstance().setEnabled(false);
		RefreshJob.getInstance().reset();
		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) {
				CommonPlugin.INSTANCE.log(e);
				throw new Exception(NLS.bind(
						PersistenceResources.invalidLibraryFileError_msg, path));
			}
		} finally {
			RefreshJob.getInstance().setEnabled(b);

			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
		//
		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(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(true);
			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(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;
	}
	
	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);
				}
			}
			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);
	}
	
	public void unloadWithoutRemove(MultiFileXMIResourceImpl resource) {
		MethodElement e = PersistenceUtil.getMethodElement(resource);
		resource.unloadWithoutRemove();
		if(e instanceof MethodConfiguration) {
			MethodLibrary lib = getMethodLibrary();
			if(lib != null) {
				lib.getPredefinedConfigurations().remove(e);
			}
		}
	}

	/**
	 * @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(element);
			}
		}

		// add new WorkOrder objects or remove unused WorkOrder objects of this
		// activity
		//
		for (Iterator iter = activity.getLinkToPredecessor().iterator(); iter
				.hasNext();) {
			WorkOrder workOrder = (WorkOrder) iter.next();
			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 getGuidToMethodElementMap() {
		if (guidToMethodElementMap == null) {
			guidToMethodElementMap = new HashMap();
		}
		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, resolved);
			}
		}
		markerMananger.proxyResolved(proxy, resolved);
	}

	private 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(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) {
		//			
		// }
	}

	// /**
	// * @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 = new ArrayList(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 = new ArrayList(getGuidToMethodElementMap().values());
			elements.removeAll(loadedElements);
		}
	}

	public void loadOppositeFeatures(List oppositeFeatures, Set deletedGUIDs) {
		int max = oppositeFeatures.size() - 1;
		if (max < 0) {
			return;
		}
		ArrayList elements = new ArrayList(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()) {
									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) {
										for (Iterator iterator = list
												.iterator(); iterator.hasNext();) {
											iterator.next();
										}
									}
								}
							} 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)) {
											element.eGet(eFeature);
										}
									}
								}
							}
						}
					}
				}
			}
			// gets the newly loaded elements to load their opposite features
			//
			loadedElements.addAll(elements);
			elements = new ArrayList(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, 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.checkModify(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 void unload(Resource resource, Map options) {
		if(resource instanceof MultiFileXMIResourceImpl) {
			unloadWithoutRemove((MultiFileXMIResourceImpl) resource);
		}
	}

	/* (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;
	}

}