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

import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.MissingResourceException;
import java.util.Set;

import org.eclipse.emf.common.notify.AdapterFactory;
import org.eclipse.emf.common.notify.Notification;
import org.eclipse.emf.common.notify.impl.NotificationImpl;
import org.eclipse.emf.common.ui.viewer.IViewerProvider;
import org.eclipse.emf.common.util.AbstractTreeIterator;
import org.eclipse.emf.common.util.EList;
import org.eclipse.emf.ecore.EAttribute;
import org.eclipse.emf.ecore.EClass;
import org.eclipse.emf.ecore.EObject;
import org.eclipse.emf.ecore.EStructuralFeature;
import org.eclipse.emf.edit.provider.AdapterFactoryTreeIterator;
import org.eclipse.emf.edit.provider.IChangeNotifier;
import org.eclipse.emf.edit.provider.IItemLabelProvider;
import org.eclipse.emf.edit.provider.ITreeItemContentProvider;
import org.eclipse.emf.edit.provider.IWrapperItemProvider;
import org.eclipse.emf.edit.provider.ItemProviderAdapter;
import org.eclipse.emf.edit.provider.ViewerNotification;
import org.eclipse.epf.common.utils.StrUtil;
import org.eclipse.epf.library.edit.IConfigurationApplicator;
import org.eclipse.epf.library.edit.IConfigurator;
import org.eclipse.epf.library.edit.IFilter;
import org.eclipse.epf.library.edit.LibraryEditPlugin;
import org.eclipse.epf.library.edit.LibraryEditResources;
import org.eclipse.epf.library.edit.Providers;
import org.eclipse.epf.library.edit.TngAdapterFactory;
import org.eclipse.epf.library.edit.command.IActionManager;
import org.eclipse.epf.library.edit.process.BSActivityItemProvider;
import org.eclipse.epf.library.edit.process.BreakdownElementWrapperItemProvider;
import org.eclipse.epf.library.edit.process.ComposedBreakdownElementWrapperItemProvider;
import org.eclipse.epf.library.edit.process.DescribableElementWrapperItemProvider;
import org.eclipse.epf.library.edit.process.IBSItemProvider;
import org.eclipse.epf.library.edit.process.RoleDescriptorWrapperItemProvider;
import org.eclipse.epf.library.edit.process.WorkProductDescriptorWrapperItemProvider;
import org.eclipse.epf.library.edit.process.command.BSDropCommand;
import org.eclipse.epf.library.edit.process.command.ProcessCommandUtil;
import org.eclipse.epf.library.edit.process.command.WBSDropCommand;
import org.eclipse.epf.library.edit.ui.UserInteractionHelper;
import org.eclipse.epf.library.edit.validation.NameChecker;
import org.eclipse.epf.uma.Activity;
import org.eclipse.epf.uma.Artifact;
import org.eclipse.epf.uma.BreakdownElement;
import org.eclipse.epf.uma.CompositeRole;
import org.eclipse.epf.uma.ContentPackage;
import org.eclipse.epf.uma.Deliverable;
import org.eclipse.epf.uma.Descriptor;
import org.eclipse.epf.uma.Guidance;
import org.eclipse.epf.uma.MethodConfiguration;
import org.eclipse.epf.uma.MethodElement;
import org.eclipse.epf.uma.MethodPlugin;
import org.eclipse.epf.uma.Process;
import org.eclipse.epf.uma.ProcessComponent;
import org.eclipse.epf.uma.ProcessPackage;
import org.eclipse.epf.uma.Role;
import org.eclipse.epf.uma.RoleDescriptor;
import org.eclipse.epf.uma.Task;
import org.eclipse.epf.uma.TaskDescriptor;
import org.eclipse.epf.uma.TeamProfile;
import org.eclipse.epf.uma.UmaFactory;
import org.eclipse.epf.uma.UmaPackage;
import org.eclipse.epf.uma.VariabilityElement;
import org.eclipse.epf.uma.VariabilityType;
import org.eclipse.epf.uma.WorkBreakdownElement;
import org.eclipse.epf.uma.WorkOrder;
import org.eclipse.epf.uma.WorkProduct;
import org.eclipse.epf.uma.WorkProductDescriptor;
import org.eclipse.epf.uma.provider.UmaEditPlugin;
import org.eclipse.epf.uma.util.AssociationHelper;
import org.eclipse.epf.uma.util.UmaUtil;
import org.eclipse.jface.viewers.IContentProvider;
import org.eclipse.jface.viewers.Viewer;

import com.ibm.icu.text.MessageFormat;
import com.ibm.icu.util.StringTokenizer;


/**
 * Utility class that defines static methods for process authoring
 * 
 * @author Phong Nguyen Le
 * @author Shilpa Toraskar
 * @since 1.0
 */
public final class ProcessUtil {
	private static Collection OBSEclasses = null;

	private static Collection WBSEclasses = null;

	private static Collection PBSEclasses = null;

	private static Collection extendAndLocalContributionVariabilityTypes = null;

	private static Collection getExtendAndLocalContributionVariabilityTypes() {
		if (extendAndLocalContributionVariabilityTypes == null) {
			extendAndLocalContributionVariabilityTypes = new ArrayList();
			extendAndLocalContributionVariabilityTypes
					.add(VariabilityType.EXTENDS_LITERAL);
			extendAndLocalContributionVariabilityTypes
					.add(VariabilityType.LOCAL_CONTRIBUTION_LITERAL);
		}
		return extendAndLocalContributionVariabilityTypes;
	}

	public static String checkBreakdownElementName(
			AdapterFactory adapterFactory, BreakdownElement e, String name, Suppression suppression) {
		return NameChecker.checkName(adapterFactory, e, UmaPackage.eINSTANCE
				.getNamedElement_Name(), name, suppression);
	}
	
	public static String checkBreakdownElementName(
			AdapterFactory adapterFactory, BreakdownElement e, String name, Suppression suppression, boolean ignoreSuppressed) {
		return NameChecker.checkName(adapterFactory, e, UmaPackage.eINSTANCE
				.getNamedElement_Name(), name, suppression, ignoreSuppressed);
	}

	public static String checkBreakdownElementPresentationName(
			AdapterFactory adapterFactory, BreakdownElement e, String name, Suppression suppression) {
		// might allow empty presentation name for extender or contributor. The element will inherit
		// the presentation name from the base element. Check will be performed on the inherited name
		//
		if (name == null || name.length() == 0) {
			if (isExtendingOrLocallyContributing(e)) {
				BreakdownElement base = (BreakdownElement) ((VariabilityElement) e)
						.getVariabilityBasedOnElement();
				name = getPresentationName(base);
			}
		}
		return NameChecker.checkName(adapterFactory, e, UmaPackage.eINSTANCE
				.getDescribableElement_PresentationName(), name, suppression);
	}
	
	public static String checkBreakdownElementPresentationName(
			AdapterFactory adapterFactory, BreakdownElement e, String name, Suppression suppression, boolean ignoreSuppressed) {

		return NameChecker.checkName(adapterFactory, e, UmaPackage.eINSTANCE
				.getDescribableElement_PresentationName(), name, suppression, ignoreSuppressed);
	}

	public static Object getRootProcess(AdapterFactory adapterFactory,
			ItemProviderAdapter adapter, Object obj) {
		Object parent = adapter.getParent(obj);
		adapter = (ItemProviderAdapter) adapterFactory.adapt(parent,
				ITreeItemContentProvider.class);
		if (parent == null) {
			return obj;
		} else {
			return getRootProcess(adapterFactory, adapter, parent);
		}
	}

	public static Collection getWBSEclasses() {
		if (WBSEclasses == null) {
			WBSEclasses = new HashSet();
			WBSEclasses.add(UmaPackage.eINSTANCE.getTaskDescriptor());
			WBSEclasses.add(UmaPackage.eINSTANCE.getActivity());
			WBSEclasses.add(UmaPackage.eINSTANCE.getMilestone());
		}
		return WBSEclasses;
	}

	public static Collection getOBSEclasses() {
		if (OBSEclasses == null) {
			OBSEclasses = new HashSet();
			OBSEclasses.add(UmaPackage.eINSTANCE.getRoleDescriptor());
			OBSEclasses.add(UmaPackage.eINSTANCE.getActivity());
			OBSEclasses.add(UmaPackage.eINSTANCE.getMilestone());
			OBSEclasses.add(UmaPackage.eINSTANCE.getTeamProfile());
			OBSEclasses.add(UmaPackage.eINSTANCE.getCompositeRole());
		}

		return OBSEclasses;
	}

	public static Collection getPBSEclasses() {
		if (PBSEclasses == null) {
			PBSEclasses = new HashSet();
			PBSEclasses.add(UmaPackage.eINSTANCE.getWorkProductDescriptor());
			PBSEclasses.add(UmaPackage.eINSTANCE.getActivity());
			PBSEclasses.add(UmaPackage.eINSTANCE.getMilestone());
		}
		return PBSEclasses;
	}

	public static boolean isFirstElement(AdapterFactory adapterFactory,
			ItemProviderAdapter itemProvider, Object obj) {
		Object parent = itemProvider.getParent(obj);
		if (parent instanceof TeamProfile)
			return true;
		LinkedList siblings = getSiblings(adapterFactory, itemProvider, obj);
		if (siblings != null && !siblings.isEmpty()) {
			return siblings.getFirst() == obj;
		}
		return true;
	}

	public static LinkedList getSiblings(AdapterFactory adapterFactory,
			ItemProviderAdapter itemProvider, Object obj) {
		Object parent = itemProvider.getParent(obj);
		if (parent == null)
			return null;
		ITreeItemContentProvider parentItemProvider = (ITreeItemContentProvider) adapterFactory
				.adapt(parent, ITreeItemContentProvider.class);
		if (parentItemProvider != null) {
			return new LinkedList(parentItemProvider.getChildren(parent));
		}
		return null;
	}

	public static boolean isLastElement(AdapterFactory adapterFactory,
			ItemProviderAdapter itemProvider, Object obj) {
		Object parent = itemProvider.getParent(obj);
		if (parent instanceof TeamProfile)
			return true;
		LinkedList siblings = getSiblings(adapterFactory, itemProvider, obj);
		if (siblings != null && !siblings.isEmpty()) {
			return siblings.getLast() == obj;
		}
		return true;
	}

	/**
	 * Gets elements that have been affected after the event that triggered the
	 * given notification.
	 * 
	 * @param notification
	 * @param filter
	 * @return
	 */
	public static List getAffectedElements(Notification notification,
			IFilter filter) {
		List affectedElements = new ArrayList();
		switch (notification.getEventType()) {
		case Notification.ADD:
			Object obj = notification.getNewValue();
			if (filter == null || filter.accept(obj)) {
				affectedElements.add(obj);
			}
			break;
		case Notification.ADD_MANY:
			for (Iterator iter = ((Collection) notification.getNewValue())
					.iterator(); iter.hasNext();) {
				Object element = iter.next();
				if (filter == null || filter.accept(element)) {
					affectedElements.add(element);
				}
			}
			break;
		case Notification.REMOVE:
			obj = notification.getOldValue();
			if (filter == null || filter.accept(obj)) {
				affectedElements.add(obj);
			}
			break;
		case Notification.REMOVE_MANY:
			for (Iterator iter = ((Collection) notification.getOldValue())
					.iterator(); iter.hasNext();) {
				Object element = iter.next();
				if (filter == null || filter.accept(element)) {
					affectedElements.add(element);
				}
			}
			break;

		case Notification.MOVE:
			obj = notification.getNewValue();
			if (obj instanceof Collection) {
				for (Iterator iter = ((Collection) obj).iterator(); iter
						.hasNext();) {
					Object element = iter.next();
					if (filter == null || filter.accept(element)) {
						affectedElements.add(element);
					}
				}
			} else {
				if (filter == null || filter.accept(obj)) {
					affectedElements.add(obj);
				}
			}
			break;
		}
		return affectedElements;
	}

	public static boolean isRefreshRequired(Notification notification,
			IFilter filter) {
		switch (notification.getEventType()) {
		case Notification.SET:
		case Notification.ADD:
			Object obj = notification.getNewValue();
			if (filter == null || filter.accept(obj)) {
				return true;
			}
			break;
		case Notification.ADD_MANY:
			for (Iterator iter = ((Collection) notification.getNewValue())
					.iterator(); iter.hasNext();) {
				Object element = iter.next();
				if (filter == null || filter.accept(element)) {
					return true;
				}
			}
			break;
		case Notification.REMOVE:
			obj = notification.getOldValue();
			if (filter == null || filter.accept(obj)) {
				return true;
			}
			break;
		case Notification.REMOVE_MANY:
			for (Iterator iter = ((Collection) notification.getOldValue())
					.iterator(); iter.hasNext();) {
				Object element = iter.next();
				if (filter == null || filter.accept(element)) {
					return true;
				}
			}
			break;

		case Notification.MOVE:
			obj = notification.getNewValue();
			if (obj instanceof Collection) {
				for (Iterator iter = ((Collection) obj).iterator(); iter
						.hasNext();) {
					Object element = iter.next();
					if (filter == null || filter.accept(element)) {
						return true;
					}
				}
			} else {
				if (filter == null || filter.accept(obj)) {
					return true;
				}
			}
			break;
		}

		return false;
	}

	public static void addToContainer(BreakdownElement e,
			ItemProviderAdapter itemProvider) {
		addToContainer(e, itemProvider, true);
	}

	/**
	 * Adds the given BreakdownElement to a new container if it does not have
	 * one or moves it to the right container if requested.
	 * 
	 * @param e
	 * @param itemProvider
	 */
	public static void addToContainer(BreakdownElement e,
			ItemProviderAdapter itemProvider, boolean move) {
		ProcessPackage pkg = null;
		Object parent = itemProvider.getParent(e);
		if (parent instanceof EObject) {
			EObject container = ((EObject) parent).eContainer();
			if (container instanceof ProcessPackage) {
				pkg = (ProcessPackage) container;
			}
		}

		if (pkg == null) {
			return;
		}

		if (e instanceof Activity) {
			Activity act = (Activity) e;
			if (act.eContainer() == null) {
				// create new ProcessPackage for the activity
				//
				ProcessPackage newPkg = UmaFactory.eINSTANCE
						.createProcessPackage();
				newPkg.setName(act.getName());
				pkg.getChildPackages().add(newPkg);
				newPkg.getProcessElements().add(e);
			} else if (move) {
				// Check if the activity's ProcessPackage is at the right place.
				// If not, move it to the right ProcessComponent.
				//
				ProcessPackage oldPkg = (ProcessPackage) act.eContainer();
				if (oldPkg.eContainer() != pkg) {
					pkg.getChildPackages().add(oldPkg);
				}
			}
		} else {
			if (e.eContainer() == null) {
				pkg.getProcessElements().add(e);
			} else if (move && e.eContainer() != pkg) {
				// move to new ProcessPackage
				//
				pkg.getProcessElements().add(e);
			}
		}
	}

