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

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

import org.eclipse.core.runtime.Assert;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.emf.common.command.BasicCommandStack;
import org.eclipse.emf.common.command.Command;
import org.eclipse.emf.common.command.CompoundCommand;
import org.eclipse.emf.common.notify.AdapterFactory;
import org.eclipse.emf.common.util.EList;
import org.eclipse.emf.ecore.EAttribute;
import org.eclipse.emf.ecore.EObject;
import org.eclipse.emf.ecore.EStructuralFeature;
import org.eclipse.emf.ecore.util.EcoreUtil;
import org.eclipse.emf.ecore.xml.type.XMLTypePackage.Literals;
import org.eclipse.emf.edit.command.CommandParameter;
import org.eclipse.emf.edit.command.CopyCommand;
import org.eclipse.emf.edit.command.CreateCopyCommand;
import org.eclipse.emf.edit.command.InitializeCopyCommand;
import org.eclipse.emf.edit.domain.AdapterFactoryEditingDomain;
import org.eclipse.emf.edit.provider.ITreeItemContentProvider;
import org.eclipse.epf.library.edit.IConfigurator;
import org.eclipse.epf.library.edit.IFilter;
import org.eclipse.epf.library.edit.LibraryEditResources;
import org.eclipse.epf.library.edit.Providers;
import org.eclipse.epf.library.edit.TngAdapterFactory;
import org.eclipse.epf.library.edit.VariabilityInfo;
import org.eclipse.epf.library.edit.process.BreakdownElementWrapperItemProvider;
import org.eclipse.epf.library.edit.util.ConfigurationSetter;
import org.eclipse.epf.library.edit.util.ConstraintManager;
import org.eclipse.epf.library.edit.util.DepthLevelAdapterFactoryTreeIterator;
import org.eclipse.epf.library.edit.util.ExtensionManager;
import org.eclipse.epf.library.edit.util.IDiagramManager;
import org.eclipse.epf.library.edit.util.ITextReferenceReplacer;
import org.eclipse.epf.library.edit.util.MethodElementPropertyHelper;
import org.eclipse.epf.library.edit.util.ProcessUtil;
import org.eclipse.epf.library.edit.util.Suppression;
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.Constraint;
import org.eclipse.epf.uma.ContentDescription;
import org.eclipse.epf.uma.Diagram;
import org.eclipse.epf.uma.MethodConfiguration;
import org.eclipse.epf.uma.MethodElementProperty;
import org.eclipse.epf.uma.Process;
import org.eclipse.epf.uma.ProcessComponent;
import org.eclipse.epf.uma.ProcessElement;
import org.eclipse.epf.uma.ProcessPackage;
import org.eclipse.epf.uma.UmaFactory;
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.MethodElementInitializeCopyCommand;
import org.eclipse.osgi.util.NLS;

/**
 * Physically copies an activity with all of its direct or inherited structural features and references.
 *   
 * @author Phong Nguyen Le - Jun 21, 2006
 * @since  1.0
 */
public class ActivityDeepCopyCommand extends CopyCommand {
	private static final AdapterFactory[] adapterFactories = {
		TngAdapterFactory.INSTANCE.getWBS_ComposedAdapterFactory(),
		TngAdapterFactory.INSTANCE.getOBS_ComposedAdapterFactory(),
		TngAdapterFactory.INSTANCE.getPBS_ComposedAdapterFactory()
	};
	
	private static final int[] diagramTypes = {
		IDiagramManager.ACTIVITY_DETAIL_DIAGRAM,
		IDiagramManager.ACTIVITY_DIAGRAM,
		IDiagramManager.WORK_PRODUCT_DEPENDENCY_DIAGRAM
	};
	
	public static AdapterFactory[] getAdapterFactories() {
		return adapterFactories;
	}
	
	private class EditingDomain extends AdapterFactoryEditingDomain {

		/**
		 * @param adapterFactory
		 * @param commandStack
		 */
		public EditingDomain() {
			super(TngAdapterFactory.INSTANCE.getWBS_ComposedAdapterFactory(), new BasicCommandStack());
		}
		
		/* (non-Javadoc)
		 * @see org.eclipse.emf.edit.domain.AdapterFactoryEditingDomain#createCommand(java.lang.Class, org.eclipse.emf.edit.command.CommandParameter)
		 */
		public Command createCommand(Class commandClass, CommandParameter commandParameter) {
			if(commandClass == CreateCopyCommand.class) {
				return new CreateDeepCopyCommand(this, commandParameter.getEOwner(), (Helper) commandParameter.getValue());
			}
			if(commandClass == InitializeCopyCommand.class) {
				return new InitializeDeepCopyCommand(this, commandParameter.getEOwner(), (Helper) commandParameter.getValue());
			}
			return super.createCommand(commandClass, commandParameter);
		}
	}
	
