//------------------------------------------------------------------------------
// Copyright (c) 2005, 2007 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
//------------------------------------------------------------------------------
//------------------------------------------------------------------------------
// Copyright (c) 2005, 2007 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.diagram.core.bridge;

import java.text.MessageFormat;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;

import org.eclipse.emf.common.util.EList;
import org.eclipse.emf.common.util.URI;
import org.eclipse.emf.ecore.EAnnotation;
import org.eclipse.emf.ecore.EClass;
import org.eclipse.emf.ecore.EModelElement;
import org.eclipse.emf.ecore.EObject;
import org.eclipse.emf.ecore.EcoreFactory;
import org.eclipse.emf.ecore.resource.Resource;
import org.eclipse.emf.ecore.resource.ResourceSet;
import org.eclipse.emf.ecore.util.EcoreUtil;
import org.eclipse.epf.diagram.core.DiagramCorePlugin;
import org.eclipse.epf.diagram.model.DiagramResources;
import org.eclipse.epf.diagram.model.LinkedObject;
import org.eclipse.epf.diagram.model.NamedNode;
import org.eclipse.epf.diagram.model.Node;
import org.eclipse.epf.library.edit.util.ProcessUtil;
import org.eclipse.epf.library.edit.util.Suppression;
import org.eclipse.epf.library.edit.util.TngUtil;
import org.eclipse.epf.library.persistence.ILibraryResource;
import org.eclipse.epf.uma.BreakdownElement;
import org.eclipse.epf.uma.DescribableElement;
import org.eclipse.epf.uma.Iteration;
import org.eclipse.epf.uma.MethodElement;
import org.eclipse.epf.uma.Milestone;
import org.eclipse.epf.uma.Phase;
import org.eclipse.epf.uma.Process;
import org.eclipse.epf.uma.ProcessElement;
import org.eclipse.epf.uma.ProcessPackage;
import org.eclipse.epf.uma.TaskDescriptor;
import org.eclipse.epf.uma.UmaFactory;
import org.eclipse.epf.uma.UmaPackage;
import org.eclipse.epf.uma.VariabilityElement;
import org.eclipse.epf.uma.WorkBreakdownElement;
import org.eclipse.epf.uma.WorkOrder;
import org.eclipse.gmf.runtime.emf.type.core.IElementType;
import org.eclipse.gmf.runtime.notation.Diagram;
import org.eclipse.gmf.runtime.notation.View;
import org.eclipse.uml2.uml.Activity;
import org.eclipse.uml2.uml.ActivityEdge;
import org.eclipse.uml2.uml.ActivityNode;
import org.eclipse.uml2.uml.ActivityPartition;
import org.eclipse.uml2.uml.ControlNode;
import org.eclipse.uml2.uml.ForkNode;
import org.eclipse.uml2.uml.JoinNode;

/**
 * @author Phong Nguyen Le
 * @author Shilpa Toraskar
 * 
 * @since 1.2
 */
public final class BridgeHelper {

	public static final String UMA_ELEMENT = "uma_element"; //$NON-NLS-1$

	public static final String UMA_URI = "uri"; //$NON-NLS-1$
	
	public static final String UMA_TYPE = "type"; //$NON-NLS-1$
	
	public static final String UMA_PHASE = "Phase"; //$NON-NLS-1$
	
	public static final String UMA_ITERATION = "Iteration"; //$NON-NLS-1$
	
	public static final String UMA_ACTIVITY = "Activity"; //$NON-NLS-1$
	
	public static final String UMA_TASK_DESCRIPTOR = "Task"; //$NON-NLS-1$
	
	public static final String UMA_MILESTONE = "Milestone"; //$NON-NLS-1$
	
	public static final String ANNOTATION_INHERIRED = "inherited"; //$NON-NLS-1$
	
	public static List<IElementType> elementTypes = new ArrayList<IElementType>();
	
	public static Map<String, EClass> typeStringToEClass = new HashMap<String, EClass>();
	