	public static void setParent(Object child, Object parent,
			AdapterFactory adapterFactory) {
		Object adapter = adapterFactory.adapt(child,
				ITreeItemContentProvider.class);
		if (adapter instanceof IBSItemProvider) {
			((IBSItemProvider) adapter).setParent(parent);
		} 
//		else {
//			System.out
//					.println(LibraryEditResources.util_ProcessUtil_err_setparent + child); //$NON-NLS-1$
//			System.out
//					.println(LibraryEditResources.util_ProcessUtil_childadapter + adapter); //$NON-NLS-1$
//		}
	}

	/**
	 * Creates a new RoleDescriptor from the given role.
	 * 
	 * @param role
	 * @return
	 */
	public static RoleDescriptor createRoleDescriptor(Role role) {
		RoleDescriptor roleDesc = UmaFactory.eINSTANCE.createRoleDescriptor();
		roleDesc.setRole(role);
		String presentationName = role.getPresentationName();
		roleDesc.setName(role.getName());
		roleDesc.setPresentationName(StrUtil.isBlank(presentationName) ? role
				.getName() : presentationName);
		// roleDesc.setBriefDescription(role.getBriefDescription());
		return roleDesc;
	}

	public static WorkProductDescriptor createWorkProductDescriptor(
			WorkProduct wp) {
		WorkProductDescriptor wpDesc = UmaFactory.eINSTANCE
				.createWorkProductDescriptor();
		wpDesc.setWorkProduct(wp);
		wpDesc.setName(wp.getName());
		wpDesc
				.setPresentationName(StrUtil.isBlank(wp.getPresentationName()) ? wp
						.getName()
						: wp.getPresentationName());
		// wpDesc.setBriefDescription(wp.getBriefDescription());
		return wpDesc;
	}

	public static Viewer getViewer(AdapterFactory adapterFactory, Process proc) {
		if (adapterFactory instanceof ExposedAdapterFactory) {
			for (Iterator iter = Collections.unmodifiableList(
					((ExposedAdapterFactory) adapterFactory)
							.getChangeListeners()).iterator(); iter.hasNext();) {
				Object listener = iter.next();
				if (listener instanceof IContentProvider && listener instanceof IViewerProvider) {					
					Viewer viewer = ((IViewerProvider) listener).getViewer();
					if (viewer.getInput() instanceof ProcessComponent
							&& ((ProcessComponent) viewer.getInput())
									.getProcess() == proc)
						return viewer;
				}
			}
		}
		return null;
	}

	public static boolean refreshNeeded(AdapterFactory adapterFactory,
			BSActivityItemProvider itemProvider) {
		Process process = (Process) itemProvider.getTopItem();
		if (process == null)
			return false;

		// check if the given process is currently opened in editor
		//
		Viewer viewer = getViewer(adapterFactory, process);
		if (viewer != null && viewer.getControl() != null
				&& !viewer.getControl().isDisposed()) {
			return true;
		}

		for (Iterator iter = TngUtil.getContributors(process); iter.hasNext();) {
			Object element = iter.next();
			BSActivityItemProvider adapter = (BSActivityItemProvider) adapterFactory
					.adapt(element, ITreeItemContentProvider.class);
			if (refreshNeeded(adapterFactory, adapter))
				return true;
		}

		for (Iterator iter = TngUtil.getGeneralizers(process,
				VariabilityType.EXTENDS_LITERAL); iter.hasNext();) {
			Object element = iter.next();
			BSActivityItemProvider adapter = (BSActivityItemProvider) adapterFactory
					.adapt(element, ITreeItemContentProvider.class);
			if (refreshNeeded(adapterFactory, adapter))
				return true;
		}

		return false;
	}
	
	public static void refreshPredeccessorLists(AdapterFactory factory, Process proc) {
		Object obj;
		Object element;
		for (Iterator iter = new AdapterFactoryTreeIterator(factory, proc); iter
		.hasNext();) {
			obj = iter.next();
			element = TngUtil.unwrap(obj);
			if(element instanceof WorkBreakdownElement) {
				Object adapter = factory.adapt(obj, ITreeItemContentProvider.class);
				if (adapter instanceof IBSItemProvider) {				
					IBSItemProvider itemProvider = (IBSItemProvider) adapter;
					PredecessorList predList = itemProvider.getPredecessors();
					if(predList != null) {
						predList.refresh();
					}
				}
			}
		}
	}
	
	/**
	 * Updates IDs of work breakdown elements of the view of the given process
	 * 
	 * @param factory
	 *            adapter factory of the current process view (WBS, TBS, WPBS,
	 *            CBS)
	 * @param proc
	 *            must be refreshed.
	 */
	public static void updateIDs(AdapterFactory factory, Process proc) {
		int id = 0;
		Object obj;
		// Map changeMap = new HashMap();
		for (Iterator iter = new AdapterFactoryTreeIterator(factory, proc); iter
				.hasNext();) {
			obj = iter.next();
			Object adapter = factory.adapt(obj, ITreeItemContentProvider.class);
			if (adapter instanceof IBSItemProvider) {
				IBSItemProvider itemProvider = (IBSItemProvider) adapter;
				if (itemProvider != null
						&& TngUtil.unwrap(obj) instanceof WorkBreakdownElement) {
					itemProvider.setId(id++);
					// changeMap.put(obj, itemProvider);
				}
			}
		}

		// refresh the label
		//
		// for (Iterator iterator = changeMap.entrySet().iterator();
		// iterator.hasNext();) {
		// Map.Entry entry = (Map.Entry) iterator.next();
		// IChangeNotifier adapter = (IChangeNotifier) entry.getValue();
		// obj = entry.getKey();
		// adapter.fireNotifyChanged(new ViewerNotification(new
		// NotificationImpl(Notification.SET, obj, obj), obj, false, true));
		// }
	}

	public static void refreshViewer(AdapterFactory factory, Process proc) {
		final Viewer viewer = getViewer(factory, proc);
		if (viewer != null && viewer.getControl() != null
				&& !viewer.getControl().isDisposed()) {
			UserInteractionHelper.runInUIThread(new Runnable() {

				public void run() {
					viewer.refresh();
				}
				
			});
		}
	}

	/**
	 * Refreshes the element IDs in those viewers that require this.
	 * 
	 * @param adapterFactory
	 */
	public static void refreshIDsInViewers(final ExposedAdapterFactory adapterFactory) {
		UserInteractionHelper.runInUIThread(new Runnable() {

			public void run() {
				for (Iterator iter = Collections.unmodifiableList(
						adapterFactory.getChangeListeners()).iterator(); iter.hasNext();) {
					Object listener = iter.next();
					if (listener instanceof IContentProvider && listener instanceof IViewerProvider) {					
						Viewer viewer = ((IViewerProvider) listener).getViewer();
						if (viewer != null && viewer.getControl() != null
								&& !viewer.getControl().isDisposed()
								&& viewer.getInput() instanceof ProcessComponent) {
							Process proc = ((ProcessComponent) viewer.getInput())
									.getProcess();
							BSActivityItemProvider itemProvider = (BSActivityItemProvider) adapterFactory
									.adapt(proc, ITreeItemContentProvider.class);
							if (itemProvider.isRefreshAllIDsRequired()) {
								updateIDs(adapterFactory, proc);
								viewer.refresh();
								itemProvider.setRefreshAllIDsRequired(false);
							}
						}
					}
				}
			}
			
		});
	}

	public static void refreshAllViewers(final ExposedAdapterFactory adapterFactory) {
		UserInteractionHelper.runInUIThread(new Runnable() {

			public void run() {
				for (Iterator iter = Collections.unmodifiableList(
						adapterFactory.getChangeListeners()).iterator(); iter.hasNext();) {
					Object listener = iter.next();
					if (listener instanceof IContentProvider && listener instanceof IViewerProvider) {					
						Viewer viewer = ((IViewerProvider) listener).getViewer();
						if (viewer != null && viewer.getControl() != null
								&& !viewer.getControl().isDisposed()
								&& viewer.getInput() instanceof ProcessComponent) {
							viewer.refresh();
						}
					}
				}
			}
			
		});
	}
	
	/**
	 * @param e
	 *            the breakdown element whose predecessor list to be checked.
	 * @param predIdList
	 *            a list of predecessor IDs (Integer) as shown in the ID column
	 *            of the editor
	 * @param adapterFactory
	 * @param process
	 * @param predecessors
	 *            output, the predecessor list
	 * @return null if predList is valid, an error message otherwise
	 */
	public static String checkPredecessorList(WorkBreakdownElement e,
			List predIdList, AdapterFactory adapterFactory, Object process,
			List predecessors) {
		// get BreakdownElement list from ID list
		//
		List beList = new ArrayList();
		List allElements = new ArrayList();
		for (Iterator iter = new AdapterFactoryTreeIterator(adapterFactory,
				process); iter.hasNext();) {
			Object obj = iter.next();
			IBSItemProvider itemProvider = (IBSItemProvider) adapterFactory
					.adapt(obj, ITreeItemContentProvider.class);
			Integer id = new Integer(itemProvider.getId());
			obj = TngUtil.unwrap(obj);
			allElements.add(obj);
			if (predIdList.contains(id)) {
				beList.add(obj);
			}
		}

		// check for circular dependency
		//
		int size = beList.size();
		for (int i = 0; i < size; i++) {
			Object obj = beList.get(i);
			if (obj instanceof WorkBreakdownElement) {
				WorkBreakdownElement pred = (WorkBreakdownElement) obj;
				if (ProcessUtil.checkCircular(e, pred, allElements)) {
					return LibraryEditResources.util_ProcessUtil_err_same_breakdown_element; //$NON-NLS-1$
				}
				if (TngUtil.isSubelementOf(pred, e, adapterFactory)) {
					return LibraryEditResources.util_ProcessUtil_err_same_sub_element; //$NON-NLS-1$
				}
				if (TngUtil.isSuperElementOf(pred, e, adapterFactory)) {
					return LibraryEditResources.util_ProcessUtil_err_child_element; //$NON-NLS-1$
				}
			} else
				return LibraryEditResources.util_ProcessUtil_err_wrong_element; //$NON-NLS-1$
		}

		if (predecessors != null)
			predecessors.addAll(beList);
		return null;
	}

	/**
	 * Checks for circular dependency
	 * 
	 * @param successor
	 * @param predecessor
	 * @param list
	 *            the list of all breakdown elements in the breakdown structure
	 */
	// public static boolean checkCircular(WorkBreakdownElement successor,
	// WorkBreakdownElement predecessor, List list) {
	// if(successor == predecessor) {
	// if(predecessor.getIsRepeatable().booleanValue()) {
	// return false;
	// }
	// return true;
	// }
	// for (Iterator iter = predecessor.getLinkToPredecessor().iterator();
	// iter.hasNext();) {
	// WorkOrder element = (WorkOrder) iter.next();
	// WorkBreakdownElement pred = element.getPred();
	// if(pred != predecessor && list.contains(pred)) {
	// if(checkCircular(successor, pred, list)) return true;
	// }
	// }
	// return false;
	// }
	public static boolean checkCircular(WorkBreakdownElement successor,
			WorkBreakdownElement predecessor, List list) {
		// if(successor == predecessor) {
		// if(predecessor.getIsRepeatable().booleanValue()) {
		// return false; // if ok return false means allowed.
		// }
		// return true;
		// }
		// List predecessorsList = new ArrayList();
		// getAllPredecessorList(predecessor, list, predecessorsList);
		// if(!predecessorsList.isEmpty()){
		// for(Iterator itor = predecessorsList.iterator(); itor.hasNext();){
		// Object obj = itor.next();
		// if(successor == obj){
		// if(((WorkBreakdownElement)obj).getIsRepeatable().booleanValue())
		// {
		// return false;
		// }
		// return true;
		// }
		// }
		// }
		return false;
	}

	public static void getAllPredecessorList(WorkBreakdownElement predecessor,
			List list, List predList) {
		if (!predList.contains(predecessor))
			predList.add(predecessor);
		for (Iterator iter = predecessor.getLinkToPredecessor().iterator(); iter
				.hasNext();) {
			WorkOrder element = (WorkOrder) iter.next();
			WorkBreakdownElement pred = (WorkBreakdownElement) element
					.getPred();
			if (pred != predecessor && list.contains(pred)) {
				if (!predList.contains(pred)) {
					predList.add(pred);
					getAllPredecessorList(pred, list, predList);
				}
			}
		}
	}

	/**
	 * 
	 * @param e
	 *            the breakdown element whose predecessor list to be checked.
	 * @param predList
	 *            a comma-separated list of predecessor IDs
	 * @param adapterFactory
	 * @param topAct
	 * @param predecessors
	 *            output, the predecessor list
	 * @param allElements
	 *            output, the whole breakdown element list is copied into this
	 *            list.
	 * @return null if predList is valid. The predecessor list is saved in
	 *         predecessors and the whole breakdown element list is saved in
	 *         allElements.
	 */
	public static String checkPredecessorList(WorkBreakdownElement e,
			String predList, AdapterFactory adapterFactory, Object topAct,
			List predecessors) {
		List idList = new ArrayList();
		for (StringTokenizer tokens = new StringTokenizer(predList, ","); tokens.hasMoreTokens();) { //$NON-NLS-1$
			String token = tokens.nextToken().trim();
			Integer id;
			try {
				id = new Integer(token);
			} catch (NumberFormatException ex) {
				return LibraryEditResources.invalidPredecessorError_msg; //$NON-NLS-1$
			}
			idList.add(id);
		}

		return checkPredecessorList(e, idList, adapterFactory, topAct,
				predecessors);
	}

