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

import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Set;

import org.eclipse.core.runtime.IStatus;
import org.eclipse.emf.common.notify.Adapter;
import org.eclipse.emf.common.util.TreeIterator;
import org.eclipse.emf.ecore.EAttribute;
import org.eclipse.emf.ecore.EObject;
import org.eclipse.emf.ecore.EReference;
import org.eclipse.emf.ecore.EStructuralFeature;
import org.eclipse.emf.ecore.ETypedElement;
import org.eclipse.emf.ecore.EcoreFactory;
import org.eclipse.emf.ecore.resource.Resource;
import org.eclipse.emf.ecore.util.EContentsEList;
import org.eclipse.emf.ecore.util.EcoreUtil;
import org.eclipse.epf.uma.Activity;
import org.eclipse.epf.uma.BreakdownElement;
import org.eclipse.epf.uma.ContentElement;
import org.eclipse.epf.uma.ContentPackage;
import org.eclipse.epf.uma.Diagram;
import org.eclipse.epf.uma.Discipline;
import org.eclipse.epf.uma.DisciplineGrouping;
import org.eclipse.epf.uma.Domain;
import org.eclipse.epf.uma.Guidance;
import org.eclipse.epf.uma.MethodElement;
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.Process;
import org.eclipse.epf.uma.ProcessComponent;
import org.eclipse.epf.uma.ProcessElement;
import org.eclipse.epf.uma.ProcessPackage;
import org.eclipse.epf.uma.Role;
import org.eclipse.epf.uma.RoleSet;
import org.eclipse.epf.uma.RoleSetGrouping;
import org.eclipse.epf.uma.Task;
import org.eclipse.epf.uma.UmaFactory;
import org.eclipse.epf.uma.UmaPackage;
import org.eclipse.epf.uma.VariabilityElement;
import org.eclipse.epf.uma.VariabilityType;
import org.eclipse.epf.uma.WorkBreakdownElement;
import org.eclipse.epf.uma.WorkOrder;
import org.eclipse.epf.uma.WorkProduct;
import org.eclipse.epf.uma.WorkProductType;

/**
 * Utility class for accessing and updating the UMA model objects.
 * 
 * @author Phong Nguyen Le
 * @author Kelvin Low
 * @since 1.0
 */
public class UmaUtil {

	public static EReference createReference(String name) {
		EReference ref =  EcoreFactory.eINSTANCE.createEReference();
		ref.eSetDeliver(false);
		ref.setName(name);
		ref.setContainment(false);
		ref.setUpperBound(ETypedElement.UNBOUNDED_MULTIPLICITY);
		return ref;
	}
	
	public static EAttribute createAttribute(String name) {
		EAttribute att =  EcoreFactory.eINSTANCE.createEAttribute();
		att.eSetDeliver(false);
		att.setName(name);
		return att;
	}
	
	public static EReference MethodElement_UdtList = EcoreFactory.eINSTANCE.createEReference();
	public static final String Unresolved = "unresolved";		//$NON-NLS-1$
	static {
		MethodElement_UdtList.setName("MethodElement_UdtList");		//$NON-NLS-1$
	}
	
	private static IUmaUtilProvider provider;
	public static Set<String> unresolvedGuidSet = new HashSet<String>();
	
	private static IUmaUtilProvider getProvider() {
		return provider;
	}

	public static void setProvider(IUmaUtilProvider provider) {
		UmaUtil.provider = provider;
	}

	public static void setUnresolved(MethodElement element) {
		element.setName(Unresolved);
	}
	
	public static boolean isUnresolved(MethodElement element) {
		return element.getName() == Unresolved;
	}
	
	/**
	 * Replaces the feature values of an old method element with the
	 * corresponding feature values of a new method element.
	 * <p>
	 * Note: All features are updated except for the GUID feature.
	 * 
	 * @param oldElement
	 *            the old method element
	 * @param newElement
	 *            the new method element
	 */
	public static void replace(MethodElement oldElement,
			MethodElement newElement) {
		List features = oldElement.eClass().getEAllStructuralFeatures();
		if (features != null) {
			int size = features.size();
			for (int i = 0; i < size; i++) {
				EStructuralFeature feature = (EStructuralFeature) features
						.get(i);
				if (feature != UmaPackage.eINSTANCE.getMethodElement_Guid()) {
					// don't replace GUID
					Object newValue = newElement.eGet(feature);
					oldElement.eSet(feature, newValue);
				}
			}
		}

	}

