//------------------------------------------------------------------------------
// 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.library.util;

import java.io.File;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
import java.util.Comparator;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Set;

import org.eclipse.core.runtime.IStatus;
import org.eclipse.emf.common.command.Command;
import org.eclipse.emf.common.notify.Adapter;
import org.eclipse.emf.common.notify.AdapterFactory;
import org.eclipse.emf.common.notify.impl.AdapterImpl;
import org.eclipse.emf.common.util.TreeIterator;
import org.eclipse.emf.common.util.URI;
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.resource.Resource;
import org.eclipse.emf.ecore.resource.ResourceSet;
import org.eclipse.emf.ecore.util.EcoreUtil;
import org.eclipse.emf.edit.provider.ITreeItemContentProvider;
import org.eclipse.epf.library.ILibraryManager;
import org.eclipse.epf.library.LibraryPlugin;
import org.eclipse.epf.library.LibraryResources;
import org.eclipse.epf.library.LibraryService;
import org.eclipse.epf.library.LibraryServiceUtil;
import org.eclipse.epf.library.configuration.ConfigurationFilter;
import org.eclipse.epf.library.configuration.ConfigurationHelper;
import org.eclipse.epf.library.edit.IFilter;
import org.eclipse.epf.library.edit.LibraryEditPlugin;
import org.eclipse.epf.library.edit.TngAdapterFactory;
import org.eclipse.epf.library.edit.TransientGroupItemProvider;
import org.eclipse.epf.library.edit.command.IActionManager;
import org.eclipse.epf.library.edit.configuration.GuidanceGroupingItemProvider;
import org.eclipse.epf.library.edit.configuration.GuidanceItemProvider;
import org.eclipse.epf.library.edit.ui.UserInteractionHelper;
import org.eclipse.epf.library.edit.util.MethodElementPropUtil;
import org.eclipse.epf.library.edit.util.MethodElementPropertyHelper;
import org.eclipse.epf.library.edit.util.MethodLibraryPropUtil;
import org.eclipse.epf.library.edit.util.MethodPluginPropUtil;
import org.eclipse.epf.library.edit.util.ModelStructure;
import org.eclipse.epf.library.edit.util.ProcessScopeUtil;
import org.eclipse.epf.library.edit.util.TngUtil;
import org.eclipse.epf.library.edit.validation.IValidatorFactory;
import org.eclipse.epf.library.persistence.ILibraryResourceSet;
import org.eclipse.epf.library.persistence.PersistenceService;
import org.eclipse.epf.library.services.SafeUpdateController;
import org.eclipse.epf.persistence.MultiFileResourceSetImpl;
import org.eclipse.epf.persistence.MultiFileXMISaveImpl;
import org.eclipse.epf.services.ILibraryPersister;
import org.eclipse.epf.services.Services;
import org.eclipse.epf.uma.BreakdownElement;
import org.eclipse.epf.uma.ContentCategory;
import org.eclipse.epf.uma.ContentPackage;
import org.eclipse.epf.uma.CustomCategory;
import org.eclipse.epf.uma.DescribableElement;
import org.eclipse.epf.uma.Guidance;
import org.eclipse.epf.uma.MethodConfiguration;
import org.eclipse.epf.uma.MethodElement;
import org.eclipse.epf.uma.MethodElementProperty;
import org.eclipse.epf.uma.MethodLibrary;
import org.eclipse.epf.uma.MethodPackage;
import org.eclipse.epf.uma.MethodPlugin;
import org.eclipse.epf.uma.MethodUnit;
import org.eclipse.epf.uma.Practice;
import org.eclipse.epf.uma.Process;
import org.eclipse.epf.uma.ProcessComponent;
import org.eclipse.epf.uma.Role;
import org.eclipse.epf.uma.SupportingMaterial;
import org.eclipse.epf.uma.Task;
import org.eclipse.epf.uma.UmaFactory;
import org.eclipse.epf.uma.UmaPackage;
import org.eclipse.epf.uma.WorkProduct;
import org.eclipse.epf.uma.ecore.EProperty;
import org.eclipse.epf.uma.ecore.impl.MultiResourceEObject;
import org.eclipse.epf.uma.util.Scope;
import org.eclipse.epf.uma.util.UmaUtil;
import org.eclipse.swt.widgets.Display;

/**
 * @author Jinhua Xi
 * @author Phong Nguyen Le
 * @since 1.0
 */
public class LibraryUtil {

	public static boolean PUBLISH_MODE = false;
	
	private static Comparator<EClass> typeComparator = new Comparator<EClass>() {

		public int compare(EClass o1, EClass o2) {
			return o1.getName().compareTo(o2.getName());
		}
		
	};

	private static List<EClass> includedElementTypes;
	
	private static final Collection<EClass> excludedTypes = Arrays.asList(new EClass[] {
			UmaPackage.eINSTANCE.getBreakdownElement(),
			UmaPackage.eINSTANCE.getCompositeRole(),
			UmaPackage.eINSTANCE.getDescribableElement(),
			UmaPackage.eINSTANCE.getDescriptor(),
			UmaPackage.eINSTANCE.getFulfillableElement(),
			UmaPackage.eINSTANCE.getKind(),
			UmaPackage.eINSTANCE.getProcessComponentDescriptor(),
			UmaPackage.eINSTANCE.getProcessComponentInterface(),
			UmaPackage.eINSTANCE.getProcessElement(),
			UmaPackage.eINSTANCE.getProcessPlanningTemplate(),
			UmaPackage.eINSTANCE.getRoleDescriptor(),
			UmaPackage.eINSTANCE.getTaskDescriptor(),
			UmaPackage.eINSTANCE.getTeamProfile(),
			UmaPackage.eINSTANCE.getWorkBreakdownElement(),
			UmaPackage.eINSTANCE.getWorkOrder(),
			UmaPackage.eINSTANCE.getWorkProductDescriptor()
	});
	
