//------------------------------------------------------------------------------
// 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.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.emf.common.notify.Adapter;
import org.eclipse.emf.common.notify.AdapterFactory;
import org.eclipse.emf.edit.provider.ITreeItemContentProvider;
import org.eclipse.emf.transaction.RollbackException;
import org.eclipse.epf.diagram.model.util.IAdapterFactoryFilter;
import org.eclipse.epf.library.edit.TngAdapterFactory;
import org.eclipse.epf.library.edit.command.IActionManager;
import org.eclipse.epf.library.edit.process.ActivityWrapperItemProvider;
import org.eclipse.epf.library.edit.process.BSActivityItemProvider;
import org.eclipse.epf.library.edit.process.BreakdownElementWrapperItemProvider;
import org.eclipse.epf.library.edit.process.IBSItemProvider;
import org.eclipse.epf.library.edit.util.ConfigurableComposedAdapterFactory;
import org.eclipse.epf.library.edit.util.PredecessorList;
import org.eclipse.epf.library.edit.util.ProcessUtil;
import org.eclipse.epf.library.edit.util.TngUtil;
import org.eclipse.epf.uma.Activity;
import org.eclipse.epf.uma.BreakdownElement;
import org.eclipse.epf.uma.MethodElement;
import org.eclipse.epf.uma.Milestone;
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.notation.Edge;
import org.eclipse.gmf.runtime.notation.View;
import org.eclipse.uml2.uml.ActivityEdge;
import org.eclipse.uml2.uml.ActivityNode;
import org.eclipse.uml2.uml.ActivityParameterNode;
import org.eclipse.uml2.uml.ControlNode;
import org.eclipse.uml2.uml.StructuredActivityNode;
import org.eclipse.uml2.uml.UMLFactory;

/**
 * @author Phong Nguyen Le
 * @author Shilpa Toraskar
 *
 * @since 1.2
 */
public class ActivityDiagramAdapter extends DiagramAdapter {
	
	public ActivityDiagramAdapter(BreakdownElementWrapperItemProvider wrapper) {
		super(wrapper);
	}

	/**
	 * @param e
	 */
	public ActivityDiagramAdapter(Activity e) {
		super(e);
	}

	protected ActivityNode addNode(Collection nodes, Object obj) {
		if (obj instanceof Activity) {
			Activity act = (Activity) obj;
			VariabilityElement base = act.getVariabilityBasedOnElement();
			if (base != null) {
				// find existing node for base and link it to the activity
				//
				org.eclipse.uml2.uml.Activity diagram = getDiagram();
				ActivityNode baseNode = BridgeHelper.findNode(diagram, base);
				if (baseNode == null) {
					baseNode = BridgeHelper.findNode(diagram, act);
				}
				if (baseNode != null) {
					// disassociate with the base
					//
					NodeAdapter nodeAdapter = BridgeHelper.getNodeAdapter(baseNode);
					if(nodeAdapter != null) {
						nodeAdapter.dispose();
					}
					
					// associate base node with the activity
					//
					nodeAdapter = createNodeAdapter(act);
					if(nodeAdapter != null) {
						initializeNodeAdapter(nodeAdapter);
						baseNode.eAdapters().add(nodeAdapter);
						nodeAdapter.updateView();
//						if(ProcessUtil.isExtendingOrLocallyContributing(act)) {
							BridgeHelper.associate(baseNode, act);
							if(BridgeHelper.isInherited(nodeAdapter.getView())){
								BridgeHelper.unmarkInHerited(nodeAdapter.getView());
							}
							nodeAdapter.setTargetReadOnly(false);
//						}
					}
					
					return null;
				}
			}
		}
		return super.addNode(nodes, obj);
	}
	
	protected NodeAdapter createNodeAdapter(MethodElement e) {
		if(e instanceof WorkBreakdownElement) {
			return new WorkBreakdownElementNodeAdapter(e);
		}
		return null;
	}
	
