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

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

import org.eclipse.emf.common.command.Command;
import org.eclipse.emf.common.notify.Adapter;
import org.eclipse.emf.common.notify.AdapterFactory;
import org.eclipse.emf.common.notify.Notification;
import org.eclipse.emf.common.notify.impl.AdapterImpl;
import org.eclipse.emf.common.util.AbstractTreeIterator;
import org.eclipse.emf.ecore.EObject;
import org.eclipse.emf.ecore.EStructuralFeature;
import org.eclipse.emf.ecore.resource.Resource;
import org.eclipse.emf.edit.command.AddCommand;
import org.eclipse.emf.edit.command.MoveCommand;
import org.eclipse.emf.edit.command.CopyCommand.Helper;
import org.eclipse.emf.edit.domain.EditingDomain;
import org.eclipse.emf.edit.provider.Disposable;
import org.eclipse.emf.edit.provider.ITableItemLabelProvider;
import org.eclipse.emf.edit.provider.ITreeItemContentProvider;
import org.eclipse.emf.edit.provider.IWrapperItemProvider;
import org.eclipse.emf.edit.provider.ViewerNotification;
import org.eclipse.epf.library.edit.ICachedChildrenItemProvider;
import org.eclipse.epf.library.edit.IConfigurable;
import org.eclipse.epf.library.edit.IConfigurator;
import org.eclipse.epf.library.edit.IFilter;
import org.eclipse.epf.library.edit.IWrapperItemProviderFactory;
import org.eclipse.epf.library.edit.IWrapperItemProviderFactoryProvider;
import org.eclipse.epf.library.edit.Providers;
import org.eclipse.epf.library.edit.VariabilityInfo;
import org.eclipse.epf.library.edit.command.IActionManager;
import org.eclipse.epf.library.edit.command.IResourceAwareCommand;
import org.eclipse.epf.library.edit.process.command.ActivityAddCommand;
import org.eclipse.epf.library.edit.util.GraphicalData;
import org.eclipse.epf.library.edit.util.PredecessorList;
import org.eclipse.epf.library.edit.util.ProcessUtil;
import org.eclipse.epf.library.edit.util.TngUtil;
import org.eclipse.epf.uma.Activity;
import org.eclipse.epf.uma.BreakdownElement;
import org.eclipse.epf.uma.Descriptor;
import org.eclipse.epf.uma.Iteration;
import org.eclipse.epf.uma.Process;
import org.eclipse.epf.uma.ProcessComponent;
import org.eclipse.epf.uma.ProcessPackage;
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.edit.command.MethodElementCreateCopyCommand;
import org.eclipse.epf.uma.edit.command.MethodElementInitializeCopyCommand;
import org.eclipse.epf.uma.provider.ActivityItemProvider;
import org.eclipse.epf.uma.util.AssociationHelper;
import org.eclipse.swt.widgets.Display;


/**
 * Abstract base class for activity's item providers used by the Process Editor.
 * 
 * @author Phong Nguyen Le
 * @since 1.0
 */