	/**
	 * Check is given plugin name is valid name in the library
	 * 
	 * @param name
	 * @return String
	 */
	public static String checkPluginName(MethodPlugin plugin, String newName) {
		MethodLibrary lib = LibraryService.getInstance()
				.getCurrentMethodLibrary();
		return IValidatorFactory.INSTANCE.createValidator(lib,
				UmaPackage.Literals.METHOD_LIBRARY__METHOD_PLUGINS,
				(IFilter) null, null, UmaPackage.Literals.NAMED_ELEMENT__NAME)
				.isValid(newName);		
	}

	/**
	 * method to check if the element is a plugin or package so that is can be selected in configuration editor. 
	 * May need a better name for this.
	 * @param element EObject
	 * @return boolean
	 */
	public static boolean selectable(EObject element) {
		return (element instanceof MethodLibrary
				|| element instanceof MethodPlugin || element instanceof MethodPackage);
	}

	/**
	 * get the container of the element that is selectable.
	 * @param element EObject
	 * @return EObject
	 */
	public static EObject getSelectable(EObject element) {
		if (element instanceof BreakdownElement) {
			EObject pkg = element.eContainer();
			while (pkg != null && !(pkg instanceof ProcessComponent) ) {
				pkg = pkg.eContainer();
			}
			return pkg;
			
		} else {
			EObject parent = element;
			while ((parent != null) && !selectable(parent)) {
				parent = parent.eContainer();
			}

			return parent;
		}
	}

	/**
	 * get the method plugin for the element
	 * 
	 * @param element EObject
	 * @return MethodPlugin
	 */
	public static MethodPlugin getMethodPlugin(EObject element) {
		// EObject parent = element;
		// while ((parent != null) && !(parent instanceof MethodPlugin)) {
		// parent = parent.eContainer();
		// }
		//
		// return (MethodPlugin) parent;

		return UmaUtil.getMethodPlugin(element);
	}

	/**
	 * get a printable name string for the element. Note, this is not the element name attribute
	 * @param element Object
	 * @return String
	 */
	public static String getName(Object element) {
		if (element == null)
			return LibraryResources.unknown_text; 

		if (element instanceof MethodElement) {
			return getFullName((MethodElement) element);
		}

		return element.toString();
	}

	/**
	 * get a printable name for the element.
	 * @param element MethodElement
	 * @return String
	 */
	public static String getFullName(MethodElement element) {
		if (selectable(element)) {
			StringBuffer buffer = new StringBuffer();
			buffer.append("[").append(element.getName()).append("]"); //$NON-NLS-1$ //$NON-NLS-2$
			MethodElement parent = element;
			while ((parent = (MethodElement) parent.eContainer()) != null) {
				if (parent instanceof MethodLibrary) {
					break;
				}
				buffer.insert(0, "[" + parent.getName() + "]."); //$NON-NLS-1$ //$NON-NLS-2$
			}
			return buffer.toString();
		} else {
			return element.getName();
		}
	}

	/**
	 * get the element's type:name as a localized string
	 * @param element MethodElement
	 * @return String
	 */
	public static String getLocalizeTypeName(MethodElement element) {
		if (element == null) {
			return ""; //$NON-NLS-1$
		}
		if (element instanceof DescribableElement) {
			String nameStr = TngUtil.getTypeText(element) + LibraryResources.colon_with_space ;
			
			if (((DescribableElement) element).getPresentationName() != null) {
				nameStr += "(" + ((DescribableElement) element).getPresentationName() //$NON-NLS-1$
						+ ") " + ((DescribableElement) element).getName(); //$NON-NLS-1$
			} else {
				nameStr += element.getName();
			}
			return nameStr ;
		} else {
			return getTypeName(element);
		}
	}
	
	/**
	 * get the element's type:name
	 * 
	 * @param element MethodElement
	 * @return String
	 */
	public static String getTypeName(MethodElement element) {
		return element == null ? "" : element.getType().getName() + ":" + element.getName(); //$NON-NLS-1$ //$NON-NLS-2$
	}
	
	/**
	 * get the element's type:name
	 * 
	 * @param element MethodElement
	 * @return String
	 */
	public static String getTypePath(MethodElement element) {
		return element == null ? "" : element.getType().getName() + ":" + TngUtil.getLabelWithPath(element); //$NON-NLS-1$ //$NON-NLS-2$
	}

	
	/**
	 * get the method plugins in the library
	 * @param library MethodLibrary
	 * @return List a list of MethodPlugin objects
	 */
	public static List<MethodPlugin> getMethodPlugins(MethodLibrary library) {
		return new ArrayList<MethodPlugin>(library.getMethodPlugins());
	}

	/**
	 * get a list of guid strings of the method plugins in the library
	 * @param library MethodLibrary
	 * @return List
	 */
	public static List getMethodPluginGuids(MethodLibrary library) {
		List items = new ArrayList();
		List elements = library.getMethodPlugins();
		if (elements != null) {
			for (Iterator it = elements.iterator(); it.hasNext();) {
				MethodPlugin element = (MethodPlugin) it.next();
				items.add(element.getGuid());
			}
		}

		return items;
	}