	@Override
	protected void addCreateCopyCommands(CompoundCommand compoundCommand,
			EObject object) {

		// Operation to handle copy replacers of the child activities
		// 
		if (copyExternalVariations && object instanceof ProcessPackage && object != this.activity.eContainer()) {			
			ProcessPackage pkg = (ProcessPackage)object;
			boolean isReplaced = false;
			Activity replacer = null;
			Activity orignalActivity = null;
			for(Object procesElement : pkg.getProcessElements()){
				if (procesElement instanceof Activity) {
					Activity childAct = (Activity) procesElement;
					if(childAct.getSuperActivities() == this.activity) {
						replacer = getReplacer( (Activity)procesElement );
						if (replacer != null ) {
							isReplaced = true;
							orignalActivity = (Activity)procesElement;
						}
						break;
					}
				}
			}
			if (isReplaced) {				
				// reset the deferredInitializationCount so
				// InitializeCopyCommand can be created for the following
				// ActivityDeepCopyCommand. See
				// org.eclipse.emf.edit.command.CopyCommand.prepare() for more
				// details.
				//
				copyHelper.decrementDeferredInitializationCount();
				ActivityDeepCopyCommand cmd = new ActivityDeepCopyCommand(replacer, (CopyHelper)copyHelper, config, 
						targetProcess, monitor, false,activityDeepCopyConfigurator);
				cmd.guidList = new LinkedList<String>(ActivityDeepCopyCommand.this.guidList);
				cmd.guidList.addAll(ProcessUtil.getGuidList(ActivityDeepCopyCommand.this.activity, orignalActivity));
				try {
					cmd.execute();
					ProcessPackage pkgCopy = cmd.pkgCopy;					
					//basic put: original prc pkg to copied pkg based on replaced package.
					((CopyHelper)copyHelper).basicPut(object, pkgCopy);			
					//basic put original activity to the copy of replacer activity.
					((CopyHelper)copyHelper).basicPut(orignalActivity, copyHelper.get(replacer));
				}finally{
					cmd.dispose();
				}	
				// restore the deferredInitializationCount so
				// InitializeCopyCommand can be created for this
				// ActivityDeepCopyCommand
				copyHelper.incrementDeferredInitializationCount();				
				return;
			}
		}
		
		super.addCreateCopyCommands(compoundCommand, object);
	
	}
	
	/**
	 * Checks for the replacer of activity in the copy based configuration.
	 *  
	 * @param activity target activity
	 * @return replcacer or null if it doesn't have one
	 */
	protected Activity getReplacer(Activity activity){		
		ConfigurationSetter configSetter = new ConfigurationSetter(getAdapterFactory());
		try {
			if (activityDeepCopyConfigurator != null ) {
				MethodConfiguration currentConfig = configSetter.getOldConfiguration(); 
				MethodConfiguration copyConfig = config == null ? (currentConfig != null ? currentConfig
						: targetProcess.getDefaultContext())
						: config;
				activityDeepCopyConfigurator.setMethodConfiguration(copyConfig);				

				VariabilityInfo variabilityInfo = activityDeepCopyConfigurator.getVariabilityInfo(activity);

				if (variabilityInfo != null && ! variabilityInfo.getInheritanceList().isEmpty() ) {
					Activity replacer = (Activity)variabilityInfo.getInheritanceList().get(0);
					return  replacer == activity ? null : replacer;
				}
			}
			return null;
		} finally{
			if (configSetter != null ) {
				configSetter.restore();
			}
		}
	}
	
	/**
	 * Checks for the contributors of activity in the copy based configuration.
	 * @param activity
	 * @return a list including contributors or empty list
	 */
	protected List getContributors(Activity activity){
		ConfigurationSetter configSetter = new ConfigurationSetter(getAdapterFactory());
		try {
			if (activityDeepCopyConfigurator != null ) {
				MethodConfiguration currentConfig = configSetter.getOldConfiguration(); 
				MethodConfiguration copyConfig = config == null ? (currentConfig != null ? currentConfig
						: targetProcess.getDefaultContext())
						: config;
				activityDeepCopyConfigurator.setMethodConfiguration(copyConfig);				

				VariabilityInfo variabilityInfo = activityDeepCopyConfigurator.getVariabilityInfo(activity);

				if (variabilityInfo != null ) {
					return variabilityInfo.getContributors();
				}
			}
			return Collections.EMPTY_LIST;
		} finally{
			if (configSetter != null ) {
				configSetter.restore();
			}
		}
	}
	private class CreateDeepCopyCommand extends CreateCopyCommand {

