//------------------------------------------------------------------------------
// 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.configuration;

import java.net.URI;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.HashSet;
import java.util.Iterator;
import java.util.LinkedHashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.TreeSet;

import org.eclipse.emf.ecore.EAttribute;
import org.eclipse.emf.ecore.EClass;
import org.eclipse.emf.ecore.EObject;
import org.eclipse.emf.ecore.EReference;
import org.eclipse.emf.ecore.EStructuralFeature;
import org.eclipse.epf.common.utils.ExtensionHelper;
import org.eclipse.epf.common.utils.StrUtil;
import org.eclipse.epf.library.ConfigHelperDelegate;
import org.eclipse.epf.library.LibraryPlugin;
import org.eclipse.epf.library.edit.PresentationContext;
import org.eclipse.epf.library.edit.meta.TypeDefUtil;
import org.eclipse.epf.library.edit.util.CategorySortHelper;
import org.eclipse.epf.library.edit.util.MethodElementPropUtil;
import org.eclipse.epf.library.edit.util.PracticePropUtil;
import org.eclipse.epf.library.edit.util.PropUtil;
import org.eclipse.epf.library.edit.util.SectionList;
import org.eclipse.epf.library.edit.util.TngUtil;
import org.eclipse.epf.library.util.LibraryUtil;
import org.eclipse.epf.library.util.ResourceHelper;
import org.eclipse.epf.uma.Activity;
import org.eclipse.epf.uma.Artifact;
import org.eclipse.epf.uma.CapabilityPattern;
import org.eclipse.epf.uma.ContentDescription;
import org.eclipse.epf.uma.ContentElement;
import org.eclipse.epf.uma.CustomCategory;
import org.eclipse.epf.uma.DeliveryProcess;
import org.eclipse.epf.uma.DescribableElement;
import org.eclipse.epf.uma.FulfillableElement;
import org.eclipse.epf.uma.MethodConfiguration;
import org.eclipse.epf.uma.MethodElement;
import org.eclipse.epf.uma.MethodPackage;
import org.eclipse.epf.uma.MethodPlugin;
import org.eclipse.epf.uma.Practice;
import org.eclipse.epf.uma.Role;
import org.eclipse.epf.uma.RoleDescriptor;
import org.eclipse.epf.uma.SupportingMaterial;
import org.eclipse.epf.uma.Task;
import org.eclipse.epf.uma.TaskDescriptor;
import org.eclipse.epf.uma.UmaPackage;
import org.eclipse.epf.uma.VariabilityElement;
import org.eclipse.epf.uma.VariabilityType;
import org.eclipse.epf.uma.WorkProduct;
import org.eclipse.epf.uma.WorkProductDescriptor;
import org.eclipse.epf.uma.ecore.impl.MultiResourceEObject;
import org.eclipse.epf.uma.ecore.util.OppositeFeature;
import org.eclipse.epf.uma.util.AssociationHelper;
import org.eclipse.epf.uma.util.Scope;
import org.eclipse.epf.uma.util.UserDefinedTypeMeta;


/**
 * @author Jinhua Xi
 * @author Phong Nguyen Le
 * @author Weiping Lu
 * @since 1.0
 */
public class ConfigurationHelper {
	
	private static ConfigHelperDelegate delegate;

	static {
		ConfigHelperDelegate extendedDelegate = (ConfigHelperDelegate) ExtensionHelper
				.getExtension(LibraryPlugin.getDefault().getId(),
						"configHelperDelegateExt");//$NON-NLS-1$
		if (extendedDelegate == null) {
			delegate = new ConfigHelperDelegate();
		} else {
			delegate = extendedDelegate;
		}
	}
	
	public static ConfigHelperDelegate getDelegate() {
		return delegate;
	}
	
	private static boolean inheritingSlotFeatures = false; 
	
	public static final String ATTRIBUTE_VALUE_SEPERATOR = "<p/>"; //$NON-NLS-1$

	private static boolean debug = LibraryPlugin.getDefault().isDebugging();

	/**
	 * check if the element is a ContentDescription
	 * 
	 * @param element {@link MethodElement}
	 * @return boolean
	 */
	public static boolean isDescriptionElement(MethodElement element) {
		if ( element == null ) {
			return false;
		}
		
		return (element instanceof ContentDescription || element.eContainer() instanceof ContentDescription);

	}

	/**
	 * check if the method pacj=kage is a global package
	 * 
	 * @param pkg {@link MethodPackage}
	 * @return boolean
	 */
	public static boolean isGlobalPackage(MethodPackage pkg) {
		if (pkg == null) {
			if (debug) {
				System.out
						.println("ConfigurationHelper.isGlobalPackage: method package is null"); //$NON-NLS-1$
			}
			return false;
		}

		MethodPlugin p = LibraryUtil.getMethodPlugin(pkg);
		if (p == null) {
			if (debug) {
				System.out
						.println("ConfigurationHelper.isGlobalPackage: Unable to find method plug-in for " + pkg.getName() + ": " + pkg.getGuid()); //$NON-NLS-1$ //$NON-NLS-2$
			}
			return false;
		}

		return getDelegate().isSystemPackage(p, pkg);
	}

	/**
	 * check if the element is in the configuration
	 * 
	 * @param element
	 * @param config
	 * @return
	 */
	public static boolean inConfig(MethodElement element,
			MethodConfiguration config) {
		return inConfig(element, config, true);
	}
	
	
	/**
	 * check if the element is in the configuration
	 * 
	 * @param element
	 * @param config
	 * @return
	 */
	public static boolean inConfig(MethodElement element,
			MethodConfiguration config, boolean checkSubtracted) {
		return inConfig(element, config, checkSubtracted, true);
	}
	
	/**
	 * check if the element is in the configuration
	 * 
	 * @param element
	 * @param config
	 * @return
	 */
	public static boolean inConfig(MethodElement element,
			MethodConfiguration config, boolean checkSubtracted, boolean checkBase) {
		if (!isOwnerSelected(element, config, checkSubtracted)) {
			return false;
		}

		//Bug 207429 - Configration: Warring info should shown when deselect the replaced element
		// for configuration closure checking, the missing base should be reported 
		// so the element been checked still treated as in config
		// added the checkBase flag to ignore the base checking
		// for configuration realization, this flag should be set to true
		// so the replacer missing base is not included in the config.
		
		// if the element is a repalcer, and it's base element has more than one
		// replacer
		// none of the replacers should be included into the configuration
		if (checkBase && (element instanceof VariabilityElement) ) {
			VariabilityElement ve = (VariabilityElement) element;
			if (isReplacer(ve)) {
				VariabilityElement base = ve.getVariabilityBasedOnElement();
				if (inConfig(base, config)) {
					
//					// Invalid hotspot created for locally replaced activity in activity diagram
//					// this is because the activity has more than one local replacers
//					// in version 7.0, local replacement is modeled the same way as nomal replacement
//					// we need to ignore this checking for activity
//					if ( element instanceof Activity ) {
//						return true;
//					}
					
					for (Iterator it = AssociationHelper.getImmediateVarieties(
							base).iterator(); it.hasNext();) {
						VariabilityElement e = (VariabilityElement) it.next();
						if ((e != element)
								&& (e.getVariabilityType() == VariabilityType.REPLACES)
								&& isOwnerSelected(e, config, checkSubtracted)) {
							if (debug) {
								System.out
										.println("ConfigurationHelper.inConfig: Ignoring replacing element '" + LibraryUtil.getTypeName(element) + "' since its base element has more than one replacer in the configuration"); //$NON-NLS-1$ //$NON-NLS-2$
							}
							return false;
						}
					}
				} else {
					return false;  // base must be in the configuration
				}
			}
		}

		return true;
	}

	private static boolean isOwnerSelected(MethodElement element,
			MethodConfiguration config, boolean checkSubtracted) {
		return getDelegate().isOwnerSelected(element, config, checkSubtracted);
	}

	/**
	 * is the element a contributor?
	 * @param element
	 * @return boolean
	 */
	public static boolean isContributor(VariabilityElement element) {
		if (element == null || element.getVariabilityBasedOnElement() == null)
			return false;

		return element.getVariabilityType() == VariabilityType.CONTRIBUTES;
	}

	/**
	 * is the element a replacer?
	 * @param element
	 * @return boolean
	 */
	public static boolean isReplacer(VariabilityElement element) {
		if (element == null || element.getVariabilityBasedOnElement() == null)
			return false;

		return element.getVariabilityType() == VariabilityType.REPLACES;
	}
	
	/**
	 * is "b" an ancestor of "a" through a "contribute chain" relationship
	 * @param a
	 * @param b
	 * @return
	 */
	public static boolean contrubuteChain(VariabilityElement a, VariabilityElement b) {	
		VariabilityElement element = a;
		while (element != null) {
			if (element.getVariabilityType() != VariabilityType.CONTRIBUTES) {
				return false;
			}
			element = element.getVariabilityBasedOnElement();
			if (element == null) {
				return false;
			}
			if (element == b) {
				return true;
			}
		}
		
		return false;
	}

	/**
	 * is the element a extend-replacer?
	 * @param element
	 * @return boolean
	 */
	public static boolean isExtendReplacer(VariabilityElement element) {
		if (element == null || element.getVariabilityBasedOnElement() == null)
			return false;

		return element.getVariabilityType() == VariabilityType.EXTENDS_REPLACES;
	}
	
	/**
	 * is the element an extender?
	 * @param element
	 * @return boolean
	 */
	public static boolean isExtender(VariabilityElement element) {
		if (element == null || element.getVariabilityBasedOnElement() == null)
			return false;

		return element.getVariabilityType() == VariabilityType.EXTENDS;
	}

