//------------------------------------------------------------------------------
// 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.edit.command.AddCommand;
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;
			}
			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) {
					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) {
		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();
		for (Iterator iter = newChildren.iterator(); iter.hasNext();) {
			Object element = iter.next();
			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;
	}
}