public abstract class BSActivityItemProvider extends ActivityItemProvider
		implements IProcessItemProvider, IBSItemProvider,
		ITableItemLabelProvider, IConfigurable, ICachedChildrenItemProvider {

	private Object parent;

	private int id;

	protected Object topItem = null;

	private boolean rolledUp;

	private GraphicalData graphicalData;

	private PredecessorList predecessors;

	private Boolean expanded;

	protected Adapter baseListener;

	private IFilter childFilter = new IFilter() {

		public boolean accept(Object obj) {
			return acceptAsChild(obj);
		}

	};

	private boolean refreshAllIDsRequired;

	private IFilter filter;

	protected List cachedChildren;

	protected List cachedRollupChildren;

	private IConfigurator configurator;

	private Disposable contributedWrappers;

	private VariabilityInfo variabilityInfo;
	
	private boolean enableVariabilityInfo = true;

	private Disposable rolledUpWrappers;

	/**
	 * @param adapterFactory
	 */
	public BSActivityItemProvider(AdapterFactory adapterFactory) {
		super(adapterFactory);
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see org.eclipse.emf.edit.provider.ItemProviderAdapter#dispose()
	 */
	public void dispose() {
		if(baseListener != null) {
			EObject currentBase = (EObject) baseListener.getTarget();
			if(currentBase != null) {
				currentBase.eAdapters().remove(baseListener);
			}
			if (getTarget() instanceof Activity) {
				Activity act = (Activity) getTarget();
				VariabilityElement base = act.getVariabilityBasedOnElement();
				if (base != null) {
					base.eAdapters().remove(baseListener);
				}
			}
		}

		if (predecessors != null) {
			predecessors.dispose();
		}

		if(cachedChildren != null) {
			cachedChildren.clear();
			cachedChildren = null;
		}
		
		if(cachedRollupChildren != null) {
			cachedRollupChildren.clear();
			cachedRollupChildren = null;
		}
		
		if(contributedWrappers != null) {
			contributedWrappers.dispose();
			contributedWrappers = null;
		}
		
		if(rolledUpWrappers != null) {
			rolledUpWrappers.dispose();
			rolledUpWrappers = null;
		}
		
		super.dispose();
	}

	/**
	 * Checks if the given object can be accepted as a child.
	 */
	protected boolean acceptAsChild(Object child) {
		if (filter != null) {
			return filter.accept(child);
		}
		return true;
	}

	/**
	 * Checks if the given object can be accepted as a rolled-up child.
	 */
	protected boolean acceptAsRolledUpChild(Object child) {
		child = TngUtil.unwrap(child);
		if (filter != null && !(child instanceof Activity)
				&& !(child instanceof TeamProfile)) {
			return filter.accept(child);
		}
		return true;
	}

	/**
	 * Gets the object associated with the given descriptor (e.g: a
	 * TaskDescriptor is associated with a Task).
	 */
	protected abstract Object getObject(Descriptor descriptor);

	public Collection getNewChildDescriptors(Object object, EditingDomain editingDomain, Object sibling) {
		// disallow creating new child if this item provider is rolled up
		//
		if(isRolledUp()) {
			return Collections.EMPTY_LIST;
		}
		
		return super.getNewChildDescriptors(object, editingDomain, sibling);
	}
	
	/*
	 * (non-Javadoc)
	 * 
	 * @see org.eclipse.emf.edit.provider.ItemProviderAdapter#collectNewChildDescriptors(java.util.Collection,
	 *      java.lang.Object)
	 */
	protected void collectNewChildDescriptors(Collection newChildDescriptors,
			Object object) {
		// if(isTopActivity(object)) {
		// newChildDescriptors.add
		// (createChildParameter
		// (UmaPackage.eINSTANCE.getActivity_BreakdownElements(),
		// UmaFactory.eINSTANCE.createPhase()));
		// newChildDescriptors.add
		// (createChildParameter
		// (UmaPackage.eINSTANCE.getActivity_BreakdownElements(),
		// UmaFactory.eINSTANCE.createIteration()));
		// }
		// else if(object instanceof Phase) {
		// newChildDescriptors.add
		// (createChildParameter
		// (UmaPackage.eINSTANCE.getActivity_BreakdownElements(),
		// UmaFactory.eINSTANCE.createIteration()));
		// }
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see com.ibm.library.edit.process.IBSItemProvider#isExpanded()
	 */
	public Boolean isExpanded() {
		return expanded;
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see com.ibm.library.edit.process.IBSItemProvider#setExpanded(boolean)
	 */
	public void setExpanded(Boolean b) {
		expanded = b;
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see org.eclipse.epf.uma.tng.process.IBSItemProvider#getId()
	 */
	public int getId() {
		return id;
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see org.eclipse.epf.uma.tng.process.IBSItemProvider#getTopItem()
	 */
	public Object getTopItem() {
		if (topItem == null) {
			if(ProcessUtil.isTopProcess(target)) {
				return target;
			}
			Object parent = getParent(target);
			if(parent != null) {
				Object ip = getRootAdapterFactory().adapt(parent, ITreeItemContentProvider.class);
				if(ip instanceof IBSItemProvider) {
					IBSItemProvider adapter = (IBSItemProvider) ip;
					if (adapter != null) {
						Object top = adapter.getTopItem();
						if (top == null && parent instanceof Process
								&& ((Process) parent).getSuperActivities() == null) {
							top = parent;
							adapter.setTopItem(top);
						}
						return top;
					}
				}
			}
		}
		return topItem;
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see org.eclipse.epf.uma.tng.process.IBSItemProvider#setId(int)
	 */
	public void setId(int id) {
		this.id = id;
	}

	private static boolean isTopActivity(Object object) {
		EObject eObj = (EObject) object;
		Object parent = eObj.eContainer();
		if (parent instanceof ProcessComponent) {
			ProcessComponent pc = (ProcessComponent) parent;
			return object == pc.getProcess();
		}
		return false;
	}

	/**
	 * @param object
	 * @return
	 */
	protected static boolean hasChildDescriptor(Activity act) {
		for (Iterator iter = act.getBreakdownElements().iterator(); iter
				.hasNext();) {
			Object element = iter.next();
			if (element instanceof Descriptor) {
				return true;
			}
		}
		return false;
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see org.eclipse.emf.edit.provider.ItemProviderAdapter#getChildrenFeatures(java.lang.Object)
	 */
	public Collection getChildrenFeatures(Object object) {
		if (childrenFeatures == null) {
			childrenFeatures = new ArrayList();
			childrenFeatures.add(UmaPackage.eINSTANCE
					.getActivity_BreakdownElements());
		}
		return childrenFeatures;
	}

	protected void setParentFor(Object child, Object parent) {
		ProcessUtil.setParent(child, parent, getRootAdapterFactory());
	}

//	private Collection getDirectChildren(Object object) {
//		List myChildren;
//		ChildrenStore store = getChildrenStore(object);
//		if (store != null) {
//			myChildren = store.getChildren();
//		} else {
//			// store = createChildrenStore(object);
//			List result = store != null ? null : new ArrayList();
//			EObject eObject = (EObject) object;
//
//			for (Iterator i = getChildrenFeatures(object).iterator(); i
//					.hasNext();) {
//				EStructuralFeature feature = (EStructuralFeature) i.next();
//				if (feature.isMany()) {					
//					List children = (List) eObject.eGet(feature);
//					
////					//Change for Activity Variability. To do realization for
////					//Browsing and Publishing.
////					List children = new ArrayList();
////					if(filter != null && filter instanceof IConfigurator){
////						children.addAll(((IConfigurator)filter).getChildren(object, feature));
////					}
////					else{
////						children = (List) eObject.eGet(feature);
////					}
//					
//					int index = 0;
//					for (Iterator ci = children.iterator(); ci.hasNext(); index++) {
//						Object child = ci.next();
//						if (acceptAsChild(child)) {
//							child = wrap(eObject, feature, child, index);
//							setParentFor(child, object);
//							// IBSItemProvider adapter = (IBSItemProvider)
//							// getBestAdapterFactory().adapt(child,
//							// ITreeItemContentProvider.class);
//							// adapter.setRolledUp(false);
//							if (store != null) {
//								store.getList(feature).add(child);
//							} else {
//								result.add(child);
//							}
//						}
//					}
//				} else {
//					Object child = eObject.eGet(feature);
//					if (acceptAsChild(child)) {
//						child = wrap(eObject, feature, child,
//								CommandParameter.NO_INDEX);
//						setParentFor(child, object);
//						// IBSItemProvider adapter = (IBSItemProvider)
//						// getBestAdapterFactory().adapt(child,
//						// ITreeItemContentProvider.class);
//						// adapter.setRolledUp(false);
//
//						if (store != null) {
//							store.setValue(feature, child);
//						} else {
//							result.add(child);
//						}
//					}
//				}
//			}
//			myChildren = store != null ? store.getChildren() : result;
//		}
//		Collection children = addInherited(object, myChildren);
//		return children;
//	}
	
	private Collection getImmediateChildren(Object object) {
		Collection children = new ArrayList();
		for (Iterator iter = super.getChildren(object).iterator(); iter.hasNext();) {
			Object child = (Object) iter.next();
			if(acceptAsChild(child)) {
				if(configurator != null) {
					child = configurator.resolve(child);
				}
				if(child != null && !children.contains(child)) {
					setParentFor(child, object);
					children.add(child);
				}
			}
		}
		children = addInherited(object, (List) children);
		return children;
	}
	
	private Collection getRolledUpChildren(Object object) {
		if (rolledUpWrappers != null) {
			rolledUpWrappers.dispose();
		}

		List children = new ArrayList();
		AbstractTreeIterator iter = new AbstractTreeIterator(object, false) {

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

			protected Iterator getChildren(Object object) {
				if (object instanceof Activity) {
					BSActivityItemProvider adapter = (BSActivityItemProvider) adapterFactory.adapt(object, ITreeItemContentProvider.class);
					Iterator iterator;
					boolean b = adapter.isRolledUp();
					try {
						adapter.basicSetRolledUp(false);
						iterator = adapter.getChildren(object).iterator();
					}
					finally {
						adapter.basicSetRolledUp(b);
					}
					return iterator;
				} else if (object instanceof BreakdownElementWrapperItemProvider
						&& !(object instanceof TeamProfileWrapperItemProvider)) {
					return ((BreakdownElementWrapperItemProvider) object)
							.getChildren(object).iterator();
				}
				return Collections.EMPTY_LIST.iterator();
			}

		};
		// make sure that only one descriptor for each content element in the roll-up list
		//
		List descriptors = new ArrayList();
		while (iter.hasNext()) {
			Object child = iter.next();
			if (acceptAsRolledUpChild(child)) {
				Object e = TngUtil.unwrap(child);
				if(e instanceof Descriptor) {
					Object desc = findDescriptor(descriptors, e);
					if(desc == null) {
						if(isWrappingRollupNeeded(child)) {
							child = createRollupWrapper(child, object, adapterFactory);
						}
						children.add(child);
						descriptors.add(child);
					}
					else {
						if(isWrappingRollupNeeded(child)) {
							ComposedBreakdownElementWrapperItemProvider composedWrapper = ProcessUtil.getComposedWrapper(desc);
							if(composedWrapper != null) {
								composedWrapper.addElement(child);
							}
						}
					}
				}
				else {
					children.add(child);
				}
			}
		}
		descriptors.clear();
		descriptors = null;
		return children;
	}
	
	/**
	 * Checks if wrapping of the specified rollup element is needed. If it's
	 * needed, the caller will use
	 * {@link #createRollupWrapper(Object, Object, AdapterFactory)} to create
	 * wrapper for the rollup element.
	 * 
	 * @param object
	 * @return
	 */
	protected boolean isWrappingRollupNeeded(Object object) {
		return false;
	}
	
	protected ComposedBreakdownElementWrapperItemProvider createComposedWrapper(Object object, Object owner, AdapterFactory adapterFactory) {
		return new ComposedBreakdownElementWrapperItemProvider(object, owner, adapterFactory);
	}
	
	protected Object createRollupWrapper(Object object, Object owner, AdapterFactory adapterFactory) {		
		ComposedBreakdownElementWrapperItemProvider wrapper = createComposedWrapper(object, owner, adapterFactory);
		wrapper.readOnly = true;
		wrapper.isRollupChild = true;
		
		if(rolledUpWrappers == null) {
			rolledUpWrappers = new Disposable();
		}
		rolledUpWrappers.add(wrapper);

		return wrapper; 		
	}		
	
	private Collection doGetChildren(Object object) {
		if(isRolledUp()) {
			return getRolledUpChildren(object);
		}
		else {
			return getImmediateChildren(object);
		}
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see org.eclipse.emf.edit.provider.ItemProviderAdapter#getChildren(java.lang.Object)
	 */
	public Collection getChildren(Object object) {
		Activity activity = (Activity) object;
		if(configurator != null) {
			
			//TODO: remove the enableVariabilityInfoFlag and  
			// create an interface or do differently
			if(enableVariabilityInfo)
				variabilityInfo = configurator.getVariabilityInfo(activity);
			else 
				variabilityInfo = null;
		}
		else {
			variabilityInfo = null;
		}
		if(variabilityInfo != null) {
			Object resolved = variabilityInfo.getInheritanceList().get(0);
			BSActivityItemProvider ip = (BSActivityItemProvider) adapterFactory.adapt(resolved, ITreeItemContentProvider.class);			
			Collection children;
			boolean b = ip.isRolledUp();
			try {
				ip.basicSetRolledUp(isRolledUp());
				children = ip.doGetChildren(resolved);
			}
			finally {
				ip.basicSetRolledUp(b);
			}
			if(!variabilityInfo.getContributors().isEmpty()) {
				ArrayList contributedChildren = new ArrayList();
				for (Iterator iter = variabilityInfo.getContributors().iterator(); iter.hasNext();) {
					Object e = iter.next();
					Object adapter = adapterFactory.adapt(e, ITreeItemContentProvider.class);
					if(adapter instanceof BSActivityItemProvider) {
						ip = ((BSActivityItemProvider)adapter);
						b = ip.isRolledUp();
						try {
							ip.basicSetRolledUp(isRolledUp());
							for (Iterator iterator = ip.getImmediateChildren(e).iterator(); iterator
							.hasNext();) {
								e = iterator.next();
								e = Providers.getConfigurationApplicator().resolve(e, configurator.getMethodConfiguration());
								if(e != null && !TngUtil.contains(children, e)) {
									contributedChildren.add(e);
								}
							}
						}
						finally {
							ip.basicSetRolledUp(b);
						}
					}
				}
				if(!contributedChildren.isEmpty()) {
					children.addAll(wrapContributed(activity, contributedChildren));
				}
			}
			return children;
		}
		return doGetChildren(object);
	}
	
	protected void updateCachedChildren(Collection children) {
//		if(isRolledUp()) {
//			if(cachedRollupChildren == null) {
//				cachedRollupChildren = new ArrayList(children);
//			}
//			else {
//				cachedRollupChildren.clear();
//				cachedRollupChildren.addAll(children);
//			}
//		}
//		else {
//			if(cachedChildren == null) {
//				cachedChildren = new ArrayList(children);
//			}
//			else {
//				cachedChildren.clear();
//				cachedChildren.addAll(children);
//			}
//		}
	}
	
	/* (non-Javadoc)
	 * @see org.eclipse.epf.library.edit.ICachedChildrenItemProvider#getChildrenFromCache()
	 */
	public Collection getChildrenFromCache() {
		if(cachedChildren == null) {
			getChildren(target);
		}
		return cachedChildren;
	}
	
	/* (non-Javadoc)
	 * @see org.eclipse.epf.library.edit.ICachedChildrenItemProvider#getRollupChildrenFromCache()
	 */
	public Collection getRollupChildrenFromCache() {
		if(cachedRollupChildren == null) {
			boolean oldRolledUp = rolledUp;
			try {
				rolledUp = true;
				getChildren(target);
			}
			finally {
				rolledUp = oldRolledUp;
			}			
		}
		return cachedRollupChildren;
	}
	
	private BreakdownElementWrapperItemProvider findWrapper(Object owner, Object value) {
		// find if a wrapper already exist for the given value and owner
		//
		Object adapter = adapterFactory.adapt(value,
				ITreeItemContentProvider.class);
		BreakdownElementWrapperItemProvider wrapper = null;
		if (adapter instanceof IBSItemProvider) {
			List listeners = ((IBSItemProvider) adapter).getListeners();
			if (listeners != null) {
				find_wrapper_loop: for (Iterator iter = listeners.iterator(); iter
						.hasNext();) {
					Object element = (Object) iter.next();
					if (element instanceof BreakdownElementWrapperItemProvider) {
						wrapper = (BreakdownElementWrapperItemProvider) element;
						if (wrapper.getValue() == value
								&& wrapper.getParent(value) == owner) {
							break find_wrapper_loop;
						} else {
							wrapper = null;
						}
					}
				}
			}
		}
		return wrapper;
	}

	private List wrapInherited(Activity owner, Collection breakdownElements) {
		if (wrappers == null) {
			wrappers = new Disposable();
		}	
		return wrap(owner, breakdownElements, true, false, wrappers);
	}
	
	private List wrapContributed(Activity owner, Collection breakdownElements) {
		if(contributedWrappers == null) {
			contributedWrappers = new Disposable();
		}
		return wrap(owner, breakdownElements, false, true, contributedWrappers);
	}
	
	private IWrapperItemProviderFactory getWrapperItemProviderFactory() {
		IWrapperItemProviderFactory factory = null;
		if(adapterFactory instanceof IWrapperItemProviderFactoryProvider) {
			factory = ((IWrapperItemProviderFactoryProvider)adapterFactory).getWrapperItemProviderFactory();
		}
		if(factory == null) {
			factory = IBreakdownElementWrapperItemProviderFactory.INSTANCE;
		}
		return factory;
	}
	
	private List wrap(Activity owner, Collection breakdownElements, boolean inherited, boolean contributed, Disposable wrappers) {
		ArrayList wrapperList = new ArrayList();
		IWrapperItemProviderFactory wrapperFactory = getWrapperItemProviderFactory();
		for (Iterator iter = breakdownElements.iterator(); iter.hasNext();) {
			Object object = iter.next();
			Object unWrapped = TngUtil.unwrap(object);
			if (unWrapped instanceof BreakdownElement) {
				BreakdownElement e = (BreakdownElement) unWrapped;
				if (!TngUtil.isBase(owner.getBreakdownElements(), e)) {
					Object child = getWrapper(owner, e, wrappers);
					if(child == null) {
						child = wrapperFactory.createWrapper(e, owner, adapterFactory);
						if(child instanceof BreakdownElementWrapperItemProvider) {
							BreakdownElementWrapperItemProvider beWrapper = (BreakdownElementWrapperItemProvider) child;
							if(inherited) {
								beWrapper.isInherited = true;
							}
							else if(contributed) {
								beWrapper.contributed = true;
								if(object instanceof BreakdownElementWrapperItemProvider
										&& ((BreakdownElementWrapperItemProvider)object).isInherited()) {
									beWrapper.isInherited = true;
								}
							}
						}
					}
					else {
						wrappers.remove(child);
					}
					wrapperList.add(child);
				}
			}
		}
		wrappers.dispose();
		wrappers.addAll(wrapperList);
		return wrapperList;
	}
	
	private static Object getWrapper(Activity owner, BreakdownElement e, Collection wrappers) {
		for (Iterator iter = wrappers.iterator(); iter.hasNext();) {
			IWrapperItemProvider wrapper = (IWrapperItemProvider) iter.next();
			if(wrapper.getOwner() == owner && wrapper.getValue() == e) {
				return wrapper;
			}
		}
		return null;
	}
	
	protected Adapter createBaseListener() {
		if (baseListener == null) {
			baseListener = new AdapterImpl() {
				/*
				 * (non-Javadoc)
				 * 
				 * @see org.eclipse.epf.uma.provider.ActivityItemProvider#notifyChanged(org.eclipse.emf.common.notify.Notification)
				 */
				public void notifyChanged(final Notification notification) {
					Activity act = (Activity) BSActivityItemProvider.this
							.getTarget();
					switch (notification.getFeatureID(Activity.class)) {
					case UmaPackage.ACTIVITY__PRESENTATION_NAME:
						if (ProcessUtil.isExtendingOrLocallyContributing(act)) {
							fireNotifyChanged(new ViewerNotification(
									notification, act, false, true));
						}
						break;

					case UmaPackage.ACTIVITY__NAME:
						if (act.getVariabilityBasedOnElement() != null) {
							fireNotifyChanged(new ViewerNotification(
									notification, act, false, true));
						}
						break;

					case UmaPackage.ACTIVITY__SUPPRESSED:
						fireNotifyChanged(new ViewerNotification(notification,
								act, true, false));
						break;
					case UmaPackage.ACTIVITY__VARIABILITY_BASED_ON_ELEMENT:
						fireNotifyChanged(new ViewerNotification(notification,
								act, true, true));
						refreshAffectedViewers();
						break;

					case UmaPackage.ACTIVITY__BREAKDOWN_ELEMENTS: {
						if(handleReplaceBreakdownElement(notification)) {
							break;
						}
						List list = getAffectedChildren(notification);
						if (!list.isEmpty()) {
							boolean updateLabel = refreshChildrenData(
									notification, list);

							// forward notification
							//
							fireNotifyChanged(new ViewerNotification(
									notification, act, true, updateLabel));

							// ProcessUtil.refreshViewer(getRootAdapterFactory(),
							// (Process) getTopItem());
							refreshAffectedViewers();
						}

						break;
					}
					}
				}
			};
		}

		return baseListener;
	}

	protected Activity listenToBaseActivity() {
		Activity act = (Activity) target;
		if (!ProcessUtil.isExtendingOrLocallyContributing(act)) {
			return null;
		}
		Activity baseAct;
		if(variabilityInfo != null) {
			if(variabilityInfo.getInheritanceList().size() > 1) {
				baseAct = (Activity) variabilityInfo.getInheritanceList().get(1);
			}			
			else {
				baseAct = (Activity) configurator.resolve(act.getVariabilityBasedOnElement());
			}
		}
		else {
			baseAct = (Activity) act.getVariabilityBasedOnElement();
		}
		if (baseAct == null) {
			return null;
		}
		
		createBaseListener();
		
		// remove baseListener from old base, if there is any
		//
		EObject oldBase = (EObject) baseListener.getTarget();
		if(oldBase != null) {
			oldBase.eAdapters().remove(baseListener);
		}
		
		if (!baseAct.eAdapters().contains(baseListener)) {
			baseAct.eAdapters().add(baseListener);
		}

		Object ip = adapterFactory.adapt(baseAct, ITreeItemContentProvider.class);
		if(ip instanceof BSActivityItemProvider) {
			BSActivityItemProvider adapter = (BSActivityItemProvider) ip;
			adapter.listenToBaseActivity();
		}
		else {
			System.out.println();
		}
		return baseAct;
	}

	protected Collection addInherited(Object object, List myChildren) {
		if (object instanceof Activity) {
			Activity act = (Activity) object;
			Activity baseAct = listenToBaseActivity();
			if (baseAct != null) {
				VariabilityType extendType = act.getVariabilityType();
				if (extendType == VariabilityType.LOCAL_REPLACEMENT_LITERAL) {
					return myChildren;
				} else if (extendType == VariabilityType.LOCAL_CONTRIBUTION_LITERAL
						|| extendType == VariabilityType.EXTENDS_LITERAL) {
					BSActivityItemProvider adapter = (BSActivityItemProvider) getRootAdapterFactory()
						.adapt(baseAct, ITreeItemContentProvider.class);
					List allChildren;					
					boolean oldRolledUp = adapter.isRolledUp();
					try {
						if(oldRolledUp) {
							adapter.basicSetRolledUp(false);
						}
						allChildren = wrapInherited(act, adapter.getChildren(baseAct));
					}
					finally {
						if(oldRolledUp) {
							adapter.basicSetRolledUp(true);
						}
					}
//					// go thru own children list and insert it to the combined
//					// child list at the right place.
//					//
//					for (Iterator iter = myChildren.iterator(); iter.hasNext();) {
//						BreakdownElement element = (BreakdownElement) iter
//								.next();
//						TngUtil.addTo(allChildren, element, object, TngUtil
//								.getBestAdapterFactory(adapterFactory));
//					}
					if(allChildren.isEmpty()) {
						return myChildren;
					}
					else {
						TngUtil.addAllTo(allChildren, myChildren);
						return allChildren;
					}
				}
			}
		}
		return myChildren;
	}

	/**
	 * Checks if there is no descriptor in <code>children</code> referring to
	 * the same object as the specified descriptor <code>child</code> does.
	 * 
	 * @param children
	 * @param child
	 * @return true if no descriptor is found in the children list that refers
	 *         to the same object as the specified child does, false otherwise.
	 */
	protected boolean isNewDescriptor(List children, Object child) {
		return findDescriptor(children, child) == null;
	}
	
	protected Object findDescriptor(List children, Object child) {
		Object obj = getObject((Descriptor) TngUtil.unwrap(child));
		if (obj == null)
			return null;
		for (int i = children.size() - 1; i > -1; i--) {
			Object o = children.get(i);
			if (obj == getObject((Descriptor) TngUtil.unwrap(o)))
				return o;
		}
		return null;

	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see org.eclipse.emf.edit.command.CreateChildCommand.Helper#getCreateChildImage(java.lang.Object,
	 *      java.lang.Object, java.lang.Object, java.util.Collection)
	 */
	public Object getCreateChildImage(Object owner, Object feature,
			Object child, Collection selection) {
		// return
		// TngEditPlugin.INSTANCE.getImage("full/ctool16/CreateActivity_breakdownElements_Activity");
		return getImage(child);
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see org.eclipse.emf.edit.provider.ItemProviderAdapter#createRemoveCommand(org.eclipse.emf.edit.domain.EditingDomain,
	 *      org.eclipse.emf.ecore.EObject,
	 *      org.eclipse.emf.ecore.EStructuralFeature, java.util.Collection)
	 */
	protected Command createRemoveCommand(EditingDomain domain, EObject owner,
			EStructuralFeature feature, Collection collection) {
		return super.createRemoveCommand(domain, owner, feature, collection);
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see org.eclipse.epf.uma.tng.process.IBSItemProvider#getItemProvider(org.eclipse.emf.ecore.EObject)
	 */
	public IBSItemProvider getItemProvider(EObject eObj) {
		return (IBSItemProvider) TngUtil
				.getAdapter(eObj, IBSItemProvider.class);
	}

	public void setParent(Object object) {
		parent = object;
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see org.eclipse.emf.edit.provider.ItemProviderAdapter#getParent(java.lang.Object)
	 */
	public Object getParent(Object object) {
		if(parent == null) {
			if(target instanceof Activity) {
				return ((Activity)target).getSuperActivities();
			}
		}
		return parent;
	}

	/**
	 * Gets the list of children that had been affected after a an ADD, REMOVE,
	 * or MOVE operation.
	 */
	protected List getAffectedChildren(Notification notification) {
		return ProcessUtil.getAffectedElements(notification, childFilter);
	}

	protected boolean refreshChildrenData(Notification notification,
			List affectedChildren) {
		return false;
	}

	protected void doRefreshChildren(Notification notification,
			List affectedChildren) {
		refreshChildrenData(notification, affectedChildren);

		Process topAct = (Process) getTopItem();
		AdapterFactory rootAdapterFactory = getRootAdapterFactory();
		ProcessUtil.refreshViewer(rootAdapterFactory, topAct);
	}

	protected void refreshChildren(final Notification notification,
			final List newOrOldChildren) {
		if (!newOrOldChildren.isEmpty()) {

			Display display = null;
			try {
				display = Display.getCurrent();
			} catch (Exception e) {
				//
			}
			Runnable runnable = new Runnable() {

				public void run() {
					doRefreshChildren(notification, newOrOldChildren);
				}

			};
			if (display != null) {
				display.asyncExec(runnable);
			} else {
				runnable.run();
			}
		}
	}

	protected void refreshAffectedViewers() {
		Display display = null;
		try {
			display = Display.getCurrent();
		} catch (Exception e) {
			//
		}
		if(display == null) {
			try {
				display = Display.getDefault();
			}
			catch(Exception e) {

			}
		}
		Runnable runnable = new Runnable() {

			public void run() {
				doRefreshAffectedViewers();
			}

		};
		if (display != null) {
			display.asyncExec(runnable);
		} else {
			runnable.run();
		}
	}

	protected void doRefreshAffectedViewers() {

	}
	
	protected boolean handlePredecessorListChange(Notification notification) {
		return TngUtil.handlePredecessorListChange(this, notification);
	}
	
	protected boolean handleReplaceBreakdownElement(Notification notification) {
		if(notification.getEventType() == Notification.SET && notification.getNewValue() != notification.getOldValue()) {
			if(notification.getNewValue() instanceof WorkBreakdownElement) {
				WorkBreakdownElement e = (WorkBreakdownElement) notification.getNewValue();
				if(!AssociationHelper.getLinkToSuccessor(e).isEmpty()) {
					ProcessUtil.refreshPredeccessorLists(adapterFactory, (Process) getTopItem());
				}
			}
			fireNotifyChanged(new ViewerNotification(notification,
					getTarget(), true, false));
			refreshAffectedViewers();
			return true;
		}
		return false;
	}
	
	/*
	 * (non-Javadoc)
	 * 
	 * @see org.eclipse.emf.common.notify.Adapter#notifyChanged(org.eclipse.emf.common.notify.Notification)
	 */
	public void notifyChanged(Notification notification) {
		updateChildren(notification);

		if (handlePredecessorListChange(notification))
			return;

		switch (notification.getFeatureID(Activity.class)) {
		case UmaPackage.ACTIVITY__BREAKDOWN_ELEMENTS:
			if(handleReplaceBreakdownElement(notification)) {
				return;
			}
			List newOrOldChildren = getAffectedChildren(notification);
			if (!newOrOldChildren.isEmpty()) {
				switch (notification.getEventType()) {
				case Notification.ADD:
				case Notification.ADD_MANY:
					createOrMovePackageFor(newOrOldChildren);
					break;
				}

				fireNotifyChanged(new ViewerNotification(notification,
						notification.getNotifier(), true, false));

				// refreshChildren(notification, newOrOldChildren);

				refreshAffectedViewers();
			}
			return;
		case UmaPackage.ACTIVITY__SUPPRESSED:
			fireNotifyChanged(new ViewerNotification(notification, notification
					.getNotifier(), true, true));
			return;
		case UmaPackage.ACTIVITY__VARIABILITY_TYPE:
		case UmaPackage.ACTIVITY__VARIABILITY_BASED_ON_ELEMENT:

			fireNotifyChanged(new ViewerNotification(notification, notification
					.getNotifier(), true, true));

			// ProcessUtil.refreshViewer(getRootAdapterFactory(), (Process)
			// getTopItem());

			refreshAffectedViewers();

			return;
		}

		super.notifyChanged(notification);
	}

	/**
	 * @param newOrOldChildren
	 */
	protected void createOrMovePackageFor(List<?> newChildren) {
		ProcessPackage pkg = (ProcessPackage) ((EObject) target).eContainer();
		if(pkg == null) {
			return;
		}
		for (Object element : newChildren) {
			if (element instanceof Activity) {
				Activity act = (Activity) element;
				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(element);
				} else {
					// 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 {
				pkg.getProcessElements().add(element);
			}
		}
	}

	private static void getAllBreakdownElements(Set set, BreakdownElement e) {
		boolean ret = set.add(e);
		if (ret && (e instanceof Activity)) {
			for (Iterator iter = ((Activity) e).getBreakdownElements()
					.iterator(); iter.hasNext();) {
				BreakdownElement element = (BreakdownElement) iter.next();
				getAllBreakdownElements(set, element);
			}
		}
	}

	/**
	 * Refresh the comma-separated list of predecessor IDs in the viewer
	 * 
	 * @param affectedBreakdownElements
	 */
	private void refreshPredecessors(Notification msg,
			List affectedBreakdownElements) {

		Set refreshList = new HashSet();
		Set allBreakdownElements = new HashSet();
		for (Iterator iter = affectedBreakdownElements.iterator(); iter
				.hasNext();) {
			BreakdownElement e = (BreakdownElement) iter.next();
			if (msg.getEventType() == Notification.REMOVE
					|| msg.getEventType() == Notification.REMOVE_MANY) {
				setParentFor(e, null);
			}
			getAllBreakdownElements(allBreakdownElements, e);
		}
		// System.out.println("BSActivityItemProvider.refreshPredecessors():
		// allBreakdownElements="+allBreakdownElements);
		for (Iterator iterator = allBreakdownElements.iterator(); iterator
				.hasNext();) {
			BreakdownElement element = (BreakdownElement) iterator.next();
			for (Iterator iterator1 = AssociationHelper.getLinkToSuccessor(
					element).iterator(); iterator1.hasNext();) {
				WorkOrder workOrder = (WorkOrder) iterator1.next();
				BreakdownElement succ = AssociationHelper
						.getSuccessor(workOrder);
				if (!allBreakdownElements.contains(succ)) {
					refreshList.add(succ);
				}
			}
		}

		// System.out.println("BSActivityItemProvider.refreshPredecessors():
		// refreshList=" + refreshList);

		for (Iterator iter = refreshList.iterator(); iter.hasNext();) {
			Object child = iter.next();
			fireNotifyChanged(new ViewerNotification(msg, child, false, true));
		}
	}

	/**
	 * @param activity
	 */
	private void createPackageFor(Activity activity, EObject parentActivity) {
		ProcessPackage parent = (ProcessPackage) parentActivity.eContainer();
		ProcessPackage newPkg = UmaFactory.eINSTANCE.createProcessPackage();
		newPkg.setName(activity.getName());
		parent.getChildPackages().add(newPkg);
		ArrayList breakdownElements = new ArrayList();
		breakdownElements.add(activity);
		breakdownElements.addAll(activity.getBreakdownElements());
		newPkg.getProcessElements().addAll(breakdownElements);
	}

	protected String getColumnName(int columnIndex) {
		AdapterFactory rootAdapterFactory = getRootAdapterFactory();
		if (rootAdapterFactory instanceof IColumnAware) {
			Map columnIndexToNameMap = ((IColumnAware) rootAdapterFactory)
					.getColumnIndexToNameMap();
			if (columnIndexToNameMap != null) {
				return (String) columnIndexToNameMap.get(new Integer(
						columnIndex));
			}
		}
		return null;
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see org.eclipse.emf.edit.provider.ITableItemLabelProvider#getColumnImage(java.lang.Object,
	 *      int)
	 */
	public Object getColumnImage(Object object, int columnIndex) {
		String colName = getColumnName(columnIndex);
		return TngUtil.getColumnImage(object, colName);
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see org.eclipse.emf.edit.provider.ITableItemLabelProvider#getColumnText(java.lang.Object,
	 *      int)
	 */
	public String getColumnText(Object object, int columnIndex) {
		String colName = getColumnName(columnIndex);
		return getAttribute(object, colName);
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see org.eclipse.emf.edit.provider.ItemProviderAdapter#getText(java.lang.Object)
	 */
	public String getText(Object object) {
		return TngUtil.getLabel(object);
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see org.eclipse.epf.uma.tng.process.IBSItemProvider#setTopItem(java.lang.Object)
	 */
	public void setTopItem(Object top) {
		topItem = top;
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see com.ibm.library.edit.process.IBSItemProvider#isRolledUp()
	 */
	public boolean isRolledUp() {
		return rolledUp;
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see com.ibm.library.edit.process.IBSItemProvider#setRolledUp(boolean)
	 */
	public void setRolledUp(boolean b) {
		rolledUp = b;
		if (!rolledUp) {
			// user roll down this activity, set rolledUp flag of all its
			// offstring to false
			//
			Iterator iter = new AbstractTreeIterator(target, false) {

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

				protected Iterator getChildren(Object object) {
					ITreeItemContentProvider adapter = (ITreeItemContentProvider) adapterFactory
							.adapt(object, ITreeItemContentProvider.class);
					return adapter.getChildren(object).iterator();
				}

			};
			while (iter.hasNext()) {
				Object child = (Object) iter.next();
				Object adapter = adapterFactory.adapt(child,
						ITreeItemContentProvider.class);
				if (adapter instanceof IBSItemProvider) {
					((IBSItemProvider) adapter).setRolledUp(false);
				}
			}
		}
	}

	public GraphicalData getGraphicalData() {
		return graphicalData;
	}

	public void setGraphicalData(GraphicalData data) {
		graphicalData = data;
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see com.ibm.library.edit.process.IBSItemProvider#getAttribute(java.lang.Object,
	 *      java.lang.String)
	 */
	public String getAttribute(Object object, String property) {
		return ProcessUtil.getAttribute(object, property, this);
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see com.ibm.library.edit.process.IBSItemProvider#setAttribute(java.lang.Object,
	 *      java.lang.String, java.lang.String)
	 */
	public void setAttribute(Object object, String prop, String txt) {
		Activity e = (Activity) object;
		ProcessUtil.setAttribute(e, prop, txt);
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see org.eclipse.emf.edit.provider.ItemProviderAdapter#createCreateChildCommand(org.eclipse.emf.edit.domain.EditingDomain,
	 *      org.eclipse.emf.ecore.EObject,
	 *      org.eclipse.emf.ecore.EStructuralFeature, java.lang.Object, int,
	 *      java.util.Collection)
	 */
	protected Command createCreateChildCommand(EditingDomain domain,
			EObject owner, EStructuralFeature feature, Object value, int index,
			Collection collection) {
		if (value instanceof Iteration) {
			((Iteration) value).setIsRepeatable(Boolean.TRUE);
		}
		return super.createCreateChildCommand(domain, owner, feature, value,
				index, collection);
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see com.ibm.library.edit.process.IBSItemProvider#getListeners()
	 */
	public List getListeners() {
		if (changeNotifier == null)
			return null;
		return Collections.unmodifiableList((List) changeNotifier);
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see com.ibm.library.edit.process.IBSItemProvider#getPredecessors()
	 */
	public PredecessorList getPredecessors() {
		if (predecessors == null) {
			predecessors = new PredecessorList(TngUtil
					.getBestAdapterFactory(adapterFactory), target);
		}
		return predecessors;
	}

	public boolean isFirstElement(Object obj) {
		return ProcessUtil.isFirstElement(getRootAdapterFactory(), this, obj);
	}

	public boolean isLastElement(Object obj) {
		return ProcessUtil.isLastElement(getRootAdapterFactory(), this, obj);
	}

	public void moveUp(Object obj, IActionManager actionMgr) {
		Object parent = this.getParent(obj);
		if ((parent != null) && (parent instanceof Activity)) {
			TngUtil.moveUp((Activity) parent, obj, getEClasses(), actionMgr);
		}
	}

	public void moveDown(Object obj, IActionManager actionMgr) {
		Object parent = this.getParent(obj);
		if ((parent != null) && (parent instanceof Activity)) {
			TngUtil.moveDown((Activity) parent, obj, getEClasses(), actionMgr);
		}
	}

	protected Command createInitializeCopyCommand(EditingDomain domain,
			EObject owner, Helper helper) {
		return new MethodElementInitializeCopyCommand(domain, owner, helper);
	}

	protected Command createCreateCopyCommand(EditingDomain domain,
			EObject owner, Helper helper) {
		return new MethodElementCreateCopyCommand(domain, owner, helper);
	}

	protected Command createAddCommand(EditingDomain domain, EObject owner,
			EStructuralFeature feature, Collection collection, int index) {
		return new ActivityAddCommand((AddCommand) super.createAddCommand(
				domain, owner, feature, collection, index));
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see org.eclipse.epf.uma.provider.ActivityItemProvider#getImage(java.lang.Object)
	 */
	public Object getImage(Object object) {
		Object img = TngUtil.getImage(object);
		return img != null ? img : super.getImage(object);
	}

	public IFilter getChildFilter() {
		return childFilter;
	}

	public void setRefreshAllIDsRequired(boolean b) {
		refreshAllIDsRequired = b;
	}

	public boolean isRefreshAllIDsRequired() {
		return refreshAllIDsRequired;
	}

	public IFilter getFilter() {
		return this.filter;
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see com.ibm.library.edit.IConfigurable#setFilter(com.ibm.library.edit.IFilter)
	 */
	public void setFilter(IFilter filter) {
		this.filter = filter;
		if(filter instanceof IConfigurator) {
			configurator = (IConfigurator)filter;
		}
		else {
			configurator = null;
		}
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see com.ibm.library.edit.IConfigurable#setLabel(java.lang.String)
	 */
	public void setLabel(String label) {
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see com.ibm.library.edit.process.IBSItemProvider#createDropCommand(java.lang.Object,
	 *      java.util.List)
	 */
	public IResourceAwareCommand createDropCommand(Object owner,
			List dropElements) {
		return null;
	}
	
	public void basicSetRolledUp(boolean b) {
		rolledUp = b;
	}
	
	/**
	 * @return the enableVariabilityInfo
	 */
	public boolean isEnableVariabilityInfo() {
		return enableVariabilityInfo;
	}

	/**
	 * @param enableVariabilityInfo the enableVariabilityInfo to set
	 */
	public void setEnableVariabilityInfo(boolean enableVariabilityInfo) {
		this.enableVariabilityInfo = enableVariabilityInfo;
	}
	
	private class MoveCommandEx extends MoveCommand implements IResourceAwareCommand {

		private Set<Resource> modifiedResources;

		public MoveCommandEx(EditingDomain domain, EObject owner, EStructuralFeature feature, Object value, int index) {
			super(domain, owner, feature, value, index);
		}				
		
		@Override
		public void doExecute() {
			// translate view index to index in breakdown elements list
			//
			List children = (List) getChildren(getTarget());
			Object child = children.get(index);
			index = ownerList.indexOf(child);
			if(index != -1) {
				super.doExecute();
			}
			
			//TODO: move in between green elements
		}

		public Collection getModifiedResources() {
			if(modifiedResources == null) {
				Resource resource = owner.eResource();
				if(resource != null) {
					modifiedResources = Collections.singleton(resource);
				}
				else {
					modifiedResources = Collections.EMPTY_SET;
				}
			}
			return modifiedResources;
		}
	}
	
	@Override
	protected Command createMoveCommand(EditingDomain domain, EObject owner, EStructuralFeature feature, Object value, int index) {
		return new MoveCommandEx(domain, owner, feature, value, index);
	}
}