	/**
	 * get the replacer of the element in the configuration. Only one replacer
	 * is allowed. If more than one replacer is found, then none of them will be
	 * returned.
	 * 
	 * @param element
	 *            VariabilityElement the element
	 * @param config
	 *            MethodConfiguration
	 * @return VariabilityElement the replacer if there is one and ONLY one,
	 *         null otherwise
	 */
	public static VariabilityElement getReplacer(VariabilityElement element,
			MethodConfiguration config) {
		VariabilityElement ve = null;

		// this will get all replacers recursively. we only need the immediate
		// ones
		// for(Iterator iterator = TngUtil.getGeneralizers(element,
		// VariabilityType.REPLACES_LITERAL); iterator.hasNext();)
		for (Iterator it = AssociationHelper.getImmediateVarieties(element)
				.iterator(); it.hasNext();) {
			VariabilityElement e = (VariabilityElement) it.next();
			if ( e == null || !inConfig(e, config) ) {
				continue;
			}

			VariabilityType type = e.getVariabilityType();
			if ( type == VariabilityType.REPLACES 
					|| type == VariabilityType.EXTENDS_REPLACES) {
				if (ve != null) {
					if (debug) {
						System.out
								.println("ConfigurationHelper.getReplacer: Replacer ignored for element '" + LibraryUtil.getTypeName(element) + "' since it has more than one replacerin the configuration"); //$NON-NLS-1$ //$NON-NLS-2$
					}
					return null; // if more than one replacer, return null
				}

				ve = e;
			}
		}

		return ve;
	}

	/**
	 * get the immediate contributors of the element within the configuration.
	 * If a contributor has immediate replacer, it is repalced with the replacer
	 * 
	 * @param element
	 * @param config
	 * @return
	 */
	public static List getContributors(VariabilityElement element,
			MethodConfiguration config) {
		List items = new ArrayList();

		if ( element == null ) {
			return items;
		}
		
		// This method get all contributors recursively,
		// we only need the first level
		// for (Iterator it = TngUtil.getContributors(element); it.hasNext(); )
		for (Iterator it = AssociationHelper.getImmediateVarieties(element)
				.iterator(); it.hasNext();) {
			VariabilityElement e = (VariabilityElement) it.next();
			if ((e != null)
					&& (e.getVariabilityType() == VariabilityType.CONTRIBUTES)
					&& inConfig(e, config)) {
				VariabilityElement replacer = getReplacer(e, config);
				if (replacer != null) {
					items.add(replacer);
				} else {
					items.add(e);
				}
			}
		}

		return items;
	}

	public static List getExtenders(VariabilityElement element,
			MethodConfiguration config) {
		List items = new ArrayList();

		if ( element == null ) {
			return items;
		}
		
		for (Iterator it = AssociationHelper.getImmediateVarieties(element)
				.iterator(); it.hasNext();) {
			VariabilityElement e = (VariabilityElement) it.next();
			if ((e != null)
					&& (e.getVariabilityType() == VariabilityType.EXTENDS)
					&& inConfig(e, config)) {
					items.add(e);
			}
		}

		return items;
	}
	
	public static Set<VariabilityElement> getLocalContributersAndReplacers(VariabilityElement element,
			MethodConfiguration config) {
		Set<VariabilityElement> items = new HashSet<VariabilityElement>();

		if ( element == null ) {
			return items;
		}
		
		for (Iterator it = AssociationHelper.getImmediateVarieties(element)
				.iterator(); it.hasNext();) {
			VariabilityElement e = (VariabilityElement) it.next();
			if ((e != null)
					&& (isLocalContributerOrReplacer(e))
					&& inConfig(e, config)) {
					items.add(e);
			}
		}

		return items;
	}
	
	private static boolean isLocalContributerOrReplacer(
			VariabilityElement ve) {
		VariabilityType type = ve.getVariabilityType();
		return type == VariabilityType.LOCAL_CONTRIBUTION
				|| type == VariabilityType.LOCAL_REPLACEMENT;
	}
	
	public static boolean canShow(MethodElement element,
			MethodConfiguration config) {
		return canShow(element,config, true);
	}
	

	/**
	 * element can't show in the configuration tree if 1. the element is not in
	 * the configuration 2. the element is a contribution to another element 3.
	 * if the element is a replacer to a 3. the element has a replacement
	 * element in the configuration
	 * 
	 * @param element
	 * @param config
	 * @return boolean
	 */
	public static boolean canShow(MethodElement element,
			MethodConfiguration config, boolean checkSubtracted) {
		if (element == null) {
			return false;
		}

		if (!inConfig(element, config, checkSubtracted)) {
			return false;
		}

//		// if it;s an activity, return since contributors are local contribution and needs to be shown
//		if (element instanceof Activity) {
//			return true;
//		}

//		/////////////////////////////////////////////////////////////////////////////////////////////////
//		// this is not needed any more since the suppression state is determined by the activity adaptor factory
//		// just leave it here for now since it does not hurt. take it away in next release
		// 
		// NO, we still need to keep this to check the suppression of descriptors referenced by another descriptor. 
		// for example, when displaying a TD page, we need to handle the suppression of the referenced WPDs and RDs. 
		// 00395278 - Browsing TD with suppressed RD/WPD under it  -- suppressed ones still showing
		// Note: this does not handle the case when the descriptor is with an inherited activity. 
		// in that case, the suppression need to be determined by the activity path. TODO
		Boolean supressed = element.getSuppressed();
		if (supressed != null && supressed.booleanValue() == true) {
			return false;
		}
//		/////////////////////////////////////////////////////////////////////////////////////////////////
		
		if ( element instanceof VariabilityElement) {
			if ( !canShowByCheckingVE((VariabilityElement) element,config) ) {
				return  false;
			}
		}

		return true;
	}
	
	/**
	 * 
	 * @param e
	 * @param config
	 * @return
	 */
	public static boolean canShowByCheckingVE(VariabilityElement e, MethodConfiguration config){		

		// if this is an extender, always show, even though it extends a
		// contributor
		if (isExtender(e)) {
			return true;
		}

		if (isContributor(e) || getReplacer(e, config) != null) {
			return false;
		}

		// for activity, don't show the ones that contains contributors 
		// the resaon for this is to simplify the logic.
		// assuming that user uses this activity to contribute to other activities
		// so that part should not be involved in the navigation
		// 
		// Jinhua Xi, 07/14/06, 
		if ( (e instanceof Activity) && hasContributor((Activity)e) ) {
			return false;
		}

		while ((e != null) && (isReplacer(e) || isExtendReplacer(e))) {
			e = (VariabilityElement) e.getVariabilityBasedOnElement();
			if (isContributor(e)) {
				return false;
			}
		}
		
		return true;
	}

	/**
	 * get the name of the element in the configuration. 1. if it's a
	 * contributor, show the name of the base element 2. if it has a
	 * replacemenet, show the name of the replacement element
	 * 
	 * @param element
	 * @param config
	 * @return String
	 */
	public static String getName(MethodElement element,
			MethodConfiguration config) {
		if (element instanceof VariabilityElement) {
			VariabilityElement e = (VariabilityElement) element;
			if (isContributor(e)) {
				return getName(e.getVariabilityBasedOnElement(), config);
			} else {
				VariabilityElement rep = getReplacer(e, config);
				if (rep != null) {
					return getName(rep, config);
				}
			}
		}

		return element.getName();
	}

	/**
	 * get the presentation name for an element in the configuration
	 * @param element
	 * @param config
	 * @return String
	 */
	public static String getPresentationName(MethodElement element,
			MethodConfiguration config) {
		
		// [Bug 196399] P-name is not inherited from its base element in an extending element
		String name = null;

		name = element.getPresentationName();
		if ( StrUtil.isBlank(name) && (element instanceof VariabilityElement) ) {
			EStructuralFeature f = UmaPackage.eINSTANCE.getVariabilityElement_VariabilityBasedOnElement();
			ElementRealizer r = DefaultElementRealizer.newElementRealizer(config);	
			MethodElement me = element;

			Set<MethodElement> seens = new HashSet<MethodElement>();
			do {
				VariabilityElement oldMe = (VariabilityElement) me;
				me = (DescribableElement)ConfigurationHelper.calc01FeatureValue(me, f, r);
				if ( me == null ) {
					break;
				} else if (oldMe == me || seens.contains(me)) {
					me = oldMe.getVariabilityBasedOnElement();
					if (me == null) {
						break;
					}
				}					
				name = ((DescribableElement)me).getPresentationName();
				if (seens.contains(me)) {	//to prevent loop in case such as											
					break;					//both extend-replacer and base have empty pres name
				}
				seens.add(oldMe);
				seens.add(me);
			} while ( StrUtil.isBlank(name) );
		}
		
		if ( StrUtil.isBlank(name) ) {
			name = TngUtil.getPresentationName(element);
		}

		return name;
	}

	/**
	 * get the variability element owner. If the element is a
	 * VariabilityElement, return itself otherwise, find it's owner. For
	 * example, a ContentDescriotion object is ownered by a VariabilityElement
	 * 
	 * @param e
	 *            MethodElement
	 * @return VariabilityElement
	 */
	public static VariabilityElement getVariableOwner(MethodElement e) {
		if (e instanceof VariabilityElement) {
			return (VariabilityElement) e;
		} else if (e instanceof ContentDescription) {
			// return AssociationHelper.getOwner( (ContentDescription)e );
			EObject eObj = e.eContainer();
			if (eObj instanceof VariabilityElement) {
				return (VariabilityElement) eObj;
			}
		}

		return null;
	}