		/**
		 * @param domain
		 * @param owner
		 * @param copyHelper
		 */
		public CreateDeepCopyCommand(EditingDomain domain, EObject owner, Helper copyHelper) {
			super(domain, owner, copyHelper);
		}
		
		/* (non-Javadoc)
		 * @see org.eclipse.emf.edit.command.CreateCopyCommand#doGetChildrenToCopy()
		 */
		public Collection<?> doGetChildrenToCopy() {
			ConfigurationSetter configSetter = new ConfigurationSetter(getAdapterFactory());
			try {
				configSetter.set(config);
				IConfigurator configurator = configSetter.getConfigurator();
				
				// Create commands to create copies of the children.
				//
				List<Object> result = new ArrayList<Object>();
				for (Iterator<EObject> i = owner.eContents().iterator(); i.hasNext(); )
				{
					Object o = i.next();
					if(o instanceof Activity) {
						// make sure that Activity will be copied first
						// so references to its inherited elements can be resolved
						// properly
						//
						if(configurator == null || configurator.accept(o)) {
							result.add(0, o);
						}
					}
					else {
						result.add(o);
					}
				}
				return result;
			}
			finally {
				configSetter.restore();
			}
		}
		
	}
	
	private class InitializeDeepCopyCommand extends MethodElementInitializeCopyCommand {
		/**
		 * List of GUIDs of activity starting from the top process to 
		 */
		private List<String> guidList;
		
		/**
		 * @param domain
		 * @param owner
		 * @param copyHelper
		 */
		public InitializeDeepCopyCommand(EditingDomain domain, EObject owner, Helper copyHelper) {
			super(domain, owner, copyHelper);
			copy = (EObject) copyHelper.get(owner);
		}
		
