//------------------------------------------------------------------------------
// 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.diagram.model.impl;

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 org.eclipse.emf.common.notify.AdapterFactory;
import org.eclipse.emf.common.notify.Notification;
import org.eclipse.emf.ecore.EClass;
import org.eclipse.emf.ecore.EObject;
import org.eclipse.emf.ecore.impl.ENotificationImpl;
import org.eclipse.emf.edit.provider.AdapterFactoryTreeIterator;
import org.eclipse.emf.edit.provider.ITreeItemContentProvider;
import org.eclipse.epf.diagram.model.ActivityDetailDiagram;
import org.eclipse.epf.diagram.model.Link;
import org.eclipse.epf.diagram.model.ModelFactory;
import org.eclipse.epf.diagram.model.ModelPackage;
import org.eclipse.epf.diagram.model.Node;
import org.eclipse.epf.diagram.model.NodeContainer;
import org.eclipse.epf.diagram.model.RoleTaskComposite;
import org.eclipse.epf.diagram.model.TaskNode;
import org.eclipse.epf.diagram.model.WorkProductComposite;
import org.eclipse.epf.diagram.model.WorkProductDescriptorNode;
import org.eclipse.epf.diagram.model.util.GraphicalDataHelper;
import org.eclipse.epf.diagram.model.util.IActivityDetailDiagramChangeListener;
import org.eclipse.epf.diagram.model.util.IAdapterFactoryFilter;
import org.eclipse.epf.library.edit.TngAdapterFactory;
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.ProcessUtil;
import org.eclipse.epf.library.edit.util.TngUtil;
import org.eclipse.epf.uma.Activity;
import org.eclipse.epf.uma.Artifact;
import org.eclipse.epf.uma.BreakdownElement;
import org.eclipse.epf.uma.Descriptor;
import org.eclipse.epf.uma.MethodElement;
import org.eclipse.epf.uma.RoleDescriptor;
import org.eclipse.epf.uma.TaskDescriptor;
import org.eclipse.epf.uma.WorkProduct;
import org.eclipse.epf.uma.WorkProductDescriptor;
import org.eclipse.epf.uma.util.AssociationHelper;

/**
 * <!-- begin-user-doc --> An implementation of the model object '<em><b>Activity Detail Diagram</b></em>'.
 * <!-- end-user-doc -->
 * <p>
 * The following features are implemented:
 * <ul>
 *   <li>{@link org.eclipse.epf.diagram.model.impl.ActivityDetailDiagramImpl#isAutoLayout <em>Auto Layout</em>}</li>
 * </ul>
 * </p>
 *
 * @generated
 */