	private static final boolean DEBUG = DiagramCorePlugin.getDefault().isDebugging();
	
	static {
		typeStringToEClass.put(UMA_PHASE, UmaPackage.Literals.PHASE);
		typeStringToEClass.put(UMA_ITERATION, UmaPackage.Literals.ITERATION);
		typeStringToEClass.put(UMA_ACTIVITY, UmaPackage.Literals.ACTIVITY);
		typeStringToEClass.put(UMA_TASK_DESCRIPTOR, UmaPackage.Literals.TASK_DESCRIPTOR);
		typeStringToEClass.put(UMA_MILESTONE, UmaPackage.Literals.MILESTONE);
	}
	
	public static void setSemanticModel(ActivityEdge link, WorkOrder workOrder) {
		// TODO Auto-generated method stub
	}

	public static boolean isReadOnly(View view) {
		NodeAdapter nodeAdapter = BridgeHelper
				.getNodeAdapter(view.getElement());
		if(nodeAdapter != null) {
			return nodeAdapter.isTargetReadOnly();
		}
		if(view.getElement() instanceof Node) {
			return ((Node)view.getElement()).isReadOnly();
		}
		
		return false;
	}
	
	/**
	 * Gets the method element that the given view represents.
	 * 
	 * @param node
	 * @return method element that the view is representing or <code>null</code>
	 *         if the view does not represent any method element or the diagram
	 *         of the view currently is not opened in a diagram editor.
	 */
	public static MethodElement getMethodElement(View view) {
		return getMethodElement(view.getElement());
	}	
	
	/**
	 * Gets the method element that the given diagram model object represents.
	 * 
	 * @param modelObject
	 * @return method element that the model object is representing or <code>null</code>
	 *         if the model object does not represent any method element or the diagram
	 *         of the model object currently is not opened in a diagram editor.
	 */
	public static MethodElement getMethodElement(EObject modelObject) {
		if(modelObject instanceof LinkedObject) {
			return ((LinkedObject)modelObject).getLinkedElement();
		}
		else if(modelObject instanceof EModelElement) {
			return getMethodElement((EModelElement) modelObject);
		}
		return null;
	}
	
	public static MethodElement getMethodElement(View view, org.eclipse.epf.uma.Activity owner) {
		EObject modelObject = view.getElement();
		if(modelObject instanceof LinkedObject) {
			return ((LinkedObject)modelObject).getLinkedElement();
		}
		else if(modelObject instanceof EModelElement) {
			Resource resource = owner.eResource();
			if(resource != null && resource.getResourceSet() != null) {
				return getMethodElementFromAnnotation((EModelElement) modelObject, resource.getResourceSet());
			}
		}
		return null;
	}
	
	public static boolean isSuppressed(View view) {
		EObject element = view.getElement();
		if(element instanceof NamedNode) {
			return ((NamedNode)element).isSuppressed();
		}
		else if(element instanceof EModelElement) {
			NodeAdapter nodeAdapter = getNodeAdapter(element);
			if(nodeAdapter != null) {
				Object o = nodeAdapter.getWrapper();
				if(o == null) {
					o = nodeAdapter.getElement();
				}
				org.eclipse.epf.uma.Activity activity = (org.eclipse.epf.uma.Activity) getMethodElement(view.getDiagram());
				Process proc = TngUtil.getOwningProcess(activity);
				Suppression suppression = Suppression.getSuppression(proc);
				return suppression.isSuppressed(o);
			}
		}
		return false;
	}
	
//	public static Object getSemanticModel(View view) {
//		EObject element = view.getElement();
//		if(element instanceof EModelElement) {
//			return getSemanticModelFromAnnotation(element, process, adapterFactory);
//		}
//		else if(element instanceof )
//			
//		}
//	}
	