	/**
	 * get the MethodPlugin in the library with the given plugin guid.
	 * 
	 * @param library MethodLibrary
	 * @param pluginGuid String
	 * @return MethodPlugin
	 */
	public static MethodPlugin getMethodPlugin(MethodLibrary library,
			String pluginGuid) {
		if (pluginGuid == null) {
			return null;
		}

		List elements = library.getMethodPlugins();
		if (elements != null) {
			for (Iterator it = elements.iterator(); it.hasNext();) {
				MethodPlugin element = (MethodPlugin) it.next();
				if (pluginGuid.equals(element.getGuid())) {
					return element;
				}
			}
		}

		return null;
	}
	
	/**
	 * get the MethodPlugin in the library with the given plugin name.
	 * 
	 * @param library MethodLibrary
	 * @param name String
	 * @return MethodPlugin
	 */
	public static MethodPlugin getMethodPluginByName(MethodLibrary library,
			String name) {
		if (name == null) {
			return null;
		}

		List elements = library.getMethodPlugins();
		if (elements != null) {
			for (Iterator it = elements.iterator(); it.hasNext();) {
				MethodPlugin element = (MethodPlugin) it.next();
				if (name.equals(element.getName())) {
					return element;
				}
			}
		}

		return null;
	}


	/**
	 * get all the contained MethodPackages for the element, return empty list if nothing found.
	 * @param element MethodElement
	 * @return List
	 */
	public static List getMethodPackages(MethodElement element) {
		List items = new ArrayList();
		for (Iterator it = element.eAllContents(); it.hasNext();) {
			EObject e = (EObject) it.next();
			if (e instanceof MethodPackage) {
				items.add(e);
			}
		}

		return items;
	}

	/**
	 * upwrap the object
	 * @param obj Object
	 * @return Object
	 */
	public static Object unwrap(Object obj) {
		return TngUtil.unwrap(obj);
	}

	/**
	 * unwrap the command
	 * @param cmd Command
	 * @return Command
	 */
	public static Command unwrap(Command cmd) {
		return TngUtil.unwrap(cmd);
	}

	/**
	 * clear the resource the elements associated to. So that the element can be
	 * added to another library and got new resource assigned.
	 * 
	 * @param importLibraty
	 *            MethodLibrary
	 */
	public static void detachFromResource(MethodLibrary importLibraty) {
		ResourceSet resSet = null;
		Resource res = importLibraty.eResource();
		if (res != null) {
			resSet = res.getResourceSet();
		}

		if (resSet != null) {
			for (TreeIterator it = resSet.getAllContents(); it.hasNext();) {
				Object obj = it.next();
				if (obj instanceof MultiResourceEObject) {
					((MultiResourceEObject) obj).eSetResource(null);
				}
			}
		}

		// clear all the unresolved proxies
		clearProxies(importLibraty);
	}

	/**
	 * clear proxy for the element. This is used to fix the element when the proxy can't be resolved.
	 * @param element EObject
	 */
	public static void clearProxies(EObject element) {
		if (element.eIsProxy()) {
			// reset the proxy to null
			setProxyURI(element, null);
		} else {
			// iterate the children
			for (TreeIterator it = element.eAllContents(); it.hasNext();) {
				EObject o = (EObject) it.next();
				if (o.eIsProxy()) {
					setProxyURI(o, null);
				}
			}
		}
	}

	/**
	 * set the object's proxy uri
	 * @param obj EObject
	 * @param uri org.eclipse.emf.common.util.URI
	 */
	public static void setProxyURI(EObject obj,
			org.eclipse.emf.common.util.URI uri) {
		((org.eclipse.emf.ecore.InternalEObject) obj).eSetProxyURI(uri);
	}

	public static Collection<Resource> getLoadedResources(MethodLibrary lib, Collection<Resource> excludes) {

		Collection<Resource> loadedres = new HashSet<Resource>();

		for (Iterator<Resource> it = lib.eResource().getResourceSet()
				.getResources().iterator(); it.hasNext(); ) {
			Resource res = (Resource)it.next();
			if ( res.isLoaded() ) {
				if ( (excludes == null) || !excludes.contains(res) ) {
					loadedres.add(res);
				}
			}
		}	
		
		return loadedres;
	}
	
	/**
	 * load all elements in the library
	 * @param lib MethodLibrary
	 */
	public static Collection<Resource> loadAll(MethodLibrary lib) {

		Collection<Resource> loadedres = getLoadedResources(lib, null);
		
		loadAllContained(lib);
		
		return getLoadedResources(lib, loadedres);
	}

	public static void loadAllContained(MethodElement me) {
		for (Iterator<EObject> iter = me.eAllContents(); iter.hasNext();) {
			try {
				EObject element = (EObject) iter.next();
				for (Iterator<EObject> iterator = element.eCrossReferences().iterator(); iterator
						.hasNext();) {
					iterator.next();
				}
			} catch (Exception e) {
				LibraryPlugin.getDefault().getLogger().logError(e);
			}
		}
	}
	
	public static void loadAllPlugins(MethodConfiguration config) {
		List<MethodPlugin> pluigns = config.getMethodPluginSelection();
		for (MethodPlugin plugin: pluigns) {
			loadAllContained(plugin);
		}
	}
	
	/**
	 * load all processes in the library
	 * @param lib MethodLibrary
	 */
	public static void loadAllProcesses(MethodLibrary lib) {

		for (Iterator iter = lib.getMethodPlugins().iterator(); iter.hasNext();) {
			try {
				MethodPlugin plugin = (MethodPlugin) iter.next();
				TngUtil.getAllProcesses(plugin);
			} catch (Exception e) {
				LibraryPlugin.getDefault().log(e);
			}
		}
	}
	
	/**
	 * save all elements in the library not matter the element is changed or not. 
	 * Don't refresh the workspace.
	 * @param lib MethodLibrary
	 * @throws Exception
	 */
	public static void saveAll(MethodLibrary lib) throws Exception {
		saveLibrary(lib, true, false);
	}