public class ActivityDetailDiagramImpl extends DiagramImpl implements
		ActivityDetailDiagram {
	/**
	 * The default value of the '{@link #isAutoLayout() <em>Auto Layout</em>}' attribute.
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @see #isAutoLayout()
	 * @generated
	 * @ordered
	 */
	protected static final boolean AUTO_LAYOUT_EDEFAULT = false;

	/**
	 * The cached value of the '{@link #isAutoLayout() <em>Auto Layout</em>}' attribute.
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @see #isAutoLayout()
	 * @generated
	 * @ordered
	 */
	protected boolean autoLayout = AUTO_LAYOUT_EDEFAULT;

	private class ActivityDetailDiagramChangeListener extends ActivityAdapter
			implements IActivityDetailDiagramChangeListener {
		// /* (non-Javadoc)
		// * @see
		// org.eclipse.epf.diagram.model.impl.DiagramImpl.ActivityAdapter#notifyChanged(org.eclipse.emf.common.notify.Notification)
		// */
		// public void notifyChanged(Notification msg) {
		// if(!notificationEnabled) return;
		// notificationEnabled = false;
		// try {
		// Object obj;
		// switch(msg.getFeatureID(Activity.class)) {
		// case UmaPackage.ACTIVITY__BREAKDOWN_ELEMENTS:
		// repopulateDiagram();
		// break;
		// }
		// }
		// finally {
		// notificationEnabled = true;
		// }
		//
		// }

	}

	/**
	 * <!-- begin-user-doc --> <!-- end-user-doc -->
	 */
	protected ActivityDetailDiagramImpl() {
		super();

		diagramChangeListener = new ActivityDetailDiagramChangeListener();
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	@Override
	public Object eGet(int featureID, boolean resolve, boolean coreType) {
		switch (featureID) {
			case ModelPackage.ACTIVITY_DETAIL_DIAGRAM__AUTO_LAYOUT:
				return isAutoLayout() ? Boolean.TRUE : Boolean.FALSE;
		}
		return super.eGet(featureID, resolve, coreType);
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	@Override
	public void eSet(int featureID, Object newValue) {
		switch (featureID) {
			case ModelPackage.ACTIVITY_DETAIL_DIAGRAM__AUTO_LAYOUT:
				setAutoLayout(((Boolean)newValue).booleanValue());
				return;
		}
		super.eSet(featureID, newValue);
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	@Override
	public void eUnset(int featureID) {
		switch (featureID) {
			case ModelPackage.ACTIVITY_DETAIL_DIAGRAM__AUTO_LAYOUT:
				setAutoLayout(AUTO_LAYOUT_EDEFAULT);
				return;
		}
		super.eUnset(featureID);
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	@Override
	public boolean eIsSet(int featureID) {
		switch (featureID) {
			case ModelPackage.ACTIVITY_DETAIL_DIAGRAM__AUTO_LAYOUT:
				return autoLayout != AUTO_LAYOUT_EDEFAULT;
		}
		return super.eIsSet(featureID);
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	@Override
	public String toString() {
		if (eIsProxy()) return super.toString();

		StringBuffer result = new StringBuffer(super.toString());
		result.append(" (autoLayout: "); //$NON-NLS-1$
		result.append(autoLayout);
		result.append(')');
		return result.toString();
	}

	/**
	 * 
	 */
	public void repopulateDiagram() {
		// clear diagram
		//

		int size = getNodes().size();

		// disable notification for all nodes in this diagram to avoid unwanted
		// concurrent modification of their connection list
		//
		for (int i = 0; i < size; i++) {
			NodeImpl node = ((NodeImpl) getNodes().get(i));
			node.notificationEnabled = false;
		}
		for (Iterator iteration = getNodes().iterator(); iteration.hasNext();) {
			Node node = (Node) iteration.next();

			// clear all links
			//
			for (Iterator iter = node.getOutgoingConnections().iterator(); iter
					.hasNext();) {
				Link link = (Link) iter.next();
				link.setTarget(null);
			}

			for (Iterator iter = node.getIncomingConnections().iterator(); iter
					.hasNext();) {
				Link link = (Link) iter.next();
				link.setSource(null);
			}
			node.getOutgoingConnections().clear();
			node.getIncomingConnections().clear();
		}

		getNodes().clear();

		populateDiagram();
	}

	/**
	 * <!-- begin-user-doc --> <!-- end-user-doc -->
	 * @generated
	 */
	@Override
	protected EClass eStaticClass() {
		return ModelPackage.Literals.ACTIVITY_DETAIL_DIAGRAM;
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 */
	public boolean isAutoLayout() {
		if(isGraphicalDataRequired()) {
			return GraphicalDataHelper.PROP_AUTO_LAYOUT_VALUE_TRUE.equals(
					GraphicalDataHelper.getAutoLayoutFlag(this));
		}
		return autoLayout;
	}



	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	public void setAutoLayout(boolean newAutoLayout) {
		boolean oldAutoLayout = autoLayout;
		autoLayout = newAutoLayout;
		if (eNotificationRequired())
			eNotify(new ENotificationImpl(this, Notification.SET, ModelPackage.ACTIVITY_DETAIL_DIAGRAM__AUTO_LAYOUT, oldAutoLayout, autoLayout));
	}
	
	public void doSetAutoLayout(boolean newAutoLayout) {
		if(isGraphicalDataRequired()) {
			GraphicalDataHelper.createProperty(this.graphNode, 
					GraphicalDataHelper.PROP_AUTO_LAYOUT, 
					String.valueOf(newAutoLayout));
		}
		else {
			setAutoLayout(newAutoLayout);
		}
	}
	
	@Override
	public Collection getChildren() {
		return getAllBreakdownElements(true);
	}

	/**
	 * Gets all breakdown elements or their wrappers for the activity of this
	 * diagram
	 * 
	 * @return
	 */
	Collection getAllBreakdownElements(boolean filterSuppressed) {
		ArrayList breakdownElements = new ArrayList();
		AdapterFactory[] adapterFactories;
		if (filter instanceof IAdapterFactoryFilter) {
			IAdapterFactoryFilter adapterFactoryFilter = (IAdapterFactoryFilter) filter;
			adapterFactories = new AdapterFactory[] {
					adapterFactoryFilter.getWBSAdapterFactory(),
					adapterFactoryFilter.getTBSAdapterFactory(),
					adapterFactoryFilter.getWPBSAdapterFactory() };
		} else {
			adapterFactories = DEFAULT_ADAPTER_FACTORIES;
		}
		if (wrapper != null) {
			List wrappers = ProcessUtil.getWrappers(wrapper, adapterFactories);
			for (Iterator iter = wrappers.iterator(); iter.hasNext();) {
				BreakdownElementWrapperItemProvider w = (BreakdownElementWrapperItemProvider) iter
						.next();
				extractChildren(w, w, breakdownElements, filterSuppressed);
			}
		} else {
			for (int i = 0; i < adapterFactories.length; i++) {
				AdapterFactory adapterFactory = adapterFactories[i];
				if (getObject() != null) {
					if (adapterFactory != null) {
						ITreeItemContentProvider adapter = (ITreeItemContentProvider) adapterFactory
								.adapt(getObject(),
										ITreeItemContentProvider.class);
						extractChildren(adapter, getObject(),
								breakdownElements, filterSuppressed);
					}
				}
			}
		}
		
		// add descriptors of subartifacts
		//
		AdapterFactory wpbsAdapterFactory = adapterFactories[2];
		for (Iterator<?> iterator = new ArrayList(breakdownElements).iterator(); iterator
				.hasNext();) {
			Object child = iterator.next();
			Object e = TngUtil.unwrap(child);
			if(e instanceof WorkProductDescriptor) {
				WorkProduct wp = ((WorkProductDescriptor)e).getWorkProduct();
				if(wp instanceof Artifact
						// FIXME: need to used realized list of subartifacts after similar fix is made in
						// org.eclipse.epf.library.edit.process.WorkProductDescriptorItemProvider.java
						//
						&& !((Artifact)wp).getContainedArtifacts().isEmpty() 
				) {
					collectSubartifactDescriptors(child, filterSuppressed, breakdownElements, wpbsAdapterFactory);
				}
			}
		}
		
		return breakdownElements;
	}

	private void collectSubartifactDescriptors(Object child,
			boolean filterSuppressed, ArrayList<Object> breakdownElements,
			AdapterFactory wpbsAdapterFactory) {
		// disable rollup before getting the children
		//
		boolean oldRolledUp = false;
		IBSItemProvider adapter = null;
		if(child instanceof BSActivityItemProvider) {
			BSActivityItemProvider itemProvider = (BSActivityItemProvider) child;
			oldRolledUp = itemProvider.isRolledUp();
			itemProvider.basicSetRolledUp(false);
			adapter = itemProvider;
		}
		else if(adapter instanceof IBSItemProvider){
			IBSItemProvider itemProvider = (IBSItemProvider) child;
			oldRolledUp = itemProvider.isRolledUp();
			itemProvider.setRolledUp(false);
			adapter = itemProvider;
		}
		
		try {

			AdapterFactoryTreeIterator<Object> iter = new AdapterFactoryTreeIterator<Object>(
					wpbsAdapterFactory, child, false);
			while (iter.hasNext()) {
				Object o = iter.next();
				if(filterSuppressed) {
					if(!getSuppression().isSuppressed(o)) {
						breakdownElements.add(o);
					}
				}
				else {
					breakdownElements.add(o);
				}
			}
		} finally {
			// restore rolled-up flag
			//
			if (adapter != null) {
				adapter.setRolledUp(oldRolledUp);
			}
		}
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see org.eclipse.epf.diagram.model.impl.DiagramImpl#populateNodes()
	 */
	protected void populateNodes() {
		boolean oldNotify = notificationEnabled;
		try {
			notificationEnabled = false;
			Activity act = (Activity) getObject();
			if (act == null)
				return;

			if (isGraphicalDataRequired()) {
				// to populate the typednode.
				super.populateNodes();
			}

			if (filter == null) {
				filter = ((ConfigurableComposedAdapterFactory) DEFAULT_ADAPTER_FACTORIES[0])
						.getFilter();
			}

			// Node newNode = null;
			ArrayList<Node> nodes = new ArrayList<Node>();
			Collection<?> breakdownElements = getAllBreakdownElements(true);
			Collection<RoleDescriptor> roleDescriptors = new HashSet<RoleDescriptor>();
			for (Iterator<?> iterator = breakdownElements.iterator(); iterator
					.hasNext();) {
				Object object = iterator.next();
				Object element = TngUtil.unwrap(object);
				if (element instanceof TaskDescriptor) {
					TaskDescriptor descriptor = (TaskDescriptor) element;
					List<RoleDescriptor> performers = descriptor
							.getPerformedPrimarilyBy();
					for (RoleDescriptor roleDescriptor : performers)	{
						if (roleDescriptor != null
								&& filter.accept(roleDescriptor)
								// TODO: need to check if the role descriptor is
								// inherited and locally suppressed
								// if locally suppressed, check the wrapper of the
								// role descriptor
								//
								&& !roleDescriptor.getSuppressed().booleanValue()
								&& !roleDescriptors.contains(roleDescriptor)) {
							roleDescriptors.add(roleDescriptor);
							// newNode = createRoleTaskComposite(roleDescriptor);
							// if(newNode != null) {
							// if(ProcessUtil.isInherited(object)) {
							// // task descriptor is inherited, its primary
							// performer is not local
							// // set role node of the RoleTaskComposite to
							// read-only
							// //
							// Node roleNode = (Node)
							// ((NodeContainer)newNode).getNodes().get(0);
							// roleNode.setReadOnly(true);
							// }
							// nodes.add(newNode);
							// }
							createRoleTaskCompositeRows(roleDescriptor, object,
									nodes);
						}
//						if (roleDescriptors.contains(roleDescriptor)) {
//							createTaskInputOutputNodes(descriptor, nodes);
//						}
					}					
				}
			}
			
			for (Node node : new ArrayList<Node>(nodes)) {
				if(node instanceof RoleTaskComposite) {
					for(Node childNode : ((RoleTaskComposite) node).getNodes()) {
						if(childNode instanceof TaskNode) {
							createTaskInputOutputNodes((TaskNode) childNode, nodes);
						}
					}
				}
			}

			selectNodes(nodes);
		} finally {
			notificationEnabled = oldNotify;
		}
	}
	
	private static int getNumberOfRows(int totalTasks, int tasksPerRow) {
		int n = totalTasks / tasksPerRow;
		return (tasksPerRow * n) == totalTasks ? n : n + 1;
	}

    private void createRoleTaskCompositeRows(RoleDescriptor roleDescriptor, 
    		Object object, List nodes) {
    	
    	int tasksPerRow = GraphicalDataHelper.getTasksPerRow();
    	List<?> primaryTaskDescriptors = //AssociationHelper.getPrimaryTaskDescriptors(roleDescriptor);
    		getRealizedPrimaryTaskDescriptors(roleDescriptor);
    	int totalTasks = primaryTaskDescriptors.size();
    	
    	if (tasksPerRow > 0 && totalTasks > 0 && totalTasks > tasksPerRow
				&& isAutoLayout()) {
			for (int i = 0; i < getNumberOfRows(totalTasks, tasksPerRow); i++) {
				Node newNode = createRoleTaskComposite(roleDescriptor, i);
				if (newNode != null) {
					if (ProcessUtil.isInherited(object)) {
						// task descriptor is inherited, its primary performer
						// is not local
						// set role node of the RoleTaskComposite to read-only
						//
						List<Node> nods = ((NodeContainer) newNode).getNodes();
						if (!nods.isEmpty()) {
							Node roleNode = (Node) nods.get(0);
							roleNode.setReadOnly(true);
						}
					}
					nodes.add(newNode);
				}
			}
		} else {
			Node newNode = createRoleTaskComposite(roleDescriptor);
			if (newNode != null) {
				if (ProcessUtil.isInherited(object)) {
					// task descriptor is inherited, its primary performer is
					// not local
					// set role node of the RoleTaskComposite to read-only
					//
					List<Node> nods = ((NodeContainer) newNode).getNodes();
					if (!nods.isEmpty()) {
						Node roleNode = (Node) nods.get(0);
						roleNode.setReadOnly(true);
					}
				}
				nodes.add(newNode);
			}
		}
    	
	}

	/**
	 * @param taskDescriptor
	 * @return
	 */
	Node createNode(TaskDescriptor taskDescriptor) {
		Node node = ModelFactory.eINSTANCE.createTaskNode();
		node.setUMAContainer(getGraphNode());
		node.setDiagram(this);
		node.setObject(taskDescriptor);
		return node;
	}

	/**
	 * @param descriptor
	 * @return
	 */
	Node createNode(WorkProductDescriptor descriptor) {
		Node node = ModelFactory.eINSTANCE.createWorkProductDescriptorNode();
		node.setUMAContainer(getGraphNode());
		node.setDiagram(this);
		node.setObject(descriptor);
		return node;
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see org.eclipse.epf.diagram.model.impl.DiagramImpl#populateLinks()
	 */
	protected void populateLinks() {
		populateLinks(getNodes(), true);
	}

	/**
	 * @param newNodes
	 * @param disableNotification
	 */
	protected void populateLinks(Collection newNodes, boolean disableNotification) {
		// fill outgoing/incoming connection lists of all nodes
		//
		int size = getNodes().size();
		boolean[] notifies = new boolean[size];
		try {
			if (disableNotification)
				// disable notification for all nodes in this diagram to avoid
				// unwanted concurrent modification of their connection list
				//
				for (int i = 0; i < size; i++) {
					Node node = ((Node) getNodes().get(i));
					notifies[i] = node.eDeliver();
					node.eSetDeliver(false);
				}

			for (Iterator iter = newNodes.iterator(); iter.hasNext();) {
				Node child = (Node) iter.next();
				if (child instanceof WorkProductComposite) {
					// WorkProductComposite workproductComposite =
					// (WorkProductComposite) child.getObject();
					WorkProductCompositeImpl workproductComposite = (WorkProductCompositeImpl) child;
					if (workproductComposite.getType() == WorkProductComposite.INPUTS) {
						Object object = workproductComposite.getObject();
						if (object instanceof TaskDescriptor) {
//							Node node = GraphicalDataHelper.findNode(this,
//									object, TaskNode.class);
							TaskNode node = workproductComposite.getTaskNode();
							if(node != null && GraphicalDataHelper.findLink(child, object) == null) {
								Link link = ModelFactory.eINSTANCE.createLink();
								link.setSource(child);
								link.setTarget(node);
								if(isGraphicalDataRequired()) {
									GraphicalDataHelper.addGraphicalData(link);
								}
							}
						}
					}
					if (workproductComposite.getType() == WorkProductComposite.OUTPUTS) {
						Object object = workproductComposite.getObject();
						if (object instanceof TaskDescriptor) {
//							Node node = GraphicalDataHelper.findNode(this,
//									object, TaskNode.class);
							TaskNode node = workproductComposite.getTaskNode();
							if(node != null && GraphicalDataHelper.findLink(node, object) == null) {
								Link link = ModelFactory.eINSTANCE.createLink();
								link.setSource(node);
								link.setTarget(child);
								if(isGraphicalDataRequired()) {
									GraphicalDataHelper.addGraphicalData(link);
								}
							}
						}
					}
				}
			}
 		} finally {
			if (disableNotification)
				// restore notification flag
				//
				for (int i = 0; i < size; i++) {
					((EObject) getNodes().get(i)).eSetDeliver(notifies[i]);
				}
		}

	}
	
	private RoleTaskComposite doCreateRoleTaskComposite(RoleDescriptor roleDescriptor, int index) {
		RoleTaskComposite roleTaskComposite = null;
		for (Iterator iter = getNodes().iterator(); iter.hasNext();) {
			Node element = (Node) iter.next();
			if (element instanceof RoleTaskComposite) {
				RoleTaskComposite rtc = (RoleTaskComposite) element;
				if(rtc.getLinkedElement() == roleDescriptor && rtc.getRowIndex() == index) {
					roleTaskComposite = rtc;
					break;
				}
			}
		}

		if (roleTaskComposite == null) {
			roleTaskComposite = ModelFactory.eINSTANCE
					.createRoleTaskComposite();
			roleTaskComposite.setUMAContainer(getGraphNode());
			roleTaskComposite.setDiagram(this);
		}
		return roleTaskComposite;
	}

	public RoleTaskComposite createRoleTaskComposite(
			RoleDescriptor roleDescriptor) {
		RoleTaskComposite roleTaskComposite = doCreateRoleTaskComposite(roleDescriptor,0);
		roleTaskComposite.setObject(roleDescriptor);
		return roleTaskComposite;
	}
	
	public RoleTaskComposite createRoleTaskComposite(
			RoleDescriptor roleDescriptor, int rowIndex) {
		RoleTaskComposite roleTaskComposite = doCreateRoleTaskComposite(roleDescriptor, rowIndex);
		((RoleTaskCompositeImpl)roleTaskComposite).setRowIndex(rowIndex);
		roleTaskComposite.setObject(roleDescriptor);
		return roleTaskComposite;
	}

	public WorkProductComposite createWorkProductComposite(
			TaskDescriptor taskDescriptor, int type) {
		WorkProductComposite workproductComposite = null;
		for (Node element : getNodes()) {
			if (element instanceof WorkProductComposite) {
				WorkProductComposite wpc = (WorkProductComposite) element;
				if(wpc.getLinkedElement() == taskDescriptor && wpc.getType() == type) {					
					workproductComposite = wpc;
					break;
				}
			}
		}
		if(workproductComposite == null) {
			workproductComposite = ModelFactory.eINSTANCE
			.createWorkProductComposite();
			workproductComposite.setType(type);
		}
		workproductComposite.setUMAContainer(getGraphNode());
		workproductComposite.setDiagram(this);
		workproductComposite.setObject(taskDescriptor);
		setState(type, workproductComposite);
		return workproductComposite;
	}

	public WorkProductComposite createWorkProductComposite(
			TaskNode taskNode, int type) {
		TaskDescriptor taskDescriptor = (TaskDescriptor) taskNode.getLinkedElement();
		// find existing WorkProductComposite for the given TaskNode
		//
		List<Link> links = type == WorkProductComposite.OUTPUTS ? taskNode.getOutgoingConnections() : taskNode.getIncomingConnections();
		WorkProductComposite workproductComposite = null;
		for (Link link : links) {
			Node node = type == WorkProductComposite.OUTPUTS ? link.getTarget() : link.getSource();
			if(node instanceof WorkProductComposite) {
				WorkProductComposite wpc = (WorkProductComposite) node;
				if(wpc.getLinkedElement() == taskDescriptor && wpc.getType() == type) {					
					workproductComposite = wpc;
					break;
				}				
			}
		}
		if(workproductComposite == null) {
			workproductComposite = ModelFactory.eINSTANCE
			.createWorkProductComposite();
			workproductComposite.setType(type);
			((WorkProductCompositeImpl) workproductComposite).setTaskNode(taskNode);
		}
		workproductComposite.setUMAContainer(getGraphNode());
		workproductComposite.setDiagram(this);
		workproductComposite.setObject(taskDescriptor);
		
		setState(type, workproductComposite);
		return workproductComposite;
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see org.eclipse.epf.diagram.model.impl.DiagramImpl#getType()
	 */
	protected int getType() {
		return GraphicalDataHelper.ACTIVITY_DETAIL_DIAGRAM;
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see org.eclipse.epf.diagram.model.impl.DiagramImpl#getDiagramChangeListenerType()
	 */
	protected Class getDiagramChangeListenerType() {
		return IActivityDetailDiagramChangeListener.class;
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see org.eclipse.epf.diagram.model.impl.DiagramImpl#getBreakdownElementType()
	 */
	protected Class getBreakdownElementType() {
		return Descriptor.class;
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see org.eclipse.epf.diagram.model.impl.DiagramImpl#toNode(org.eclipse.epf.uma.MethodElement)
	 */
	protected Node toNode(MethodElement e) {
		if (e instanceof RoleDescriptor) {
			List list = //AssociationHelper.getPrimaryTaskDescriptors((RoleDescriptor) e);
				getRealizedPrimaryTaskDescriptors((RoleDescriptor)e);
			if(!list.isEmpty()) {
				for (Iterator iterator = list.iterator(); iterator.hasNext();) {
					Object obj = iterator.next();
					if (obj instanceof TaskDescriptor) {
						createTaskInputOutputNodes((TaskDescriptor) obj, getNodes());
					}
				}
				return createRoleTaskComposite((RoleDescriptor) e);
			}
		} else if (e instanceof TaskDescriptor) {
			createTaskInputOutputNodes((TaskDescriptor) e, getNodes());
		}
		return null;
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see org.eclipse.epf.diagram.model.impl.DiagramImpl#addNode(java.lang.Object)
	 */
	protected Node addNode(Object obj) {
		if (filter == null) {
			filter = ((ConfigurableComposedAdapterFactory) DEFAULT_ADAPTER_FACTORIES[0])
					.getFilter();
		}
		Node node = null;
		if (obj instanceof TaskDescriptor) {
			List<RoleDescriptor> descList = ((TaskDescriptor) obj).getPerformedPrimarilyBy();
			find_node:
			for (RoleDescriptor roleDescriptor : descList)	{
				if (filter.accept(roleDescriptor)) {
					node = findNode(this, roleDescriptor);
					if (node == null) {
						node = createRoleTaskComposite(roleDescriptor);
						getNodes().add(node);
					} else {
						node = super.addNode(getNodes(), obj);
					}
					if(node != null) {
						break find_node;
					}
				}
			}
		} else {
			node = super.addNode(getNodes(), obj);
		}
		if (node != null) {
			populateLinks(Collections.singletonList(node), false);
		}
		return node;
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see org.eclipse.epf.diagram.model.impl.DiagramImpl#addNodes(java.util.Collection)
	 */
	protected Collection addNodes(Collection collection) {
		Collection nodes = super.addNodes(collection);
		if (!nodes.isEmpty()) {
			populateLinks(nodes, false);
		}
		return nodes;
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see org.eclipse.epf.diagram.model.impl.DiagramImpl#removeFromUmaModel(org.eclipse.epf.diagram.model.Node)
	 */
	protected void removeFromUmaModel(Node removedNode) {
		// if the removed node is a TaskNode that had been moved to a
		// RoleTaskComposite
		// then its TaskDescriptor will not be removed from model
		//
		if (GraphicalDataHelper.findNode(this, removedNode.getObject()) != null) {
			return;
		}
		if (removedNode instanceof RoleTaskComposite
				|| removedNode instanceof WorkProductComposite)
			return;

		super.removeFromUmaModel(removedNode);
	}

	protected void addToUmaModel(int position, Node addedNode) {
		super.addToUmaModel(position, addedNode);

		if (addedNode.getObject() instanceof BreakdownElement) {
			Activity act = (Activity) getObject();
			// translate Node index to Activity index
			int i = toActivityIndex(position);
			System.out
					.println("ActivityDetailDiagram.addToUmaModel(): WorkBreakdownElement index: " + i); //$NON-NLS-1$
			if (i == -1) {
				act.getBreakdownElements().add((BreakdownElement) addedNode.getObject());
			} else {
				act.getBreakdownElements().add(i, (BreakdownElement) addedNode.getObject());
			}
		}

	}

	private int toActivityIndex(int index) {
		if (index == -1)
			return index;
		int size = getNodes().size();
		int i = index + 1;
		if (i == size)
			return -1;
		Node node = (Node) getNodes().get(i);
		if (node == null)
			return -1;

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

	}

	public Node findNode(ActivityDetailDiagram diagram, Object object) {
		for (Iterator iter = diagram.getNodes().iterator(); iter.hasNext();) {
			Node element = (Node) iter.next();
			if (object == element.getObject()) {
				return element;
			}
		}
		return null;
	}
	
	private static final AdapterFactory[] DEFAULT_ADAPTER_FACTORIES = {			
		TngAdapterFactory.INSTANCE.getWBS_ComposedAdapterFactory(),
		TngAdapterFactory.INSTANCE.getOBS_ComposedAdapterFactory(),
		TngAdapterFactory.INSTANCE.getPBS_ComposedAdapterFactory() 
	}; 
	
	public void createTaskInputOutputNodes(TaskDescriptor descriptor, Collection nodes) {
		Node newNode = null;
		if (!descriptor.getMandatoryInput().isEmpty()) {
			newNode = createWorkProductComposite(descriptor,
					WorkProductComposite.INPUTS);
			nodes.add(newNode);
		}
		if (!descriptor.getOutput().isEmpty()) {
			newNode = createWorkProductComposite(descriptor,
					WorkProductComposite.OUTPUTS);
			nodes.add(newNode);
		}
	}
	
	public void createTaskInputOutputNodes(TaskNode taskNode, Collection nodes) {
		TaskDescriptor descriptor = (TaskDescriptor) taskNode.getLinkedElement();
		Node newNode = null;
		if (!descriptor.getMandatoryInput().isEmpty()) {
			newNode = createWorkProductComposite(taskNode,
					WorkProductComposite.INPUTS);
			nodes.add(newNode);
		}
		if (!descriptor.getOutput().isEmpty()) {
			newNode = createWorkProductComposite(taskNode,
					WorkProductComposite.OUTPUTS);
			nodes.add(newNode);
		}		
	}
	
	/* (non-Javadoc)
	 * @see org.eclipse.epf.diagram.model.impl.DiagramImpl#setNew(boolean)
	 */
	public void setNew(boolean n) {
		super.setNew(n);
		if(n){
			doSetAutoLayout(true);
		}
	}
	
	@Override
	/**
	 * Enable this code, once the task index is fixed in the roletaskcomposite.
	 */
	public void moveNode(Object movedObject, int position, Object oldPosition) {
		if(!(movedObject instanceof TaskDescriptor))
			return;
		TaskDescriptor taskDescriptor = (TaskDescriptor) movedObject;
		List<RoleDescriptor> descList = ((TaskDescriptor) movedObject)
				.getPerformedPrimarilyBy();
		find_node:
		for (RoleDescriptor roleDescriptor : descList) {
			if (filter.accept(roleDescriptor)) {
				Node roleNode = findNode(this, roleDescriptor);
				if (roleNode != null) {
					int oldPos = 0;
					if (oldPosition instanceof Integer) {
						oldPos = ((Integer) oldPosition).intValue();
					}
					TaskNode taskNode = (TaskNode) GraphicalDataHelper
							.findNode((NodeContainer) roleNode, taskDescriptor,
									TaskNode.class);

					// move up
					if (oldPos > position) {
						int i = taskNode.getIndex();
						Node prevNode = findTaskNode(
								(RoleTaskComposite) roleNode, i - 1);
						if (prevNode != null) {
							taskNode.setIndex(i - 1);
							((TaskNode) prevNode).setIndex(i);
						}

					} else {
						// move down
						int i = taskNode.getIndex();
						Node nextNode = findTaskNode(
								(RoleTaskComposite) roleNode, i + 1);
						if (nextNode != null) {
							taskNode.setIndex(i + 1);
							((TaskNode) nextNode).setIndex(i);
						}
					}
					
					break find_node;
				}
			}
		}
	}
	
	private Node findTaskNode(RoleTaskComposite container, int index) {
		for (Iterator iter = container.getNodes().iterator(); iter.hasNext();) {
			Node element = (Node) iter.next();
			if(element instanceof TaskNode){
				if(((TaskNode)element).getIndex() == index){
					return element;
				}
			}
		}
		return null;
	}
	
	public List getRealizedPrimaryTaskDescriptors(RoleDescriptor r){
		List list = new ArrayList();
		if(r != null){
			List actualList = AssociationHelper.getPrimaryTaskDescriptors(r);
			Collection collection = getAllBreakdownElements(true);
			for(Iterator iterator = actualList.iterator(); iterator.hasNext();){
				Object e = iterator.next();
				if(TngUtil.contains(collection, e)){
					list.add(e);
				}
			}
		}
		return list;
	}
	
	private void setState(int type, Node node) {
		if (node instanceof NodeContainer) {
			for (Node element : ((NodeContainer)node).getNodes()) {
				if (element instanceof WorkProductDescriptorNode) {
					WorkProductDescriptorNode wpNode = (WorkProductDescriptorNode) element;
					MethodElement methodElement = wpNode.getLinkedElement();
					if (methodElement instanceof WorkProductDescriptor){
						String stateText = null;
						if (type == WorkProductComposite.INPUTS)
							stateText = ((WorkProductDescriptor) methodElement).getActivityEntryState();
						else if (type == WorkProductComposite.OUTPUTS)
							stateText = ((WorkProductDescriptor) methodElement).getActivityExitState();
						wpNode.setState(stateText);
					}					
				}
			}	
		}
	}
	
} // ActivityDetailDiagramImpl