	public static void removeLink(ActivityEdge link) {
		// TODO: still need to disable notification before removing link???
		Activity activity = link.getActivity();
		ActivityNode sourceNode = link.getSource();
		ActivityNode targetNode = link.getTarget();
		boolean srcNotify = sourceNode != null ? sourceNode.eDeliver() : false;
		boolean targetNotify = targetNode != null ? targetNode.eDeliver()
				: false;
		try {
			if (sourceNode != null) {
				sourceNode.eSetDeliver(false);
			}
			if (targetNode != null) {
				targetNode.eSetDeliver(false);
			}
			link.setSource(null);
			link.setTarget(null);
			if(activity != null){
				activity.getEdges().remove(link);
			}
		} finally {
			if (sourceNode != null) {
				sourceNode.eSetDeliver(srcNotify);
			}
			if (targetNode != null) {
				targetNode.eSetDeliver(targetNotify);
			}
		}
	}

	/**
	 * Finds node whose linked object or one of its base is the given object
	 * 
	 * @param container
	 * @param object
	 * @return
	 */
	public static ActivityNode findNode(Activity container, Object object,
			boolean checkBase) {
		for (Iterator iter = container.getNodes().iterator(); iter.hasNext();) {
			ActivityNode node = (ActivityNode) iter.next();
			MethodElement e = BridgeHelper.getMethodElement(node);
			if (object == e) {
				return node;
			} else if (checkBase && e instanceof VariabilityElement) {
				for (VariabilityElement ve = ((VariabilityElement) e)
						.getVariabilityBasedOnElement(); ve != null; ve = ve
						.getVariabilityBasedOnElement()) {
					if (ve == object) {
						return node;
					}
				}
			}
		}
		return null;
	}

	public static boolean isSynchBar(ActivityNode node) {
		return node instanceof ForkNode || node instanceof JoinNode;
	}

	/**
	 * Finds node whose linked object is the given object
	 * 
	 * @return
	 */
	public static ActivityNode findNode(Activity container, Object object) {
		for (Iterator iter = container.getNodes().iterator(); iter.hasNext();) {
			ActivityNode node = (ActivityNode) iter.next();
			if (object == BridgeHelper.getMethodElement(node)) {
				return node;
			}
		}
		return null;
	}

	public static URI getProxyURI(MethodElement e) {
		Resource resource = e.eResource();
		if (resource instanceof ILibraryResource) {
			return ((ILibraryResource) resource).getProxyURI(e);
		} else if (resource != null) {
			return resource.getURI().appendFragment(e.getGuid());
		}
		return null;
	}
	
	/**
	 * Associates a {@link EModelElement} with a {@link MethodElement} by
	 * creating or updating the UMA_ELEMENT annotation of the given
	 * {@link EModelElement}.
	 * 
	 * @param element
	 * @param me
	 * @return true if successful, false otherwise
	 * @see #addEAnnotation(EModelElement, MethodElement)
	 */
	public static boolean associate(EModelElement element, MethodElement me) {
		EAnnotation annotation = addEAnnotation(element, me);
		if(annotation != null) {
			String type = getType(me);
			if(type != null) {
				annotation.getDetails().put(UMA_TYPE, type);
			}
			return true;
		}
		return false;
	}
	
	public static EClass getType(String type) {
		return typeStringToEClass.get(type);
	}
	