	/**
	 * Adds the given object's method package and plugin to the default
	 * configuration of the given process if they are not in the configuration
	 * yet.
	 * 
	 * @param proc
	 * @param object
	 * @param addedObjects
	 */
	public static void addToDefaultConfiguration(Process proc, EObject e,
			Set addedObjects) {
		// add the element's method package to the default configuration
		//
		MethodConfiguration config = proc.getDefaultContext();
		if (e instanceof Task) {
			addTaskToDefaultConfiguration(proc, (Task) e, addedObjects, true);
		} else if (e instanceof WorkProduct) {
			WorkProduct wp = (WorkProduct) e;
			addWPToDefaultConfiguration(proc, wp, addedObjects);
			List tasks = getTasksForWorkProduct(wp, config);
			if (tasks != null)
			{
				for (Iterator iter = tasks.iterator(); iter.hasNext();) {
					addTaskToDefaultConfiguration(proc, (Task) iter.next(),
							addedObjects, false);
				}
			}
		} else if (e instanceof Role) {
			Role role = (Role) e;
			addRoleToDefaultConfiguration(proc, role, addedObjects);

		} else if (e instanceof Activity) {
			addActivityToDefaultConfiguration(proc, (Activity) e, addedObjects);
		} else if (e instanceof Guidance) {
			TngUtil.addToConfiguration(config, (Guidance) e, addedObjects);
		}
	}
	
	private static void addActivityToDefaultConfiguration(Process proc, Activity activity, Set addedObjects) {
		MethodConfiguration config = proc.getDefaultContext();
		TngUtil.addTo(config, UmaUtil.getProcessComponent(activity), addedObjects);
		// add linked element of descriptors
		//
		for (Iterator iter = activity.getBreakdownElements().iterator(); iter.hasNext();) {
			Object e = (Object) iter.next();
			if(e instanceof Descriptor) {
				MethodElement o = ProcessUtil.getAssociatedElement((Descriptor) e);
				if(o != null) {
					addToDefaultConfiguration(proc, o, addedObjects);
				}
			}
			else if (e instanceof Activity){
				// this is needed for adding sub-activities descriptors 
				addActivityToDefaultConfiguration(proc, (Activity) e, addedObjects);
			}
		}

		// add all the base elements if there is any
		for (Activity base = (Activity) activity.getVariabilityBasedOnElement(); base != null; base = (Activity) base
		.getVariabilityBasedOnElement()) {
			addActivityToDefaultConfiguration(proc, base, addedObjects);
		}
	}

	private static void addTaskToDefaultConfiguration(Process proc, Task task,
			Set addedObjects, boolean includeWorkProducts) {
		MethodConfiguration config = proc.getDefaultContext();

		TngUtil.addToConfiguration(config, task, addedObjects);

		// add all other dependencies
		//

		// add roles
		ArrayList dependencies = new ArrayList();
		dependencies.addAll(task.getAdditionallyPerformedBy());
		dependencies.add(task.getPerformedBy());
		for (Iterator iter = dependencies.iterator(); iter.hasNext();) {
			TngUtil.addToConfiguration(config, (EObject) iter.next(),
					addedObjects);
		}

		// add work products
		if (includeWorkProducts) {
			dependencies.clear();
			dependencies.addAll(task.getOptionalInput());
			dependencies.addAll(task.getOutput());
			dependencies.addAll(task.getMandatoryInput());
			for (Iterator iter = dependencies.iterator(); iter.hasNext();) {
				addWPToDefaultConfiguration(proc, (WorkProduct) iter.next(),
						addedObjects);
			}
		}

		for (Iterator iter = task.getSteps().iterator(); iter.hasNext();) {
			VariabilityElement step = (VariabilityElement) iter.next();
			EObject base = step.getVariabilityBasedOnElement();
			if (base != null) {
				TngUtil.addToConfiguration(config, base, addedObjects);
			}
		}

	}

	private static void addRoleToDefaultConfiguration(Process proc,
			Role role, Set addedObjects) {
		MethodConfiguration config = proc.getDefaultContext();
		TngUtil.addToConfiguration(config, role, addedObjects);
		
		// add work products
		ArrayList dependencies = new ArrayList();
	
		dependencies.addAll(role.getModifies());
		dependencies.addAll(role.getResponsibleFor());
		for (Iterator iter = dependencies.iterator(); iter.hasNext();) {
			addWPToDefaultConfiguration(proc, (WorkProduct) iter.next(),
					addedObjects);
		}
	}
	
	private static void addWPToDefaultConfiguration(Process proc,
			WorkProduct wp, Set addedObjects) {
		MethodConfiguration config = proc.getDefaultContext();
		TngUtil.addToConfiguration(config, wp, addedObjects);
		if (wp instanceof Deliverable) {
			for (Iterator iter = ((Deliverable) wp).getDeliveredWorkProducts()
					.iterator(); iter.hasNext();) {
				TngUtil.addToConfiguration(config, (EObject) iter.next(),
						addedObjects);
			}
		}
	}

	public static void updateTaskDescriptorSteps(Activity activity,
			TaskDescriptor taskDesc) {
		if (taskDesc == null) {
			return;
		}

		Task task = taskDesc.getTask();

		IConfigurationApplicator configApplicator = Providers
				.getConfigurationApplicator();
		MethodConfiguration config = TngUtil.getOwningProcess(activity)
				.getDefaultContext();
		List steps = (List) configApplicator.getReference(task,
				UmaPackage.eINSTANCE.getTask_Steps(), config);

		// add those steps to TaskDescriptor if they are not there yet.
		//
		for (Iterator iter = steps.iterator(); iter.hasNext();) {
			Object step = iter.next();
			if (!taskDesc.getSelectedSteps().contains(step)) {
				taskDesc.getSelectedSteps().add(step);
			}
		}
	}

	/**
	 * Gets the MethodElement that the given descriptor is associated with.
	 * 
	 * @param descriptor
	 * @return
	 */
	public static MethodElement getAssociatedElement(Descriptor descriptor) {
		if (descriptor instanceof RoleDescriptor) {
			return ((RoleDescriptor) descriptor).getRole();
		} else if (descriptor instanceof TaskDescriptor) {
			return ((TaskDescriptor) descriptor).getTask();
		} else if (descriptor instanceof WorkProductDescriptor) {
			return ((WorkProductDescriptor) descriptor).getWorkProduct();
		}
		return null;
	}

	public static void disposeWrappers(Collection children) {
		if (children == null)
			return;
		for (Iterator iter = children.iterator(); iter.hasNext();) {
			Object element = iter.next();
			if (element instanceof IWrapperItemProvider) {
				((IWrapperItemProvider) element).dispose();
			}
		}
	}

	/**
	 * Get all tasks that have the given workproduct in their output
	 * in the given configuration
	 * 
	 * @param wp
	 * @param config
	 * @return
	 */
	public static List getTasksForWorkProduct(WorkProduct wp,
			MethodConfiguration config) {
		IConfigurationApplicator configApplicator = Providers.getConfigurationApplicator();

		List tasks = (List) configApplicator.getReference(wp, AssociationHelper.WorkProduct_OutputFrom_Tasks, config);

		return tasks;
	}

	/**
	 * Get all workproducts that have the role as responsible role in the
	 * given configuration
	 * 
	 * @param wp
	 * @param config
	 * @return
	 */
	public static List getWorkProductsForRole(Role role,
			MethodConfiguration config) {
		IConfigurationApplicator configApplicator = Providers.getConfigurationApplicator();
		List wps = (List) configApplicator.getReference(role, UmaPackage.eINSTANCE.getRole_ResponsibleFor(), config);
		return wps;
	}

	/**
	 * Gets all workproducts which are, except the contributor, in the given
	 * plugin.
	 * 
	 * @param plugin
	 * @return
	 */
	public static List getAllWorkProducts(MethodPlugin plugin) {

		ContentPackage coreContentPkg = UmaUtil.findContentPackage(plugin,
				ModelStructure.DEFAULT.coreContentPath);
		Iterator iter = new AbstractTreeIterator(coreContentPkg, false) {

			/**
			 * Comment for <code>serialVersionUID</code>
			 */
			private static final long serialVersionUID = 3833752066324837937L;

			protected Iterator getChildren(Object object) {
				if (!(object instanceof ContentPackage))
					return Collections.EMPTY_LIST.iterator();
				ContentPackage pkg = (ContentPackage) object;
				List children = new ArrayList();
				for (Iterator iterator = pkg.getChildPackages().iterator(); iterator
						.hasNext();) {
					Object element = iterator.next();
					if (element instanceof ContentPackage) {
						children.add(element);
					}
				}
				for (Iterator iterator = pkg.getContentElements().iterator(); iterator
						.hasNext();) {
					Object element = iterator.next();

					if ((element instanceof WorkProduct)
							&& !TngUtil
									.isContributor((VariabilityElement) element)) {
						children.add(element);
					}
				}
				return children.iterator();
			}

		};
		List methodElements = new ArrayList();
		while (iter.hasNext()) {
			Object e = iter.next();
			if (e instanceof WorkProduct) {
				methodElements.add(e);
			}
		}
		return methodElements;
	}

	/**
	 * Gets all task, except the contributor, in the given plugin.
	 * 
	 * @param plugin
	 * @return
	 */
	public static List getAllTasks(MethodPlugin plugin) {
		ContentPackage coreContentPkg = UmaUtil.findContentPackage(plugin,
				ModelStructure.DEFAULT.coreContentPath);
		Iterator iter = new AbstractTreeIterator(coreContentPkg, false) {

			/**
			 * Comment for <code>serialVersionUID</code>
			 */
			private static final long serialVersionUID = 3833752066324837937L;

			protected Iterator getChildren(Object object) {
				if (!(object instanceof ContentPackage))
					return Collections.EMPTY_LIST.iterator();
				ContentPackage pkg = (ContentPackage) object;
				List children = new ArrayList();
				for (Iterator iterator = pkg.getChildPackages().iterator(); iterator
						.hasNext();) {
					Object element = iterator.next();
					if (element instanceof ContentPackage) {
						children.add(element);
					}
				}
				for (Iterator iterator = pkg.getContentElements().iterator(); iterator
						.hasNext();) {
					Object element = iterator.next();
					if (element instanceof Task
							&& !TngUtil
									.isContributor((VariabilityElement) element)) {
						children.add(element);
					}
				}
				return children.iterator();
			}

		};
		List tasks = new ArrayList();
		while (iter.hasNext()) {
			Object e = iter.next();
			if (e instanceof Task) {
				tasks.add(e);
			}
		}
		return tasks;
	}

	public static boolean isExtendingOrLocallyContributing(BreakdownElement e) {
		return TngUtil.isGeneralizer(e,
				getExtendAndLocalContributionVariabilityTypes());
	}
	

	public static String getPresentationName(BreakdownElement e) {
		if (e.getPresentationName() == null
				|| e.getPresentationName().length() == 0) {
			if (isExtendingOrLocallyContributing(e)) {
				BreakdownElement base = (BreakdownElement) ((VariabilityElement) e)
						.getVariabilityBasedOnElement();
				return getPresentationName(base);
			}
		}

		return e.getPresentationName();
	}

	public static String getLabelWithPath(BreakdownElement e) {
		StringBuffer path = new StringBuffer(e.getName());
		Process proc = TngUtil.getOwningProcess(e);
		if (proc != null) {
			path.append(", "); //$NON-NLS-1$
			MethodPlugin plugin = UmaUtil.getMethodPlugin(proc);
			if (plugin != null) {
				path.append(plugin.getName());
			}
			if (e != proc) {
				path.append('/').append(proc.getName());
			}
		}
		return path.toString();
	}

	/**
	 * Gets the model info of the given BreakdownElement in the given
	 * StringBuffer
	 * 
	 * @param e
	 * @param adapter
	 * @param modelInfo
	 */
	public static void getModelInfo(BreakdownElement e, Object adapter,
			StringBuffer modelInfo) {
		if (e instanceof VariabilityElement) {
			VariabilityElement ve = (VariabilityElement) e;
			VariabilityElement base = ve.getVariabilityBasedOnElement();
			if (base != null) {
				VariabilityType type = ve.getVariabilityType();
				if (modelInfo.length() > 0) {
					modelInfo.append("; "); //$NON-NLS-1$
				}
				String pattern = null;
				if (type == VariabilityType.CONTRIBUTES_LITERAL) {
					pattern = LibraryEditResources.util_ProcessUtil_contributesto; //$NON-NLS-1$
				} else if (type == VariabilityType.LOCAL_CONTRIBUTION_LITERAL) {
					pattern = LibraryEditResources.util_ProcessUtil_localContributesto; //$NON-NLS-1$
				} else if (type == VariabilityType.EXTENDS_LITERAL) {
					pattern = LibraryEditResources.process_extends; //$NON-NLS-1$
				} else if (type == VariabilityType.REPLACES_LITERAL) {
					pattern = LibraryEditResources.process_replaces; //$NON-NLS-1$
				} else if (type == VariabilityType.LOCAL_REPLACEMENT_LITERAL) {
					pattern = LibraryEditResources.process_localReplaces; //$NON-NLS-1$
				}

				// if(adapter instanceof ItemProviderAdapter) {
				// AdapterFactory factory =
				// ((ItemProviderAdapter)adapter).getAdapterFactory();
				// Object itemProvider = factory.adapt(base,
				// ITreeItemContentProvider.class);
				// if(itemProvider instanceof IBSItemProvider) {
				// IBSItemProvider bsItemProvider = (IBSItemProvider)
				// itemProvider;
				// Process proc = (Process) bsItemProvider.getTopItem();
				// if(proc != null) {
				// strbuf.append(UmaUtil.getMethodPlugin(proc).getName()).append(':')
				// .append(proc.getName()).append(':');
				// }
				// }
				// }

				// Process proc = TngUtil.getOwningProcess((BreakdownElement)
				// base);
				// if(proc != null) {
				// MethodPlugin plugin = UmaUtil.getMethodPlugin(proc);
				// if(plugin != null) {
				// modelInfo.append(UmaUtil.getMethodPlugin(proc).getName()).append(':');
				// }
				// modelInfo.append(proc.getName());
				// }
				//				
				// if(base != proc) {
				// modelInfo.append(':').append(base.getName());
				// }
				// modelInfo.append("'"); //$NON-NLS-1$
				if (pattern != null) {
					String path = getLabelWithPath((BreakdownElement) base);
					modelInfo.append(MessageFormat.format(pattern,
							new Object[] { path }));

					getModelInfo((BreakdownElement) base, adapter, modelInfo);
				}
			}
		} else if (adapter instanceof BreakdownElementWrapperItemProvider) {
			BreakdownElementWrapperItemProvider wrapper = (BreakdownElementWrapperItemProvider) adapter;
			wrapper.getOwner();
			if (wrapper.getFeature() != null) {
				modelInfo.append(TngUtil.getFeatureText(wrapper.getFeature()));
			} else {
				if (wrapper instanceof WorkProductDescriptorWrapperItemProvider) {
//					getModelInfoForWorkProductDescriptor(modelInfo,
//							(WorkProductDescriptor) TngUtil.unwrap(wrapper));
					getWPDModelInfo(modelInfo, wrapper, wrapper);
				}
			}
		}
	}
	