	/**
	 * Checks whether a model object has a direct resource.
	 * 
	 * @param e
	 *            a model object
	 * @return <code>true</code> if the specified model object is contained by
	 *         a resource
	 */
	public static boolean hasDirectResource(EObject e) {
		Resource resource = e.eResource();
		return (resource != null && resource.getContents().contains(e));
	}
	
	/**
	 * Gets all resources owned by the specified object.
	 * 
	 * @param e
	 * @return
	 */
	public static Collection<Resource> getResources(EObject e) {
		HashSet<Resource> resources = new HashSet<Resource>();
		getResources(e, resources);
		return resources;
	}
	
	public static void getResources(EObject e, Collection<Resource> resources) {
		if (UmaUtil.hasDirectResource(e)) {
			resources.add(e.eResource());
		} else {
			for (Iterator iter = e.eContents().iterator(); iter.hasNext();) {
				getResources((EObject) iter.next(), resources);
			}
		}
	}

	/**
	 * Gets a specific type of adapter associated with a notifier.
	 * 
	 * @param eObj
	 *            a notifier
	 * @param cls
	 *            the adapter class
	 * @return an <code>Adapter<code> object or <code>null</code>
	 */
	public static Object getAdapter(EObject eObj, Class cls) {
		for (Iterator adapters = eObj.eAdapters().iterator(); adapters
				.hasNext();) {
			Adapter adapter = (Adapter) adapters.next();
			if (cls.isInstance(adapter)) {
				return adapter;
			}
		}
		return null;
	}
	
	/**
	 * Removes all adapters of the specified object and all of its children.
	 * 
	 * @param eObject
	 */
	public static void removeAllAdapters(EObject eObject) {
		for (TreeIterator<EObject> iter = eObject.eAllContents(); iter.hasNext();) {
			EObject o = iter.next();
			o.eAdapters().clear();
		}
	}

	/**
	 * Gets the method package with a specific name.
	 * 
	 * @param methodPackages
	 *            a list of method packages
	 * @param name
	 *            a method package name
	 * @return a method package with the matching name or <code>null</code>
	 */
	public static MethodPackage findMethodPackage(List methodPackages,
			String name) {
		for (int i = methodPackages.size() - 1; i > -1; i--) {
			Object obj = methodPackages.get(i);
			if (obj instanceof MethodPackage) {
				MethodPackage pkg = (MethodPackage) obj;
				if (name.equals(pkg.getName())) {
					return pkg;
				}
			}
		}
		return null;
	}

	/**
	 * Gets the method package with a specific path.
	 * 
	 * @param methodPlugin
	 *            a method plug-in
	 * @param path
	 *            an array of method element path fragments
	 * @return a method package with the matching path or <code>null</code>
	 */
	public static MethodPackage findMethodPackage(MethodPlugin methodPlugin,
			String[] path) {
		MethodPackage pkg = null;
		List list = methodPlugin.getMethodPackages();
		for (int i = 0; i < path.length; i++) {
			pkg = findMethodPackage(list, path[i]);
			if (pkg == null) {
				return null;
			}
			list = pkg.getChildPackages();
		}
		return pkg;
	}

	/**
	 * Gets the parent activity of a breakdown element.
	 * 
	 * @param e
	 *            a breakdown element
	 * @return the parent activity or <code>null</code>
	 */
	public static Activity getParentActivity(BreakdownElement e) {
		return e.getSuperActivities();
	}

	/**
	 * Gets the parent activity of a work order.
	 * 
	 * @param workOrder
	 *            a work order
	 * @return the parent activity or <code>null</code>
	 */
	public static Activity getOwningActivity(WorkOrder workOrder) {
		ProcessPackage pkg = (ProcessPackage) workOrder.eContainer();
		for (Iterator iter = pkg.getProcessElements().iterator(); iter
				.hasNext();) {
			Object element = iter.next();
			if (element instanceof Activity) {
				return (Activity) element;
			}
		}
		return null;
	}