	/**
	 * check if the feature value is mergable or not
	 * @param feature
	 * @return boolean
	 */
	public static boolean isMergableAttribute(EStructuralFeature feature) {
		if (!feature.getEType().getInstanceClassName().equals(
				"java.lang.String")) //$NON-NLS-1$
		{
			return false;
		}

		// feature id is not globally unique, can't do a switch here
		// compare the acture featrue instead
		/*
		 * switch ( feature.getFeatureID() ) { case
		 * UmaPackage.METHOD_ELEMENT__GUID: case
		 * UmaPackage.METHOD_ELEMENT__NAME:
		 * Contributing a Unique ID for work product renders
		 * bad html // don't merge Unique ID: case
		 * UmaPackage.WORK_PRODUCT_DESCRIPTION__EXTERNAL_ID: return false; }
		 */

		if (feature == UmaPackage.eINSTANCE.getMethodElement_Guid()
				|| feature == UmaPackage.eINSTANCE.getNamedElement_Name()
				|| feature == UmaPackage.eINSTANCE
						.getContentDescription_ExternalId() 
				|| feature == UmaPackage.eINSTANCE.getMethodElement_PresentationName()) {
			return false;
		}

		return true;
	}

	/**
	 * is attribute feature value?
	 * @param feature
	 * @return boolean
	 */
	public static boolean isAttributeFeature(EStructuralFeature feature) {
		return (feature.getEType() instanceof EAttribute);
	}
	
	/**
	 * is this a to-one feature?
	 * @param feature
	 * @return boolean
	 */
	public static boolean is01Feature(EStructuralFeature feature) {
		return (feature.getEType() instanceof EClass) && !feature.isMany();
	}

	/**
	 * is this a to-many feature?
	 * @param feature
	 * @return boolean
	 */
	public static boolean is0nFeature(EStructuralFeature feature) {
		return (feature.getEType() instanceof EClass) && feature.isMany();
	}

	
	/**
	 * calculate the value of the specified element and feature
	 * 
	 * @param element
	 * @param feature
	 * @param config
	 * @param values
	 *            The List of values of the feature. if the feature is a 0..1
	 *            association, the List holds a single value if any for
	 *            reference list feature, it's a list of references for
	 *            attribute feature, it's a list of attribute values to be
	 *            mergered for 0..1 association, the list may contain 1 value.
	 */
//	private static void calculateFeature(MethodElement element,
//			EStructuralFeature feature, MethodConfiguration config,
//			List values, ElementRealizer realizer) {
//		calculateFeature(element, null, feature, config, values, realizer);
//	}

	private static void calculateFeature(MethodElement element,
			MethodElement OwnerElement, EStructuralFeature feature,
			MethodConfiguration config, FeatureValue values, ElementRealizer realizer) {
		
		TypeDefUtil typeDefUtil = TypeDefUtil.getInstance();
		
		// make sure this is a valid feature 
		// for example, if an activity contributes to a Capability Pattern,
		// some CapabilityPattern specific feature may not be a valid feature for the Activity
//		List features = element.getInstanceProperties();
		List features = LibraryUtil.getStructuralFeatures(element, true);
		if ( !features.contains(feature)) {
			if (element instanceof Practice) {
				PracticePropUtil practicePropUtil = PracticePropUtil.getPracticePropUtil();
				Practice practice = (Practice) element;
				UserDefinedTypeMeta meta = practicePropUtil.getUdtMeta(practice);
				if (meta == null || ! meta.isQualifiedRefernce((EReference) feature)) {
					return;
				}
			} else {	
				return;
			}
		}
		
		// EClassifier type = feature.getEType();
		VariabilityElement ve = getVariableOwner((OwnerElement == null) ? element
				: OwnerElement);

//		Object value = element.eGet(feature);
		Object value = typeDefUtil.eGet(element, feature);

		values.add(ve, value);

		if (config == null || config instanceof Scope) {
			return;
		}

		// realize the variability relationship
		if (ve == null) {
			return;
		}
		
		// according to Peter, the realization should be always top down.
		// i.e realize the base first, then include the contributions
		__mergeBase(element, ve, feature, config, values, realizer);
		
		if (element instanceof FulfillableElement) {
			if (feature != UmaPackage.eINSTANCE
					.getFulfillableElement_Fulfills()) {
				mergeSlotFeatureValues((FulfillableElement) element, feature,
						config, values, realizer);
			}
		} else if (OwnerElement instanceof FulfillableElement) {
			mergeSlotFeatureValues(element, (FulfillableElement) OwnerElement,
					feature, config, values, realizer);	
		}
		
		if (realizer != null) {
			realizer.addExtraFeatureValues(element, feature, values);
		}
		
		if (!is01Feature(feature) || (values.size() == 0) ) {
			__mergeContributors(element, ve, feature, config, values, realizer);
		}
	}
	
	public static List<FulfillableElement> calcFulfillableElement_Fulfills(FulfillableElement element,
					MethodConfiguration config) {
		List<FulfillableElement> resultList = new ArrayList<FulfillableElement>();
		
		ElementRealizer realizer = DefaultElementRealizer.newElementRealizer(config);
		Object fullfillsObj = calc0nFeatureValue(element,
				UmaPackage.eINSTANCE.getFulfillableElement_Fulfills(),
				realizer);	
		
		if (! (fullfillsObj instanceof List)) {
			return resultList;
		}

		EStructuralFeature feature = UmaPackage.eINSTANCE.getFulfillableElement_Fulfills();
		for (FulfillableElement slot : (List<FulfillableElement>) fullfillsObj) {
			slot = (FulfillableElement) getCalculatedElement(slot, config);
			if (slotMatching(slot, element, realizer)) {
				resultList.add(slot);
			}
		}
		
		if (resultList.size() > 1) {
			Comparator comparator = PresentationContext.INSTANCE.getPresNameComparator();
			Collections.<FulfillableElement>sort(resultList, comparator);
		}
		
		return resultList;
	}
	
	private static void mergeSlotFeatureValues(FulfillableElement element,
			EStructuralFeature feature, MethodConfiguration config,
			FeatureValue values, ElementRealizer realizer) {
		if (!inheritingSlotFeatures) {
			return;
		}
		
		if (feature == UmaPackage.eINSTANCE.getFulfillableElement_Fulfills()) {			
			return;
		}
		if (!(element instanceof WorkProduct)) {
			return;
		}
		if (values.size() > 0) {
			return;
		}
		
		List<FulfillableElement> slots = calcFulfillableElement_Fulfills(element, config);

		for (FulfillableElement slot : slots) {
			if (slot instanceof WorkProduct) {
				slot = (FulfillableElement) getCalculatedElement(slot, config);
				calculateFeature(slot, null, feature, config, values,
						realizer);
			}
		}
	}
	
	private static void mergeSlotFeatureValues(MethodElement element, FulfillableElement OwnerElement,
			EStructuralFeature feature, MethodConfiguration config,
			FeatureValue values, ElementRealizer realizer) {
		if (!inheritingSlotFeatures) {
			return;
		}
		
		if (! (element instanceof ContentDescription)) {
			return;
		}
		
		if (!(OwnerElement instanceof WorkProduct)) {
			return;
		}
		if (values.size() > 0) {
			return;
		}
		
		List<FulfillableElement> slots = calcFulfillableElement_Fulfills(OwnerElement, config);

		for (FulfillableElement slot : slots) {
			if (slot instanceof WorkProduct) {
				slot = (FulfillableElement) getCalculatedElement(slot, config);
				ContentDescription slotOwnedElement = slot.getPresentation();				
				calculateFeature(slotOwnedElement, slot, feature, config, values,
						realizer);
			}
		}
	}
	
	private static void mergeSlotOppositeFeatureValues(FulfillableElement element,
			OppositeFeature feature, MethodConfiguration config,
			FeatureValue values, ElementRealizer realizer) {
		if (!inheritingSlotFeatures) {
			return;
		}
		
		if (feature == AssociationHelper.FulFills_FullFillableElements) {
			return;
		}
		
		if (!(element instanceof WorkProduct)) {
			return;
		}
		if (values.size() > 0) {
			return;
		}
		
		List<FulfillableElement> slots = calcFulfillableElement_Fulfills(element, config);

		for (FulfillableElement slot : slots) {
			slot = (FulfillableElement) getCalculatedElement(slot, config);
			calculateOppositeFeature(slot, feature, realizer, values);
		}
	}
	
	public static List<FulfillableElement> calcFulfills_FulfillableElement(
			FulfillableElement slot, MethodConfiguration config) {
		List<FulfillableElement> resultList = new ArrayList<FulfillableElement>();

		ElementRealizer realizer = DefaultElementRealizer
				.newElementRealizer(config);

		List fulfillingList = calc0nFeatureValue(slot, AssociationHelper.FulFills_FullFillableElements, realizer);

		for (FulfillableElement element : (List<FulfillableElement>) fulfillingList) {
			element = (FulfillableElement) getCalculatedElement(element, config);
			if (slotMatching(slot, element, realizer)) {
				resultList.add(element);
			}
		}
		
		if (resultList.size() > 1) {
			Comparator comparator = PresentationContext.INSTANCE.getPresNameComparator();
			Collections.<FulfillableElement>sort(resultList, comparator);
		}
		
		return resultList;
	}		
	
	private static boolean slotMatching(FulfillableElement slot,
			FulfillableElement element, ElementRealizer realizer) {
		if (slot == null || !slot.getIsAbstract()) {
			return false;
		}		

		if (realizer != null) {	
			return realizer.slotMatching(slot, element);
		}

		return true;
	}
	