	public static String getColumnName(String property) {
		if (IBSItemProvider.COL_ID.equals(property)) {
			return IBSItemProvider.COL_ID;
		} else if (IBSItemProvider.COL_NAME.equals(property)) {
			return IBSItemProvider.COL_NAME;
		} else if (IBSItemProvider.COL_PRESENTATION_NAME.equals(property)) {
			return IBSItemProvider.COL_PRESENTATION_NAME;
		} else if (IBSItemProvider.COL_PREDECESSORS.equals(property)) {
			return IBSItemProvider.COL_PREDECESSORS;
		} else if (IBSItemProvider.COL_IS_EVENT_DRIVEN.equals(property)) {
			return IBSItemProvider.COL_IS_EVENT_DRIVEN;
		} else if (IBSItemProvider.COL_IS_ONGOING.equals(property)) {
			return IBSItemProvider.COL_IS_ONGOING;
		} else if (IBSItemProvider.COL_IS_REPEATABLE.equals(property)) {
			return IBSItemProvider.COL_IS_REPEATABLE;
		} else if (IBSItemProvider.COL_PREFIX.equals(property)) {
			return IBSItemProvider.COL_PREFIX;
		} else if (IBSItemProvider.COL_MODEL_INFO.equals(property)) {
			return IBSItemProvider.COL_MODEL_INFO;
		} else if (IBSItemProvider.COL_TYPE.equals(property)) {
			return IBSItemProvider.COL_TYPE;
		} else if (IBSItemProvider.COL_TEAMS.equals(property)) {
			return IBSItemProvider.COL_TEAMS;
		} else if (IBSItemProvider.COL_ENTRY_STATE.equals(property)) {
			return IBSItemProvider.COL_ENTRY_STATE;
		} else if (IBSItemProvider.COL_EXIT_STATE.equals(property)) {
			return IBSItemProvider.COL_EXIT_STATE;
		} else if (IBSItemProvider.COL_DELIVERABLE.equals(property)) {
			return IBSItemProvider.COL_DELIVERABLE;
		} else if (IBSItemProvider.COL_IS_OPTIONAL.equals(property)) {
			return IBSItemProvider.COL_IS_OPTIONAL;
		} else if (IBSItemProvider.COL_IS_PLANNED.equals(property)) {
			return IBSItemProvider.COL_IS_PLANNED;
		} else if (IBSItemProvider.COL_HAS_MULTIPLE_OCCURRENCES.equals(property)) {
			return IBSItemProvider.COL_HAS_MULTIPLE_OCCURRENCES;
		}
		return null;
	}

	public static String getAttribute(Object object, String property,
			Object adapter) {
		BreakdownElement e = (BreakdownElement) TngUtil.unwrap(object);
		if (property == IBSItemProvider.COL_ID) {
			if (e instanceof WorkBreakdownElement
					&& adapter instanceof IBSItemProvider) {
				return String.valueOf(((IBSItemProvider) adapter).getId());
			}
		} else if (property == IBSItemProvider.COL_NAME) {
			if (adapter instanceof IItemLabelProvider) {
				return ((IItemLabelProvider) adapter).getText(e);
			}
		} else if (property == IBSItemProvider.COL_PRESENTATION_NAME) {
			return getPresentationName(e);
		} else if (property == IBSItemProvider.COL_PREDECESSORS) {
			if (adapter instanceof IBSItemProvider) {
				return ((IBSItemProvider) adapter).getPredecessors().toString();
			}
		} else if (property == IBSItemProvider.COL_IS_EVENT_DRIVEN) {
			if (e instanceof WorkBreakdownElement) {
				return String.valueOf(((WorkBreakdownElement) e)
						.getIsEventDriven());
			}
		} else if (property == IBSItemProvider.COL_IS_ONGOING) {
			if (e instanceof WorkBreakdownElement) {
				return String
						.valueOf(((WorkBreakdownElement) e).getIsOngoing());
			}
		} else if (property == IBSItemProvider.COL_IS_REPEATABLE) {
			if (e instanceof WorkBreakdownElement) {
				return String.valueOf(((WorkBreakdownElement) e)
						.getIsRepeatable());
			}
		} else if (property == IBSItemProvider.COL_PREFIX) {
			return e.getPrefix();
		} else if (property == IBSItemProvider.COL_MODEL_INFO) {
			StringBuffer modelInfo = new StringBuffer();
			getModelInfo(e, adapter, modelInfo);
			return modelInfo.toString();
		} else if (property == IBSItemProvider.COL_TYPE) {
			String typeName = null;
			if (e instanceof WorkProductDescriptor) {
				WorkProduct wp = ((WorkProductDescriptor) e)
						.getWorkProduct();
				if (wp != null) {
					typeName = wp.eClass().getName() + "Descriptor"; //$NON-NLS-1$  
				}
			}
			if (typeName == null && e instanceof EObject) {
				typeName = ((EObject) e).eClass().getName();
			}
			if (typeName != null) {
				return UmaEditPlugin.INSTANCE
						.getString("_UI_" + typeName + "_type"); //$NON-NLS-1$ //$NON-NLS-2$
			}
		} else if (property == IBSItemProvider.COL_TEAMS) {
			if (e instanceof TeamProfile) {
				return TngUtil.getPresentationName(((TeamProfile) e)
						.getSuperTeam());
			}
			else if (e instanceof RoleDescriptor && adapter instanceof ITreeItemContentProvider) {
				AdapterFactory adapterFactory = null;
				if(adapter instanceof BreakdownElementWrapperItemProvider) {
					adapterFactory = ((BreakdownElementWrapperItemProvider)adapter).getAdapterFactory();
				}
				else if(adapter instanceof ItemProviderAdapter) {
					adapterFactory = ((ItemProviderAdapter)adapter).getAdapterFactory();
				}
				return getTeamListString(getTeamProfiles(object, (ITreeItemContentProvider)adapter, adapterFactory));
 			}
		}
		if (property == IBSItemProvider.COL_ENTRY_STATE) {
			if (e instanceof WorkProductDescriptor) {
				WorkProductDescriptor wpd = (WorkProductDescriptor) e;
				return TngUtil.checkNull(wpd.getActivityEntryState());
			}
		} else if (property == IBSItemProvider.COL_EXIT_STATE) {
			if (e instanceof WorkProductDescriptor) {
				WorkProductDescriptor wpd = (WorkProductDescriptor) e;
				return TngUtil.checkNull(wpd.getActivityExitState());
			}
		} else if (property == IBSItemProvider.COL_DELIVERABLE) {
			if (e instanceof WorkProductDescriptor) {
				List deliverables = AssociationHelper
						.getDeliverableDescriptors((WorkProductDescriptor) e);
				if (deliverables.isEmpty())
					return ""; //$NON-NLS-1$
				StringBuffer strBuf = new StringBuffer();
				int max = deliverables.size() - 1;
				for (int i = 0; i < max; i++) {
					strBuf.append(
							TngUtil.getPresentationName(deliverables.get(i)))
							.append(',');
				}
				strBuf.append(TngUtil
						.getPresentationName(deliverables.get(max)));
				return strBuf.toString();
			}
		} else if (property == IBSItemProvider.COL_IS_OPTIONAL) {
			return String.valueOf(e.getIsOptional());
		} else if (property == IBSItemProvider.COL_IS_PLANNED) {
			return String.valueOf(e.getIsPlanned());
		} else if (property == IBSItemProvider.COL_HAS_MULTIPLE_OCCURRENCES) {
			return String.valueOf(e.getHasMultipleOccurrences());
		}
		return ""; //$NON-NLS-1$
	}

	/**
	 * Get parent activity for team profile breakdown element
	 * UmaUtil.getParentActivity doesn't work correctly for sub-teams
	 * This method should only be used for breakdown elements under teamallocation
	 * @param team
	 * @return
	 */
	public static Object getParentActivityOfTeam(BreakdownElement brElement)
	{
		AdapterFactory adapterFactory = TngAdapterFactory.INSTANCE.getOBS_ComposedAdapterFactory();
		ItemProviderAdapter adapter = (ItemProviderAdapter) adapterFactory
				.adapt(brElement, ITreeItemContentProvider.class);
		Object parent = adapter.getParent(brElement);
		while (!(parent instanceof Activity)) {
			brElement = (BreakdownElement) parent;
			adapter = (ItemProviderAdapter) adapterFactory.adapt(brElement,
					ITreeItemContentProvider.class);
			parent = adapter.getParent(brElement);
		}

		return parent;	
	}
	
	
	/**
	 * Return roledescriptors under activity which could possible match for
	 * roles under the teams. It will recurse thru all child activities to find 
	 * role descriptors
	 * 
	 * @param adapterFactory
	 * @param parent
	 * @param roleDescList
	 * @param roles
	 */
	public static void getRoleDescriptor(AdapterFactory adapterFactory,
			Activity parent,  List roleDescList, List roles) {
		ItemProviderAdapter adapter = (ItemProviderAdapter) adapterFactory
				.adapt(parent, ITreeItemContentProvider.class);

		Object o = adapter.getChildren(parent);
		if (o instanceof List) {
			List children = (List) o;
			for (Iterator itor = children.iterator(); itor.hasNext();) {
				Object obj = itor.next();
				if (obj instanceof Activity) {
					getRoleDescriptor(adapterFactory, (Activity) obj,
							roleDescList, roles);
				}
				if (obj instanceof RoleDescriptor)
				{
					RoleDescriptor roleDesc = (RoleDescriptor) obj;
					if ((roleDesc.getRole()!= null) && 
							(roles.contains(roleDesc.getRole())))
						roleDescList.add(obj);
				}
			}
		}
	}
	
	private static String getTeamListString(List teamProfiles) {
		if (teamProfiles.isEmpty())
			return ""; //$NON-NLS-1$
		StringBuffer strBuf = new StringBuffer();
		int max = teamProfiles.size() - 1;
		for (int i = 0; i < max; i++) {
			strBuf.append(TngUtil.getPresentationName(teamProfiles.get(i)))
					.append(',');
		}
		strBuf.append(TngUtil.getPresentationName(teamProfiles.get(max)));
		return strBuf.toString();
	}

	public static void setAttribute(WorkBreakdownElement e, String prop,
			String txt) {
		if (prop == IBSItemProvider.COL_NAME) {
			e.setName(txt);
		} else if (prop == IBSItemProvider.COL_PREFIX) {
			e.setPrefix(txt);
		} else if (prop == IBSItemProvider.COL_IS_EVENT_DRIVEN) {
			e.setIsEventDriven(Boolean.valueOf(txt));
		} else if (prop == IBSItemProvider.COL_IS_ONGOING) {
			e.setIsOngoing(Boolean.valueOf(txt));
		} else if (prop == IBSItemProvider.COL_IS_REPEATABLE) {
			e.setIsRepeatable(Boolean.valueOf(txt));
		}
	}

	public static void setAttribute(IActionManager actionMgr,
			BreakdownElement e, String prop, String txt) {
		if (prop == IBSItemProvider.COL_NAME) {
			actionMgr.doAction(IActionManager.SET, e, UmaPackage.eINSTANCE
					.getNamedElement_Name(), txt, -1);
		} else if (prop == IBSItemProvider.COL_PREFIX) {
			actionMgr.doAction(IActionManager.SET, e, UmaPackage.eINSTANCE
					.getBreakdownElement_Prefix(), txt, -1);
		} else if (prop == IBSItemProvider.COL_IS_EVENT_DRIVEN) {
			actionMgr.doAction(IActionManager.SET, e, UmaPackage.eINSTANCE
					.getWorkBreakdownElement_IsEventDriven(), Boolean
					.valueOf(txt), -1);
		} else if (prop == IBSItemProvider.COL_IS_ONGOING) {
			actionMgr.doAction(IActionManager.SET, e, UmaPackage.eINSTANCE
					.getWorkBreakdownElement_IsOngoing(), Boolean.valueOf(txt),
					-1);
		} else if (prop == IBSItemProvider.COL_IS_REPEATABLE) {
			actionMgr.doAction(IActionManager.SET, e, UmaPackage.eINSTANCE
					.getWorkBreakdownElement_IsRepeatable(), Boolean
					.valueOf(txt), -1);
		} else if (prop == IBSItemProvider.COL_PRESENTATION_NAME) {
			actionMgr.doAction(IActionManager.SET, e, UmaPackage.eINSTANCE
					.getDescribableElement_PresentationName(), txt, -1);
		} else if (prop == IBSItemProvider.COL_IS_OPTIONAL) {
			actionMgr
					.doAction(IActionManager.SET, e, UmaPackage.eINSTANCE
							.getBreakdownElement_IsOptional(), Boolean
							.valueOf(txt), -1);
		} else if (prop == IBSItemProvider.COL_IS_PLANNED) {
			actionMgr.doAction(IActionManager.SET, e, UmaPackage.eINSTANCE
					.getBreakdownElement_IsPlanned(), Boolean.valueOf(txt), -1);
		} else if (prop == IBSItemProvider.COL_HAS_MULTIPLE_OCCURRENCES) {
			actionMgr.doAction(IActionManager.SET, e, UmaPackage.eINSTANCE
					.getBreakdownElement_HasMultipleOccurrences(), Boolean
					.valueOf(txt), -1);
		} else if (e instanceof WorkProductDescriptor) {
			if (prop == IBSItemProvider.COL_ENTRY_STATE) {
				actionMgr
						.doAction(IActionManager.SET, e, UmaPackage.eINSTANCE
								.getWorkProductDescriptor_ActivityEntryState(),
								txt, -1);
			} else if (prop == IBSItemProvider.COL_EXIT_STATE) {
				actionMgr.doAction(IActionManager.SET, e, UmaPackage.eINSTANCE
						.getWorkProductDescriptor_ActivityExitState(), txt, -1);
			}
		}

	}