		/*
		 * (non-Javadoc)
		 * 
		 * @see org.eclipse.epf.uma.edit.command.MethodElementInitializeCopyCommand#copyReferences()
		 */
		protected void copyReferences() {
			Activity base = null;
			Activity baseCopy = null;
			Collection<Object> childBaseCopies = new HashSet<Object>();
			ConfigurationSetter configSetter = null;
			IConfigurator configurator = null;
			boolean baseAccepted = false;
			try {
				if(owner instanceof Activity) {
					Activity activity = (Activity) owner;
					if(ProcessUtil.isExtendingOrLocallyContributing(activity)) {
						configSetter = new ConfigurationSetter(getAdapterFactory());
						configSetter.set(config);
						configurator = configSetter.getConfigurator();
						// copy inherited elements by deep-copying base activity
						//
						// deep copy of base activity at this point is essential so references to predecessors
						// will be copied correctly
						//
						base = (Activity) activity.getVariabilityBasedOnElement();
						baseAccepted = configurator == null || configurator.accept(base);
						if(baseAccepted) {							
							CopyHelper helper = (CopyHelper)copyHelper;
							Activity oldBaseCopy = (Activity) helper.get(base);
							// this will redirect any reference to copy of base in diagram to the copy of the activity
							//
							helper.putVariabilityElement(base, activity);
							ArrayList childBases = new ArrayList();
							for (Iterator iter = activity.getBreakdownElements().iterator(); iter.hasNext();) {
								Object e = iter.next();
								if(e instanceof VariabilityElement) {
									VariabilityElement ve = (VariabilityElement) e;
									VariabilityElement baseElement = ve.getVariabilityBasedOnElement();
									if(baseElement != null &&
											(ve.getVariabilityType() == VariabilityType.LOCAL_CONTRIBUTION || ve.getVariabilityType() == VariabilityType.LOCAL_REPLACEMENT))
									{
										helper.putVariabilityElement(baseElement, ve);
										childBases.add(baseElement);
									}
								}
							}

							ActivityDeepCopyCommand cmd = new ActivityDeepCopyCommand(base, helper, config, targetProcess, monitor, false,activityDeepCopyConfigurator);
							cmd.copyExternalVariations = copyExternalVariations;
							cmd.guidList = new LinkedList<String>(ActivityDeepCopyCommand.this.guidList);
							cmd.guidList.addAll(ProcessUtil.getGuidList(ActivityDeepCopyCommand.this.activity, activity));
							try {
								cmd.execute();

								baseCopy = (Activity) helper.get(base);
								if(activity.getVariabilityType() == VariabilityType.EXTENDS) {
									// keep activity only as backup copy of base
									//
									helper.removeVariabilityElement(base);
									helper.putBackupCopy(base, activity);

									// put back oldBaseCopy
									if(oldBaseCopy != null) {
										helper.basicPut(base, oldBaseCopy);
									}
								}

								// remove the copies of all base since base copies are not added to the process
								//
								helper.remove(base);
								for (Iterator iter = childBases.iterator(); iter.hasNext();) {
									EObject childBaseCopy = (EObject) helper.remove(iter.next());
									if(childBaseCopy != null) {
										childBaseCopies.add(childBaseCopy);
										EcoreUtil.remove(childBaseCopy.eContainer());
									}
								}

								Activity activityCopy = (Activity) copy;

								// remove the copies of base diagram if the activity already have diagram of the same type
								//
								for (int i = 0; i < diagramTypes.length; i++) {
									int type = diagramTypes[i];
									if(diagramMgr.getDiagram(activity, type) != null) {
										Diagram diagram = diagramMgr.getDiagram(activityCopy, type);
										if(diagram != null) {
											EcoreUtil.remove(diagram);
										}
									}
								}

								// move content of base package over to the activity's package
								//
								moveContent(cmd.pkgCopy, activityCopy);	

								// record the copy of the wrappers
								//
								for (Iterator iterator = baseCopy.getBreakdownElements().iterator(); iterator
								.hasNext();) {
									BreakdownElement e = (BreakdownElement) iterator.next();
									if(!childBaseCopies.contains(e)) {
										BreakdownElement original = (BreakdownElement) helper.getOriginal(e);
										List<String> list = new ArrayList<String>(cmd.guidList);
										list.add(original.getGuid());
										helper.putWrapperCopy(ProcessUtil.toGuidPath(list), e);								
									}
								}
							}
							finally {
								cmd.dispose();
							}
						}
					}
				}

				super.copyReferences();

				if(base != null) {
					Activity activity = (Activity) owner;
					Activity activityCopy = ((Activity) copy);					
					
					if(baseAccepted) {
						// copy inherited breakdown elements from the base activity in the right order
						//
						MethodConfiguration currentConfig = configSetter.getOldConfiguration();

						// Add breakdown elements from base copy to the activity copy. 
						// Don't add copy of base element of the existing children
						//
						List<BreakdownElement> breakdownElements = new ArrayList<BreakdownElement>();
						for (Iterator<BreakdownElement> iter = baseCopy.getBreakdownElements().iterator(); iter.hasNext();) {
							BreakdownElement e = iter.next();
							if(!childBaseCopies.contains(e) && (configurator == null || configurator.accept(e))) {
								breakdownElements.add(e);
							}						
						}
						activityCopy.getBreakdownElements().addAll(0, breakdownElements);
						baseCopy.setSuperActivities(null);
						EcoreUtil.remove(baseCopy);


						// copy other string attributes as well after realize them
						//
						MethodConfiguration copyConfig = config == null ? (currentConfig != null ? currentConfig
								: targetProcess.getDefaultContext())
								: config;
						for (EAttribute attribute : getAttributesToCopy()) {
							if (attribute.isChangeable() && !attribute.isDerived()) {
								Object value = Providers.getConfigurationApplicator().getAttribute(activity, attribute, copyConfig);
								activityCopy.eSet(attribute, value);
							}
						}
						ContentDescription content = activity.getPresentation();
						for (EAttribute attribute : content.eClass().getEAllAttributes()) {
							if (attribute.isChangeable() && !attribute.isDerived()
									&& attribute.getEAttributeType().getInstanceClass() == Literals.STRING.getInstanceClass())
							{
								Object value = Providers.getConfigurationApplicator().getAttribute(content, activity, attribute, copyConfig);
								activityCopy.getPresentation().eSet(attribute, value);
							}
						}
					}

					// copy presentation name
					//
					activityCopy.setPresentationName(ProcessUtil.getPresentationName(activity));					
				}
				
				// copy contributors				
				if (copyExternalVariations && owner instanceof Activity && (copyContributors || owner != ActivityDeepCopyCommand.this.activity)) {
					Activity activity = (Activity)owner;					
					List contributors = getContributors(activity);
					if (!contributors.isEmpty()) {
						doCopyContributors(contributors,activity);
					}
				}
				
				// clear the variability data
				//
				if (copy instanceof Activity) {
					Activity activityCopy = ((Activity) copy);
					activityCopy.setVariabilityBasedOnElement(null);
					activityCopy.setVariabilityType(null);
				}
			}
			finally {
				if(configSetter != null) {
					configSetter.restore();
				}
			}

			if(copy instanceof Activity) {
				Activity activityCopy = ((Activity) copy);					

				// clear suppression data
				//
				Constraint rule = ConstraintManager.getConstraint(activityCopy, ConstraintManager.PROCESS_SUPPRESSION, false);
				if(rule != null) {
					EcoreUtil.remove(rule);
				}
			}
		}
		
		
		/**
		 * Copy contributors
		 * @param contributors
		 */
		protected void doCopyContributors(List contributors, Activity owner ) {
			ConfigurationSetter configSetter = new ConfigurationSetter(getAdapterFactory());
			try {
				MethodConfiguration currentConfig = configSetter.getOldConfiguration();
				MethodConfiguration copyConfig = config == null ? (currentConfig != null ? currentConfig
						: targetProcess.getDefaultContext())
						: config;
				configSetter.set(copyConfig);
				IConfigurator configurator = configSetter.getConfigurator();
				for (Iterator iterator = contributors.iterator(); iterator.hasNext();) {
					Activity contributedActivity = (Activity) iterator.next();
					CopyHelper helper = (CopyHelper)copyHelper;
					Activity contributorCopy = (Activity) helper.get(contributedActivity);
					ActivityDeepCopyCommand cmd = new ActivityDeepCopyCommand(contributedActivity, helper, 
							config, targetProcess, monitor, false,activityDeepCopyConfigurator);
					cmd.copyContributors = false; // don't copy contributor's contributors since they already are included in the given contributors list
					cmd.guidList = new LinkedList<String>(ActivityDeepCopyCommand.this.guidList);
					cmd.guidList.addAll(ProcessUtil.getGuidList(ActivityDeepCopyCommand.this.activity, owner));
					try {
						cmd.execute();

						contributorCopy = (Activity) helper.get(contributedActivity);

						Activity activityCopy = (Activity) copy;

						// remove the copies of base diagram if the activity already have diagram of the same type
						//
						for (int i = 0; i < diagramTypes.length; i++) {
							int type = diagramTypes[i];
							if(diagramMgr.getDiagram(activity, type) != null) {
								Diagram diagram = diagramMgr.getDiagram(activityCopy, type);
								if(diagram != null) {
									EcoreUtil.remove(diagram);
								}
							}
						}

						// move content of base package over to the activity's package
						//
						moveContent(cmd.pkgCopy, activityCopy);	

						List<BreakdownElement> breakdownElements = new ArrayList<BreakdownElement>();
						for (Iterator<BreakdownElement> iter = contributorCopy.getBreakdownElements().iterator(); iter.hasNext();) {
							BreakdownElement e = iter.next();
							if(configurator == null || configurator.accept(e)){
								breakdownElements.add(e);
							}						
						}
						activityCopy.getBreakdownElements().addAll(breakdownElements);
						contributorCopy.setSuperActivities(null);
						EcoreUtil.remove(contributorCopy);

					}
					finally {
						cmd.dispose();
					}
				}
			}finally{
				if (configSetter != null ) {
					configSetter.restore();
				}
			}
		}
	}