	/**
	 * Gets the content package with a specific name.
	 * 
	 * @param methodPackages
	 *            a list of method packages
	 * @param name
	 *            a content package name
	 * @return a content package with the mathcing name or <code>null</code>
	 */
	public static ContentPackage findContentPackage(List methodPackages,
			String name) {
		for (int i = methodPackages.size() - 1; i > -1; i--) {
			Object obj = methodPackages.get(i);
			if (obj instanceof ContentPackage) {
				ContentPackage pkg = (ContentPackage) obj;
				if (name.equals(pkg.getName())) {
					return pkg;
				}
			}
		}
		return null;
	}

	/**
	 * Returns the content package with a specific path.
	 * 
	 * @param methodPlugin
	 *            a method plug-in
	 * @param path
	 *            an array of method element path fragments
	 * @return a content package with the matching path or <code>null</code>
	 */
	public static ContentPackage findContentPackage(MethodPlugin methodPlugin,
			String[] path) {
		ContentPackage pkg = null;
		List list = methodPlugin.getMethodPackages();
		for (int i = 0; i < path.length; i++) {
			pkg = findContentPackage(list, path[i]);
			if (pkg == null) {
				return null;
			}
			list = pkg.getChildPackages();
		}
		return pkg;
	}

	/**
	 * Gets the parent method plug-in of a method element.
	 * 
	 * @param element
	 *            a Method element
	 * @return the parent method plug-in or <code>null</code>
	 */
	public static MethodPlugin getMethodPlugin(EObject element) {
		for (EObject obj = element; obj != null; obj = obj.eContainer()) {
			if (obj instanceof MethodPlugin) {
				return (MethodPlugin) obj;
			}
		}
		return null;
	}

	/**
	 * Gets the parent method library of a method element.
	 * 
	 * @param element
	 *            a method element
	 * @return the parent method library or <code>null</code>
	 */
	public static MethodLibrary getMethodLibrary(EObject element) {
		for (EObject obj = element; obj != null; obj = obj.eContainer()) {
			if (obj instanceof MethodLibrary) {
				return (MethodLibrary) obj;
			}
		}
		return null;
	}
	
	public static EObject getTopContainer(EObject element) {
		EObject container = null;
		for (EObject obj = element.eContainer(); obj != null; obj = obj.eContainer()) {
			container = obj;
		}
		return container;		
	}

	/**
	 * Gets the parent content package of a content element.
	 * 
	 * @param element
	 *            a content element
	 * @return the parent content package or <code>null</code>
	 */
	public static ContentPackage getContentPackage(EObject element) {
		for (EObject obj = element; obj != null; obj = obj.eContainer()) {
			if (obj instanceof ContentPackage) {
				return (ContentPackage) obj;
			}
		}
		return null;
	}

	/**
	 * Gets the parent process package of a process element.
	 * 
	 * @param element
	 *            a Process element
	 * @return the parent process package or <code>null</code>
	 */
	public static ProcessPackage getProcessPackage(EObject element) {
		for (EObject obj = element; obj != null; obj = obj.eContainer()) {
			if (obj instanceof ProcessPackage) {
				return (ProcessPackage) obj;
			}
		}
		return null;
	}

	/**
	 * Gets the parent diagram of a diagram element.
	 * 
	 * @param element
	 *            a diagram element
	 * @return the parent diagram or <code>null</code>
	 */
	public static Diagram getDiagram(EObject element) {
		for (EObject obj = element; obj != null; obj = obj.eContainer()) {
			if (obj instanceof Diagram) {
				return (Diagram) obj;
			}
		}
		return null;
	}

	/**
	 * Checks whether a method element is contained by a specific content
	 * package.
	 * 
	 * @param element
	 *            a method element
	 * @param contentPackage
	 *            a content package
	 * @return <code>true</code> if the method element is contained by the
	 *         content package
	 */
	public static boolean isContainedByContentPackage(EObject element,
			ContentPackage contentPackage) {
		return isContainedBy(element, contentPackage);
	}

