//------------------------------------------------------------------------------
// 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.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.Process;
import org.eclipse.epf.uma.ProcessComponent;
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.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();
			fixProcessComponent();
			replaceTextReferences();
		}
	}
	
	/**
	 * 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);
					}
				}
			}
		}
	}
	
	/* (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;
	}
}