	protected void addToUmaModel(int position, ActivityNode addedNode) {
		MethodElement e = BridgeHelper.getMethodElement(addedNode);
		if(e == null) {
			return;
		}
		Activity act = (Activity) getElement();

		// translate ActivityNode index to Activity index
		//
		int i = toActivityIndex(position);

		NodeAdapter nodeAdapter = BridgeHelper.getNodeAdapter(addedNode);
		boolean notify = nodeAdapter.notificationEnabled;
		try {
			nodeAdapter.notificationEnabled = false;
			getActionManager().doAction(IActionManager.ADD, act, UmaPackage.Literals.ACTIVITY__BREAKDOWN_ELEMENTS, e, i);
			BridgeHelper.addEAnnotation(addedNode, e);
		}
		finally {
			nodeAdapter.notificationEnabled = notify;
		}

		super.addToUmaModel(position, addedNode);
	}
	
	private int toActivityIndex(int index) {
		if (index == -1)
			return index;
		int size = getNodes().size();
		int i = index + 1;
		if (i == size)
			return -1;
		ActivityNode node = (ActivityNode) getNodes().get(i);
		if (node == null)
			return -1;

		for (; !(BridgeHelper.getMethodElement(node) instanceof BreakdownElement) && i < size; i++) {
			node = (ActivityNode) getNodes().get(i);
		}
		if (i == size)
			return -1;
		Activity act = (Activity) getElement();
		return act.getBreakdownElements().indexOf(BridgeHelper.getMethodElement(node));
	}

	protected List getBreakdownElementTypes() {
		return Collections.singletonList(WorkBreakdownElement.class);
	}

	/* (non-Javadoc)
	 * @see org.eclipse.epf.diagram.core.bridge.DiagramAdapter#newNode(org.eclipse.epf.uma.MethodElement)
	 */
	protected ActivityNode newNode(MethodElement e) {
		ActivityNode node = null;
		if(e instanceof Activity ) {
			node = UMLFactory.eINSTANCE.createStructuredActivityNode();
		}
		else if(e instanceof TaskDescriptor || e instanceof Milestone) {
			node = UMLFactory.eINSTANCE.createActivityParameterNode();
		}
		else if(e instanceof WorkBreakdownElement) {
			node = UMLFactory.eINSTANCE.createStructuredActivityNode();
		}
		if(node != null) {
			BridgeHelper.associate(node, e);
		}
		return node;
	}
	
	
	private boolean isValid(ActivityEdge link) {
		if (link.getSource() == null || link.getTarget() == null
				|| !getNodes().contains(link.getSource())
				|| !getNodes().contains(link.getTarget())) {
			return false;
		}
		return true;
	}
	
	private static boolean isValidWorkOrder(WorkOrder wo, Object pred) {
		if (wo.getPred() == pred) {
			return true;
		}

		if (pred instanceof Activity) {
			Activity act = (Activity) pred;
			// check if predecessor reference in the given work order is base of
			// pred
			//
			for (VariabilityElement ve = act.getVariabilityBasedOnElement(); ve != null; ve = ve
					.getVariabilityBasedOnElement()) {
				if (ve == wo.getPred()) {
					return true;
				}
			}
		}

		return false;
	}
	
	/**
	 * Checks if Node src can reach Node target as the first ActivityNode in the
	 * diagram
	 * 
	 * @param predNode
	 * @param node
	 * @return
	 */
	private static boolean canReachAsFirstActivityNode(ActivityNode predNode, ActivityNode node) {
		for (Iterator iter = predNode.getOutgoings().iterator(); iter
				.hasNext();) {
			ActivityEdge link = (ActivityEdge) iter.next();
			if (link.getTarget() == node) {
				return true;
			}
			if (link.getTarget() instanceof ControlNode
					&& canReachAsFirstActivityNode(link.getTarget(), node)) {
				return true;
			}
		}
		return false;
	}
	