	/**
	 * Checks whether a model object is contained by a specific container.
	 * 
	 * @param eObj
	 *            a model object
	 * @param container
	 *            a container
	 * @return <code>true</code> if the model object is contained by the
	 *         container
	 */
	public static boolean isContainedBy(EObject eObj, Object container) {
		if (eObj == null) {
			return false;
		}
		for (EObject obj = eObj.eContainer(); obj != null; obj = obj
				.eContainer()) {
			if (obj == container) {
				return true;
			}
		}
		return false;
	}

	/**
	 * Generates and returns a unique ID.
	 * 
	 * @return a unique ID
	 */
	public static String generateGUID() {
		return EcoreUtil.generateUUID();
	}

	/**
	 * Creates and returns the content description name of a given method
	 * element.
	 * 
	 * @param element
	 *            a method element
	 * @return a suitable content description name
	 */
	public static String createContentDescriptionName(MethodElement e) {
		return e.getName() + ',' + e.getGuid();
	}

	public static void getAllSupers(List supers, VariabilityElement e,
			VariabilityType type) {
		VariabilityElement base = e.getVariabilityBasedOnElement();
		if (base != null && e.getVariabilityType() == type
				&& !supers.contains(base)) {
			supers.add(base);
			getAllSupers(supers, base, type);
		}
	}

	public static void getAllSupersBoth(List supers, VariabilityElement e,
			VariabilityType type1, VariabilityType type2) {
		VariabilityElement base = e.getVariabilityBasedOnElement();
		if (base != null
				&& (e.getVariabilityType() == type1 || e.getVariabilityType() == type2)
				&& !supers.contains(base)) {
			supers.add(base);
			getAllSupersBoth(supers, base, type1, type2);
		}
	}

	/**
	 * Gets the class of a content element.
	 * 
	 * @param contentElement
	 *            a content element
	 * @return the content element class
	 */
	public static Class getClassOfContentElement(ContentElement contentElement) {
		if (contentElement instanceof Role)
			return Role.class;
		if (contentElement instanceof Task)
			return Task.class;
		if (contentElement instanceof WorkProduct)
			return WorkProduct.class;
		if (contentElement instanceof Guidance)
			return Guidance.class;
		if (contentElement instanceof Domain)
			return Domain.class;
		if (contentElement instanceof Discipline)
			return Discipline.class;
		if (contentElement instanceof DisciplineGrouping)
			return DisciplineGrouping.class;
		if (contentElement instanceof RoleSet)
			return RoleSet.class;
		if (contentElement instanceof RoleSetGrouping)
			return RoleSetGrouping.class;
		if (contentElement instanceof WorkProductType)
			return WorkProductType.class;
		return Object.class;
	}

	/**
	 * Creates a default work order for two work breakdown elements.
	 * 
	 * @param e
	 *            a work breakdown element
	 * @param predecessor
	 *            the predecessor work breakdown element
	 * @return the newly created work order
	 */
	public static WorkOrder createDefaultWorkOrder(WorkBreakdownElement succ,
			WorkBreakdownElement pred) {
		return createDefaultWorkOrder(succ, pred, true);
	}
	
	public static WorkOrder createDefaultWorkOrder(WorkBreakdownElement succ,
			WorkBreakdownElement pred, boolean link) {
		WorkOrder wo = UmaFactory.eINSTANCE.createWorkOrder();
		wo.setPred(pred);
		if(link) {
			succ.getLinkToPredecessor().add(wo);
		}
		return wo;
	}	

	/**
	 * Locates the work order associated with two work breakdown elements.
	 * 
	 * @param e
	 *            a work breakdown element
	 * @param predecessor
	 *            the predecessor work breakdown element
	 * @return a work order or <code>null</code>
	 */
	public static WorkOrder findWorkOrder(WorkBreakdownElement e,
			Object predecessor) {
		for (Iterator iter = e.getLinkToPredecessor().iterator(); iter
				.hasNext();) {
			WorkOrder workOrder = (WorkOrder) iter.next();
			if (workOrder.getPred() == predecessor)
				return workOrder;
		}

		return null;
	}
	