	private static void __mergeBase(MethodElement element,
			VariabilityElement ve, EStructuralFeature feature,
			MethodConfiguration config, FeatureValue values, ElementRealizer realizer) {
	
		// if the element is an extended element, get the base element's
		// properties if needed
		boolean extendReplace = isExtendReplacer(ve) || 
				ElementRealizer.isExtendReplaceEnabled() && isReplacer(ve);
		boolean isExtender = isExtender(ve);
		
		if (extendReplace && PropUtil.getPropUtil().isCustomize(ve)) {
			return;
		}
		
		if (isExtender || extendReplace) {
			boolean mergebase = false;
			if (is0nFeature(feature)) {
				mergebase = true;
				if ( extendReplace 
						|| isExtender && ElementRealizer.ignoreBaseToManyAssociations()) {
					mergebase = (values.size() == 0);
				}
			} else if (is01Feature(feature)) {
				mergebase = (values.size() == 0);
			} else {
				mergebase = (isMergableAttribute(feature) && (values.size() == 0));
			}

			if (mergebase) {
				// Authoring: Extending a base that has been
				// replaced, does not extend the replacement
				// need to get the realized element,
				// the base element might be replaced by another one,
				// or might be a contributor to another base
				MethodElement e = ve.getVariabilityBasedOnElement();
				if ( !extendReplace ) {
					e= getCalculatedElement(e, config);
				}					
				MethodElement o = e;

				// if it's a containment feature, such as sub-artifacts
				// the base should not be the container
				// 162154 - Check circular references with parent-/sub-artifacts and practices/sub-practices				
				if ( isContainmentFeature(feature) ) {
					List containers = getContainers(ve, config);
					if (containers.contains(e) ) {
						mergebase = false;
					}
				}

				if (mergebase && (ve != e) && inConfig(e, config)) {
					// if the current element is a description,
					// get the the description object of the base
					if (element instanceof ContentDescription) {
						try {
							e = ((DescribableElement) e).getPresentation();
						} catch (Exception e1) {
							e1.printStackTrace();
						}
					}

					calculateFeature(e, o, feature, config, values, realizer);

					// for extender, we need to re-sort the steps based on the
					// extender defined order
					if ((ve instanceof ContentElement)
							&& (feature == UmaPackage.eINSTANCE
									.getContentDescription_Sections())) {
						orderSections((ContentElement) ve, (List)values.getValue());
					}
				}
			}
		}
	
	}

	private static void __mergeContributors(MethodElement element,
			VariabilityElement ve, EStructuralFeature feature,
			MethodConfiguration config, FeatureValue values, ElementRealizer realizer) {
		boolean mergeable = true;
		if ( isAttributeFeature(feature) && !isMergableAttribute(feature) ) {
			mergeable = false;
		} 
		
		if ( mergeable ) {
			// if the element has contributors in the configuration, get the
			// reference properties
			// if a contributor has replacer, it's replacer is used
			List items = getContributors(ve, config);
			if (items != null && items.size() > 0) {
				for (Iterator it = items.iterator(); it.hasNext();) {
					MethodElement e = (MethodElement) it.next();
					MethodElement o = e;  // the owner

					// if the current element is a description,
					// get the the description object of the contributor
					if (element instanceof ContentDescription) {
						e = ((DescribableElement) e).getPresentation();
					}
					calculateFeature(e, o, feature, config, values, realizer);
				}
			}
		}
		
	}
	
	/**
	 * calculate the reflist for the specified element and OppositeFeature
	 * 
	 * @param element
	 * @param feature
	 *            OppositeFeature
	 * @param realizer ElementRealizer
	 * @param values
	 *            The List of values of the feature. for reference list feature,
	 *            it's a list of references for attribute feature, it's a list
	 *            of attribute values to be mergered
	 */
	private static void calculateOppositeFeature(MethodElement element,
			OppositeFeature feature, ElementRealizer realizer, FeatureValue values) {
		calculateOppositeFeature(element, feature, true, false, realizer, values);
	}
	
	
	/**
	 * calculate the reflist for the specified element and OppositeFeature
	 * 
	 * @param element
	 * @param feature
	 *            OppositeFeature
	 * @param realizer ElementRealizer
	 * @param values
	 *            The List of values of the feature. for reference list feature,
	 *            it's a list of references for attribute feature, it's a list
	 *            of attribute values to be mergered
	 */
	private static void calculateOppositeFeature(MethodElement element,
			OppositeFeature feature, boolean mergeReplacerBase, boolean mergeExtenderBase, 
			ElementRealizer realizer, FeatureValue values) {
		// must be a MultiResourceEObject
		if (!(element instanceof MultiResourceEObject)) {
			return;
		}

		MethodConfiguration config = realizer.getConfiguration();

		VariabilityElement ve = getVariableOwner(element);

		Object value = ((MultiResourceEObject) element)
				.getOppositeFeatureValue(feature);
		values.add(ve, value);

		if (element instanceof VariabilityElement && config != null) {
			VariabilityElement ce = (VariabilityElement) element;

			// if the element has contributors in the configuration, get the
			// reference properties
			List items = getContributors(ce, config);
			if (items != null && items.size() > 0) {
				for (Iterator it = items.iterator(); it.hasNext();) {
					MethodElement e = (MethodElement) it.next();
					calculateOppositeFeature(e, feature, mergeReplacerBase, mergeExtenderBase, realizer, values);
				}
			}

			// if the element is a replacer of a base element, 
			// get the base element's properties
			// only cover 01 or 0m references
			// attributes can't be opposite feature

			// replaced element does not show incoming
			// relationships
			// imcoming relationships are represented by opposite feature
			// so keep the references to the base element
			
			// Inconsistency between Published Work Product: Workload Analysis Page and Referenced Pages
			// this is from the base of the extender. 
			// incoming associations from the base should be discarded for extenders
			boolean mergebase = false;
			boolean isExtender = isExtender(ce);
			boolean isReplacer = isReplacer(ce);
			boolean isExtendReplacer = isExtendReplacer(ce) || 
				ElementRealizer.isExtendReplaceEnabled() && isReplacer;
			
//			//This is a conservative fix for "Extends-replace displine rendered wrong in conf tree view"
//			if (isExtendReplacer(ce) &&  realizer.getClass() == DefaultElementRealizer.class) {
//				if (feature == AssociationHelper.Discipline_DisciplineGroupings) {
//					isReplacer = true;
//				}
//				if (feature == AssociationHelper.RoleSet_RoleSetGrouppings) {
//					isReplacer = true;
//				}				
//			}
			
			// extenderReplacer behaves like replacer when realizing incoming associations
			// Bug 199694 - Extends-Replace ignores incoming relationships of contributer
			if ( isExtendReplacer ) {
				isReplacer = true;
			}
			
			if (isReplacer) {
				mergebase = mergeReplacerBase && ((value instanceof List) || (values.size() == 0));
			} else if (isExtender) {
				mergebase = mergeExtenderBase;
			}

			if (mergebase) {
				// resolve the base contributor to the base if i am not a
				// replacer
				// don't resolve the contributors to the base if i am a
				// replacer,
				// the call is coming from the base. So if resolve to base again
				// will cause deadlock.
				// don't resolve to the replacer since we need to carry down all
				// the incoming 0n associations from base
				// actually should resolve to replacer if i am not a replacer
				// (i.e. i am an entender)
				// this handles the senario: G2 replaces G1 and G3 extends G1
				ElementRealizer realizer2 = 
					DefaultElementRealizer.newElementRealizer(config, (!isReplacer), (!isReplacer));

				MethodElement e = getCalculatedElement(ce
						.getVariabilityBasedOnElement(), realizer2);
				
				// if the base element resolved to null, 
				// this is because canShow() don't allow replaced element to show.
				// we don't want to take the risk to fix ElementRealizer
				// so fix here since 7.0.1_ifix1, 
				// Jinhua Xi, 4/17/06
				if ( e == null ) {
					e = ce.getVariabilityBasedOnElement();
				}
				
				if ((e != ce) && inConfig(e, config)) {
					calculateOppositeFeature(e, feature, mergeReplacerBase, mergeExtenderBase, realizer, values);
				}
			}
			
			if (element instanceof FulfillableElement) {
				mergeSlotOppositeFeatureValues((FulfillableElement) element, feature, config, values, realizer);
			}
			
		}
	}

	/**
	 * calculate the elements in the list, and returns a new list of unique
	 * elements
	 * 
	 * @param elements
	 * @param config
	 * @return List
	 */
	public static List getCalculatedElements(List elements,
			MethodConfiguration config) {
		return getCalculatedElements(elements, DefaultElementRealizer.newElementRealizer(config) );
	}
	
	/**
	 * calculate the elements in the list, and returns a new list of unique
	 * elements
	 * 
	 * @param elements
	 * @param realizer ElementRealizer
	 * @return List
	 */
	public static List getCalculatedElements(List elements, ElementRealizer realizer ) {
		// calculate each element in the list and return a new list of elements
		List values = new ArrayList();
		for (Iterator it = elements.iterator(); it.hasNext();) {
			MethodElement e = (MethodElement) it.next();
			e = ConfigurationHelper.getCalculatedElement(e, realizer);
			if ((e != null) && (!values.contains(e))) {
				values.add(e);
			}
		}

		return values;
	}

	/**
	 * calculate the element based on tle configuration. If nothing can be
	 * shown, return null.
	 * 
	 * @param element
	 * @param config
	 * @return
	 */
	public static MethodElement getCalculatedElement(MethodElement element,
			MethodConfiguration config) {
		ElementRealizer realizer = DefaultElementRealizer.newElementRealizer(config, true, true);

		return getCalculatedElement(element, realizer);
	}
	
	public static MethodElement getCalculatedElement(MethodElement element,
			ElementRealizer realizer) {

		MethodElement e = element;
		MethodElement e2;
		while ((e2 = realizer.realize(e)) != e) {
			e = e2;
		}
		return e;
	}

	/**
	 * get the calculated 0..1 feature value of the specipied element and
	 * feature
	 * 
	 * @return MethodElement
	 */
	public static MethodElement calc01FeatureValue(MethodElement element,
			EStructuralFeature feature, ElementRealizer realizer) {
		return calc01FeatureValue(element, null, feature, realizer);
	}
	