	public static String getType(MethodElement me) {
		if(me instanceof Phase) {
			return UMA_PHASE;
		}
		else if(me instanceof Iteration) {
			return UMA_ITERATION;
		}
		else if(me instanceof Milestone) {
			return UMA_MILESTONE;
		}
		else if(me instanceof org.eclipse.epf.uma.Activity) {
			return UMA_ACTIVITY;
		}
		else if(me instanceof TaskDescriptor) {
			return UMA_TASK_DESCRIPTOR;
		}
		return null;
	}
	
//	/**
//	 * Creates or updates the UMA_ELEMENT annotation for the given
//	 * {@link EModelElement} with the given method element or its wrapper
//	 * 
//	 * @param element
//	 * @param me
//	 * @return
//	 */
//	public static EAnnotation addEAnnotation(EModelElement element, Object breakdownElementOrWrapper) {
//		String uriStr = null;
//		if(breakdownElementOrWrapper instanceof MethodElement) {
//			URI uri = getProxyURI((MethodElement) breakdownElementOrWrapper);
//			if(uri != null) {
//				uriStr = uri.toString();
//			}
//		}
//		else if(breakdownElementOrWrapper instanceof BreakdownElementWrapperItemProvider){
//			uriStr = Suppression.getPath((BreakdownElementWrapperItemProvider) breakdownElementOrWrapper);
//		}
//		if(uriStr != null) {
//			EAnnotation eAnnotation = element.getEAnnotation(UMA_ELEMENT);
//			if (eAnnotation == null) {
//				eAnnotation = EcoreFactory.eINSTANCE.createEAnnotation();
//				eAnnotation.setSource(UMA_ELEMENT);
//				element.getEAnnotations().add(eAnnotation);
//			}
//			eAnnotation.getDetails().put(UMA_URI, uriStr);
//			return eAnnotation;
//		}
//		return null;
//	}
	
	/**
	 * Creates or updates the UMA_ELEMENT annotation for the given
	 * {@link EModelElement} with the given method element
	 * 
	 * @param element
	 * @param me
	 * @return
	 */
	public static EAnnotation addEAnnotation(EModelElement element,
			MethodElement me) {
		URI uri = getProxyURI(me);
		if (uri != null) {
			EAnnotation eAnnotation = element.getEAnnotation(UMA_ELEMENT);
			if (eAnnotation == null) {
				eAnnotation = EcoreFactory.eINSTANCE.createEAnnotation();
				eAnnotation.setSource(UMA_ELEMENT);
				element.getEAnnotations().add(eAnnotation);
			}
			eAnnotation.getDetails().put(UMA_URI, uri.toString());
			return eAnnotation;
		}
		return null;
	}

	private static Activity getActivity(EModelElement e) {
		EObject o = e;
		for(; o != null && !(o instanceof Activity); o = o.eContainer());
		return (Activity) o;
	}
	
//	public static Object getSemanticModelFromAnnotation(EModelElement model, Process process, AdapterFactory adapterFactory) {
//		EAnnotation eAnnotation = model.getEAnnotation(UMA_ELEMENT);
//		if (eAnnotation != null) {
//			String uriStr = (String) eAnnotation.getDetails().get(UMA_URI);
//			if (uriStr != null) {
//				URI uri = URI.createURI(uriStr);
//				if(MultiFileURIConverter.SCHEME.equals(uri.scheme())) {
//					EObject o = process.eResource().getResourceSet().getEObject(uri, false);
//					if (o instanceof MethodElement) {
//						return (MethodElement) o;
//					} else {
//						// TODO: log error
//						System.err.println("Not a method element: " + o); //$NON-NLS-1$
//					}
//				}
//				else {
//					// must be a wrapper path
//					//
//					String[] guidPath = uri.segments();
//					return Suppression.getSuppression(process).getObjectByPath(guidPath, adapterFactory);
//				}
//			}
//		}
//		return null;
//	}
	
	public static MethodElement getMethodElementFromAnnotation(EModelElement node, ResourceSet resourceSet) {
		EAnnotation eAnnotation = node.getEAnnotation(UMA_ELEMENT);
		if (eAnnotation != null) {
			String uri = (String) eAnnotation.getDetails().get(UMA_URI);
			if (uri != null) {
				EObject o = resourceSet.getEObject(
						URI.createURI(uri), false);
				if (o instanceof MethodElement) {
					return (MethodElement) o;
				} else {
					if(DEBUG) {
						System.err.println("Not a method element: " + o); //$NON-NLS-1$
					}
				}
			}
		}
		return null;
	}
	