	/**
	 * Locates the work order associated with two work breakdown elements. If
	 * includeBase is true, will collect WorkOrder for base element of the
	 * predecessor as well.
	 * 
	 * @param e
	 * @param predecessor
	 * @param includeBase
	 * @return
	 */
	public static Collection<WorkOrder> findWorkOrder(WorkBreakdownElement e, WorkBreakdownElement predecessor, boolean includeBase) {
		if(!includeBase) {
			WorkOrder wo = findWorkOrder(e, predecessor);
			return (Collection<WorkOrder>) (wo == null ? Collections.emptyList() : Collections.singletonList(wo));
		}
		ArrayList<WorkOrder> workOrders = new ArrayList<WorkOrder>();
		collectWorkOrders(workOrders, e, predecessor);
		return workOrders;
	}
	
	/**
	 * Collects the WorkOrder objects associated between the specified work
	 * breakdown element <code>e</code> and the predecessor or any of its base elements.
	 * 
	 * @param workOrders
	 * @param e
	 * @param predecessor
	 */
	public static void collectWorkOrders(Collection<WorkOrder> workOrders,
			WorkBreakdownElement e, Object predecessor) {
		for (Iterator iter = e.getLinkToPredecessor().iterator(); iter
				.hasNext();) {
			WorkOrder workOrder = (WorkOrder) iter.next();
			if (workOrder.getPred() == predecessor) {
				workOrders.add(workOrder);
			}
		}
		if(predecessor instanceof VariabilityElement) {
			VariabilityElement ve = ((VariabilityElement)predecessor).getVariabilityBasedOnElement();
			if(ve != null) {
				collectWorkOrders(workOrders, e, ve);
			}
		}
	}

	/**
	 * Removes the work order associated with two work breakdown elements.
	 * 
	 * @param e
	 *            a work breakdown element
	 * @param predecessor
	 *            the predecessor work breakdown element
	 * @return the removed work order or <code>null</code>
	 */
	public static WorkOrder removeWorkOrder(WorkBreakdownElement e,
			Object predecessor) {
		for (Iterator iterator = e.getLinkToPredecessor().iterator(); iterator
				.hasNext();) {
			WorkOrder order = (WorkOrder) iterator.next();
			if (order.getPred() == predecessor) {
				iterator.remove();
				return order;
			}
		}
		return null;
	}

	/**
	 * Gets the parent process component of a method element.
	 * 
	 * @param e
	 *            a method element, typically a process element
	 * @return the parent process component or <code>null</code>
	 */
	public static ProcessComponent getProcessComponent(MethodElement e) {
		EObject container;
		for (container = e; container != null
				&& !(container instanceof ProcessComponent); container = container
				.eContainer())
			;
		if (container != null) {
			return ((ProcessComponent) container);
		}
		return null;
	}

	/**
	 * Gets the parent method unit of a method element.
	 * 
	 * @param e
	 *            a method element
	 * @return the parent method unit or <code>null</code>
	 */
	public static MethodUnit getMethodUnit(MethodElement e) {
		EObject container;
		for (container = e; container != null
				&& !(container instanceof MethodUnit); container = container
				.eContainer())
			;
		if (container != null) {
			return ((MethodUnit) container);
		}
		return null;

	}