	/**
	 * get the calculated 0..1 feature value of the specipied element and
	 * feature
	 * 
	 * @return MethodElement
	 */
	public static MethodElement calc01FeatureValue(MethodElement element, MethodElement ownerElement, 
			EStructuralFeature feature, ElementRealizer realizer) {
		// presentation object feature should never be realized. always keep
		// it's own value
		Object v = element.eGet(feature);
		if (v instanceof ContentDescription) {
			return (MethodElement) v;
		}

		ToOneFeatureValue values = new ToOneFeatureValue(element, ownerElement, feature, realizer);
		calculateFeature(element, ownerElement, feature, realizer.getConfiguration(), values, realizer);
//		if (values.size() > 0) {
//			v = (MethodElement) values.get(0);
//			if (v instanceof MethodElement) {
//				return getCalculatedElement((MethodElement) v, realizer.getConfiguration());
//			}
//		}

		return (MethodElement)values.getValue();
	}


	/**
	 * is this feature for containd children? such as artifact's contained artifact.
	 * @param feature 
	 * @return boolean
	 */
	public static boolean isContainmentFeature(EStructuralFeature feature) {
		return feature == UmaPackage.eINSTANCE.getArtifact_ContainedArtifacts()
				|| feature == UmaPackage.eINSTANCE.getPractice_SubPractices();
	}

	/**
	 * check if the element allow contained element
	 * @param element
	 * @return boolean
	 */
	public static boolean isContainmentElement(Object element) {
		return element instanceof Artifact || element instanceof Practice;
	}

	private static List getContainers(MethodElement element,
			MethodConfiguration config) {
		List items = new ArrayList();

		EObject o = element;
		while ((o != null) && ((o = o.eContainer()) != null)
				&& o.getClass().isInstance(element)) {
			if (o instanceof VariabilityElement) {
				o = getCalculatedElement((VariabilityElement) o, config);
			}

			if ((o != null) && !items.contains(o)) {
				items.add(o);
			}
		}

		return items;
	}

	/**
	 * get the 01 opposite feature (if any) for the given feature. returns null
	 * if no such feature
	 * 
	 * @param feature
	 *            EStructuralFeature
	 * @return OppositeFeature the 01 opposite feature of the given feature,
	 *         null if no such thing
	 */
	public static OppositeFeature get01OppositeFeature(
			EStructuralFeature feature) {
		
		// since 1.0m4, these are not 01 feature any more
//		if (feature == UmaPackage.eINSTANCE.getDiscipline_Tasks()) {
//			return AssociationHelper.Task_Discipline;
//		} else if (feature == UmaPackage.eINSTANCE.getRole_ResponsibleFor()) {
//			return AssociationHelper.WorkProduct_ResponsibleRole;
//		}
		
//		if ( feature == UmaPackage.eINSTANCE.getDomain_WorkProducts() ) {
//			return AssociationHelper.WorkProduct_Domains;
//		} 
		
		return null;
	}


	/**
	 * get the target feature for the opposite feature if the target feature is a to-One feature, 
	 * otherwise, return null.
	 * @param oFeature
	 * @return EStructuralFeature
	 */
	public static EStructuralFeature get01Feature(OppositeFeature oFeature) {		
/*		if ( oFeature == AssociationHelper.Role_Primary_Tasks 
				|| oFeature == AssociationHelper.RoleDescriptor_PrimaryTaskDescriptors ) {
			return oFeature.getTargetFeature();
		}*/
		
		return null;
	}
	
	/**
	 * get the calculated 0..n feature value of the specipied element, it's
	 * owner element and feature
	 * 
	 * @param element {@link MethodElement}
	 * @param feature {@link EStructuralFeature}
	 * @param realizer {@link ElementRealizer}
	 * @return List a list of {@link MethodElement}
	 */
	public static List calc0nFeatureValue(MethodElement element,
			EStructuralFeature feature, ElementRealizer realizer) {
		TypeDefUtil typeDefUtil = TypeDefUtil.getInstance();
		if (realizer == null) {
			Object value = typeDefUtil.eGet(element, feature);
			return value instanceof List ? (List) value : null;
		}
		
		if (realizer != null && realizer.getConfiguration() instanceof Scope) {
//			Object value = element.eGet(feature);
			Object value = typeDefUtil.eGet(element, feature);
			if (value instanceof List) {
				List listValue = new ArrayList((List) value); 
				for (int i = 0; i < listValue.size(); i++) {
					if (listValue.get(i) instanceof MethodElement) {
						MethodElement e0 = (MethodElement) listValue.get(i);
						MethodElement e1 = realizer.realize(e0);
						if (e1 != null && e1 != e0) {
							listValue.set(i, e1);
						}
					} else {
						break;
					}
				}
				return listValue;
			}
			return null;
		}
		return calc0nFeatureValue(element, null, feature, realizer);
	}
	
	/**
	 * get the calculated 0..n feature value of the specipied element and
	 * feature. if the opposite feature on the other end is a to-one feature,
	 * the feature value item can't be in the value list unless it's opposite
	 * feature value is the current element. For example, for discipline_tasks,
	 * the tasks can be selected if and ONLY if the task's task_discipline
	 * opposite feature value is the current discipline
	 * 
	 * @param element MethodElement
	 * @param ownerElement {@link MethodElement}
	 * @param feature {@link EStructuralFeature}
	 * @param realizer {@link ElementRealizer}
	 * @return List a list of {@link MethodElement}
	 */
	public static List calc0nFeatureValue(MethodElement element, MethodElement ownerElement, 
			EStructuralFeature feature, ElementRealizer realizer) {
		List ret = calc0nFeatureValue_(element, ownerElement, feature, realizer);
		if (ret != null && !ret.isEmpty() && (element instanceof Task) && feature == UmaPackage.eINSTANCE.getTask_OptionalInput()) {
			List mInputs = calc0nFeatureValue_(element, ownerElement, UmaPackage.eINSTANCE.getTask_MandatoryInput(), realizer);
			if (mInputs != null && ! mInputs.isEmpty()) {
				ret.removeAll(mInputs);
			}			
		}		
		return ret;
	}
	
	private static List calc0nFeatureValue_(MethodElement element, MethodElement ownerElement, 
			EStructuralFeature feature, ElementRealizer realizer) {
				
		List v = null;
		MethodConfiguration config = realizer.getConfiguration();
		
		// Wrong "modifies" information published in team allocation view for small configuration
		// need to manually calculate the modify features
		// can't rely on the uma model since that is not configuration specific.
		// role modifies product means:
		// role performs on tasks, and tasks produce workproducts as output
		// so handle these scenarios as special cases
		if ( element instanceof Role && feature == UmaPackage.eINSTANCE.getRole_Modifies() ) {
//			List v2 = new ArrayList();
//			calculateOppositeFeature(element, AssociationHelper.Role_Primary_Tasks, realizer, v2);
//			if ( v2.size() > 0 ) {
//				for (Iterator it = v2.iterator(); it.hasNext(); ) {
//					MethodElement e = (MethodElement)it.next();
//					calculateFeature(e, ownerElement, UmaPackage.eINSTANCE.getTask_Output(), config, v, realizer);					
//				}
//			}	
			v = calcModifiedWorkProducts((Role)element, ownerElement, realizer);
		}else if ( element instanceof RoleDescriptor && feature == UmaPackage.eINSTANCE.getRoleDescriptor_Modifies() ) {
//			List v2 = new ArrayList();
//			calculateOppositeFeature(element, AssociationHelper.RoleDescriptor_PrimaryTaskDescriptors, realizer, v2);
//			if ( v2.size() > 0 ) {
//				for (Iterator it = v2.iterator(); it.hasNext(); ) {
//					MethodElement e = (MethodElement)it.next();
//					calculateFeature(e, ownerElement, UmaPackage.eINSTANCE.getTaskDescriptor_Output(), config, v, realizer);					
//				}
//			}
			v = calcModifiedWorkProductDescriptors((RoleDescriptor)element, ownerElement, realizer);
		} else {
			ToManyFeatureValue fv = new ToManyFeatureValue(element, ownerElement, feature, realizer);
			calculateFeature(element, ownerElement, feature, config, fv, realizer);
			v = (List)fv.getValue();
		}
		
		List values = getCalculatedElements(v, realizer);
		if (values.contains(element)) {
			values.remove(element);
		}

		// * if the opposite feature on the other end is a to-one feature,
		// * the feature value item can't be in the value list unless it's
		// opposite feature value is the current element.
		// * For example, for discipline_tasks, the tasks can be selected
		// * if and ONLY if the task's task_discipline opposite feature value is
		// the current discipline
		OppositeFeature of = get01OppositeFeature(feature);
		if (of != null) {
			int i = 0;
			while (i < values.size()) {
				MethodElement o = (MethodElement) values.get(i);

				// calculate it's opposite feature value, the value must be the
				// given element
				// otherwise, remove it
				// note: don't use the current realizer
				// use the default realizer since we need to realize the element in the default way
				// 158924 - wrong categories in configuration view

				
				// workaround to allow show/hide subtracted elements
				ElementRealizer r = DefaultElementRealizer.newElementRealizer(config);
				r.setShowSubtracted(realizer.showSubtracted());
				
				MethodElement oo = calc01FeatureValue(o, of, r);
				if (oo != element) {
					values.remove(i);
				} else {
					i++;
				}
			}
		}

		// containment feature value should not contain the owner element or its
		// parents
		// for example, artifact_containedArtifacts should not be the artifact
		// itself or its parents
		if (isContainmentFeature(feature)) {
			List containers = getContainers(element, config);
			int i = 0;
			while (i < values.size()) {
				Object o = (Object) values.get(i);
				if (o == element || containers.contains(o)) {
					values.remove(i);
				} else {
					i++;
				}
			}
		}
		
		List returnList = realizer.realize(element, feature, values);
		if (CategorySortHelper.needToSort(element, feature)) {
			Map map = MethodElementPropUtil.getMethodElementPropUtil().getExtendedPropertyMap(element, false);
			if (map == null || ! map.containsKey(ConfigurationFilter.isEmptyCheckLock)) {
				returnList = CategorySortHelper.sortCategoryElements(element, returnList.toArray(), true, feature, config);
			}
		}

		// the following part might not be general to all cases
		// so put it into the realizer
		return returnList;
		
//		// if the feature value is containment element such as artifact
//		// the child element can't show if any of the parent(s) are in the list
//		// Published site: Display of WPs under responsible role
//		if (feature.isMany() && values.size() > 0
//				&& isContainmentElement(values.get(0))) {
//			int i = 0;
//			while (i < values.size()) {
//				MethodElement o = (MethodElement) values.get(i);
//
//				// if the container of the element is in the list, remove this
//				// element from the list
//				if (isContainerInList(o, values, config)) {
//					values.remove(i);
//				} else {
//					i++;
//				}
//			}
//		}
//
//		// need to sort the concept and papers by type
//		if ((feature == UmaPackage.eINSTANCE
//				.getContentElement_ConceptsAndPapers())
//				&& (values.size() > 0)) {
//			List papers = new ArrayList();
//			int i = 0;
//			while (i < values.size()) {
//				Object o = values.get(i);
//				if (o instanceof Whitepaper) {
//					papers.add(o);
//					values.remove(i);
//				} else {
//					i++;
//				}
//			}
//
//			if (papers.size() > 0) {
//				values.addAll(papers);
//			}
//		}
//
//		return values;
	}