	public static Activity generalize(Activity base, VariabilityType type) {
		Activity act = UmaFactory.eINSTANCE.createActivity();
		act.setName(base.getName());
		if (type == VariabilityType.LOCAL_REPLACEMENT_LITERAL) {
			String presentationName = getPresentationName(base);
			act.setPresentationName(StrUtil.isBlank(presentationName) ? base
					.getName() : presentationName);
		}
		act.setVariabilityBasedOnElement(base);
		act.setVariabilityType(type);

		if (type == VariabilityType.EXTENDS_LITERAL) {
			// inherit boolean attributes from base
			//
			for (Iterator iter = base.eClass().getEAllAttributes().iterator(); iter
					.hasNext();) {
				EAttribute attribute = (EAttribute) iter.next();
				if (attribute.getEAttributeType().getInstanceClass() == Boolean.class) {
					act.eSet(attribute, base.eGet(attribute));
				}
			}
		}

		// copy predecessors list
		// TODO: need to check with variability rules.
		//
		ArrayList workOrders = new ArrayList();
		for (Iterator iter = new ArrayList(base.getLinkToPredecessor())
				.iterator(); iter.hasNext();) {
			workOrders.add(TngUtil.copy((WorkOrder) iter.next()));
		}

		act.getLinkToPredecessor().addAll(workOrders);
		return act;
	}

	/**
	 * Returns list of elements specified in class "type" eg.(RoleDescriptor,
	 * WorkProductDescriptor" until the root level.
	 * 
	 * @param adapterFactory
	 * @param element
	 * @param type
	 * @param items
	 * @return
	 */
	public static List getElementsInScope(AdapterFactory adapterFactory,
			BreakdownElement element, Class type, List items) {
		// get children for activity
		ITreeItemContentProvider itemProvider = (ITreeItemContentProvider) adapterFactory
				.adapt(element, ITreeItemContentProvider.class);
		if (element instanceof Activity) {
			Collection children = ((Activity) element).getBreakdownElements();
			for (Iterator itor = children.iterator(); itor.hasNext();) {
				Object obj = itor.next();
				if (type.isInstance(obj)) {
					// System.out.println("Obj -" + obj);
					if (!(items.contains(obj))) {
						items.add(obj);
					}
				}
			}
		}

		// get parent
		Object currentParent = itemProvider.getParent(element);
		if (currentParent != null) {
			// go up
			getElementsInScope(adapterFactory,
					(BreakdownElement) currentParent, type, items);
		}
		return items;

	}

	/**
	 * Get roles from roledescriptor list
	 * 
	 * @param roleDescList
	 * @return
	 */

	public static List getRoles(List roleDescList) {
		List roleList = new ArrayList();
		if (roleDescList != null) {
			for (Iterator itor = roleDescList.iterator(); itor.hasNext();) {
				Object obj = itor.next();
				if (obj instanceof RoleDescriptor) {
					Role role = ((RoleDescriptor) obj).getRole();
					roleList.add(role);
				}
			}
		}
		return roleList;
	}

	/**
	 * Get associated method element list
	 * 
	 * @param descriptorList
	 * @return
	 */
	public static List getAssociatedElementList(List descriptorList) {
		List elementList = new ArrayList();
		if (descriptorList != null) {
			for (Iterator itor = descriptorList.iterator(); itor.hasNext();) {
				Object obj = itor.next();
				if (obj instanceof Descriptor) {
					MethodElement element = getAssociatedElement((Descriptor) obj);
					elementList.add(element);
				}
			}
		}
		return elementList;
	}

	public static BreakdownElement getTopBreakdownElement(ProcessComponent pc) {
		BreakdownElement be = pc.getProcess();
		if (be == null)
			return null;
		Object adapter = TngAdapterFactory.INSTANCE
				.getWBS_ComposedAdapterFactory().adapt(be,
						ITreeItemContentProvider.class);
		if (!(adapter instanceof IBSItemProvider))
			return be;
		IBSItemProvider itemProvider = (IBSItemProvider) adapter;
		if (itemProvider.getTopItem() == null) {
			itemProvider.setTopItem(be);
			itemProvider = (IBSItemProvider) TngAdapterFactory.INSTANCE
					.getOBS_ComposedAdapterFactory().adapt(be,
							ITreeItemContentProvider.class);
			itemProvider.setTopItem(be);
			itemProvider = (IBSItemProvider) TngAdapterFactory.INSTANCE
					.getPBS_ComposedAdapterFactory().adapt(be,
							ITreeItemContentProvider.class);
			itemProvider.setTopItem(be);
			itemProvider = (IBSItemProvider) TngAdapterFactory.INSTANCE
					.getProcessComposedAdapterFactory().adapt(be,
							ITreeItemContentProvider.class);
			itemProvider.setTopItem(be);
		}
		ProcessUtil.updateIDs(be, be);
		return be;
	}

	private static void updateIDs(EObject topAct, Object newObj) {
		ItemProviderAdapter adapter = (ItemProviderAdapter) TngAdapterFactory.INSTANCE
				.getWBS_ComposedAdapterFactory().adapt(topAct,
						ITreeItemContentProvider.class);
		AdapterFactory factory = TngUtil.getBestAdapterFactory(adapter
				.getAdapterFactory());
		boolean updateWholeProcess = topAct == newObj
				&& topAct instanceof Process;
		if (updateWholeProcess) {
			Process proc = (Process) topAct;
			updateIDs(factory, proc);
			refreshViewer(factory, proc);
		} else {
			AdapterFactoryTreeIterator iter = new AdapterFactoryTreeIterator(
					factory, topAct);
			updateIDs(factory, iter, newObj);
		}

		// No more ID column in TBS and WPBS
		//
		// adapter = (ItemProviderAdapter)
		// TngAdapterFactory.INSTANCE.getOBS_ComposedAdapterFactory().adapt(topAct,
		// ITreeItemContentProvider.class);
		// factory = TngUtil.getBestAdapterFactory(adapter.getAdapterFactory());
		// iter = new AdapterFactoryTreeIterator(factory, topAct);
		// ProcessUtil.updateIDs(factory, iter, newObj);
		// adapter = (ItemProviderAdapter)
		// TngAdapterFactory.INSTANCE.getPBS_ComposedAdapterFactory().adapt(topAct,
		// ITreeItemContentProvider.class);
		// factory = TngUtil.getBestAdapterFactory(adapter.getAdapterFactory());
		// iter = new AdapterFactoryTreeIterator(factory, topAct);
		// ProcessUtil.updateIDs(factory, iter, newObj);

		adapter = (ItemProviderAdapter) TngAdapterFactory.INSTANCE
				.getProcessComposedAdapterFactory().adapt(topAct,
						ITreeItemContentProvider.class);
		factory = TngUtil.getBestAdapterFactory(adapter.getAdapterFactory());
		if (updateWholeProcess) {
			Process proc = (Process) topAct;
			updateIDs(factory, proc);
			refreshViewer(factory, proc);
		} else {
			AdapterFactoryTreeIterator iter = new AdapterFactoryTreeIterator(
					factory, topAct);
			updateIDs(factory, iter, newObj);
		}
	}

	/**
	 * @param iter
	 * @param newObj
	 */
	public static void updateIDs(AdapterFactory factory,
			AdapterFactoryTreeIterator iter, Object newObj) {
		int id = 0;
		Object obj;
		Map changeMap = new HashMap();
		while (iter.hasNext()) {
			obj = iter.next();
			IBSItemProvider itemProvider = (IBSItemProvider) factory.adapt(obj,
					ITreeItemContentProvider.class);
			itemProvider.setId(id++);
			changeMap.put(obj, itemProvider);
		}

		// refresh the label
		//
		for (Iterator iterator = changeMap.entrySet().iterator(); iterator
				.hasNext();) {
			Map.Entry entry = (Map.Entry) iterator.next();
			IChangeNotifier adapter = (IChangeNotifier) entry.getValue();
			obj = entry.getKey();
			adapter.fireNotifyChanged(new ViewerNotification(
					new NotificationImpl(Notification.SET, obj, obj), obj,
					false, true));
		}
	}

	/**
	 * 
	 * @param descriptor
	 * @param obj
	 * @return
	 * @see #checkDescriptorReferences(Collection, Descriptor)
	 */
	public static boolean checkDescriptorReferences(Descriptor descriptor,
			Descriptor obj) {
		Collection descriptors = descriptor != null ? Collections
				.singleton(descriptor) : Collections.EMPTY_SET;
		return checkDescriptorReferences(descriptors, obj);
	}

	
	/**
	 * Check whether there are any references of the object "obj". If references
	 * exist in any descriptor in <code>descriptors</code>, ignore it.
	 * 
	 * @param descriptors
	 * @param obj
	 * @return
	 */
	public static boolean checkDescriptorReferences(Collection descriptors,
			Descriptor obj) {
		boolean referencesExists = false;

		if (obj instanceof RoleDescriptor) {
			RoleDescriptor refObject = (RoleDescriptor) obj;
			List list = new ArrayList();
			list.addAll(AssociationHelper.getAssistedTaskDescriptors(refObject));
			list.addAll(refObject.getResponsibleFor());
			list.addAll(AssociationHelper.getAdditionalTaskDescriptors(refObject));
			list.addAll(AssociationHelper.getPrimaryTaskDescriptors(refObject));
			list.addAll(AssociationHelper.getTeamProfiles(refObject));

			for (Iterator refItor = list.iterator(); refItor.hasNext();) {
				Object refItorObject = (Object) refItor.next();
				if (((refItorObject instanceof Descriptor) && !descriptors
						.contains(refItorObject))
						|| (refItorObject instanceof TeamProfile)) {
					referencesExists = true;
					break;
				}

			}
		} else if (obj instanceof WorkProductDescriptor) {		
			return checkWorkProductDescriptorReferences(descriptors, (WorkProductDescriptor) obj, false, -1);
		} else if (obj instanceof TaskDescriptor) {
			TaskDescriptor refObject = (TaskDescriptor) obj;
			List list = new ArrayList();
			list.addAll(refObject.getAdditionallyPerformedBy());
			list.addAll(refObject.getAssistedBy());
			list.addAll(refObject.getExternalInput());
			list.addAll(refObject.getMandatoryInput());
			list.addAll(refObject.getOptionalInput());
			list.addAll(refObject.getOutput());
			list.add(refObject.getPerformedPrimarilyBy());

			for (Iterator refItor = list.iterator(); refItor.hasNext();) {
				Object refItorObject = (Object) refItor.next();
				if ((refItorObject instanceof Descriptor)
						&& !descriptors.contains(refItorObject)) {
					referencesExists = true;
					break;
				}
			}
		}

		return referencesExists;
	}
	
	/**
	 * Check whether there are any references of the workProductdescriptor object "refObject. 
	 * If references exist in any descriptor in <code>descriptors</code>, ignore it.
	 * 
	 * @param descriptors
	 * @param refObject
	 * @param removeRelation - flag to indicate whether we're removing relation
	 *     By default this should be false. 
	 *     This is only applicable if you are coming from properties view. 
	 *     eg. removing relationship of work product descriptor to task descriptor 
	 * @param featureID
	 * 		This is only applicable if "removeRelation" is true. You need to give featureID
	 * 		for which relation you are removing.
	 * @return
	 */
	public static boolean checkWorkProductDescriptorReferences(
			Collection descriptors, WorkProductDescriptor refObject, boolean removeRelation, int featureID) {
		
		List allObjects = new ArrayList();
		allObjects.add(refObject);

		Activity parentActivity = UmaUtil.getParentActivity(refObject);
		// check whether reference object instance of artifact
		if (refObject.getWorkProduct() instanceof Artifact) {
			List containedArtifacts = ((Artifact) refObject.getWorkProduct())
					.getContainedArtifacts();

			List containedWpDescList = getWpDescForArtifacts(
					containedArtifacts, parentActivity);

			List containerArtifacts = new ArrayList();
			Artifact artifact = ((Artifact) refObject.getWorkProduct())
					.getContainerArtifact();
			while (artifact != null) {
				containerArtifacts.add(artifact);
				artifact = ((Artifact) artifact).getContainerArtifact();
			}
			List containerWpDescList = getWpDescForArtifacts(
					containerArtifacts, parentActivity);

			allObjects.addAll(containedWpDescList);
			allObjects.addAll(containerWpDescList);
		}

		for (int i = 0; i < allObjects.size(); i++) {
			WorkProductDescriptor wpObj = (WorkProductDescriptor) allObjects
					.get(i);

			List list = new ArrayList();
			list.addAll(wpObj.getImpactedBy());
			list.addAll(wpObj.getImpacts());
			list.addAll(AssociationHelper.getResponsibleRoleDescriptors(wpObj));
			list.addAll(wpObj.getDeliverableParts());

			List inputList = new ArrayList();
			inputList.addAll(AssociationHelper.getExternalInputTo(wpObj));
			inputList.addAll(AssociationHelper.getMandatoryInputTo(wpObj));
			inputList.addAll(AssociationHelper.getOptionalInputTo(wpObj));

			List outputList = AssociationHelper.getOutputFrom(wpObj);
			if (removeRelation)
			{
				switch (featureID) {
				case UmaPackage.TASK_DESCRIPTOR__EXTERNAL_INPUT:
				case UmaPackage.TASK_DESCRIPTOR__MANDATORY_INPUT:
				case UmaPackage.TASK_DESCRIPTOR__OPTIONAL_INPUT:
					if (outputList.containsAll(descriptors))
						return true;
					break;
				case UmaPackage.TASK_DESCRIPTOR__OUTPUT :				
					if (inputList.containsAll(descriptors))
						return true;
				}
			}

			list.addAll(inputList);
			list.addAll(outputList);
			
			for (Iterator refItor = list.iterator(); refItor.hasNext();) {
				Object refItorObject = (Object) refItor.next();
				if ((refItorObject instanceof Descriptor)
						&& !descriptors.contains(refItorObject)) {
					return true;
				}
			}
		}
		return false;
	}

	
	/**
	 * Return list of corresponding work product descriptors for artifacts
	 * @param artifacts
	 * @param parentActivity
	 * @return
	 */
	public static List getWpDescForArtifacts(List artifacts, Activity parentActivity)
	{
		List wpDescList = new ArrayList();
		for (int i=0; i < artifacts.size(); i++)
		{
			Artifact artifact = (Artifact) artifacts.get(i);
			List brElements = parentActivity.getBreakdownElements();
			for (Iterator itor = brElements.iterator(); itor.hasNext();)
			{
				Object brObj = (Object) itor.next();
				if (brObj instanceof WorkProductDescriptor) 
				{
					WorkProductDescriptor wpDesc = (WorkProductDescriptor) brObj;
					if (wpDesc.getWorkProduct() instanceof Artifact)
					{
						if (wpDesc.getWorkProduct().equals(artifact))
							wpDescList.add(wpDesc);
					}
				}
			}
		}
		return wpDescList;
	}