	/**
	 * save the specified method library based on the library resourceset. You
	 * need to set the resource set before calling this method to save the
	 * library
	 * 
	 * @param lib
	 *            MethodLibrary
	 * @param saveAll
	 *            boolean if true, force saving all the resources even if they
	 *            are not modified.
	 */
	public static void saveLibrary(MethodLibrary lib, boolean saveAll,
			boolean refresh) throws Exception {
		ILibraryResourceSet libResourceSet = (ILibraryResourceSet) lib.eResource().getResourceSet();
		if(libResourceSet instanceof MultiFileResourceSetImpl) {
			MultiFileResourceSetImpl resourceSet = (MultiFileResourceSetImpl) libResourceSet;

			ILibraryManager manager = LibraryService.getInstance()
			.getCurrentLibraryManager();
			Map saveOptions = manager != null ? manager.getSaveOptions()
					: new HashMap();

			// back up current REFRESH_NEW_RESOURCE option
			Object old = saveOptions.get(MultiFileXMISaveImpl.REFRESH_NEW_RESOURCE);
			Object oldCheckModify = saveOptions
			.get(MultiFileXMISaveImpl.CHECK_MODIFY);
			try {
				// disable workspace refresh when new file is created
				saveOptions.put(MultiFileXMISaveImpl.REFRESH_NEW_RESOURCE,
						refresh ? "true" : "false"); //$NON-NLS-1$ //$NON-NLS-2$
				saveOptions.put(MultiFileXMISaveImpl.CHECK_MODIFY, "false"); //$NON-NLS-1$

				// save resource set here
				resourceSet.save(saveOptions, saveAll);
			} finally {
				// restore REFRESH_NEW_RESOURCE option
				saveOptions.put(MultiFileXMISaveImpl.REFRESH_NEW_RESOURCE, old);
				saveOptions.put(MultiFileXMISaveImpl.CHECK_MODIFY, oldCheckModify);
			}
		}
		else {
			libResourceSet.save(Collections.EMPTY_MAP);
		}
	}

	/**
	 * load the library at the specified path. return the MethodLibrary.
	 * This method is different from the the open library in LibraryService. 
	 * It only load the row library object but will not impact the current EPF environment.
	 * @param libraryPath String
	 * @return MethodLibrary
	 * @throws Exception
	 */
	public static MethodLibrary loadLibrary(String libraryPath)
			throws Exception {
		ILibraryResourceSet resourceSet = PersistenceService.INSTANCE.createResourceSet(Services.XMI_PERSISTENCE_TYPE);
		resourceSet.loadMethodLibraries(URI.createFileURI(libraryPath), Collections.EMPTY_MAP);
		return resourceSet.getFirstMethodLibrary();
	}

	/**
	 * get the root path of the method library 
	 * @param lib MethodLibrary
	 * @return File
	 */
	public static File getLibraryRootPath(MethodLibrary lib) {
		Resource res = lib.eResource();
		if (res == null) {
			return null;
		}

		URI uri = res.getURI();
		String path = uri.toFileString();
		File f = new File(path);
		return f.getParentFile();
	}

	/**
	 * get all packages in the plugin
	 * @param plugin MethodPlugin
	 * @return List
	 */
	public static List getAllPackages(MethodPlugin plugin) {
		List allPkgs = new ArrayList();

		List pkgs = plugin.getMethodPackages();
		allPkgs.addAll(pkgs);

		for (Iterator it = pkgs.iterator(); it.hasNext();) {
			getAllChildPackages((MethodPackage) it.next(), allPkgs);
		}

		return allPkgs;
	}

	/**
	 * get all child packages of the given MethodPackage and add to the list
	 * @param pkg MethodPackage
	 * @param result List the packages found
	 */
	public static void getAllChildPackages(MethodPackage pkg, List result) {
		List pkgs = pkg.getChildPackages();
		result.addAll(pkgs);

		for (Iterator it = pkgs.iterator(); it.hasNext();) {
			getAllChildPackages((MethodPackage) it.next(), result);
		}
	}

	/**
	 * get all configurations referenced by this plugin
	 * 
	 * @param plugin
	 * @return List of MethodConfiguration
	 */
	public static List<MethodConfiguration> getAssociatedConfigurations(MethodPlugin plugin) {
		// get the configs that references this method plugin
		Set<MethodConfiguration> allConfigs = new HashSet<MethodConfiguration>();
/*		List configs = (List) ((MultiResourceEObject) plugin)
				.getOppositeFeatureValue(AssociationHelper.MethodPlugin_MethodConfigurations);
		addUniqueItems(configs, allConfigs);

		// get the configs that references the packages in this plugin
		List pkgs = getAllPackages(plugin);
		for (Iterator it = pkgs.iterator(); it.hasNext();) {
			MultiResourceEObject o = (MultiResourceEObject) it.next();

			configs = (List) o
					.getOppositeFeatureValue(AssociationHelper.MethodPackage_MethodConfigurations);
			addUniqueItems(configs, allConfigs);
		}
*/
		// get the congigurations that referenced by the processes in this
		// plugin
		MethodLibrary lib = UmaUtil.getMethodLibrary(plugin);		
		
		List procs = TngUtil.getAllProcesses(plugin);
		for (Iterator it = procs.iterator(); it.hasNext();) {
			org.eclipse.epf.uma.Process p = (org.eclipse.epf.uma.Process) it
					.next();
			MethodConfiguration c = p.getDefaultContext();
			if ((c != null && !(c instanceof Scope))) {
				allConfigs.add(c);
				allConfigs.addAll(p.getValidContext());
			} else if (lib != null) {
				for (MethodConfiguration config : lib.getPredefinedConfigurations()) {
					if (ConfigurationHelper.inConfig(p, config)) {
						allConfigs.add(config);
					}
				}
			}
//			addUniqueItems(p.getValidContext(), allConfigs);
		}

		return new ArrayList<MethodConfiguration>(allConfigs);
	}