	/**
	 * check if the container of the element is in the list or not
	 * 
	 * @param element
	 * @param items
	 * @param config
	 * @return
	 */
	public static boolean isContainerInList(MethodElement element, List items,
			MethodConfiguration config) {
		EObject o = element;
		while ((o != null) && ((o = o.eContainer()) != null)
				&& o.getClass().isInstance(element)) {
			if (items.contains(o)) {
				return true;
			}

			if (o instanceof VariabilityElement) {
				o = getCalculatedElement((VariabilityElement) o, config);
			}

			if ((o != null) && items.contains(o)) {
				return true;
			}
		}

		return false;
	}

	/**
	 * get the calculated attribute feature value of the specipied element and
	 * feature
	 * 
	 * @param element {@link MethodElement}
	 * @param feature {@link EStructuralFeature}
	 * @param config {@link MethodConfiguration}
	 * @return Object
	 */
	public static Object calcAttributeFeatureValue(MethodElement element,
			EStructuralFeature feature, MethodConfiguration config) {
		return calcAttributeFeatureValue(element, null, feature, config);
	}

	/**
	 * get the calculated attribute feature value of the specipied element and
	 * feature
	 * 
	 * @param element MethodElement
	 * @param ownerElement {@link MethodElement}
	 * @param feature {@link EStructuralFeature}
	 * @param config {@link MethodConfiguration}
	 * @return Object
	 */
	public static Object calcAttributeFeatureValue(MethodElement element,
			MethodElement ownerElement, EStructuralFeature feature,
			MethodConfiguration config) {
		if (config instanceof Scope) {
//			Object value = element.eGet(feature);
			Object value = TypeDefUtil.getInstance().eGet(element, feature);
			if (value instanceof MethodElement) {
				ElementRealizer realizer = DefaultElementRealizer.newElementRealizer(config);
				value = realizer.realize((MethodElement) value);
			}
			return value;
		}

		//Inherent externalId for a extends and extends-replaces variability element
		if (ownerElement instanceof DescribableElement
				&& ownerElement instanceof VariabilityElement
				&& element instanceof ContentDescription
				&& feature == UmaPackage.eINSTANCE
						.getContentDescription_ExternalId()) {
			VariabilityElement va = (VariabilityElement) ownerElement;
			ContentDescription presentation = (ContentDescription) element;
			while (presentation != null) {
				String extenalId = presentation.getExternalId();
				if (extenalId != null && extenalId.trim().length() > 0) {
					return extenalId;
				}
				presentation = null;
				if (va.getVariabilityType() == VariabilityType.EXTENDS
						|| va.getVariabilityType() == VariabilityType.EXTENDS_REPLACES) {
					va = va.getVariabilityBasedOnElement();
					if (va != null) {
						presentation = ((DescribableElement) va)
								.getPresentation();
					}
				}
			}
		}
		
		if (isMergableAttribute(feature)) {
			// merge the attribute values
			ElementRealizer realizer = DefaultElementRealizer.newElementRealizer(config);
			AttributeFeatureValue values = new AttributeFeatureValue(element, ownerElement, feature, realizer);
			calculateFeature(element, ownerElement, feature, config, values,
						realizer);

//			StringBuffer buffer = new StringBuffer();
//			for (Iterator it = values.iterator(); it.hasNext();) {
//				FeatureValue av = (FeatureValue) it.next();
//				if (av.text == null || av.text.toString().length() == 0) {
//					continue;
//				}
//
//				if (feature == UmaPackage.eINSTANCE
//						.getMethodElement_PresentationName()) {
//					if (values.size() > 1) {
//						// something wrong here, will not happen but put test
//						// message here just in case
//						if (debug) {
//							System.out
//									.println("ConfigurationHelper.calcAttributeFeatureValue: Presentation Name get more then one entry: " + LibraryUtil.getTypeName(element)); //$NON-NLS-1$
//						}
//					}
//					return av.text;
//				}
//
//				if (buffer.length() > 0) {
//					buffer.append(ATTRIBUTE_VALUE_SEPERATOR); 
//				}
//
//				if (av.element == element) {
//					buffer.append(av.text);
//				} else {
//					String contentPath = ResourceHelper
//							.getElementPath((av.element instanceof ContentDescription) ? (MethodElement) av.element
//									.eContainer()
//									: av.element);
//
//					String backPath = ResourceHelper
//							.getBackPath((element instanceof ContentDescription) ? ((ownerElement != null) ? ownerElement
//									: (MethodElement) element.eContainer())
//									: element);
//
//					buffer.append(ResourceHelper.fixContentUrlPath(av.text,
//							contentPath, backPath));
//				}
//			}
//
//			return buffer.toString();
			
			return values.getValue();
		}

//		return element.eGet(feature);
		return TypeDefUtil.getInstance().eGet(element, feature);
	}

	/**
	 * get the calculated 0..n opposite feature value of the specipied element
	 * and opposite feature
	 * 
	 * @param element MethodElement
	 * @param feature {@link EStructuralFeature}
	 * @param realizer {@link ElementRealizer}
	 * @return List a list of {@link MethodElement}
	 */
	public static List calc0nFeatureValue(MethodElement element,
			OppositeFeature feature, ElementRealizer realizer) {
		return calc0nFeatureValue(element, feature, true, false, realizer);
	}

	/**
	 * get the calculated 0..n opposite feature value of the specipied element
	 * and opposite feature
	 * 
	 * @param element MethodElement
	 * @param ownerElement {@link MethodElement}
	 * @param feature {@link OppositeFeature}
	 * @param mergeReplacerBase boolean
	 * @param mergeExtenderBase boolean
	 * @param realizer {@link ElementRealizer}
	 * @return List a list of {@link MethodElement}
	 */
	public static List calc0nFeatureValue(MethodElement element,
			OppositeFeature feature, boolean mergeReplacerBase, boolean mergeExtenderBase, ElementRealizer realizer) {
		ToManyOppositeFeatureValue values = new ToManyOppositeFeatureValue(element, feature, realizer);
		calculateOppositeFeature(element, feature, mergeReplacerBase, mergeExtenderBase, realizer, values);
		List ret = (List)values.getValue();
		if (feature == AssociationHelper.DescribableElement_CustomCategories) {
			Set<CustomCategory> set = ConfigurationHelper.getDelegate().getDynamicCustomCategories(element);
			if (set != null && !set.isEmpty()) {
				set.removeAll(ret);
				if (! set.isEmpty()) {
					ret.addAll(set);
				}
			}
		}				
		return ret;
	}
	
	/**
	 * get the calculated 0..1 feature value of the specipied element and
	 * opposite feature
	 * @param element {@link MethodElement}
	 * @param feature {@link OppositeFeature}
	 * @param realizer {@link ElementRealizer}
	 * 
	 * @return MethodElement
	 */
	public static MethodElement calc01FeatureValue(MethodElement element,
			OppositeFeature feature, ElementRealizer realizer) {
		ToOneOppositeFeatureValue values = new ToOneOppositeFeatureValue(element, feature, realizer);
		calculateOppositeFeature(element, feature, realizer, values);
//		if (values.size() > 0) {
//			return getCalculatedElement((MethodElement) values.get(0), realizer);
//		}
//
//		return null;
		
		return (MethodElement)values.getValue();
		
	}

	/**
	 * order the sections
	 * 
	 * @param element {@link ContentElement}
	 * @param values {@link List} 
	 */
	public static void orderSections(ContentElement element, List values) {
		String orderingGuide = element.getOrderingGuide();
		if (orderingGuide == null || orderingGuide.trim().length() == 0) {
			return;
		}
		SectionList slist = new SectionList(element,
				SectionList.STEPS_FOR_ELEMENT_AND_PARENTS);

		if (isSameList(values, slist)) {
			values.clear();
			values.addAll(slist);
			return;
		}

		// otherwise, need to reorder the list
		OrderedListComparator comp = new OrderedListComparator(new ArrayList(
				values), slist);
		TreeSet s = new TreeSet(comp);
		s.addAll(values);

		values.clear();
		values.addAll(s);
	}