	protected List<WorkBreakdownElement> getLocalPredecessors(ActivityNode node) {
		Activity diagramActivity = (Activity) BridgeHelper.getMethodElement(getDiagram());
		AdapterFactory adapterFactory = getAdapterFactory();
		ITreeItemContentProvider adapter = (ITreeItemContentProvider) adapterFactory.adapt(diagramActivity, ITreeItemContentProvider.class);
		Collection<?> children = adapter.getChildren(diagramActivity);
		return getLocalPredecessors(node, children);
	}
	
	private List<WorkBreakdownElement> getLocalPredecessors(ActivityNode node, Collection<?> activityChildren) {
		MethodElement e = BridgeHelper.getMethodElement(node);
		if(e instanceof WorkBreakdownElement) {
			// find item provider
			//
			Object object = null;
			for (Object child : activityChildren) {
				if(e == TngUtil.unwrap(child)) {
					object = child;
					break;
				}
			}
			if(object != null) {
				Object ip = getAdapterFactory().adapt(object, ITreeItemContentProvider.class);
				if(ip instanceof IBSItemProvider) {
					Object parent = ((ITreeItemContentProvider) ip).getParent(object);
					ArrayList<WorkBreakdownElement> preds = new ArrayList<WorkBreakdownElement>();
					PredecessorList predList = ((IBSItemProvider) ip).getPredecessors();
					for (Object predIp : predList) {
						Object pred = TngUtil.unwrap(predIp);
						// make sure that predecessors are sibling
						//
						if(((ITreeItemContentProvider) predIp).getParent(pred) == parent) {
							if(pred instanceof WorkBreakdownElement) {
								preds.add((WorkBreakdownElement) pred);
							} else if (pred instanceof Adapter) {
								pred = ((Adapter) pred).getTarget();
								if(pred instanceof WorkBreakdownElement) {
									preds.add((WorkBreakdownElement) pred);
								}
							}
						}
					}
					return preds;
				}
			}
		}
		return Collections.emptyList();
	}

	AdapterFactory getAdapterFactory(){
		AdapterFactory adapterFactory = null;
		if (filter == null) {
			adapterFactory = TngAdapterFactory.INSTANCE.getWBS_ComposedAdapterFactory();
		} else if (filter instanceof IAdapterFactoryFilter) {
			adapterFactory = (ConfigurableComposedAdapterFactory) ((IAdapterFactoryFilter) filter)
					.getWBSAdapterFactory();
		}
		return adapterFactory;
	}
	