	public static CompositeRole createCompositeRole(CompositeRole obj) {
		CompositeRole compRole = UmaFactory.eINSTANCE.createCompositeRole();
		compRole.getAggregatedRoles().addAll(obj.getAggregatedRoles());

		String presentationName = obj.getPresentationName();
		compRole.setName(obj.getName());
		compRole.setPresentationName(StrUtil.isBlank(presentationName) ? obj
				.getName() : presentationName);
		return compRole;
	}

	public static void addTaskToActivity(Task task, Activity act) {
		WBSDropCommand cmd = new WBSDropCommand(act, Collections
				.singletonList(task));
		BSDropCommand.IExecutor executor = cmd.getExecutor();
		if (executor.preExecute()) {
			executor.doExcecute();
		}
	}

	public static boolean hasProcessNotOfType(ProcessPackage pkg,
			EClass processType) {
		if (pkg instanceof ProcessComponent) {
			Process proc = ((ProcessComponent) pkg).getProcess();
			if (proc != null && !processType.isInstance(proc)) {
				return true;
			}
		}
		for (Iterator iterator = pkg.getChildPackages().iterator(); iterator
				.hasNext();) {
			Object childPkg = iterator.next();
			if (childPkg instanceof ProcessComponent) {
				Process proc = ((ProcessComponent) childPkg).getProcess();
				if (proc != null && !processType.isInstance(proc)) {
					return true;
				}
			} else if (childPkg instanceof ProcessPackage) {
				if (hasProcessNotOfType((ProcessPackage) childPkg, processType)) {
					return true;
				}
			}
		}
		return false;
	}

	/**
	 * Find correspoding roleDescriptor in team since we maintain two role
	 * descriptor for the same role
	 * 
	 * @param team
	 * @param roleDesc
	 * @return
	 */
	public static Object findRoleDescriptor(TeamProfile team,
			RoleDescriptor roleDesc) {
		List teamRoles = team.getTeamRoles();

		for (Iterator itor = teamRoles.iterator(); itor.hasNext();) {
			Object itorObject = itor.next();
			if (roleDesc instanceof CompositeRole) {
				if (itorObject instanceof CompositeRole) {
					List firstObjectAggRoles = ((CompositeRole) roleDesc)
							.getAggregatedRoles();
					List secondObjectAggRoles = ((CompositeRole) itorObject)
							.getAggregatedRoles();
					if (firstObjectAggRoles.equals(secondObjectAggRoles)) {
						return itorObject;
					}
				}
			} else if (roleDesc instanceof RoleDescriptor) {
				if ((itorObject instanceof RoleDescriptor)
						&& (!(itorObject instanceof CompositeRole))) {
					Object objRole = ((RoleDescriptor) roleDesc).getRole();
					Object itorObjRole = ((RoleDescriptor) itorObject)
							.getRole();
					if (objRole.equals(itorObjRole)) {
						return itorObject;
					}
				}
			}
		}

		return null;
	}

	/**
	 * Creates a columnIndexToNameMap from the comma-separated list of column
	 * names
	 * 
	 * @param newValue
	 * @return
	 */
	public static Map toColumnIndexToNameMap(String colNames) {
		Map columnIndexToNameMap = new HashMap();
		StringTokenizer tokens = new StringTokenizer(colNames, ","); //$NON-NLS-1$
		int id = 0;
		while (tokens.hasMoreTokens()) {
			String token = tokens.nextToken();
			columnIndexToNameMap.put(new Integer(id), getColumnID(token));
			id++;
		}
		return columnIndexToNameMap;
	}

	/**
	 * @param token
	 * @return
	 */
	private static String getColumnID(String colName) {
		for (int i = 0; i < IBSItemProvider.COLUMNS.length; i++) {
			String col = IBSItemProvider.COLUMNS[i];
			if (col.equals(colName)) {
				return col;
			}
		}
		return null;
	}

	// This method is used to check whether an new descriptor can be created for a given method element
	// under the given activity, considering all inherited descriptors of the activity.
	// It is NOT EFFICIENT to collect all linked elements of the inherited descriptors into a list and then check if
	// whether the given method element is in the list.
	//
	// Use ProcessCommandUtil#getValidDescriptor(Object obj, Activity activity) instead
	//
//	public static List getVariabilityElement(Object owner) {
//		List baseElements = new ArrayList();
//		if (owner instanceof Activity) {
//			Activity activity = (Activity) owner;
//			while (!activity.getVariabilityType().equals(
//					VariabilityType.NA_LITERAL)) {
//				VariabilityElement element = activity
//						.getVariabilityBasedOnElement();
//
//				if ((element != null) && (element instanceof Activity)) {
//					Activity baseActivity = (Activity) element;
//
//					List breakdownElements = baseActivity
//							.getBreakdownElements();
//					for (Iterator itor = breakdownElements.iterator(); itor
//							.hasNext();) {
//						Object object = itor.next();
//						if (object instanceof Descriptor) {
//							Object baseObj = getAssociatedElement((Descriptor) object);
//							if (baseObj != null) {
//								baseElements.add(baseObj);
//							}
//						}
//					}
//
//					activity = baseActivity;
//				}
//				else {
//					break;
//				}
//			}
//		}
//
//		return baseElements;
//	}

	/**
	 * Refreshes predecessor list of all item providers of the given process
	 * 
	 * @param factory
	 * @param proc
	 * @param elements
	 */
	public static void removePredecessors(AdapterFactory factory, Process proc,
			List removedElements) {
		HashSet elements = new HashSet(removedElements);
		for (Iterator iter = new AdapterFactoryTreeIterator(factory, proc); iter
				.hasNext();) {
			Object obj = iter.next();
			IBSItemProvider itemProvider = (IBSItemProvider) factory.adapt(obj,
					ITreeItemContentProvider.class);
			if (itemProvider != null
					&& TngUtil.unwrap(obj) instanceof WorkBreakdownElement) {
				for (Iterator iterator = itemProvider.getPredecessors()
						.iterator(); iterator.hasNext();) {
					Object e = TngUtil.unwrap(iterator.next());
					if (e instanceof ItemProviderAdapter) {
						e = ((ItemProviderAdapter) e).getTarget();
					}
					if (elements.contains(e)) {
						iterator.remove();
					}
				}
			}
		}

	}

	private static void addToActivity(Activity act, BreakdownElement be, Object[] prevAndNext) {
		Object next = prevAndNext[1];
		boolean added = false;
		if(next != null) {
			int id = act.getBreakdownElements().indexOf(next);
			if(id != -1) { 
				act.getBreakdownElements().add(id, be);
				added = true;
			}
		}
		if(!added) {
			Object prev = prevAndNext[0];
			if(prev != null) {				
				int id = act.getBreakdownElements().indexOf(prev);
				if(id != -1) {
					act.getBreakdownElements().add(id + 1, be);
				}
				else {
					act.getBreakdownElements().add(be);
				}
			}
			else {
				act.getBreakdownElements().add(be);
			}
		}

	}
	
	/**
	 * Locally contributes to the inherited activity represented by the given adapter
	 * 
	 * @param adapter
	 * @param createdActivities
	 * @return
	 */
	public static Activity contributeToActivity(
			BreakdownElementWrapperItemProvider adapter, List createdActivities) {
		Object parent = adapter.getParent(null);
		Object[] prevAndNext = ProcessUtil
				.getPreviousAndNext(adapter);
		if (parent instanceof BreakdownElementWrapperItemProvider) {
			parent = contributeToActivity(
					(BreakdownElementWrapperItemProvider) parent,
					createdActivities);
		}
		Activity act = ProcessUtil.generialize(adapter,
				VariabilityType.LOCAL_CONTRIBUTION_LITERAL, prevAndNext);
		Activity parentAct = ((Activity) parent);
		addToActivity(parentAct, act, prevAndNext);
		createdActivities.add(act);
		return act;
	}

	/**
	 * Locally replaces the inherited activity represented by the given adapter
	 * 
	 * @param adapter
	 * @param createdActivities
	 */
	public static void replaceActivityLocally(
			BreakdownElementWrapperItemProvider adapter, List createdActivities) {
		Object parent = adapter.getParent(null);
		Object[] prevAndNext = ProcessUtil
				.getPreviousAndNext(adapter);
		if (parent instanceof BreakdownElementWrapperItemProvider) {
			parent = contributeToActivity(
					(BreakdownElementWrapperItemProvider) parent,
					createdActivities);
		}
		Activity act = ProcessUtil.generialize(adapter,
				VariabilityType.LOCAL_REPLACEMENT_LITERAL, prevAndNext);
		Activity parentAct = ((Activity) parent);
		addToActivity(parentAct, act, prevAndNext);
		createdActivities.add(act);
	}

	static Object[] getPreviousAndNext(
			BreakdownElementWrapperItemProvider adapter) {
		Object parent = adapter.getParent(null);
		AdapterFactory adapterFactory = TngUtil.getBestAdapterFactory(adapter
				.getAdapterFactory());
		ITreeItemContentProvider itemProvider = (ITreeItemContentProvider) adapterFactory
				.adapt(parent, ITreeItemContentProvider.class);
		List children = (List) itemProvider.getChildren(parent);
		int id = children.indexOf(adapter) + 1;
		Object next = null;
		if (id < children.size()) {
			next = children.get(id);
		}
		Object prev = null;
		id -= 2;
		if (id > -1) {
			prev = children.get(id);
		}

		Object[] prevAndNext = { prev, next };
		return prevAndNext;
	}

	static Activity generialize(BreakdownElementWrapperItemProvider adapter,
			VariabilityType type, Object[] prevAndNext) {
		AdapterFactory adapterFactory = TngUtil.getBestAdapterFactory(adapter
				.getAdapterFactory());

		Activity act = generalize((Activity) adapter.getValue(), type);
		Object next = prevAndNext[1];
		if(next != null) {
			act.setPresentedAfter((BreakdownElement) TngUtil.unwrap(next));
			if(next instanceof BreakdownElement) {
				((BreakdownElement)next).setPresentedBefore(act);
			}
		}
		Object prev = prevAndNext[0];
		if(prev != null) {
			act.setPresentedBefore((BreakdownElement) TngUtil.unwrap(prev));
			if (prev instanceof BreakdownElement) {
				((BreakdownElement)prev).setPresentedAfter(act);
			}
		}
		IBSItemProvider bsItemProvider = (IBSItemProvider) adapterFactory
				.adapt(act, ITreeItemContentProvider.class);
		bsItemProvider.setExpanded(adapter.isExpanded());
		return act;
	}

	/**
	 * Gets the immediate base process of the given
	 * BreakdownElementWrapperItemProvider that represents an inherited
	 * breakdown element.
	 * 
	 * @param itemProvider
	 * @return
	 */
	public static Process getImmediateBaseProcess(
			BreakdownElementWrapperItemProvider itemProvider) {
		Activity inheritor = getInheritor(itemProvider);
		if (inheritor != null) {
			return TngUtil.getOwningProcess((BreakdownElement) inheritor
					.getVariabilityBasedOnElement());
		}
		return null;
	}

	/**
	 * Gets the activity in the process of the given item provider that inherits
	 * the element represented by the given item provider
	 * 
	 * @param itemProvider
	 * @return
	 */
	public static Activity getInheritor(
			BreakdownElementWrapperItemProvider itemProvider) {
		if (itemProvider.isReadOnly()) {
			// this represents an inherited breakdown element
			//
			for (Object parent = itemProvider.getParent(itemProvider); parent != null;) {
				if (parent instanceof BreakdownElementWrapperItemProvider) {
					parent = ((BreakdownElementWrapperItemProvider) parent)
							.getParent(parent);
				} else {
					return (Activity) parent;
				}
			}
		}
		return null;
	}

	/**
	 * Gets parent list of <code>wrapper</code> from <code>from</code>,
	 * excluded <code>from</code>
	 * 
	 * @param from
	 * @param wrapper
	 * @return list of unwrapped parent objects
	 */
	public static List getParentList(Object from,
			BreakdownElementWrapperItemProvider wrapper) {
		return getParentList(wrapper, from, wrapper.getAdapterFactory());
	}
	
	/**
	 * Gets parent list of <code>object</code> from <code>from</code>,
	 * excluded <code>from</code>
	 * 
	 * @param object
	 * @param from
	 * @param adapterFactory
	 * @return list of unwrapped parent objects
	 */
	public static List getParentList(Object object, Object from, AdapterFactory adapterFactory) {
		ArrayList parentList = new ArrayList();
		ITreeItemContentProvider itemProvider = (ITreeItemContentProvider) adapterFactory.adapt(object, ITreeItemContentProvider.class);
		for (Object parent = itemProvider.getParent(object); parent != from
				&& parent != null;) {
			Object obj = TngUtil.unwrap(parent);
			MethodElement e;			
			if (obj instanceof MethodElement) {
				e = (MethodElement) obj;
				ITreeItemContentProvider adapter;
				if (parent instanceof ITreeItemContentProvider) {
					adapter = (ITreeItemContentProvider) parent;
				} else {
					adapter = (ITreeItemContentProvider) adapterFactory.adapt(
							parent, ITreeItemContentProvider.class);
				}
				if(ProcessUtil.isTopProcess(e)) {
					parent = null;
				}
				else {
					parent = adapter.getParent(parent);
				}
			} else {
				// must be a ItemProviderAdapter
				//
				ItemProviderAdapter adapter = ((ItemProviderAdapter) obj);
				e = (MethodElement) adapter.getTarget();
				parent = adapter.getParent(parent);
			}
			parentList.add(0, e);
		}
		return parentList;
	}