	private static void addUniqueItems(List from, List to) {
		if (from == null || to == null || from.size() == 0) {
			return;
		}

		for (Iterator it = from.iterator(); it.hasNext();) {
			Object o = it.next();
			if (!to.contains(o)) {
				to.add(o);
			}
		}
	}

	/**
	 * validate the configuration by forcing to select the global packages of
	 * the selected method plugins, this is needed for configuration exporting.
	 * If global packages are missing, the exported configuration is not valid
	 * 
	 * @param actionMgr if not null, will use the given IActionManager to change the configuration, otherwise configuration will be changed directly
	 * @param plugin
	 */
	public static void validateMethodConfiguration(IActionManager actionMgr, MethodConfiguration config) {
//		List plugins = config.getMethodPluginSelection();
//		List pkgSels = config.getMethodPackageSelection();
//
//		for (Iterator itp = plugins.iterator(); itp.hasNext();) {
//			MethodPlugin plugin = (MethodPlugin) itp.next();
//			List pkgs = TngUtil.getAllSystemPackages(plugin);
//			for (Iterator it = pkgs.iterator(); it.hasNext();) {
//				Object pkg = it.next();
//				if (!pkgSels.contains(pkg)) {
//					pkgSels.add(pkg);
//				}
//			}
//		}
		
		// moved to TngUtil
		TngUtil.validateMethodConfiguration(actionMgr, config);
	}

	/**
	 * validate the configuration by forcing to select the global packages of
	 * the selected method plugins, this is needed for configuration exporting.
	 * If global packages are missing, the exported configuration is not valid
	 * @param plugin
	 */
	public static void validateMethodConfiguration(MethodConfiguration config) {
		validateMethodConfiguration(null, config);
	}
	
	/**
	 * get the copyright object for an element
	 * @param element MethodElement
	 * @return SupportingMaterial
	 */
	public static SupportingMaterial getCopyright(MethodElement element) {
		SupportingMaterial sm = null;
		if (element instanceof MethodUnit) {
			sm = ((MethodUnit) element).getCopyrightStatement();
		} else if (element instanceof DescribableElement) {
			sm = ((DescribableElement) element).getPresentation()
					.getCopyrightStatement();
		}

		// if no copyright of it's own, get the copyright from the plugin
		if (sm == null) {
			MethodPlugin p = getMethodPlugin(element);
			if (p != null) {
				sm = p.getCopyrightStatement();
			}
		}

		return sm;
	}

	/**
	 * for the given container and elements list, check if the element in the list is contained by the container or not. 
	 * return all the contained elements for a given container
	 * @param container Object
	 * @param elements Collection
	 * @return Collection
	 */
	public static Collection getContainedElements(Object container,
			Collection elements) {
		if (container instanceof TransientGroupItemProvider) {
			container = ((TransientGroupItemProvider) container).getTarget();
		}
		ArrayList contained = new ArrayList();
		for (Iterator iter = elements.iterator(); iter.hasNext();) {
			Object element = iter.next();
			if (element instanceof EObject
					&& UmaUtil.isContainedBy((EObject) element, container)) {
				contained.add(element);
			}
		}
		return contained;
	}

	/**
	 * check if two method element are identical or not. Two elements are
	 * identical if and only if: all the attribute values are equal all the
	 * referenced elements are equal all the contained elements are identical
	 * 
	 * @param oldObj
	 *            MethodElement
	 * @param newObj
	 *            MethodElement
	 * @return boolean
	 */
	public static boolean isIdentical(MethodElement oldObj, MethodElement newObj) {

		if ((oldObj == null) && (newObj == null)) {
			return true;
		}

		if ((oldObj == null) || (newObj == null)) {
			return false;
		}

		// this does not work, the toString contains the object instance info
		// return oldObj.toString().equals(newObj.toString());

		List features = getStructuralFeatures(oldObj);
//		List properties = oldObj.getInstanceProperties();
		if (features != null) {
			for (int i = 0; i < features.size(); i++) {
				EStructuralFeature feature = (EStructuralFeature) features
						.get(i);
				Object oldValue = oldObj.eGet(feature);
				Object newValue = newObj.eGet(feature);
				if (oldValue == null && newValue == null) {
					continue;
				}

				if (oldValue == null || newValue == null) {
					return false;
				}

				if (oldValue instanceof MethodElement) {

					// if it'c containment feature value, iterate it
					MethodElement olde = (MethodElement) oldValue;
					if (olde.eContainer() == oldObj) {
						if (!isIdentical(olde, (MethodElement) newValue)) {
							return false;
						}
					} else if (oldValue != newValue) {
						return false;
					}
				} else if (oldValue instanceof List) {
					List oldl = (List) oldValue;
					List newl = (List) newValue;
					if (oldl.size() != newl.size()) {
						return false;
					}

					for (int x = 0; x < oldl.size(); x++) {
						Object o = oldl.get(x);
						Object n = newl.get(x);
						if (o instanceof MethodElement) {
							// if it'c containment feature value, iterate it
							MethodElement olde = (MethodElement) o;
							if (olde.eContainer() == oldObj) {
								if (!isIdentical(olde, (MethodElement) n)) {
									return false;
								}
							} else if (oldValue != newValue) {
								return false;
							}
						} else {
							if (!o.equals(n)) {
								return false;
							}
						}
					}
				} else {
					if (!oldValue.equals(newValue)) {
						return false;
					}
				}
			}
		}

		return true;
	}
	