	/**
	 * Gets the method element that the given diagram model object represents
	 * and stores the linkage info in its annotation.
	 * 
	 * @param node
	 *            the diagram model object
	 * @return method element that the model object is representing or
	 *         <code>null</code> if the model object does not represent any
	 *         method element or the diagram of the model object currently is
	 *         not opened in a diagram editor.
	 */
	public static MethodElement getMethodElementFromAnnotation(EModelElement node) {		
		Activity diagram = getActivity(node);
		if(diagram == null) {
			return null;
		}
		NodeAdapter nodeAdapter = getNodeAdapter(diagram);
		if(nodeAdapter == null || nodeAdapter.getElement() == null) {
			return null;
		}
		Resource resource = nodeAdapter.getElement().eResource();
		if (resource != null && resource.getResourceSet() != null) {
			return getMethodElementFromAnnotation(node, resource.getResourceSet());
		}
		return null;
	}
	
	public static MethodElement getMethodElement(EModelElement node) {
		NodeAdapter nodeAdapter = BridgeHelper.getNodeAdapter(node);
		return nodeAdapter != null ? nodeAdapter.getElement()
				: getMethodElementFromAnnotation(node);
	}

	public static NodeAdapter getNodeAdapter(EObject node) {
		if (node != null) {
			for (Iterator iter = node.eAdapters().iterator(); iter.hasNext();) {
				Object adapter = (Object) iter.next();
				if (adapter instanceof NodeAdapter) {
					return (NodeAdapter) adapter;
				}
			}
		}
		return null;
	}
	
	public static DiagramAdapter getDiagramAdapter(EObject node) {
		for (Iterator iter = node.eAdapters().iterator(); iter.hasNext();) {
			Object adapter = (Object) iter.next();
			if (adapter instanceof DiagramAdapter) {
				return (DiagramAdapter) adapter;
			}
		}
		return null;
	}

	/**
	 * Method to get the sources of SyncBar (ForkNode or JoinNode) inComming
	 * connections and if syncbar have incoming connection from decision point,
	 * and decision point have incomming connections (workbreaddown elemtns)
	 * collections will ignore all the incoming connection from decision point.
	 * @return
	 */
	public static void getSyncBarSourceNodes(ActivityNode node,
			Collection actNodes) {
		for (Iterator iter = node.getIncomings().iterator(); iter.hasNext();) {
			ActivityEdge link = (ActivityEdge) iter.next();
			ActivityNode source = link.getSource();
			if (getMethodElement(source) instanceof WorkBreakdownElement) {
				actNodes.add(source);
			} else if (isSynchBar(source)) {
				getSyncBarSourceNodes(source, actNodes);
			}
		}
	}

	/**
	 * Gets all nodes with the given type that are direct or indirect targets of
	 * the given node.
	 * 
	 * @param actNodes
	 * @param node
	 * @param type
	 *            the type of method element associated with the view
	 */
	public static void getTargetNodes(Collection actNodes, ActivityNode node,
			Class type) {
		if (node != null) {
			for (Iterator iter = node.getOutgoings().iterator(); iter.hasNext();) {
				ActivityEdge link = (ActivityEdge) iter.next();
				ActivityNode target = link.getTarget();
				if (type.isInstance(getMethodElement(target))) {
					actNodes.add(target);
				} else if (target instanceof ControlNode) {
					getTargetNodes(actNodes, target, type);
				}
			}
		}
	}
	
	public static void getSuccessorNodes(Collection<ActivityNode> actNodes, ActivityNode node) {
		if (node != null) {
			for (ActivityEdge link : node.getOutgoings()) {
				ActivityNode target = link.getTarget();
				if (getMethodElement(target) instanceof WorkBreakdownElement) {
					actNodes.add(target);
				} else if (isSynchBar(target)) {
					getSuccessorNodes(actNodes, target);
				}
			}
		}		
	}
	
	public static void getPredecessorNodes(Collection<ActivityNode> actNodes, ActivityNode node) {
		if (node != null) {
			for (ActivityEdge link : node.getIncomings()) {
				ActivityNode source = link.getSource();
				if (getMethodElement(source) instanceof WorkBreakdownElement) {
					actNodes.add(source);
				} else if (isSynchBar(source)) {
					getPredecessorNodes(actNodes, source);
				}
			}
		}		
	}
	