	/**
	 * Gets the wrappers of all breakdown structure (BS) views in the following
	 * order: WBS, TBS, WPBS
	 * 
	 * @param wrapper
	 *            the wrapper of a BS view
	 * @return
	 */
	public static List getWrappers(BreakdownElementWrapperItemProvider wrapper, AdapterFactory[] adapterFactories) {
		ArrayList rolledUpItemProviders = new ArrayList();
		try {
			AdapterFactory rootAdapterFactory = TngUtil.getBestAdapterFactory(wrapper.getAdapterFactory());
			Object proc = wrapper.getTopItem();						
			ArrayList objects = new ArrayList(ProcessUtil.getParentList(proc,
					wrapper));
			ArrayList wrappers = new ArrayList();
			for (int i = 0; i < adapterFactories.length; i++) {
				AdapterFactory adapterFactory = adapterFactories[i];
				if (adapterFactory == rootAdapterFactory) {
					wrappers.add(wrapper);
					continue;
				}
				Object e = TngUtil.unwrap(wrapper);
				objects.add(e);
				Object object = proc;
				for (Iterator iter1 = objects.iterator(); iter1.hasNext();) {
					Object element = iter1.next();
					ITreeItemContentProvider adapter = (ITreeItemContentProvider) adapterFactory
					.adapt(object, ITreeItemContentProvider.class);
					
					// make sure the activity is rolled down before looking into its children
					//
					Object be = TngUtil.unwrap(object);								
					if(be instanceof Activity) {
						if(adapter instanceof BSActivityItemProvider) {
							BSActivityItemProvider itemProvider = (BSActivityItemProvider) adapter;
							if(itemProvider.isRolledUp()) {
								itemProvider.basicSetRolledUp(false);
								rolledUpItemProviders.add(itemProvider);
							}
						}
						else if(adapter instanceof IBSItemProvider) {
							IBSItemProvider itemProvider = (IBSItemProvider) adapter;
							if(itemProvider.isRolledUp()) {
								itemProvider.setRolledUp(false);
								rolledUpItemProviders.add(itemProvider);
							}
						}
					}
					
					find_child: for (Iterator iterator = adapter
							.getChildren(object).iterator(); iterator.hasNext();) {
						Object child = iterator.next();
						if (element == TngUtil.unwrap(child)) {
							object = child;
							break find_child;
						}
					}
				}
				if (object instanceof BreakdownElementWrapperItemProvider) {
					wrappers.add(object);
				} else {
					throw new RuntimeException(
							"Could not find wrapper for " + e + " using adapter factory " + adapterFactory); //$NON-NLS-1$ //$NON-NLS-2$
				}
			}
			return wrappers;
		}
		finally {
			if(!rolledUpItemProviders.isEmpty()) {
				// restore the rolledUp flag
				//
				for (Iterator iter = rolledUpItemProviders.iterator(); iter
				.hasNext();) {
					((BSActivityItemProvider) iter.next()).basicSetRolledUp(true);
				}
			}
		}
	}
	
	/**
	 * Gets WorkProductDescriptor specific model info 
	 * @param modelInfo
	 * @param object WorkProductDescriptor or its wrapper
	 * @param itemProvider item provider of WorkProductDescriptor or its wrapper
	 */
	public static void getWPDModelInfo(StringBuffer modelInfo, Object object, Object itemProvider) {
		Object element = TngUtil.unwrap(object);
		if(element instanceof WorkProductDescriptor) {	
			WorkProductDescriptor wpd = (WorkProductDescriptor)element;
			if(itemProvider instanceof ITreeItemContentProvider) {
				// check if this work product descriptor is shown under a task descriptor or role descriptor
				//
				AdapterFactory adapterFactory = null;
				if(itemProvider instanceof ItemProviderAdapter) {
					adapterFactory = ((ItemProviderAdapter)itemProvider).getAdapterFactory();
				}
				else if(itemProvider instanceof BreakdownElementWrapperItemProvider) {
					adapterFactory = ((BreakdownElementWrapperItemProvider)itemProvider).getAdapterFactory();
				}
				if(adapterFactory != null) {
					Object parentDescriptor = null;
					ITreeItemContentProvider adapter = (ITreeItemContentProvider)itemProvider;
					findParentDescriptor:
						for(Object parent = adapter.getParent(object); parent != null; parent = adapter.getParent(parent)) {
							Object e = TngUtil.unwrap(parent);
							if(e instanceof TaskDescriptor) {
								parentDescriptor = e;
								break findParentDescriptor;
							}
							else if(e instanceof Activity) {
								break findParentDescriptor;
							}
							adapter = (ITreeItemContentProvider) adapterFactory.adapt(parent, ITreeItemContentProvider.class);
						}
					if(parentDescriptor != null) {	
						// work product descriptor is shown under a task descriptor
						// show only model info related to this task descriptor
						//
						ArrayList features = new ArrayList();
						if(AssociationHelper.getMandatoryInputTo(wpd).contains(parentDescriptor)) {
							features.add(UmaPackage.eINSTANCE.getTaskDescriptor_MandatoryInput());
						}
						if(AssociationHelper.getOptionalInputTo(wpd).contains(parentDescriptor)) {
							features.add(UmaPackage.eINSTANCE.getTaskDescriptor_OptionalInput());							
						}
						if(AssociationHelper.getOutputFrom(wpd).contains(parentDescriptor)) {
							features.add(UmaPackage.eINSTANCE.getTaskDescriptor_Output());
						}
						if(!features.isEmpty()) {
							if (modelInfo.toString().length() > 0) {
								modelInfo.append(","); //$NON-NLS-1$
							}
							for (int i = 0; i < features.size(); i++) {
								EStructuralFeature feature = (EStructuralFeature) features.get(i);
								modelInfo.append(TngUtil.getFeatureText(feature));
								if(i < features.size() -1){
									modelInfo.append(",");
								}
							}						
						}
						return;
					}
				}
			}
			getModelInfoForWorkProductDescriptor(modelInfo, wpd);
		}
	}

	/**
	 * Retrieves the ModelInformation specific to WorkProductDescriptor. Model
	 * Information is for PBS (WorkProductDescriptors, including Extended
	 * Activity's WorkProductDescriptors).
	 */
	private static void getModelInfoForWorkProductDescriptor(
			StringBuffer modelInfo, WorkProductDescriptor object) {
		String comma = ","; //$NON-NLS-1$
		if (!AssociationHelper.getMandatoryInputTo(object).isEmpty()) {
			if (modelInfo.toString().length() > 0) {
				modelInfo.append(comma);
			}
			modelInfo.append(UmaEditPlugin.INSTANCE
					.getString("_UI_TaskDescriptor_mandatoryInput_feature")); //$NON-NLS-1$
		}
		if (!AssociationHelper.getOptionalInputTo(object).isEmpty()) {
			if (modelInfo.toString().length() > 0) {
				modelInfo.append(comma);
			}
			modelInfo.append(UmaEditPlugin.INSTANCE
					.getString("_UI_TaskDescriptor_optionalInput_feature")); //$NON-NLS-1$
		}
		if (!AssociationHelper.getOutputFrom(object).isEmpty()) {
			if (modelInfo.toString().length() > 0) {
				modelInfo.append(comma);
			}
			modelInfo.append(UmaEditPlugin.INSTANCE
					.getString("_UI_TaskDescriptor_output_feature")); //$NON-NLS-1$
		}
	}

	public static Collection getDuplicateDescriptorsAfterReveal(Collection elementsToReveal) {
		Collection duplicates = new ArrayList();
		for (Iterator iter = elementsToReveal.iterator(); iter.hasNext();) {
			Object element = iter.next();
			if(element instanceof Descriptor) {
				Descriptor desc = (Descriptor) element;
				MethodElement e = ProcessUtil.getAssociatedElement(desc);
				if(e != null) {
					Activity act = UmaUtil.getParentActivity(desc);
					MethodConfiguration config = TngUtil.getOwningProcess(act).getDefaultContext();
					e = (MethodElement) Providers.getConfigurationApplicator().resolve(e, config);
					Object duplicate = ProcessCommandUtil.getDescriptor(e, act, config);
					if(duplicate != null) {
						duplicates.add(duplicate);
					}
				}
			}
		}
		
		return duplicates;
	}
	
	public static Collection getDuplicateDescriptorsAfterSuppress(Collection elementsToSuppress) {
		Collection duplicates = new ArrayList();
		for (Iterator iter = elementsToSuppress.iterator(); iter.hasNext();) {
			Object item = iter.next();
			if(item instanceof Descriptor) {
				Descriptor desc = (Descriptor) item;
				MethodElement e = ProcessUtil.getAssociatedElement(desc);
				if(e != null) {
					Activity act = UmaUtil.getParentActivity(desc);
					for (Iterator iterator = act.getBreakdownElements().iterator(); iterator.hasNext();) {
						BreakdownElement element = (BreakdownElement) iterator.next();
						if(element != e && element instanceof Descriptor && element.getSuppressed().booleanValue()) {
							MethodElement linkedElement = ProcessUtil.getAssociatedElement((Descriptor) element);
							if(linkedElement == e) {
								duplicates.add(element);
							}
						}
					}
				}
			}
		}
		
		return duplicates;
		
	}

	/**
	 * Checks if the given object is representing a inherited element in a breakdown structure tree of process editor
	 * 
	 * @param object
	 * @return
	 */
	public static boolean isInherited(Object object) {
		return object instanceof DescribableElementWrapperItemProvider
		&& ((DescribableElementWrapperItemProvider)object).isInherited();
	}
	
	/**
	 * Checks if the given activity has inherited any breakdown element via extension of local contribution
	 * 
	 * @param activity
	 * @return
	 */
	public static boolean hasInherited(Activity activity) {
		Iterator iter = new AbstractTreeIterator(activity) {

			/**
			 * Comment for <code>serialVersionUID</code>
			 */
			private static final long serialVersionUID = 0L;

			protected Iterator getChildren(Object object) {
				if(object instanceof Activity) {
					return ((Activity)object).getBreakdownElements().iterator();
				}
				return Collections.EMPTY_LIST.iterator();
			}
			
		};
		while(iter.hasNext()) {
			Object o = iter.next();
			if(o instanceof Activity) {
				Activity act = (Activity) o;
				VariabilityElement ve = act.getVariabilityBasedOnElement();
				if(ve != null) {
					VariabilityType type = act.getVariabilityType();
					if(type == VariabilityType.EXTENDS_LITERAL || type == VariabilityType.LOCAL_CONTRIBUTION_LITERAL) {
						return true;
					}
				}
			}
		}
		return false;
	}
	
	public static boolean isContributed(Object object) {
		return object instanceof BreakdownElementWrapperItemProvider
		&& ((BreakdownElementWrapperItemProvider)object).isContributed();
	}	
	
	public static void getAllSubTeams(TeamProfile team, List teams) {
		teams.add(team);
		List subTeams = team.getSubTeam();
		for (Iterator itor = subTeams.iterator(); itor.hasNext();) {
			TeamProfile subTeam = (TeamProfile) itor.next();

			getAllSubTeams(subTeam, teams);
		}
	}
	
	private static List getTeamProfiles(Object object, ITreeItemContentProvider adapter, AdapterFactory adapterFactory) {
		RoleDescriptor roleDesc = (RoleDescriptor) TngUtil.unwrap(object);
		List teams = new ArrayList(AssociationHelper.getTeamProfiles(roleDesc));
		
		// get all the team profiles that are in scope of the wrapper
		//
		HashSet visibleTeams = new HashSet();
		for (Object parent = adapter.getParent(object); parent != null;) {
			adapter = (ITreeItemContentProvider) adapterFactory.adapt(parent, ITreeItemContentProvider.class);		
			for (Iterator iter = adapter.getChildren(parent).iterator(); iter.hasNext();) {
				Object e = TngUtil.unwrap(iter.next());
				if (e instanceof TeamProfile) {
					List activityTeams = new ArrayList();
					getAllSubTeams((TeamProfile) e, activityTeams);
					for (Iterator itor = activityTeams.iterator(); itor.hasNext();)	{
						Object o = itor.next();
						if(o instanceof TeamProfile && ((TeamProfile)o).getTeamRoles().contains(roleDesc)) {
							visibleTeams.add(o);
						}
					}
				}
			}
			Object newParent = adapter.getParent(parent);
			if(newParent == null && parent instanceof Activity) {
				newParent = UmaUtil.getParentActivity((Activity)parent);
			}
			parent = newParent;
		}
		
		// remove any team profile that is not in the scope of the wrapper
		//
		for (Iterator iter = teams.iterator(); iter.hasNext();) {
			Object team = iter.next();
			if(!visibleTeams.contains(team)) {
				iter.remove();
			}
		}
		
		return teams;

	}
	
	/**
	 * Gets the list of visible team profiles for the role descriptor represented by the given wrapper
	 * 
	 * @param roleDescWrapper
	 * @return
	 */
	public static List getTeamProfiles(RoleDescriptorWrapperItemProvider roleDescWrapper) {
		return getTeamProfiles(roleDescWrapper, roleDescWrapper, roleDescWrapper.getAdapterFactory());
	}
	
	public static List getTeamProfiles(RoleDescriptor roleDesc, AdapterFactory adapterFactory) {
		ITreeItemContentProvider adapter = (ITreeItemContentProvider) adapterFactory.adapt(roleDesc, ITreeItemContentProvider.class);
		return getTeamProfiles(roleDesc, adapter, adapterFactory);
	}
	
	public static void getChildElements(Activity act, Class type, Collection collection) {
		for (int i = act.getBreakdownElements().size() - 1; i > -1; i--) {
			Object element = act.getBreakdownElements().get(i);
			if(type.isInstance(element)) {
				collection.add(element);
			}
			else if(element instanceof Activity) {
				getChildElements((Activity) element, type, collection);
			}
		}
	}
	
	public static IFilter getFilter(AdapterFactory adapterFactory) {
		AdapterFactory rootAdapterFactory = TngUtil.getBestAdapterFactory(adapterFactory);
		if(rootAdapterFactory instanceof ConfigurableComposedAdapterFactory) {
			return ((ConfigurableComposedAdapterFactory)rootAdapterFactory).getFilter();
		}
		return null;
	}
	
	/**
	 * Gets the calculated list of artifact contained by the given artifact based on the
	 * configuration associated with the given adapter factory.
	 * 
	 * @param artifact
	 * @param adapterFactory
	 * @return
	 */
	public static List getContainedArtifacts(Artifact artifact, AdapterFactory adapterFactory) {
		MethodConfiguration config = null;
		IFilter filter = ProcessUtil.getFilter(adapterFactory);
		if(filter instanceof IConfigurator) {
			config = ((IConfigurator)filter).getMethodConfiguration();
		}
		
		if(config == null) {
			return artifact.getContainedArtifacts();
		}
		else {
			return (List) Providers.getConfigurationApplicator().getReference(
					artifact,
					UmaPackage.eINSTANCE.getArtifact_ContainedArtifacts(),
					config);
		}		
	}
	