	@Override
	protected void populateLinks(List<ActivityNode> selectedNodes) {
		if(selectedNodes.isEmpty()) {
			return;
		}
		
		super.populateLinks(selectedNodes);

		// remove the invalid links
		//
		for (ActivityNode node : selectedNodes) {
			WorkBreakdownElement wbe = null;
			MethodElement me;
			if ((me = BridgeHelper.getMethodElement(node)) instanceof WorkBreakdownElement) {
				wbe = (WorkBreakdownElement) me;
			}
			ArrayList<ActivityEdge> linksToRemove = new ArrayList<ActivityEdge>();
			linkListWalk: for (Iterator iterator = node
					.getIncomings().iterator(); iterator.hasNext();) {
				ActivityEdge link = (ActivityEdge) iterator.next();
				if (!isValid(link)) {
					linksToRemove.add(link);
				}

				if (wbe != null) {
					// TODO: need revisit to check the valid connection from a
					// ForkNode or JoinNode
					//
					
					if (link.getSource() != null && link.getSource() instanceof ControlNode)
						continue linkListWalk;
					
					boolean workOrderFound = false;
					WorkOrder workOrder = (WorkOrder) BridgeHelper.getMethodElement(link);
					if(workOrder == null) {
						Object pred = BridgeHelper.getMethodElement(link.getSource());
						find_WorkOrder: for (Iterator iterator1 = wbe
								.getLinkToPredecessor().iterator(); iterator1
								.hasNext();) {
							WorkOrder wo = (WorkOrder) iterator1.next();
							if (isValidWorkOrder(wo, pred)) {
								workOrderFound = true;
								break find_WorkOrder;
							}
						}
					} else {
						workOrderFound = true;
					}
					if (!workOrderFound) {
						// invalid link, remove it
						//
						linksToRemove.add(link);
					}
				}
			}

			for (ActivityEdge link : linksToRemove) {
				BridgeHelper.removeLink(link);
			}
			linksToRemove.clear();

			for (Iterator iterator = node.getOutgoings().iterator(); iterator
					.hasNext();) {
				ActivityEdge link = (ActivityEdge) iterator.next();
				if (!isValid(link)) {
					linksToRemove.add(link);
				}
			}

			for (Iterator iterator = linksToRemove.iterator(); iterator
					.hasNext();) {
				ActivityEdge link = (ActivityEdge) iterator.next();
				BridgeHelper.removeLink(link);
			}
			linksToRemove.clear();
			linksToRemove = null;
		}

		// Check the links of each ActivityNode
		// set the WorkOrder to the link if needed
		// add new link for those WorkOrders that still don't have the
		// corresponding link
		//
		Activity diagramActivity = (Activity) BridgeHelper.getMethodElement(getDiagram());
		AdapterFactory adapterFactory = getAdapterFactory();
		ITreeItemContentProvider adapter = (ITreeItemContentProvider) adapterFactory.adapt(diagramActivity, ITreeItemContentProvider.class);
		Collection<?> children = adapter.getChildren(diagramActivity);
		
		for (ActivityNode node : selectedNodes) {
			List<WorkBreakdownElement> preds = getLocalPredecessors(node, children);

			// Iterate work orders and create links.
			for (WorkBreakdownElement pred : preds) {
				ActivityNode predNode = BridgeHelper.findNode(getDiagram(),
						pred, true);
				if (predNode != null) {
					// check if there is a link for this work order
					// already
					//
					boolean linkFound = false;
					find_link: for (Iterator<?> iterator1 = node
							.getIncomings().iterator(); iterator1
							.hasNext();) {
						ActivityEdge link = (ActivityEdge) iterator1.next();
						if (link.getSource() == predNode) {
							// link already exists
							// check if work order is set to this link
							//
							linkFound = true;
//							MethodElement me = BridgeHelper.getMethodElement(link);
//							if (link != null) {
//								BridgeHelper.setSemanticModel(
//										link, workOrder);
//							}
							break find_link;
						}
					}
					if (!linkFound) {
						// check if this WorkOrder can be represented
						// via links of TypedNodes
						//
						if (!canReachAsFirstActivityNode(predNode, node)) {
							// add new link for this work order
							//
							NodeAdapter nodeAdapter = BridgeHelper.getNodeAdapter(node);
							NodeAdapter predNodeAdapter = BridgeHelper.getNodeAdapter(predNode);
							if(nodeAdapter != null && predNodeAdapter != null) {
								boolean oldNotify = nodeAdapter.notificationEnabled;
								boolean predNodeNotify = predNodeAdapter.notificationEnabled;
								try {
									nodeAdapter.notificationEnabled = false;
									predNodeAdapter.notificationEnabled = false;
									ActivityEdge edge = nodeAdapter.addIncomingConnection(pred);
									if(BridgeHelper.isInherited(node)) {
										// target node is inherited, must find the custom work order and associate it with the edge
										//
										WorkBreakdownElement inheritedChild = (WorkBreakdownElement) BridgeHelper.getMethodElement(node);
										if(inheritedChild != null) {
											WorkOrder wo = ProcessUtil.findWorkOrder(diagramActivity, inheritedChild, pred);
											if(wo != null) {
												BridgeHelper.associate(edge, wo);
											}
										}
									}
								} finally {
									nodeAdapter.notificationEnabled = oldNotify;
									predNodeAdapter.notificationEnabled = predNodeNotify;
								}
							}
						}
					}
				}
			}
		}
		cleanDuplicateLinks(selectedNodes);
	}