	/**
	 * Gets all nodes with the given type that are direct or indirect sources of
	 * the given node.
	 * 
	 * @param actNodes
	 * @param node
	 * @param type
	 *            the type of method element associated with the view
	 */

	public static void getSourceNodes(Collection actNodes, ActivityNode node,
			Class type) {
		if (node != null) {
			for (Iterator iter = node.getIncomings().iterator(); iter.hasNext();) {
				ActivityEdge link = (ActivityEdge) iter.next();
				ActivityNode source = link.getSource();
				if (type.isInstance(getMethodElement(source))) {
					actNodes.add(source);
				} else if (source instanceof ControlNode) {
					getSourceNodes(actNodes, source, type);
				}
			}
		}
	}
	
	/*
	 * Method to collect synchronization bar outgoing connection
	 * except any connection going to decision points.  
	 */
	public static void getSyncBarTargetNodes(ActivityNode typedNode, Collection actNodes){
		for (Iterator iter = typedNode.getOutgoings().iterator(); iter.hasNext();) {
				ActivityEdge link = (ActivityEdge) iter.next();
				ActivityNode target = link.getTarget();
				if(BridgeHelper.getMethodElement(target) instanceof WorkBreakdownElement){
					actNodes.add(target);
				} else if (isSynchBar(target)) {
					getSyncBarTargetNodes(target, actNodes);
				}
		}
	}
	
	/**
	 * Method to check before deleting a link. If duplicate predecessor exists
	 * in the legacy data, check if deleting link should remove all the
	 * predecessors or not by verifying if target or indirect target have direct
	 * or indirect links.
	 */
	public static boolean canRemoveAllPreds(ActivityEdge link, ActivityNode oldSource,
			ActivityNode oldTarget) {
		MethodElement targetElement = getMethodElement(oldTarget);
		if (targetElement instanceof WorkBreakdownElement) {
			List inlist = oldTarget.getIncomings();
			for (Iterator itor = inlist.iterator(); itor.hasNext();) {
				ActivityEdge incominglink = (ActivityEdge) itor.next();
				// RATLC00384245 : Predecessor changes should be done only in
				// case of Synchronization Bar.
				if (isSynchBar(incominglink.getSource())) {
					Collection col = new ArrayList(); 
					getSourceNodes(col, incominglink.getSource(),
							WorkBreakdownElement.class);
					if (col.contains(oldSource)) {
						return false;
					}
				} else if (incominglink.getSource() != null &&
						getMethodElement(incominglink.getSource()) instanceof WorkBreakdownElement) {
					if (incominglink.getSource().equals(oldSource))
						return false;
				}
			}
		}
		return true;
	}
	
	public static void markInherited(EModelElement element) {
		EAnnotation eAnnotation = element.getEAnnotation(ANNOTATION_INHERIRED);
		if (eAnnotation == null) {
			eAnnotation = EcoreFactory.eINSTANCE.createEAnnotation();
			eAnnotation.setSource(ANNOTATION_INHERIRED);
			element.getEAnnotations().add(eAnnotation);
		}
	}
	public static void unmarkInHerited(EModelElement element) {
		EAnnotation eAnnotation = element.getEAnnotation(ANNOTATION_INHERIRED);
		if (eAnnotation != null) {
			element.getEAnnotations().remove(eAnnotation);
		}
	}
	

	public static Diagram copyDiagram(Diagram baseDiagram) {
		Diagram copy = (Diagram) EcoreUtil.copy(baseDiagram);

		// HACK:
		// go thru the nodes of the diagram copy, if any node is a UI-only node
		// (see TypedNode)
		// save the GUID of the original one in its briefDescription to remember
		// who is base.
		//
//		int size = copy.getContained().size();
//		for (int i = 0; i < size; i++) {
//			GraphNode gNode = (GraphNode) copy.getContained().get(i);
//			if (GraphicalDataHelper.isUIGraphNode(gNode)) {
//				gNode.setBriefDescription(((DiagramElement) baseDiagram
//						.getContained().get(i)).getGuid());
//			}
//		}
		List children = copy.getChildren();
		int size = children.size();		
		for (int i = 0; i < size; i++) {
			View view = (View) children.get(i);
			markInherited(view);
		}

		return copy;
	}