	public static List getContainedArtifactsDescriptors(WorkProductDescriptor artifactDesc, List artifactDescriptors) {
		if(artifactDescriptors.isEmpty()) {
			return Collections.EMPTY_LIST;
		}
		Artifact artifact = (Artifact) artifactDesc.getWorkProduct();
		
		// collect own and contributing subartifact descriptors
		//
		ArrayList containedDescriptors = new ArrayList();
		for(int i = artifactDescriptors.size() - 1; i > -1; i--) {
			WorkProductDescriptor wpd = ((WorkProductDescriptor)artifactDescriptors.get(i));
			WorkProduct a = wpd.getWorkProduct();
			if(a != null) {
				EObject container = a.eContainer();
				if(container == artifact || 
						(container instanceof Artifact && TngUtil.isContributorOf(artifact, (Artifact) container))) {
					containedDescriptors.add(wpd);
				}
			}
		}
		return containedDescriptors;
	}
	
//	public static boolean isContainedBy(Artifact parent, Artifact child, AdapterFactory adapterFactory) {
//		MethodConfiguration config = null;
//		IFilter filter = ProcessUtil.getFilter(adapterFactory);
//		if(filter instanceof IConfigurator) {
//			config = ((IConfigurator)filter).getMethodConfiguration();
//		}
//		
//		if(config == null) {
//			return UmaUtil.isContainedBy(child, parent);
//		}
//		
//		final MethodConfiguration cfg = config;		
//		Iterator iter = new AbstractTreeIterator(parent, false) {
//
//			/**
//			 * Comment for <code>serialVersionUID</code>
//			 */
//			private static final long serialVersionUID = 1L;
//
//			protected Iterator getChildren(Object object) {
//				return ((Collection) Providers.getConfigurationApplicator().getReference(
//						(VariabilityElement) object,
//						UmaPackage.eINSTANCE.getArtifact_ContainedArtifacts(),
//						cfg)).iterator();
//			}
//			
//		};
//		while(iter.hasNext()) {
//			if(child == iter.next()) {
//				return true;
//			}
//		}
//		
//		return false;
//	}
	
	/**
	 * Checks if the given WorkProductDescriptor <code>parent</code> can represent the parent of the WorkProductDescriptor
	 * <code>child</code> based on the relationship of their linked artifact and the list of available artifact descriptors
	 */
	public static boolean isContainedBy(WorkProductDescriptor parent, WorkProductDescriptor child, final List artifactDescList) {
//		Iterator iter = new AbstractTreeIterator(parent, false) {
//			
//			/**
//			 * Comment for <code>serialVersionUID</code>
//			 */
//			private static final long serialVersionUID = 1L;
//			
//			protected Iterator getChildren(Object object) {
//				return getContainedArtifactsDescriptors((WorkProductDescriptor) object, artifactDescList).iterator();
//			}
//			
//		};
//		while(iter.hasNext()) {
//			if(child == iter.next()) {
//				return true;
//			}
//		}
//		
//		return false;
		
		return UmaUtil.isContainedBy(child.getWorkProduct(), parent.getWorkProduct());
	}

	public static List removeSubartifactsFromChildren(final Collection children, boolean unwrap) {
		List artifactList = new ArrayList();
	
		// get the artifact list
		//
		for (Iterator iter = children.iterator(); iter.hasNext();) {
			Object child = iter.next();
			if(unwrap) {
				child = TngUtil.unwrap(child);
			}
			if (child instanceof WorkProductDescriptor) {
				WorkProduct wp = ((WorkProductDescriptor) child)
						.getWorkProduct();
				if (wp instanceof Artifact) {
					artifactList.add(wp);
				}
			}
		}
	
		// process the artifact list to get the top-most ones
		//
		Set topMostArtifacts = new HashSet();
		Artifact candidate = null;
	
		boolean found = false;
		while (!artifactList.isEmpty()) {
			
			if (!found)
			{
				candidate = (Artifact) artifactList.get(0);
				artifactList.remove(0);
			}
			for (Iterator iter = artifactList.iterator(); iter.hasNext();) {
				Artifact artifact = (Artifact) iter.next();
				found = false;
				// if(candidate.getContainedArtifacts().contains(artifact)) {
				if (UmaUtil.isContainedBy(artifact, candidate)) {
					iter.remove();
				}
				else if (UmaUtil.isContainedBy(candidate, artifact)) {
					iter.remove();
					candidate = artifact;
					found = true;
					break;
				}
			}
			if (!found || artifactList.isEmpty())
				topMostArtifacts.add(candidate);
			else if (artifactList.isEmpty())
					topMostArtifacts.add(candidate);		
		}
	
		List result = new ArrayList();
		for (Iterator ci = children.iterator(); ci.hasNext();) {
			Object child = ci.next();
			Object e = unwrap ? TngUtil.unwrap(child) : child;
			boolean selected = false;
			if (e instanceof WorkProductDescriptor) {
				WorkProductDescriptor wpd = ((WorkProductDescriptor) e);
				WorkProduct wp = wpd.getWorkProduct();
				if (!(wp instanceof Artifact)) {
					selected = true;
				} else if (topMostArtifacts.contains(wp)) {
					selected = true;
				}
			} else {
				selected = true;
			}
			if (selected) {
				result.add(child);
			}
		}
		return result;
	}

	/**
	 * This method helps build the artifact descriptor tree correctly
	 * 
	 * @param children
	 * @param unwrap
	 * @param adapterFactory
	 * @return
	 */
	public static List removeSubartifactsFromChildren(final Collection children, boolean unwrap, AdapterFactory adapterFactory) {
		List artifactDescList = new ArrayList();

		// get the artifact list
		//
		for (Iterator iter = children.iterator(); iter.hasNext();) {
			Object child = iter.next();
			if(unwrap) {
				child = TngUtil.unwrap(child);
			}
			if (child instanceof WorkProductDescriptor) {
				WorkProduct wp = ((WorkProductDescriptor) child)
						.getWorkProduct();
				if (wp instanceof Artifact) {
					artifactDescList.add(child);
				}
			}
		}

		if(artifactDescList.isEmpty()) {
			if(children instanceof List) {
				return (List) children;
			}
			else {
				return new ArrayList(children);
			}
		}
		
		// process the artifact list to get the top-most ones
		//
		Set topMostArtifactDescList = new HashSet();
		List artifactDescriptors = new ArrayList(artifactDescList);
		WorkProductDescriptor candidate = null;
		boolean found = false;
		while (!artifactDescList.isEmpty()) {
			
			if (!found)
			{
				candidate = (WorkProductDescriptor) artifactDescList.get(0);
				artifactDescList.remove(0);
			}
			for (Iterator iter = artifactDescList.iterator(); iter.hasNext();) {
				WorkProductDescriptor artifactDesc = (WorkProductDescriptor) iter.next();
				found = false;
				if (ProcessUtil.isContainedBy(candidate, artifactDesc, artifactDescriptors)) {
					iter.remove();
				}
				else if (ProcessUtil.isContainedBy(artifactDesc, candidate, artifactDescriptors)) {
					iter.remove();
					candidate = artifactDesc;

					found = true;
					break;
				}
			}
			if (!found || artifactDescList.isEmpty())
				topMostArtifactDescList.add(candidate);
			else if (artifactDescList.isEmpty())
					topMostArtifactDescList.add(candidate);		
		}

		List result = new ArrayList();
		for (Iterator ci = children.iterator(); ci.hasNext();) {
			Object child = ci.next();
			Object e = unwrap ? TngUtil.unwrap(child) : child;
			boolean selected = false;
			if (e instanceof WorkProductDescriptor) {
				WorkProductDescriptor wpd = ((WorkProductDescriptor) e);
				WorkProduct wp = wpd.getWorkProduct();
				if (!(wp instanceof Artifact)) {
					selected = true;
				} else if (topMostArtifactDescList.contains(wpd)) {
					selected = true;
				}
			} else {
				selected = true;
			}
			if (selected) {
				result.add(child);
			}
		}
		return result;
	}

	public static Activity findActivity(ProcessPackage procPackage) {
		if(procPackage instanceof ProcessComponent) {
			return ((ProcessComponent)procPackage).getProcess();
		}
		for (Iterator iterator = procPackage
				.getProcessElements().iterator(); iterator
				.hasNext();) {
			Object element = iterator.next();
			if (element instanceof Activity) {
				return ((Activity) element);
			}
		}
		return null;
	}	
	
	public static void fixBreakdonwElementOrderRecursively(Activity act) {
		Iterator iter = new AbstractTreeIterator(act) {

			/**
			 * Comment for <code>serialVersionUID</code>
			 */
			private static final long serialVersionUID = 3368261685663354478L;

			protected Iterator getChildren(Object object) {
				ArrayList activities = new ArrayList();
				for (Iterator iterator = ((Activity)object).getBreakdownElements().iterator(); iterator
						.hasNext();) {
					Object element = iterator.next();
					if(element instanceof Activity) {
						activities.add(element);
					}
				}
				return activities.iterator();
			}
			
		};
		while(iter.hasNext()) {
			fixBreakdownElementOrder((Activity)iter.next());
		}
	}

	/**
	 * @param activity
	 */
	public static void fixBreakdownElementOrder(Activity activity) {
		EList list = (EList) activity.getBreakdownElements();
		for (Iterator iter = new ArrayList(list).iterator(); iter.hasNext();) {
			BreakdownElement e = (BreakdownElement) iter.next();
			BreakdownElement succ = e.getPresentedAfter();
			if(succ != null && succ != e) {
				int succId = list.indexOf(succ);
				if(succId != -1) {
					int id = list.indexOf(e);
					if(id != succId - 1) {
						if(id < succId) {
							list.move(succId - 1, id);
						}
						else {
							list.move(succId, id);
						}
					}
					e.setPresentedAfter(null);
				}
			}
		}
	}

	/**
	 * Initializes item provider path of the given activity, the path from top process to the activity
	 * 
	 * @param activity
	 * @param adapterFactory
	 */
	public static void initializeItemProviderPath(Activity activity, AdapterFactory adapterFactory) {
		// get the activity path
		//
		ArrayList actPath = new ArrayList();
		for(activity = activity.getSuperActivities(); activity != null; activity = activity.getSuperActivities()) {
			actPath.add(0, activity);
		}
		for (Iterator iter = actPath.iterator(); iter.hasNext();) {
			Object act = iter.next();
			ITreeItemContentProvider ip = (ITreeItemContentProvider) adapterFactory.adapt(act, ITreeItemContentProvider.class);
			ip.getChildren(act);
		}
	}		

	/**
	 * Check if the given activity or any of its subactivities is a contributor or replacer
	 * 
	 * @param activity
	 * @return
	 */
	public static boolean hasContributorOrReplacer(Activity activity) {
		Iterator iter = new AbstractTreeIterator(activity) {

			/**
			 * Comment for <code>serialVersionUID</code>
			 */
			private static final long serialVersionUID = 0L;

			protected Iterator getChildren(Object object) {
				if(object instanceof Activity) {
					ArrayList children = new ArrayList();
					for (Iterator iterator = ((Activity)object).getBreakdownElements().iterator(); iterator
							.hasNext();) {
						Object element = iterator.next();
						if(element instanceof VariabilityElement) {
							children.add(element);
						}
					}
					return children.iterator();
				}
				return Collections.EMPTY_LIST.iterator();
			}
			
		};
		
		while(iter.hasNext()) {
			VariabilityElement ve = (VariabilityElement) iter.next();
			VariabilityElement base = ve.getVariabilityBasedOnElement();
			VariabilityType vType = ve.getVariabilityType();
			if(base != null && (vType == VariabilityType.CONTRIBUTES_LITERAL || vType == VariabilityType.REPLACES_LITERAL)) {
//				Process proc = TngUtil.getOwningProcess((BreakdownElement) base);
//				if(proc != process) {
//					return true;
//				}
				
				return true;
			}
		}
		
		return false;
	}	
	
	/**
	 * @param target
	 * @return
	 */
	public static boolean isTopProcess(Object target) {
		return target instanceof Process && ((Process)target).eContainer() instanceof ProcessComponent;
	}

	/**
	 * @param wpDescList
	 * @return
	 */
	public static WorkProductDescriptor getWorkProductDescriptor(Collection elements, WorkProduct wp) {
		for (Iterator iter = elements.iterator(); iter.hasNext();) {
			Object e = (Object) iter.next();
			if(e instanceof WorkProductDescriptor) {
				WorkProductDescriptor wpd = ((WorkProductDescriptor)e);
				if(wpd.getWorkProduct() == wp) {
					return wpd;
				}

			}
		}
		return null;
	}

	/**
	 * @param taskDescList
	 * @param task
	 * @return
	 */
	public static TaskDescriptor getTaskDescriptor(Collection elements, Task task) {
		for (Iterator iter = elements.iterator(); iter.hasNext();) {
			Object e = (Object) iter.next();
			if(e instanceof TaskDescriptor) {
				TaskDescriptor td = (TaskDescriptor) e;
				if(td.getTask() == task) {
					return td;
				}
			}
		}
		return null;
	}

	/**
	 * Gets the owning work breakdown element of a work order.
	 * 
	 * @param workOrder
	 *            a work order
	 * @return a work breakdown element that owns the work order or
	 *         <code>null</code>
	 */
	public static WorkBreakdownElement getOwner(WorkOrder workOrder) {
		return AssociationHelper.getSuccessor(workOrder);
	}

	public static ComposedBreakdownElementWrapperItemProvider getComposedWrapper(Object object) {
		while(!(object instanceof ComposedBreakdownElementWrapperItemProvider)
				&& object instanceof IWrapperItemProvider) {
			object = ((IWrapperItemProvider)object).getValue();
		}
		if(object instanceof ComposedBreakdownElementWrapperItemProvider) {
			return (ComposedBreakdownElementWrapperItemProvider) object;
		}
		return null;
	}
	
	/**
	 * Gets the display name for the given breakdown structure column ID. The
	 * breakdown structure column IDs are defined as constants in
	 * {@link IBSItemProvider} that start with COL_
	 * 
	 * @param columnName
	 *            one of the columns ID constants (COL_XXX) defined in
	 *            {@link IBSItemProvider}
	 * @return
	 */
	public static final String getColumnDisplayName(String columnId) {
		try {
			return LibraryEditPlugin.INSTANCE.getString("BS_Column_" + columnId); //$NON-NLS-1$ //$NON-NLS-2$
		} catch (MissingResourceException e) {
		}
		return columnId;
	}

}