	private void cleanDuplicateLinks(List<ActivityNode> selectedNodes) {
		List<ActivityEdge> duplicateLinks = new ArrayList<ActivityEdge>();
		for (ActivityNode wbNode : selectedNodes) {
			if(wbNode.getIncomings() != null){
				findDuplicateLinks(duplicateLinks, wbNode.getIncomings());
			}
			if(wbNode.getOutgoings() !=null){
				findDuplicateLinks(duplicateLinks, wbNode.getOutgoings());
			}
		}
		for (ActivityEdge link : duplicateLinks) {
			BridgeHelper.removeLink(link);
		}
		duplicateLinks.clear();
		duplicateLinks = null;
	}

	private void findDuplicateLinks(List duplicateLinks, List links) {
		for (int i = 0; i < links.size(); i++) {
			ActivityEdge link = (ActivityEdge) links.get(i);
			if(!duplicateLinks.contains(link)){
				for (int j = i + 1; j < links.size(); j++) {
					ActivityEdge link1 = (ActivityEdge) links.get(j);
					if (link1.getSource() == link.getSource()
							&& link1.getTarget() == link.getTarget()) {
						duplicateLinks.add(link1);
					}
				}
			}
		}
	}

	protected Collection populateNodes() {
		HashSet selectedNodes = new HashSet();
		Collection children = getChildren();

		// associate control nodes
		//
		selectedNodes.addAll(associateControlNodes(children));
		
		// add WorkBreakdownElementNodes
		//
		selectedNodes.addAll(addElementNodes(children));
		
		return selectedNodes;
	}
	
	@Override
	protected void updateView(Collection<?> selectedNodes)
			throws InterruptedException, RollbackException {
		super.updateView(selectedNodes);
		hideUnusedSyncBars();
	}
	
	protected void hideUnusedSyncBars() {
		View diagram = getView();
		for (Object child : diagram.getVisibleChildren()) {
			View childView = (View) child;
			// hide a sync bar that is not connected to any visible target node
			// or source node, which is associated with a work breakdown element
			//
			if(childView.getElement() instanceof ControlNode && 
					BridgeHelper.isSynchBar((ActivityNode) childView.getElement()) &&
					!isConnectedToVisibleWBENode(childView)) {
				childView.setVisible(false);
			}
		}
	}
	
	private static boolean isConnectedToVisibleWBENode(View view) {
		// check source nodes
		//
		for(Object object : view.getTargetEdges()) {
			View connectedView = ((Edge) object).getSource();
			if(connectedView != null && connectedView.isVisible() && 
					connectedView.getElement() instanceof ActivityNode &&
					BridgeHelper.getMethodElement(connectedView) instanceof WorkBreakdownElement) {
				return true;
			}
		}
		
		// check target nodes
		//
		for(Object object : view.getSourceEdges()) {
			View connectedView = ((Edge) object).getTarget();
			if(connectedView != null && connectedView.isVisible() && 
					connectedView.getElement() instanceof ActivityNode &&
					BridgeHelper.getMethodElement(connectedView) instanceof WorkBreakdownElement) {
				return true;
			}
		}
		
		return false;
	}
	
	private List<? extends ControlNode> associateControlNodes(Collection<?> methodElements) {
		List<ControlNode> ctrlNodes = new ArrayList<ControlNode>();
		for (Iterator<?> iter = getDiagram().getNodes().iterator(); iter.hasNext();) {
			ActivityNode node = (ActivityNode) iter.next();
			if(node instanceof ControlNode) {
				if(addNodeAdapterTo(node) != null) {
					ctrlNodes.add((ControlNode) node);
				}
			}
		}
		return ctrlNodes;
	}