	/**
	 * check if the element is a process or not. 
	 * A Process is a CapabilityPattern or DeliveryProcess object 
	 * that is contained by a ProcessComponent.
	 * @param e EObject
	 * @return boolean
	 */
	public static boolean isProcess(EObject e) {
		return (e instanceof org.eclipse.epf.uma.Process) && 
			(e.eContainer() instanceof ProcessComponent);
	}
	
	public static List getValidViews(MethodConfiguration config) {
		
		List views = new ArrayList();
		for ( Iterator it = config.getProcessViews().iterator(); it.hasNext(); ) {
			ContentCategory view = (ContentCategory)it.next();
			if ( !ConfigurationHelper.isContributor(view) ) {
				view = (ContentCategory)ConfigurationHelper.getCalculatedElement(view, config);
				if ( view != null && !views.contains(view) ) {
					views.add(view);
				} 
			}	
		}
				
		return views;
	}
	
//	public static List getSuperActivities(BreakdownElement element) {
//		List items = new ArrayList();
//
//		// build the parent nodes
//		BreakdownElement parent = element.getSuperActivities(); 
//		while ( parent != null ) {
//			items.add(0, parent);
//			if (LibraryUtil.isProcess(parent) ) {
//				break;
//			}
//			parent = parent.getSuperActivities();
//		}
//
//		return items;
//	}
	
	/**
	 * Returns all structural features for the given method element
	 * @param element
	 * @return
	 */
	public static List getStructuralFeatures(MethodElement element) {
		List properties = element.getInstanceProperties();

		if (properties != null) {
			List<EStructuralFeature> features = new ArrayList<EStructuralFeature>();
			// get all features
			for (int i = 0; i < properties.size(); i++) {
				EProperty property = (EProperty) properties.get(i);
				if (property != null) {
					EStructuralFeature feature = property
							.getEStructuralFeature();
					features.add(feature);
				}
			}
			return features;
		} else
			return null;
	}
	
	public static List<EClass> getIncludedElementTypes() {
		if (includedElementTypes == null) {
			synchronized (LibraryUtil.class) {
				if (includedElementTypes == null) {
					includedElementTypes = new ArrayList<EClass>();
					for (EClassifier cls : UmaPackage.eINSTANCE
							.getEClassifiers()) {
						if (cls instanceof EClass
								&& UmaPackage.eINSTANCE.getDescribableElement()
										.isSuperTypeOf((EClass) cls)) {
							includedElementTypes.add((EClass) cls);
						}
					}
					includedElementTypes.removeAll(excludedTypes);
					Collections.sort(includedElementTypes, typeComparator);
					includedElementTypes = Collections.unmodifiableList(includedElementTypes);
				}
			}
		}
		return includedElementTypes;
	}
	
	public static List<DescribableElement> getIncludedElements(CustomCategory category, MethodConfiguration config) {
		List<DescribableElement> includedElements = new ArrayList<DescribableElement>();
		if (config == null) {
			return includedElements;
		}
		MethodElementProperty prop = MethodElementPropertyHelper.getProperty(category, MethodElementPropertyHelper.CUSTOM_CATEGORY__INCLUDED_ELEMENTS);
		EClassifier cls = prop == null ? null : UmaPackage.eINSTANCE.getEClassifier(prop.getValue());
		if(cls instanceof EClass) {
			EClass eClass = (EClass) cls;
			if (UmaPackage.eINSTANCE.getDescribableElement().isSuperTypeOf(eClass)) {
				MethodLibrary lib = (MethodLibrary) config
						.eContainer();
				Iterator<EObject> iter = lib.eAllContents();
				while (iter.hasNext()) {
					EObject eObject = iter.next();
					if (eClass.isInstance(eObject)) {
						includedElements.add((DescribableElement) eObject);
					}
				}
			}
		}
		return includedElements;
	}
	
	private static Adapter nameTrackPresentationNameMark = new AdapterImpl();		
	public static void addNameTrackPresentationNameMark(MethodElement element) {
		element.eAdapters().add(nameTrackPresentationNameMark);
	}
	public static void removeNameTrackPresentationNameMark(MethodElement element) {
		element.eAdapters().remove(nameTrackPresentationNameMark);
	}
	public static boolean hasNameTrackPresentationNameMark(MethodElement element) {
		for (Adapter adpter: element.eAdapters()) {
			if (adpter == nameTrackPresentationNameMark) {
				return true;
			}
		}		
		return false;
	}
	
	public static boolean markLibrarySynFree(final MethodLibrary lib, boolean toSave) {
		boolean b = markLibrarySynFree(lib, toSave, true);
		return b;
	}
	
	public static boolean markLibrarySynFree(final MethodLibrary lib, boolean toSave, boolean synFreeValue) {
		if (lib == null) {
			return true;
		}
		MethodLibraryPropUtil propUtil = MethodLibraryPropUtil.getMethodLibraryPropUtil();
		if (propUtil.isSynFree(lib) == synFreeValue) {
			return true;
		}

		final List<MethodPlugin> plugins = lib.getMethodPlugins();
		final List<Resource> resourcesToSave = new ArrayList<Resource>(); 
		if (toSave) {
			MethodPluginPropUtil pluginPropUtil = MethodPluginPropUtil.getMethodPluginPropUtil();
			for (int i = 0; i < plugins.size(); i++) {
				MethodPlugin plugin = plugins.get(i);
				if (pluginPropUtil.isSynFree(plugin) != synFreeValue) {
					Resource res = plugin.eResource();
					if (res != null) {
						resourcesToSave.add(res);
					}
				}
			}
			resourcesToSave.add(lib.eResource());			
			if (! checkModify(resourcesToSave)) {
				return false;
			}
		}
		
		propUtil.setSynFree(lib, synFreeValue);
		for (int i = 0; i < plugins.size(); i++) {
			markPluginSynFree(plugins.get(i), true, synFreeValue);
		}
		
		if (toSave) {
			SafeUpdateController.syncExec(new Runnable() {
				public void run() {
					ILibraryPersister.FailSafeMethodLibraryPersister persister = LibraryServiceUtil
							.getCurrentPersister().getFailSafePersister();
					try {
						for (Resource res : resourcesToSave) {
							persister.save(res);
						}
						persister.commit();
					} catch (Exception e) {
						persister.rollback();
						LibraryPlugin.getDefault().getLogger().logError(e);
					}
				}
			});
		}
		
		return true;
	}
	