	protected ProcessPackage pkgCopy;
	protected MethodConfiguration config;
	protected IDiagramManager diagramMgr;

	protected Process targetProcess;

	protected IProgressMonitor monitor;

	protected Activity activity;

	private LinkedList<String> guidList;

	private BreakdownElementWrapperItemProvider wrapper;
	
	//used to retrieve replacers and contributors
	private IConfigurator activityDeepCopyConfigurator;
	
	private boolean copyExternalVariations = true;
	
	private boolean copyContributors = true;
	
	private ActivityDeepCopyCommand(Activity activity, CopyHelper copyHelper,
			MethodConfiguration config, Process targetProcess,
			IProgressMonitor monitor, boolean initGuidList,IConfigurator activityDeepCopyConfigurator) {
		super(null, activity.eContainer(), copyHelper);
		Assert.isTrue(activity.eContainer() instanceof ProcessPackage, "Activity's container must be a ProcessPackage"); //$NON-NLS-1$
		this.activity = activity;
		domain = new EditingDomain();
		this.config = config;
		this.targetProcess = targetProcess;
		diagramMgr = ExtensionManager.getDiagramManager();
		Assert.isNotNull(diagramMgr, "Could not load diagram manager"); //$NON-NLS-1$
		this.monitor = monitor;
		if(initGuidList) {
			guidList = ProcessUtil.getGuidList(null, this.activity);
		}
		this.activityDeepCopyConfigurator = activityDeepCopyConfigurator;
	}
	