	public static EList addEAnnotationDetail(EModelElement element, String detailName, String detailValue ) {
		EAnnotation eAnnotation = element.getEAnnotation(UMA_ELEMENT);
		if (eAnnotation == null) {
			eAnnotation = EcoreFactory.eINSTANCE.createEAnnotation();
			eAnnotation.setSource(UMA_ELEMENT);
			// detail must be put before the new annotation can be added to the annotation list
			// so any adapter that listen to change in the annotation list can get the details
			// when it gets notified.
			//
			eAnnotation.getDetails().put(UMA_TYPE, detailValue);
			element.getEAnnotations().add(eAnnotation);
		}
		else {
			eAnnotation.getDetails().put(UMA_TYPE, detailValue);
		}		
		return element.getEAnnotations();
	}
	
	/**
	 * Creates and/or adds the eAnnotation detail for type. {@link BridgeHelper.UMA_TYPE}
	 * @param element
	 * @param type
	 */
	public static EList addEAnnotationType(EModelElement element, String type) {
		EList result = addEAnnotationDetail(element, UMA_TYPE, type);
		
		if(element instanceof ActivityNode) {
			ActivityNode node = (ActivityNode) element;
//			ActivityParameterNode node = (ActivityParameterNode) element;
			MethodElement e = BridgeHelper.getMethodElement(node);				
			if(e instanceof BreakdownElement && 
					type != null && !type.equals(BridgeHelper.getType(e))) {
				// replace the currently linked method element with the right one
				//
				EClass rightType = getType(type);
				if(rightType != null) {
					BreakdownElement rightElement = (BreakdownElement) UmaFactory.eINSTANCE.create(rightType);
					org.eclipse.epf.uma.Activity activity = ((BreakdownElement)e).getSuperActivities();
					if(activity != null) {
						List list = activity.getBreakdownElements();
						list.set(list.indexOf(e), rightElement);
						ProcessPackage pkg = (ProcessPackage) activity.eContainer();
						if (pkg != null) {
							pkg.getProcessElements().add(rightElement);
							// Also set the rightElement to its own process package.
							List childPkgs = pkg.getChildPackages();
							if (!childPkgs.isEmpty()) {
								for (Iterator iter = pkg.getChildPackages()
										.iterator(); iter.hasNext();) {
									ProcessPackage child = (ProcessPackage) iter
									.next();
									List<ProcessElement> pList = child
									.getProcessElements();
									if (!pList.isEmpty()) {
										if (pList.contains(e)) {
											pList.set(pList.indexOf(e),
													rightElement);
										}
									}
								}
							}
						}

						// associate the new method element with the node
						//
						associate(node, rightElement);
						// remove old node adapter and add new one
						//
						NodeAdapter nodeAdapter = BridgeHelper.getNodeAdapter(node);
						if(nodeAdapter != null) {
							nodeAdapter.dispose();
						}					
						DiagramAdapter diagramAdapter = (DiagramAdapter) getNodeAdapter(node.getActivity());
						diagramAdapter.addNodeAdapterTo(node);
					}
				}

			}
		}

		return result;
	}
	
	/**
	 * To get the eAnnotation detail based on name. (eg: type)
	 * @deprecated replaced with {@link #getEAnnotationDetail(EModelElement, String)}
	 */
	public static String getEAnnotationType(EModelElement element, String detailName) {
		return getEAnnotationDetail(element, detailName);
	}
	
	public static String getEAnnotationDetail(EModelElement element, String detailName) {
		EAnnotation eAnnotation = element.getEAnnotation(UMA_ELEMENT);
		if(eAnnotation != null){
			return (String)eAnnotation.getDetails().get(detailName);
		}
		return null;
	}
	