	/**
	 * Checks whether a method plug-in has method elements that reference
	 * elements in a base plug-in.
	 * <p>
	 * Note: This is a expensive call to make for a large method plug-in.
	 * 
	 * @param plugin
	 *            a method plug-in
	 * @param base
	 *            a base method plug-in
	 * @return <code>true</code> if the specified method plug-in contain
	 *         method elements that reference elements in a base plug-in.
	 */
	public static boolean hasReference(MethodPlugin plugin, MethodPlugin base) {
		for (EContentsEList.FeatureIterator featureIterator = (EContentsEList.FeatureIterator) plugin
				.eCrossReferences().iterator(); featureIterator.hasNext();) {
			EObject ref = (EObject) featureIterator.next();
			EStructuralFeature f = featureIterator.feature();

			if (f != UmaPackage.eINSTANCE.getMethodPlugin_Bases()
					&& UmaUtil.getMethodPlugin(ref) == base) {
				return true;
			}
		}

		for (Iterator iter = plugin.eAllContents(); iter.hasNext();) {
			EObject element = (EObject) iter.next();

			// ignore ProcessElement b/c it can references anything
			//
			if (element instanceof ProcessElement) {
				continue;
			}

			for (Iterator iterator = element.eCrossReferences().iterator(); iterator
					.hasNext();) {
				EObject ref = (EObject) iterator.next();
				if (getMethodPlugin(ref) == base) {
					return true;
				}
			}
		}
		return false;
	}

	/**
	 * Removes all element references in a method plug-in that point to elements
	 * in a base plug-in.
	 * <p>
	 * Note: This is a expensive call to make for a large method plug-in.
	 * 
	 * @param plugin
	 *            a method plug-in
	 * @param base
	 *            the base method plug-in
	 * @return <code>true</code> if the operation is successful
	 */
	public static boolean removeReferences(MethodPlugin plugin,
			MethodPlugin base) {
		for (Iterator iter = plugin.eAllContents(); iter.hasNext();) {
			EObject element = (EObject) iter.next();

			// ignore ProcessElement b/c it can references anything
			//
			if (element instanceof ProcessElement) {
				continue;
			}

			for (EContentsEList.FeatureIterator featureIterator = (EContentsEList.FeatureIterator) element
					.eCrossReferences().iterator(); featureIterator.hasNext();) {
				EObject ref = (EObject) featureIterator.next();

				if (getMethodPlugin(ref) == base) {
					EStructuralFeature f = featureIterator.feature();
					if (f.isMany()) {
						((Collection) element.eGet(f)).remove(ref);
					} else {
						element.eSet(f, null);
					}
				}
			}
		}

		return false;
	}

	public static String getMessage(IStatus status) {
		String msg = status.getMessage();
		if (status.isMultiStatus()) {
			StringBuffer strBuf = new StringBuffer(msg);
			IStatus statuses[] = status.getChildren();
			for (int i = 0; i < statuses.length; i++) {
				strBuf.append('\n').append(statuses[i].getMessage());
			}
			msg = strBuf.toString();
		}
		if (msg != null && msg.trim().length() == 0) {
			msg = null;
		}
		return msg;
	}

	/**
	 * Generates a GUID using a base GUID.
	 * 
	 * @param baseGUID
	 *            a base GUID
	 * @return a unique ID
	 */
	public static final String generateGUID(String baseGUID) {
		return GUID.generate(baseGUID);
	}

	private static class GUID {
		private static MessageDigest md5 = null;

		private static MessageDigest getMD5() {
			if (md5 == null) {
				synchronized (GUID.class) {
					if (md5 == null) {
						try {
							md5 = MessageDigest.getInstance("MD5"); //$NON-NLS-1$
						} catch (NoSuchAlgorithmException e) {
							e.printStackTrace();
						}
					}
				}
			}
			return md5;
		}

		public static final String generate(String baseGUID) {
			MessageDigest md5 = getMD5();
			md5.update(baseGUID.getBytes());
			byte[] hash = md5.digest();
			char[] buffer = new char[23];
			buffer[0] = '-';

			// Do a base 64 conversion by turning every 3 bytes into 4 base 64
			// characters
			//
			for (int i = 0; i < 5; ++i) {
				buffer[4 * i + 1] = BASE64_DIGITS[(hash[i * 3] >> 2) & 0x3F];
				buffer[4 * i + 2] = BASE64_DIGITS[((hash[i * 3] << 4) & 0x30)
						| ((hash[i * 3 + 1] >> 4) & 0xF)];
				buffer[4 * i + 3] = BASE64_DIGITS[((hash[i * 3 + 1] << 2) & 0x3C)
						| ((hash[i * 3 + 2] >> 6) & 0x3)];
				buffer[4 * i + 4] = BASE64_DIGITS[hash[i * 3 + 2] & 0x3F];
			}

			// Handle the last byte at the end.
			//
			buffer[21] = BASE64_DIGITS[(hash[15] >> 2) & 0x3F];
			buffer[22] = BASE64_DIGITS[(hash[15] << 4) & 0x30];

			return new String(buffer);
		}