	public ActivityDeepCopyCommand(Activity activity, CopyHelper copyHelper,
			MethodConfiguration config, Process targetProcess,
			IProgressMonitor monitor, IConfigurator activityDeepCopyConfigurator) {
		this(activity, copyHelper, config, targetProcess, monitor, true,activityDeepCopyConfigurator);		
	}
	
	public ActivityDeepCopyCommand(Object activityOrWrapper, CopyHelper copyHelper, MethodConfiguration config,
			Process targetProcess, IProgressMonitor monitor, IConfigurator activityDeepCopyConfigurator) {
		this((Activity)TngUtil.unwrap(activityOrWrapper), copyHelper, config, targetProcess, monitor, 
				activityOrWrapper instanceof Activity,activityDeepCopyConfigurator);
		if(activityOrWrapper instanceof BreakdownElementWrapperItemProvider) {
			wrapper = (BreakdownElementWrapperItemProvider) activityOrWrapper;
			guidList = ProcessUtil.getGuidList(wrapper);
		}
	}	
	
	public void setCopyExternalVariations(boolean copyExternalVariations) {
		this.copyExternalVariations = copyExternalVariations;
	}
	
	public AdapterFactory getAdapterFactory() {
		return ((AdapterFactoryEditingDomain)domain).getAdapterFactory();
	}
	
	/* (non-Javadoc)
	 * @see org.eclipse.emf.edit.command.CopyCommand#execute()
	 */
	public void execute() {
		monitor.subTask(NLS.bind(LibraryEditResources.copyingActivities_msg, ProcessUtil.getPresentationName(activity)));
		super.execute();
		Collection<?> result = super.getResult();
		if(!result.isEmpty()) {
			pkgCopy = (ProcessPackage) result.iterator().next();
			fixCustomWorkOrders();
			fixProcessComponent();
			replaceTextReferences();
		}
	}
	
	private void fixCustomWorkOrders() {
		Map<?, ?> objectToCopyMap = ((CopyHelper) copyHelper).getObjectToCopyMap();
		Map<String, String> oldGuidToNewGuidMap = new HashMap<String, String>();
		for (Map.Entry<?, ?> entry : objectToCopyMap.entrySet()) {
			if(entry.getKey() instanceof WorkBreakdownElement) {
				oldGuidToNewGuidMap.put(((WorkBreakdownElement) entry.getKey()).getGuid(),
						((WorkBreakdownElement) entry.getValue()).getGuid());
			}
		}
		for (ProcessElement element : pkgCopy.getProcessElements()) {
			if(element instanceof WorkOrder) {
				MethodElementProperty prop = MethodElementPropertyHelper.getProperty(element, MethodElementPropertyHelper.WORK_ORDER__SUCCESSOR);
				if(prop != null) {
					String newGuid = oldGuidToNewGuidMap.get(prop.getValue());
					if(newGuid != null) {
						prop.setValue(newGuid);
					}
				}
			}
		}
		oldGuidToNewGuidMap.clear();
		objectToCopyMap.clear();
	}

	/**
	 * fix the process component to make it a process package.
	 * This method might be overriden by subclass to achive difference result.
	 * For example, 
	 */
	protected void fixProcessComponent() {
		if(pkgCopy instanceof ProcessComponent) {
			// replace the ProcessComponent with a equivalent ProcessPackage
			//
			ProcessPackage pkg = UmaFactory.eINSTANCE.createProcessPackage();
			Collection features = new ArrayList(pkgCopy.eClass().getEAllStructuralFeatures());
			features.retainAll(pkg.eClass().getEAllStructuralFeatures());
			for (Iterator iter = features.iterator(); iter.hasNext();) {
				EStructuralFeature feature = (EStructuralFeature) iter.next();
				Object value = pkgCopy.eGet(feature);
				pkg.eSet(feature, value);
			}
			Process proc = ((ProcessComponent)pkgCopy).getProcess();
			if(proc != null) {
				pkg.getProcessElements().add(0, proc);
			}
			pkgCopy = pkg;
		}		
	}
	