	private static boolean isSameList(List l1, List l2) {
		if (l1.size() != l2.size()) {
			return false;
		}

		for (Iterator it = l1.iterator(); it.hasNext();) {
			Object o = it.next();
			if (!l2.contains(o)) {
				return false;
			}
		}

		return true;
	}

	/**
	 * calculate the copyright of the element int he configuration. Rule: 1.
	 * contributors' copyright statment should be merged to the base 2. extended
	 * element inherites the copyrights from the base 3. replacer don't inherite
	 * the copyrights from the base 4. copyright elements should be unique, no
	 * duplicate entry
	 * 
	 * @param element
	 * @param config
	 * @param values
	 */
	private static void calculateCopyright(MethodElement element,
			MethodConfiguration config, List values) {
		SupportingMaterial copyright = (SupportingMaterial) getCalculatedElement(
				LibraryUtil.getCopyright(element), config);
		if (copyright != null && !values.contains(copyright)) {
			values.add(copyright);
		}

		VariabilityElement ve = getVariableOwner(element);
		if (ve == null) {
			return;
		}

		if (config == null) {
			return;
		}

		// merge copyrights of contributors
		List items = getContributors(ve, config);
		if (items != null && items.size() > 0) {
			for (Iterator it = items.iterator(); it.hasNext();) {
				MethodElement e = (MethodElement) it.next();
				calculateCopyright(e, config, values);
			}
		}

		// if the element is an extended element, get the base element's
		// copyright
		// the base element's copyright should appear first
		if (isExtender(ve)) {
			// realize the base element first.
			MethodElement e = getCalculatedElement(ve
					.getVariabilityBasedOnElement(), config);
			if ((ve != e) && inConfig(e, config)) {
				List baseItems = new ArrayList();
				calculateCopyright(e, config, baseItems);

				// add the base items to the begining
				if (baseItems.size() > 0) {
					// Authoring: Duplicate copyrights when 2
					// elements with the same coyright are extending each other
					// remove the duplicate ones
					int i = 0;
					while (i < values.size()) {
						if (baseItems.contains(values.get(i))) {
							values.remove(i);
						} else {
							i++;
						}
					}

					values.addAll(0, baseItems);
				}
			}
		}

	}

	/**
	 * get the copyright text
	 * 
	 * @param element {@link MethodElement}
	 * @param config {@link MethodConfiguration}
	 * @return String
	 */
	public static String getCopyrightText(MethodElement element,
			MethodConfiguration config) {
		StringBuffer copyrights = new StringBuffer();
		List items = new ArrayList();
		ConfigurationHelper.calculateCopyright(element, config, items);
		if (items.size() > 0) {
			SupportingMaterial copyright;
			for (Iterator it = items.iterator(); it.hasNext();) {
				copyright = (SupportingMaterial) it.next();

				// Contributing support material does not show
				// up in copy right
				// need to resolve the feature value. can't just get the value,
				// it may have contributors
				// String statement =
				// copyright.getPresentation().getMainDescription();
				//											
				String statement = (String) calcAttributeFeatureValue(copyright
						.getPresentation(), copyright, UmaPackage.eINSTANCE
						.getContentDescription_MainDescription(), config);
				if (statement != null && statement.length() > 0) {
					// need to fix the content for relative links.
					// since the link is a relative path to the
					// SupportingMaterial location,
					// need to convert to relative to the current element
					// so re-calcuate the back path
					// jxi, 06/28/05
					String contentPath = ResourceHelper
							.getElementPath(copyright);
					String backPath = ResourceHelper.getBackPath(element);
					statement = ResourceHelper.fixContentUrlPath(statement,
							contentPath, backPath);

					if (copyrights.length() > 0) {
						copyrights.append("<p/>"); //$NON-NLS-1$
					}
					copyrights.append(statement);
				}
			}
		}

		return copyrights.toString();
	}

	/**
	 * Gets String attribute values of an activity
	 * 
	 * @param e Activity or it's ContentDescription
	 * @param attrib
	 * @param config
	 * @return String
	 */
	public static String getActivityStringAttribute(MethodElement e, MethodElement ownerElement, 
			EAttribute attrib, MethodConfiguration config) {
		if(!String.class.isAssignableFrom(attrib.getEAttributeType().getInstanceClass())) {
			throw new IllegalArgumentException("The specified attribute is not of type String: " + attrib); //$NON-NLS-1$
		}
		
		Object str = null;
		boolean isDesc;
		VariabilityElement ve;
		if ( e instanceof ContentDescription )
		{
			ve = (VariabilityElement) e.eContainer();
			if ( ve == null ) {
				ve = (VariabilityElement)ownerElement;
			}
			isDesc = true;
		}
		else if ( e instanceof VariabilityElement)
		{
			ve = (VariabilityElement)e;
			isDesc = false;
		} else {
//			str = e.eGet(attrib);
			str = TypeDefUtil.getInstance().eGet(e, attrib);
			return (str==null) ? "" : str.toString(); //$NON-NLS-1$
		}
		
		
		if(attrib == UmaPackage.eINSTANCE.getMethodElement_Guid() || attrib == UmaPackage.eINSTANCE.getNamedElement_Name()) {
			return (String)e.eGet(attrib);
		}		
					
		VariabilityElement base = ve.getVariabilityBasedOnElement();
		VariabilityType variabilityType = ve.getVariabilityType();
		if( base != null && variabilityType == VariabilityType.LOCAL_CONTRIBUTION) {
			// for local contribution, append the text to the base
			Object strBase;
			if ( isDesc ) {
//				str = ((DescribableElement)ve).getPresentation().eGet(attrib);
				str = TypeDefUtil.getInstance().eGet(((DescribableElement)ve).getPresentation(), attrib);
				strBase = calcAttributeFeatureValue( ((DescribableElement)base).getPresentation(), base, attrib, config);
			} else {
				str = ve.eGet(attrib);
				strBase = calcAttributeFeatureValue(base, null, attrib, config);				
			}
			
			if ( strBase != null && strBase.toString().length() > 0 ) {
				if ( str != null && str.toString().length() > 0 ) {
					str = strBase + ATTRIBUTE_VALUE_SEPERATOR + str;
				} else {
					str = strBase;
				}
			}
		} else {
			str = calcAttributeFeatureValue(e, ve, attrib, config);
		}

		return (str==null) ? "" : str.toString(); //$NON-NLS-1$
		
//		List values = new ArrayList();
//		VariabilityElement base;
//		VariabilityType variabilityType;	
//		boolean concat = attrib != UmaPackage.eINSTANCE.getMethodElement_PresentationName();
//		while(true) {
//			base = ve.getVariabilityBasedOnElement();
//			if(base == null) {
//				Object str;
//				if ( isDesc ) {
//					str = ((DescribableElement)ve).getPresentation().eGet(attrib); 
//				} else {
//					str =  ve.eGet(attrib); 
//				}
//				if(str == null || str.toString().length() == 0) {
//					if(values.isEmpty()) {
//						values.add(str);
//					}
//				}
//				else {
//					values.add(0, str);
//				}
//				break;
//			}
//			else if(base instanceof Activity) {
//				Object str;
//				if ( isDesc ) {
//					str = ((DescribableElement)ve).getPresentation().eGet(attrib); 
//				} else {
//					str = ve.eGet(attrib); 
//				}
//
//				variabilityType = ve.getVariabilityType();
//				if(variabilityType == VariabilityType.EXTENDS_LITERAL) {
//					if(str == null || str.toString().length() == 0) {
//						// use the value of the base
//						//
//						ve = base;
//					}
//					else {
//						values.add(0, str);
//						break;
//					}
//				}
//				else if(variabilityType == VariabilityType.LOCAL_CONTRIBUTION_LITERAL) {					
//					if(str != null && str.toString().length() > 0) {
//						// add to the list
//						//
//						values.add(0, str);
//						if(!concat) {
//							break;
//						}
//					}
//					// go to the base
//					ve = base;
//				}
//				else if(variabilityType == VariabilityType.LOCAL_REPLACEMENT_LITERAL) {
//					values.add(0, str);
//					break;
//				}
//				//TODO: handle CONTRIBUTES AND REPLACES
//			}
//		}
//		
//		if ( values.size() == 0 ) {
//			return ""; //$NON-NLS-1$
//		}
//		else if ( values.size() ==1 ) {
//			return (String)values.get(0);
//		}
//		else {
//			StringBuffer buffer = new StringBuffer();
//			for (Iterator it = values.iterator(); it.hasNext(); ) {
//				if ( buffer.length() > 0 ) {
//					buffer.append(ATTRIBUTE_VALUE_SEPERATOR);
//				}
//				buffer.append(it.next());
//			}
//			return buffer.toString();			
//		}
	}
	
	/**
	 * get all processes in the configuration
	 * 
	 * @param config
	 * @return List
	 */
	public static List getAllProcesses(MethodConfiguration config) {
		List processes = new ArrayList();
		List plugins = config.getMethodPluginSelection();
		for (Iterator it = plugins.iterator(); it.hasNext(); ) {
			List items = TngUtil.getAllProcesses((MethodPlugin)it.next());
			for ( Iterator itp = items.iterator(); itp.hasNext(); ) {
				org.eclipse.epf.uma.Process p = (org.eclipse.epf.uma.Process)itp.next();
				if ( canShow(p, config) && !processes.contains(p) ) {
					processes.add(p);
				}
			}
		}
		
		return processes;
	}
	