		private static final char[] BASE64_DIGITS = { 'A', 'B', 'C', 'D', 'E',
				'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q',
				'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z', 'a', 'b', 'c',
				'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o',
				'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z', '0',
				'1', '2', '3', '4', '5', '6', '7', '8', '9', '-', '_' };
	}
	
	public static void main(String[] args) {
		System.out.println(generateGUID());
	}
	
	public static boolean isSynFree() {
		IUmaUtilProvider p = getProvider();
		return p == null ? true : p.isSynFree();
	}
	
	public static boolean isSynFreeLibrary(MethodLibrary lib) {
		IUmaUtilProvider p = getProvider();
		return p == null ? true : p.isSynFreeLibrary(lib);
	}
	
	public static boolean isSynFreePlugin(MethodPlugin plugin) {
		IUmaUtilProvider p = getProvider();
		return p == null ? true : p.isSynFreePlugin(plugin);
	}
	
	public static boolean isSynFreeProcess(Process proc) {
		IUmaUtilProvider p = getProvider();
		return p == null ? true : p.isSynFreeProcess(proc);	
	}
	
	public static void setSynFreeLibrary(MethodLibrary lib, boolean value) {
		IUmaUtilProvider p = getProvider();
		if (p == null) {
			return;
		}
		p.setSynFreeLibrary(lib, value);
	}
	
	public static void setSynFreePlugin(MethodPlugin plugin, boolean value) {
		IUmaUtilProvider p = getProvider();
		if (p == null) {
			return;
		}
		p.setSynFreePlugin(plugin, value);
	}
	
	public static void setSynFreeProcess(Process proc, boolean value) {
		IUmaUtilProvider p = getProvider();
		if (p == null) {
			return;
		}
		p.setSynFreeProcess(proc, value);
	}
	
	public static boolean isInLibrary(MethodElement element) {
		if (element == null) {
			return false;
		}
		EObject cont = element.eContainer();
		while (cont instanceof MethodElement) {
			if (cont instanceof MethodLibrary) {
				return true;
			}
			cont = cont.eContainer();
		}
		
		return false;
	}
	
	public static Set<MethodPackage> getDecendentPackages(MethodPackage pkg) {		
		Set<MethodPackage> set = new HashSet<MethodPackage>();
		for (MethodPackage childPkg : pkg.getChildPackages()) {
			set.add(childPkg);
			set.addAll(getDecendentPackages(childPkg));
		}
		return set;
	}
	
	public static Set<MethodPackage> getAllMethodPackages(MethodPlugin plugin) {
		Set<MethodPackage> set = new HashSet<MethodPackage>();
		for (MethodPackage pkg : plugin.getMethodPackages()) {
			set.add(pkg);
			set.addAll(getDecendentPackages(pkg));
		}
		return set;
	}
	
	public static Process getProcess(MethodElement e) {
		ProcessComponent procComp = UmaUtil.getProcessComponent(e);
		if (procComp != null) {
			org.eclipse.epf.uma.Process proc = procComp.getProcess();
			return proc;
		}
		return null;
	}
	
	public static Scope getScope(Process proc) {
		if (proc == null || !(proc.getDefaultContext() instanceof Scope)) {
			return null;
		}
		
		Scope scope = (Scope) proc.getDefaultContext();		
		return scope;
	}
	
	public static boolean isConfigFree(Process process) {
		if (getScope(process) != null) {
			return true;
		}
	
		if (process.getDefaultContext() == null && process
						.getValidContext().isEmpty()) {
			return true;
		}
		if (! process.getValidContext().isEmpty()) {
			return process.getValidContext().get(0) instanceof Scope;
		}
				
		return false;
	}

}