	/**
	 * Adds element nodes for the specified method elements if they don't exist yet.
	 * 
	 * @param methodElements
	 */
	private List addElementNodes(Collection methodElements) {	
		ArrayList nodes = new ArrayList();
		ArrayList newNodes = new ArrayList();
		for (Iterator iter = methodElements.iterator(); iter.hasNext();) {
			Object e = iter.next();
			Object child = TngUtil.unwrap(e);
			if (child instanceof WorkBreakdownElement) {
				ActivityNode node = BridgeHelper.findNode(getDiagram(), child);
				if(node == null) {
					node = toNode((MethodElement) child);
					newNodes.add(node);
				}
				else {
					// synchronize name with linked element
					//
					String name = BridgeHelper.getNodeName((MethodElement) child);
					if(!name.equals(node.getName())) {
						node.setName(name);
					}
					
					addNodeAdapterTo(node);
				}
				nodes.add(node);
				if (e instanceof BreakdownElementWrapperItemProvider && !isTargetReadOnly()) {
					BreakdownElementWrapperItemProvider wrapper = ((BreakdownElementWrapperItemProvider) e);
					if (wrapper.isReadOnly()) {
						NodeAdapter nodeAdapter = BridgeHelper.getNodeAdapter(node);
						nodeAdapter.wrapper = wrapper;
						// readOnly attribute is still needed
						// after introduction of wrapper. 
						// For example, we can have a node adapter for a read-only base activity
						// without supplying wrapper for this base activity.
						//
						nodeAdapter.basicSetTargetReadOnly(true);
					}
				}
			}
		}
		getNodes().addAll(newNodes);		
		return nodes;
	}

	/**
	 * Moved code from getChildren. getAdapter() will return Adapter,
	 * which will allow us to find itemprovider for the children. 
	 * 
	 * @return
	 */
	private ITreeItemContentProvider getAdapter(){
		ITreeItemContentProvider adapter = null;
		if (wrapper != null) {
			adapter = wrapper;
		} else {
			adapter = (ITreeItemContentProvider) getAdapterFactory().adapt(
					getElement(), ITreeItemContentProvider.class);
		}
		return adapter;
	}

	public Collection getChildren() {
		ITreeItemContentProvider adapter = getAdapter();
		if (adapter != null) {
			
			//Turn off the VariabilityInfo for the activity diagram.
			Object obj = null;
			boolean enableVariabilityInfo = false;
			if(adapter instanceof ActivityWrapperItemProvider){
				obj = ((ActivityWrapperItemProvider)adapter).getDelegatingItemProvider();
			}
			if(adapter instanceof BSActivityItemProvider){
				obj = adapter;
			}
			
			if(obj instanceof BSActivityItemProvider){
				enableVariabilityInfo = ((BSActivityItemProvider)obj).isEnableVariabilityInfo();
				((BSActivityItemProvider)obj).setEnableVariabilityInfo(false);
			}
			// end of variability info 
			
			
			// return adapter.getChildren(getObject());
			// commented above line, For diagrams - rollup should be false, for
			// handling rollup state below code.
			List children = new ArrayList();
			extractChildren(adapter, getElement(), children);
			
			// reset variabilityinfo status back
			if(obj instanceof BSActivityItemProvider){
				((BSActivityItemProvider)obj).setEnableVariabilityInfo(enableVariabilityInfo);
			}
			
			return children;
		} else {
			return Collections.EMPTY_LIST;
		}
	}

	protected boolean removeNode(Object obj) {
		if (obj instanceof Activity) {
			Activity act = (Activity) obj;
			VariabilityElement base = act.getVariabilityBasedOnElement();
			if (base != null) {
				org.eclipse.uml2.uml.Activity diagram = getDiagram();
				
				// find existing node for the old activity and relink it to its
				// base
				//
				ActivityNode node = BridgeHelper.findNode(diagram, act);
				if(node == null) {
					node = BridgeHelper.findNode(diagram, base);
				}
				if (node != null) {
					// disassociate with the old activity
					//
					NodeAdapter nodeAdapter = BridgeHelper.getNodeAdapter(node);
					if(nodeAdapter != null) {
						nodeAdapter.dispose();
					}
					
					// associate node with the base activity
					//
					nodeAdapter = createNodeAdapter(base);
					if(nodeAdapter != null) {
						initializeNodeAdapter(nodeAdapter);
						nodeAdapter.basicSetTargetReadOnly(true);
						node.eAdapters().add(nodeAdapter);
						nodeAdapter.updateView();
						if(!BridgeHelper.isInherited(nodeAdapter.getView())){
							BridgeHelper.markInherited(nodeAdapter.getView());
						}
					}

					return false;
				}
			}
		}
		return super.removeNode(obj);
	}