	public static String getType(ActivityNode node) {
		return getEAnnotationDetail(node, UMA_TYPE);
	}
	
	/**
	 * 
	 * @param e
	 * @return one of the type constants: {@link #UMA_ACTIVITY},
	 *         {@link #UMA_ITERATION}, {@link #UMA_MILESTONE},
	 *         {@link #UMA_PHASE}, {@link #UMA_TASK_DESCRIPTOR},
	 */
	public static String getType(BreakdownElement e) {
		if(e instanceof Iteration) {
			return UMA_ITERATION;
		}
		else if(e instanceof Phase) {
			return UMA_PHASE;
		}
		else if(e instanceof org.eclipse.epf.uma.Activity) {
			return UMA_ACTIVITY;
		}
		else if(e instanceof Milestone) {
			return UMA_MILESTONE;
		}
		else if(e instanceof TaskDescriptor) {
			return UMA_TASK_DESCRIPTOR;
		}
		else {
			return null;
		}
	}
	
	public static boolean isInherited(EModelElement e){
		EAnnotation eAnnotation = e.getEAnnotation(ANNOTATION_INHERIRED);
		if (eAnnotation != null) {
			String source = eAnnotation.getSource();
			if(source != null && source.length() > 0){
				return true;
			}
		}
		return false;
	}
	
	private static EClass getEClassFromType(String annotationType) {
		if(UMA_ACTIVITY.equals(annotationType)) {
			return UmaPackage.eINSTANCE.getActivity();
		}
		else if(UMA_ITERATION.equals(annotationType)) {
			return UmaPackage.eINSTANCE.getIteration();
		} else if(UMA_MILESTONE.equals(annotationType)) {
			return UmaPackage.eINSTANCE.getMilestone();
		} else if(UMA_PHASE.equals(annotationType)) {
			return UmaPackage.eINSTANCE.getPhase();
		} else if(UMA_TASK_DESCRIPTOR.equals(annotationType)) {
			return UmaPackage.eINSTANCE.getTaskDescriptor();
		}
		return null;
	}
	
	public static void setDefaultName(ActivityNode node) {
		Activity parentAct = node.getActivity();
		MethodElement element = BridgeHelper.getMethodElement(parentAct);
		MethodElement obj = BridgeHelper.getMethodElement(node);
		int classID = obj.eClass().getClassifierID();
		org.eclipse.epf.uma.Activity act = (org.eclipse.epf.uma.Activity) element;
		ArrayList siblings = new ArrayList();
		for (Iterator iter = act.getBreakdownElements().iterator(); iter
				.hasNext();) {
			BreakdownElement e = (BreakdownElement) iter.next();
			if (e.eClass().getClassifierID() == classID) {
				siblings.add(e);
			}
		}
		String baseName = MessageFormat
				.format(
						DiagramResources.defaultBaseName, new Object[] { TngUtil.getTypeText(obj.eClass().getName()) }); 
		TngUtil.setDefaultName(siblings, obj, baseName);
		node.setName(obj.getName());
	}
	
	public static View getView(View diagram, Object node) {
		for (Iterator iter = diagram.getChildren().iterator(); iter.hasNext();) {
			View child = (View) iter.next();
			if(child.getElement() == node) {
				return child;
			}
			if(child.getElement() instanceof ActivityPartition){
				for (Iterator iterator = child.getChildren().iterator(); iterator
						.hasNext();) {
					View element = (View) iterator.next();
					if(element.getElement() == node) {
						return child;
					}
				}
			}
		}
		return null;
	}

	/**
	 * Gets node name for the given method element.
	 * 
	 * @param e
	 * @return
	 */
	public static String getNodeName(MethodElement e) {
		if(e instanceof BreakdownElement) {
			return ProcessUtil.getPresentationName((BreakdownElement) e);
		}
		else if(e instanceof DescribableElement) {
			return ((DescribableElement)e).getPresentationName();
		}
		else {
			return e.getName();
		}
	}
	
}