	public static boolean markPluginSynFree(final MethodPlugin plugin, boolean toSave) {
		return markPluginSynFree(plugin, toSave, true);
	}
	
	public static boolean markPluginSynFree(final MethodPlugin plugin, boolean toSave, boolean synFreeValue) {
		if (plugin == null) {
			return true;
		}
		MethodPluginPropUtil propUtil = MethodPluginPropUtil.getMethodPluginPropUtil();
		if (propUtil.isSynFree(plugin) == synFreeValue) {
			return true;
		}
		
		if (toSave && plugin.eResource() != null) {
			List<Resource> resourcesToSave = new ArrayList<Resource>(); 
			resourcesToSave.add(plugin.eResource());
			if (! checkModify(resourcesToSave)) {
				return false;
			}
		}
		

		propUtil.setSynFree(plugin, synFreeValue);

		if (toSave && plugin.eResource() != null) {
			SafeUpdateController.syncExec(new Runnable() {
				public void run() {
					ILibraryPersister.FailSafeMethodLibraryPersister persister = LibraryServiceUtil
							.getCurrentPersister().getFailSafePersister();
					try {
						persister.save(plugin.eResource());
						persister.commit();
					} catch (Exception e) {
						persister.rollback();
						LibraryPlugin.getDefault().getLogger().logError(e);		
					}
				}
			});
		}
	
		return true;
		
	}
	
	private static boolean checkModify(List<Resource> resourcesToSave) {
		IStatus status = UserInteractionHelper.checkModify(resourcesToSave,
				Display.getCurrent().getActiveShell());

		if (!status.isOK()) {
			// To do: display error msg
			return false;
		}
		
		return true;
	}
	
	public static List<Practice> getPractices(MethodConfiguration config) {
		List<Practice> practiceList = new ArrayList<Practice>();
		if (config == null) {
			return practiceList;
		}
				
		Set<Practice> practiceSet = new HashSet<Practice>();
		
		IFilter filter = new ConfigurationFilter(config);
		AdapterFactory adapterFactory = TngAdapterFactory.INSTANCE.getConfigurationView_AdapterFactory(filter);
		ITreeItemContentProvider adapter = (ITreeItemContentProvider) adapterFactory.adapt(config, ITreeItemContentProvider.class);
		GuidanceGroupingItemProvider guidanceGroupingItemProvider = null;
		for (Object child : adapter.getChildren(config)) {
			if(child instanceof GuidanceGroupingItemProvider) {
				guidanceGroupingItemProvider = (GuidanceGroupingItemProvider) child;
				break;
			}
		}
		
		if(guidanceGroupingItemProvider != null) {
			GuidanceItemProvider practicesItemProvider = null;
			Collection<?> children = guidanceGroupingItemProvider.getChildren(guidanceGroupingItemProvider);
			for (Object child : children) {
				if(child instanceof GuidanceItemProvider) {
					GuidanceItemProvider ip = (GuidanceItemProvider) child;
					if(ip.getGuidanceFilter() == GuidanceGroupingItemProvider.practiceFilter) {
						practicesItemProvider = ip;
						break;
					}
				}
			}
			if(practicesItemProvider != null) {
				children = practicesItemProvider.getChildren(practicesItemProvider);
				for (Object child : children) {
					if(child instanceof Practice && ! practiceSet.contains(child)) {
						Practice p = (Practice) child;
						practiceList.add(p);
						practiceSet.add(p);
					}
				}
			}
		}
		
		return practiceList;
	}
	
	private static CustomCategory createCustomCategory(MethodPlugin plugin, CustomCategory parent, String name) {
		ContentPackage pkg = UmaUtil.findContentPackage(plugin, ModelStructure.DEFAULT.customCategoryPath);
		CustomCategory cc = UmaFactory.eINSTANCE.createCustomCategory();

		pkg.getContentElements().add(cc);
		if ( parent != null ) {
			((CustomCategory)parent).getCategorizedElements().add(cc);
		}
		else {
			TngUtil.getRootCustomCategory(plugin).getCategorizedElements().add(cc);
		}
		cc.setName(name);
		cc.setPresentationName(name);
		cc.setGuid(EcoreUtil.generateUUID());
		
		return cc;
	}
	
	public static class ConfigAndPlugin {
		public MethodConfiguration config;
		public MethodPlugin plugin;
	}
	
