//------------------------------------------------------------------------------
// 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) {
		if (container != null) {
			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); 
        try { 
            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$ 
                            } 
                    } 
                } 
            } 
        } catch (Exception e) { 
                DiagramCorePlugin.getDefault().getLogger().logError(e); 
                return null; 
        } 
        
        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();
		}
	}
	
}