	/**
	 * If textual descriptions in the copied elements contain references (URLs) to other elements 
	 * within the same copied process then replace these references with references that point to 
	 * the new elements in the copied structures.
	 */
	protected void replaceTextReferences() {
		ITextReferenceReplacer txtRefReplacer = ExtensionManager.getTextReferenceReplacer();
		if(txtRefReplacer == null) return;

		Map oldToNewObjectMap = ((CopyHelper) copyHelper).getObjectToCopyMap();
		for (Iterator iter = pkgCopy.eAllContents(); iter.hasNext();) {
			EObject element = (EObject) iter.next();
			for (Iterator attributes = element.eClass().getEAllAttributes().iterator(); attributes.hasNext(); )
			{
				EAttribute attribute = (EAttribute) attributes.next();
				if (attribute.isChangeable() && !attribute.isDerived() && (attribute.isMany() || element.eIsSet(attribute))
						&& attribute.getEAttributeType().getInstanceClass() == Literals.STRING.getInstanceClass())
				{
					String text = (String) element.eGet(attribute);
					if(text != null) {
						text = txtRefReplacer.replace(text, targetProcess, oldToNewObjectMap);
						element.eSet(attribute, text);
					}
				}
			}
		}
		oldToNewObjectMap.clear();
	}
	
	/* (non-Javadoc)
	 * @see org.eclipse.emf.common.command.CompoundCommand#getResult()
	 */
	public Collection<?> getResult() {
		if(pkgCopy != null) {
			Activity act = ProcessUtil.findActivity(pkgCopy);
			if(act != null) {
				return Collections.singletonList(act);
			}
		}
		return Collections.EMPTY_LIST;
	}
	
	/**
	 * Moves content of source object <code>src</code> over to the target objec <code>target</code>
	 * @param src
	 * @param target
	 */
	private static void moveContent(ProcessPackage src, Activity act) {
		ProcessPackage target = (ProcessPackage) act.eContainer();
		// move content of base package over to the activity's package					
		for (Iterator iter = new ArrayList(src.eContents()).iterator(); iter.hasNext();) {
			EObject e = (EObject) iter.next();
			EStructuralFeature f = e.eContainingFeature();						
			if(f.isMany()) {
				((List)target.eGet(f)).add(e);
			}
		}
		if(src instanceof ProcessComponent) {
			Process baseCopy = ((ProcessComponent)src).getProcess();
			target.getProcessElements().add(baseCopy);
		}

	}
	
	private static BreakdownElement getTopElement(BreakdownElement e) {
		if(e == null) {
			return null;
		}
		BreakdownElement top = e;
		for(BreakdownElement o = e.getSuperActivities(); o != null; o = o.getSuperActivities()) {
			top = o;
		}
		return top;
	}
	