	public static ConfigAndPlugin addTempConfigAndPluginToCurrentLibrary(List<Process> configFreeProcesses) {
		if (configFreeProcesses == null || configFreeProcesses.isEmpty()) {
			return null;
		}
		MethodLibrary lib = LibraryService.getInstance().getCurrentMethodLibrary();
		if (lib == null) {
			return null;
		}
		MethodElementPropUtil proppUtil = MethodElementPropUtil.getMethodElementPropUtil();
		ConfigAndPlugin tempConfigAndPlugin = new ConfigAndPlugin();	
		MethodConfiguration tempConfig = UmaFactory.eINSTANCE.createMethodConfiguration();
		tempConfig.setName("Generated_Configuration");		//$NON-NLS-1$
		MethodPlugin tempPlugin = null;
		CustomCategory defaultView = null;
		proppUtil.setTransientElement(tempConfig, true);

		try {
			tempPlugin = LibraryServiceUtil.createMethodPlugin("viewPlugin", null, null, null); //$NON-NLS-1$
			proppUtil.setTransientElement(tempPlugin, true);
			tempConfigAndPlugin.plugin = tempPlugin;
			defaultView = createCustomCategory(tempPlugin, null, LibraryResources.configFreeProcessView_title);
			proppUtil.setTransientElement(defaultView, true);
			tempConfig.getMethodPluginSelection().add(tempPlugin);
			tempConfig.getMethodPackageSelection().addAll(UmaUtil.getAllMethodPackages(tempPlugin));
			tempConfig.getProcessViews().add(defaultView);
			tempConfig.setDefaultView(defaultView);
			
		} catch (Exception e) {
			LibraryPlugin.getDefault().getLogger().logError(e);
			return null;
		}

		Set<Task> taskSet = new HashSet<Task>();
		Set<Role> roleSet = new HashSet<Role>();
		Set<WorkProduct> wpSet = new HashSet<WorkProduct>();
		Set<Guidance> guidanceSet = new HashSet<Guidance>();
		
		Set<MethodPlugin> addedPlugins = new HashSet<MethodPlugin>();
		for (Process proc : configFreeProcesses) {
			Scope scope = ProcessScopeUtil.getInstance().loadScope(proc);
			if (scope == null) {
				continue;
			}
			for (MethodPlugin plugin : scope.getMethodPluginSelection()) {
				if (addedPlugins.contains(plugin)) {
					continue;
				}				
				addedPlugins.add(plugin);
				tempConfig.getMethodPluginSelection().add(plugin);
				tempConfig.getMethodPackageSelection().addAll(UmaUtil.getAllMethodPackages(plugin));
				for (TreeIterator it = plugin.eAllContents(); it.hasNext();) {
					Object obj = it.next();
					if (obj instanceof Task) {
						taskSet.add((Task) obj);
					} else if (obj instanceof Role) {
						roleSet.add((Role) obj);
					} else if (obj instanceof WorkProduct) {
						wpSet.add((WorkProduct) obj);
					} else if (obj instanceof Guidance) {
						guidanceSet.add((Guidance) obj);
					}
				}				
			}
		}
		
		createSubGroup(tempPlugin, defaultView, taskSet,  LibraryEditPlugin.INSTANCE.getString("_UI_Tasks_group"));//$NON-NLS-1$
		createSubGroup(tempPlugin, defaultView, roleSet, LibraryEditPlugin.INSTANCE.getString("_UI_Roles_group"));//$NON-NLS-1$
		createSubGroup(tempPlugin, defaultView, wpSet, LibraryEditPlugin.INSTANCE.getString("_UI_WorkProducts_group"));//$NON-NLS-1$
		createSubGroup(tempPlugin, defaultView, guidanceSet, LibraryEditPlugin.INSTANCE.getString("_UI_Guidances_group"));//$NON-NLS-1$
		createSubGroup(tempPlugin, defaultView, configFreeProcesses, LibraryEditPlugin.INSTANCE.getString("_UI_Processes_group"));//$NON-NLS-1$
				
		boolean oldDeliver = lib.eDeliver();
		lib.eSetDeliver(false);
		try {
			lib.getPredefinedConfigurations().add(tempConfig);
		} finally {
			if (oldDeliver) {
				lib.eSetDeliver(oldDeliver);
			}
		}
		
		LibraryService.getInstance().getConfigurationManager(tempConfig);
		
		tempConfigAndPlugin.config = tempConfig;
		tempConfigAndPlugin.plugin = null;
		
		return tempConfigAndPlugin;
	}

	private static void createSubGroup(MethodPlugin tempPlugin, CustomCategory defaultView,
			Collection<? extends DescribableElement> elements, String name) {
		MethodElementPropUtil propUtil = MethodElementPropUtil.getMethodElementPropUtil();
		if (elements != null && ! elements.isEmpty()) {
			CustomCategory cc = createCustomCategory(tempPlugin, defaultView, name);
			propUtil.setTransientElement(cc, true);
			cc.setBriefDescription(LibraryResources.systemCreatedCustomCategory_brief);
			cc.getCategorizedElements().addAll(elements);
		}
	}
	
	public static void removeTempConfigAndPluginFromCurrentLibrary(
			ConfigAndPlugin tempConfigAndPlugin) {
		if (tempConfigAndPlugin == null) {
			return;
		}
		MethodConfiguration tempConfig = tempConfigAndPlugin.config;
		MethodPlugin tempPlugin = tempConfigAndPlugin.plugin;
		if (tempConfig == null && tempPlugin == null) {
			return;
		}
		
		MethodLibrary lib = LibraryService.getInstance()
				.getCurrentMethodLibrary();
		if (lib != null) {
			boolean oldDeliver = lib.eDeliver();
			lib.eSetDeliver(false);
			try {
				lib.getPredefinedConfigurations().remove(tempConfig);
				lib.getMethodPlugins().remove(tempPlugin);
			} finally {
				if (oldDeliver) {
					lib.eSetDeliver(oldDeliver);
				}
			}
		}
		LibraryService.getInstance().removeConfigurationManager(tempConfig);
	}
	
}