	/**
	 * get all processes in the plugin and the configuration
	 * 
	 * @param plugin
	 * @param config
	 * @return List
	 */
	public static List getAllProcesses(MethodPlugin plugin, MethodConfiguration config) {
		List processes = new ArrayList();
		List items = TngUtil.getAllProcesses(plugin);
		for ( Iterator itp = items.iterator(); itp.hasNext(); ) {
			org.eclipse.epf.uma.Process p = (org.eclipse.epf.uma.Process)itp.next();
			if ( canShow(p, config) && !processes.contains(p) ) {
				processes.add(p);
			}
		}
	
		return processes;
	}
	
	/**
	 * get all delivery processes in the plugin and configuration
	 * @param plugin
	 * @param config
	 * @return List
	 */
	public static List getAllDeliveryProcesses(MethodPlugin plugin, MethodConfiguration config) {
		List processes = new ArrayList();
		List items = TngUtil.getAllProcesses(plugin);
		for ( Iterator itp = items.iterator(); itp.hasNext(); ) {
			org.eclipse.epf.uma.Process p = (org.eclipse.epf.uma.Process)itp.next();
			if ( p instanceof DeliveryProcess ) {
				if ( canShow(p, config) && !processes.contains(p) ) {
					processes.add(p);
				}
			}
		}
	
		return processes;
	}
	
	/**
	 * get all CapabilityPatterns in the plugin and configuration
	 * 
	 * @param plugin
	 * @param config
	 * @return List
	 */
	public static List getAllCapabilityPatterns(MethodPlugin plugin, MethodConfiguration config) {
		List processes = new ArrayList();
		List items = TngUtil.getAllProcesses(plugin);
		for ( Iterator itp = items.iterator(); itp.hasNext(); ) {
			org.eclipse.epf.uma.Process p = (org.eclipse.epf.uma.Process)itp.next();
			if ( p instanceof CapabilityPattern ) {
				if ( canShow(p, config) && !processes.contains(p) ) {
					processes.add(p);
				}
			}
		}
	
		return processes;
	}
	
	/**
	 * calculate the work products modified by the specified role, in the configuration
	 * 
	 * @param element Role
	 * @param ownerElement MethodElement the owner to accept the calculated value
	 * @param realizer
	 * @return List list of work products being modified by the role
	 */
	public static List calcModifiedWorkProducts(Role element, MethodElement ownerElement, ElementRealizer realizer) {
		List v = new ArrayList();
		OppositeFeature ofeature = AssociationHelper.Role_Primary_Tasks;
		ToManyOppositeFeatureValue fv2 = new ToManyOppositeFeatureValue(element, ofeature, realizer);
		calculateOppositeFeature(element, ofeature, realizer, fv2);
		
		if ( fv2.size() > 0 ) {
			List v2 = (List)fv2.getValue();
			EStructuralFeature feature = UmaPackage.eINSTANCE.getTask_Output();
			Set set = new LinkedHashSet();
			for (Iterator it = v2.iterator(); it.hasNext(); ) {
				MethodElement e = (MethodElement)it.next();
				ToManyFeatureValue fv = new ToManyFeatureValue(element, ownerElement, feature, realizer);
				
//				This is wrong: fv.getValue() may return a copy instead of the reference of the internal value field! 				
//				((List)).addAll(v);   
				
				calculateFeature(e, ownerElement, 
						feature, 
						realizer.getConfiguration(), fv, realizer);	
//				v = (List)fv.getValue();
				List list = (List)fv.getValue();
				if (list != null && !list.isEmpty()) {
					set.addAll(list);
				}								
			}
			if (! set.isEmpty()) {
				v.addAll(set);
			}
		}	
		
		return v;
	}
		
	/**
	 * calculate the work product descriptors modified by the specified role descriptor, in the configuration
	 * 
	 * @param element RoleDescriptor
	 * @param ownerElement MethodElement the owner to accept the calculated value
	 * @param realizer
	 * @return List list of work product descriptors being modified by the role descriptor
	 * @deprecated use the RoleDescriptorLayout to calculate the feature value
	 */
	public static List calcModifiedWorkProductDescriptors(RoleDescriptor element, MethodElement ownerElement, ElementRealizer realizer) {
		List v = new ArrayList();
		OppositeFeature ofeature = AssociationHelper.RoleDescriptor_PrimaryTaskDescriptors;
		ToManyOppositeFeatureValue fv2 = new ToManyOppositeFeatureValue(element, ofeature, realizer);
		calculateOppositeFeature(element, ofeature, realizer, fv2);
		if ( fv2.size() > 0 ) {
			List v2 = (List)fv2.getValue();
			EStructuralFeature feature = UmaPackage.eINSTANCE.getTaskDescriptor_Output();
			for (Iterator it = v2.iterator(); it.hasNext(); ) {
				MethodElement e = (MethodElement)it.next();
				
				ToManyFeatureValue fv = new ToManyFeatureValue(element, ownerElement, feature, realizer);
				((List)fv.getValue()).addAll(v);
				
				calculateFeature(e, ownerElement, 
						feature, 
						realizer.getConfiguration(), fv, realizer);	
				v = (List)fv.getValue();
			}
		}
		
		return v;
	}
	
	/**
	 * calculate the roles that modifies the specified work product in the configuration
	 * @param element WorkProduct
	 * @param realizer
	 * @return List the roles
	 */
	public static List calcModifyRoles(WorkProduct element, ElementRealizer realizer) {
		List tasks = ConfigurationHelper.calc0nFeatureValue(
				element, 
				AssociationHelper.WorkProduct_OutputFrom_Tasks, 
				realizer);
		List modifyRoles = new ArrayList();
		for (Iterator it = tasks.iterator(); it.hasNext(); ) {
			Task t = (Task)it.next();
			List<Role> rList = (List<Role>)ConfigurationHelper.calc0nFeatureValue(
					t, 
					UmaPackage.eINSTANCE.getTask_PerformedBy(), 
					realizer);
			for (Role r: rList) {
				if ( (r != null) && !modifyRoles.contains(r) ) {
					modifyRoles.add(r);
				}
			}
		}
		
		return modifyRoles;
	}
	
	/**
	 * calculate the role descriptors that modifies the specified work product descriptor in the configuration
	 * @param element WorkProductDescriptor
	 * @param realizer
	 * @return List the role descriptors
	 * @deprecated use the WorkProductDescriptorlayout to calculate the feature value
	 */
	public static List calcModifyRoleDescriptors(WorkProductDescriptor element, ElementRealizer realizer) {
		List taskDescriptors = ConfigurationHelper.calc0nFeatureValue(
				element, 
				AssociationHelper.WorkProductDescriptor_OutputFrom_TaskDescriptors, 
				realizer);
		List modifyRoles = new ArrayList();
		for (Iterator it = taskDescriptors.iterator(); it.hasNext(); ) {
			TaskDescriptor t = (TaskDescriptor)it.next();
			RoleDescriptor r = (RoleDescriptor)ConfigurationHelper.calc01FeatureValue(
					t, 
					UmaPackage.eINSTANCE.getTaskDescriptor_PerformedPrimarilyBy(), 
					realizer);
			if ( (r != null) && !modifyRoles.contains(r) ) {
				modifyRoles.add(r);
			}
		}
		
		return modifyRoles;
	}
	
	/**
	 * check if the activity is a contributor 
	 * or contains any sub-activities that are contributors
	 * @param element Activity
	 * @return boolean
	 */
	public static boolean hasContributor(Activity element) {
		if ( isContributor(element)) {
			return true;
		}

		for ( Iterator it = element.getBreakdownElements().iterator(); it.hasNext(); ) {
			Object o = it.next();
			if ( !(o instanceof Activity) ) {
				continue;
			}
			
			if ( hasContributor( (Activity)o ) ) {
				return true;
			}
		}
		
		return false;
	}
	
	/**
	 * get the base processes for an {@link Activity} in the Configuration
	 * @param element
	 * @param config
	 * @return List
	 */
	public static List getBaseProcesses(Activity element, MethodConfiguration config) {
		List value = new ArrayList();
		getBaseProcesses(element, config, value);
		return value;
	}
	
	/**
	 * get all base processes for an activity in the configuration
	 * @param element
	 * @param config
	 * @param value List the bases processes
	 */
	public static void getBaseProcesses(Activity element, MethodConfiguration config, List value) {
		
		// get it's own base
		if ( ConfigurationHelper.isExtender(element) ) {
			Activity base = (Activity)element.getVariabilityBasedOnElement();
			if ( base != null 
					&& !value.contains(base) 
					&& (base instanceof org.eclipse.epf.uma.Process) ) {
				if ( canShow(base, config) ) {
					value.add(base);
				}
				getBaseProcesses(base, config, value);
			}
		}
		
		// if the sub-activities have base, process it
		for ( Iterator it = element.getBreakdownElements().iterator(); it.hasNext(); ) {
			Object o = it.next();
			if ( o instanceof Activity ) {
				getBaseProcesses((Activity)o, config, value);
			}
		}
	}
	
	public static URI getInheritingUri(DescribableElement obj, URI uri,
			VariabilityElement[] uriInheritingBases, MethodConfiguration config, int uriType) {
		VariabilityElement ve = (VariabilityElement) obj;
		VariabilityElement base = ve.getVariabilityBasedOnElement();
		if (base != null
				&& (ve.getVariabilityType() == VariabilityType.EXTENDS || ve
						.getVariabilityType() == VariabilityType.EXTENDS_REPLACES)) {
			base = (VariabilityElement) ConfigurationHelper.getCalculatedElement(base, config);
			if (base != null) {
				if (uriType == 0) {
					uri = ((DescribableElement) base).getNodeicon();
				} else if (uriType == 1) {
					uri = ((DescribableElement) base).getShapeicon();
				}
				if (uri != null) {
					uriInheritingBases[0] = base;
				}
			}
		}
		return uri;
	}
}