	public void copySuppressionStates() {
		Collection<?> result = getResult();
		if(result.isEmpty()) {
			return;
		}
		String wrapperPath = wrapper != null ? ProcessUtil.toGuidPath(guidList) : null;
		for (int i = 0; i < adapterFactories.length; i++) {
			AdapterFactory adapterFactory = adapterFactories[i];
			boolean isWBS = adapterFactory == TngAdapterFactory.INSTANCE.getWBS_ComposedAdapterFactory();
			IFilter filter = ProcessUtil.getFilter(adapterFactory);
			IConfigurator configurator = null;
			MethodConfiguration currentConfig = null;
			if(filter instanceof IConfigurator) {
				configurator = (IConfigurator) filter;
				currentConfig = configurator.getMethodConfiguration();
				configurator.setMethodConfiguration(config);
			}
			try {
				Activity act = ProcessUtil.findActivity((ProcessPackage) owner);
				ProcessUtil.initializeItemProviderPath(act, adapterFactory);
				Process proc = TngUtil.getOwningProcess(act);
				Suppression suppression = Suppression.getSuppression(proc);
				DepthLevelAdapterFactoryTreeIterator<?> iter = new DepthLevelAdapterFactoryTreeIterator<Object>(adapterFactory, proc);
				int depthLevel = -1;
				find_deep_copied_activity:
					while(iter.hasNext()) {
						Object child = iter.next();

						// set depth level if the current child is the deep-copied activity
						//
						if(wrapper == null) {
							if(child == activity) {
								depthLevel = iter.getDepthLevel();
								break find_deep_copied_activity;
							}
						}
						else {
							if(child instanceof BreakdownElementWrapperItemProvider) {
								String path = Suppression.getPathWithoutViewType((BreakdownElementWrapperItemProvider) child).toString();
								if(wrapperPath.equals(path)) {
									depthLevel = iter.getDepthLevel();
									break find_deep_copied_activity;
								}
							}
						}					
					}
				
				// copy suppression state of all suppressed elements under deep-copied activity
				//
				CopyHelper helper = (CopyHelper)copyHelper;
				Map<?, ?> originalToCopyMap = helper.getObjectToCopyMap();
				Map<Object, Object> elementOrWrapperToCopyMap = null;
				if(isWBS) {
					elementOrWrapperToCopyMap = new HashMap<Object, Object>();
					Activity deepCopy = (Activity) result.iterator().next();
					elementOrWrapperToCopyMap.put(wrapper != null ? wrapper : activity, deepCopy);
				}
				while(iter.hasNext()) {
					Object child = iter.next();
					if(iter.getDepthLevel() > depthLevel) {
						Object e = TngUtil.unwrap(child);
						if(e instanceof BreakdownElement) {
							if(!isWBS && e instanceof Activity) {
								// skip copying suppression state and ordering
								// breakdown elements for activity in other view
								// than WBS
								//
								continue;
							}
//							BreakdownElement original = (BreakdownElement) e;
//							BreakdownElement copy = (BreakdownElement) originalToCopyMap.get(original);
//							
//							if(TngUtil.DEBUG) {
//								String copyName = (copy != null ? copy.getName() : null);
//								BreakdownElement top = getTopElement(copy);
//								if(copy == null || !original.getName().equals(copyName) || top != deepCopy) {
//									System.err.println("original: '" + original.getName() + "', copy: '" + copyName + "', copy's top activity: " + top);
//								}
//							}
							BreakdownElement copy = null;
							boolean isSuppressed = suppression.isSuppressed(child);
							
							// find copy to suppress or, if element is an activity, to reorder its breakdown elements
							//
							if(isSuppressed || isWBS) {
								if(child == e) {	
									copy = (BreakdownElement) originalToCopyMap.get(e);
								}
								else if(child instanceof BreakdownElementWrapperItemProvider) {
									BreakdownElementWrapperItemProvider childWrapper = (BreakdownElementWrapperItemProvider) child;
									if(childWrapper.isInherited()) {
										String guidPath = Suppression.getPathWithoutViewType(childWrapper).toString();
										copy = helper.getWrapperCopy(guidPath);
									}
								}
								if(copy != null) {
									if(isSuppressed) {
										copy.setSuppressed(Boolean.TRUE);
									}
									if(isWBS) {
										elementOrWrapperToCopyMap.put(child, copy);
									}
								}
							}
						}
					}
					else {
						break;
					}
				}
				// reorder breakdown elements of activities
				//
				if(isWBS) {
					for (Map.Entry<Object, Object> entry : elementOrWrapperToCopyMap.entrySet()) {
						Object o = entry.getKey();
						Object copy = entry.getValue();
						if(copy instanceof Activity) {
							ITreeItemContentProvider ip = (ITreeItemContentProvider) adapterFactory.adapt(o, ITreeItemContentProvider.class);
							Collection<?> children = ip.getChildren(o);
							EList<?> list =  (EList<?>) ((Activity) copy).getBreakdownElements();
							List<?> childrenList = children instanceof List<?> ? (List<?>) children : new ArrayList<Object>(children);
							int size = childrenList.size();
							for (int j = 0; j < size; j++) {
								Object child = childrenList.get(j);
								Object childCopy = elementOrWrapperToCopyMap.get(child);
								if(childCopy != null) {
									if(j < size - 1) {
										Object nextChild = childrenList.get(j + 1);
										Object nextChildCopy = elementOrWrapperToCopyMap.get(nextChild);	
										if(nextChildCopy != null) {
											int succId = list.indexOf(nextChildCopy);
											if(succId != -1) {
												int id = list.indexOf(childCopy);
												if(id != succId - 1) {
													if(id < succId) {
														list.move(succId - 1, id);
													}
													else {
														list.move(id, succId);
													}
												}
											}										
										}
										else if(TngUtil.DEBUG) {
											System.err.println("Element does not have copy: " + nextChild); //$NON-NLS-1$
										}
									}
								}
								else if(TngUtil.DEBUG) {
									System.err.println("Element does not have copy: " + child); //$NON-NLS-1$
								}
							}
						}
					}
				}
			}
			finally {
				if(configurator != null) {
					configurator.setMethodConfiguration(currentConfig);
				}
			}
		}
	}
	
	public CopyHelper getCopyHelper() {
		return (CopyHelper) copyHelper;
	}
}