	protected NodeAdapter addNodeAdapterTo(ActivityNode node) {
		NodeAdapter adapter = BridgeHelper.getNodeAdapter(node);
		if(adapter != null) {
			return adapter;
		}
		if(node instanceof ControlNode) {
			adapter = new ControlNodeAdapter();
		}
		else {
			MethodElement e = BridgeHelper.getMethodElement(node);
			if(e == null) {
				if(node instanceof StructuredActivityNode) {
					String type = BridgeHelper.getType((StructuredActivityNode)node);
					if (BridgeHelper.UMA_PHASE.equals(type)) {
						e = UmaFactory.eINSTANCE.createPhase();
					}
					else if (BridgeHelper.UMA_ITERATION.equals(type)) {
						e = UmaFactory.eINSTANCE.createIteration();
					}
					else {
						e = UmaFactory.eINSTANCE.createActivity();
					}
				}
				else if(node instanceof ActivityParameterNode) {
					String type = BridgeHelper.getType((ActivityParameterNode)node);
					if(BridgeHelper.UMA_MILESTONE.equals(type)) {
						e = UmaFactory.eINSTANCE.createMilestone();
					}
					else {
						e = UmaFactory.eINSTANCE.createTaskDescriptor();
					}
				}
			}
			if(e != null) {
				adapter = new WorkBreakdownElementNodeAdapter(e);
			}
		}
		if(adapter != null) {
			initializeNodeAdapter(adapter);
			node.eAdapters().add(adapter);
			return adapter;
		}
		return null;
	}
	
	private ActivityNode reassociateBaseNode(Activity act) {
		VariabilityElement base = act.getVariabilityBasedOnElement();
		if (base != null) {
			// find existing node for base and link it to the activity
			//
			org.eclipse.uml2.uml.Activity diagram = getDiagram();
			ActivityNode baseNode = BridgeHelper.findNode(diagram, base);
			if (baseNode == null) {
				baseNode = BridgeHelper.findNode(diagram, act);
			}
			if (baseNode != null) {
				// disassociate with the base
				//
				NodeAdapter nodeAdapter = BridgeHelper.getNodeAdapter(baseNode);
				if(nodeAdapter != null) {
					nodeAdapter.dispose();
				}
				
				// associate base node with the activity
				//
				nodeAdapter = createNodeAdapter(act);
				if(nodeAdapter != null) {
					initializeNodeAdapter(nodeAdapter);
					baseNode.eAdapters().add(nodeAdapter);
					nodeAdapter.updateView();
//					if(ProcessUtil.isExtendingOrLocallyContributing(act)) {
						BridgeHelper.associate(baseNode, act);
						if(BridgeHelper.isInherited(nodeAdapter.getView())){
							BridgeHelper.unmarkInHerited(nodeAdapter.getView());
						}
						nodeAdapter.setTargetReadOnly(false);
//					}
				}
				
				return baseNode;
			}
		}
		
		return null;
	}

	@Override
	protected void replaceNode(Object oldElement, Object newElement) {
		if(newElement instanceof MethodElement) {
			// find existing node for old element and link it to the new element
			//
			org.eclipse.uml2.uml.Activity diagram = getDiagram();
			ActivityNode oldNode = BridgeHelper.findNode(diagram, oldElement);
			if (oldNode != null) {
				// disassociate with the old element
				//
				NodeAdapter nodeAdapter = BridgeHelper.getNodeAdapter(oldNode);
				if(nodeAdapter != null) {
					nodeAdapter.dispose();
				}

				// associate base node with the new element
				//
				MethodElement e = (MethodElement) newElement;
				nodeAdapter = createNodeAdapter(e);
				if(nodeAdapter != null) {
					initializeNodeAdapter(nodeAdapter);
					oldNode.eAdapters().add(nodeAdapter);
					nodeAdapter.updateView();
					BridgeHelper.associate(oldNode, e);
				}
			}
		}
	}
}
