/******************************************************************************
 * Copyright (c) 2002, 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 API and implementation 
 ****************************************************************************/

package org.eclipse.gmf.runtime.emf.clipboard.core;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;

import org.eclipse.emf.ecore.EAnnotation;
import org.eclipse.emf.ecore.EAttribute;
import org.eclipse.emf.ecore.EObject;
import org.eclipse.emf.ecore.EReference;
import org.eclipse.emf.ecore.resource.Resource;
import org.eclipse.emf.ecore.util.FeatureMapUtil;
import org.eclipse.emf.ecore.xmi.XMLResource;
import org.eclipse.gmf.runtime.emf.clipboard.core.internal.MergedEObjectInfo;
import org.eclipse.gmf.runtime.emf.clipboard.core.internal.ObjectCopyType;
import org.eclipse.gmf.runtime.emf.clipboard.core.internal.PasteIntoParentOperation;
import org.eclipse.gmf.runtime.emf.clipboard.core.internal.ResourceInfoProcessor;
import org.eclipse.gmf.runtime.emf.clipboard.core.internal.l10n.EMFClipboardCoreMessages;


/**
 * An operation to paste a child object into a new target parent object.
 * 
 * @author Yasser Lulu
 */
public class PasteChildOperation
	extends BasePasteOperation {

	/**
	 * Localized prefix to prepend onto element names to disambiguate them
	 * in resolving paste collisions.
	 */
	protected static final String COPY = EMFClipboardCoreMessages.pasteChildOperation_copyPrefix;

	/**
	 * A reusable empty array of paste child operations.
	 */
	protected static final PasteChildOperation[] EMPTY_ARRAY = new PasteChildOperation[0];

	private Map auxiliaryChildPasteProcessMap;

	private PasteChildOperation mainChildPasteProcess;

	private PasteChildOperation postPasteOperation;

	private List alwaysCopyObjectPasteOperations;

	private ObjectInfo childObjectInfo;

	private EObject childEObject;

	private EObject pastedElement;

	private EObject copyParentEObject;

	private ObjectInfo copyParentObjectInfo;

	private EObject directContainerEObject;

	private OverridePasteChildOperation overrideChildPasteOperation;

	private EReference containmentFeature;

	private Map embeddedCopyParentObjectInfoMap = new HashMap();

	/**
	 * Initializes me.
	 * 
	 * @param parentPasteProcess my superordinate operation, that created me
	 *      in order to paste one of its copied objects into its target parent
	 *      object
	 * @param childEObjectInfo the metadata for the child object to be pasted
	 */
	public PasteChildOperation(PasteIntoParentOperation parentPasteProcess,
		ObjectInfo childEObjectInfo) {
		super(parentPasteProcess);
		this.childObjectInfo = childEObjectInfo;
		auxiliaryChildPasteProcessMap = new HashMap();
	}

	/**
	 * Gets the containment feature into which I would prefer to paste my child
	 * element into the parent.
	 * 
	 * @return the preferred containment feature to paste into
	 */
	protected EReference getContainmentFeature() {
		if (containmentFeature == null) {
			containmentFeature = getParentPasteProcess().getContainmentFeature(
				getEObject());
		}
		return containmentFeature;
	}

	/**
	 * Initializes me as an auxiliary to another child paste operation.
	 * 
	 * @param mainChildPasteProcess the main child paste operation
	 * @param childEObjectInfo the metadata for the child object to be pasted
	 */
	private PasteChildOperation(PasteChildOperation mainChildPasteProcess,
		ObjectInfo childEObjectInfo) {
		this(mainChildPasteProcess.getParentPasteProcess(), childEObjectInfo);
		this.mainChildPasteProcess = mainChildPasteProcess;
	}

	/**
	 * Initializes me as an override- or post-paste operation.
	 * 
	 * @param mainChildPasteProcess the paste-child process that I am overriding
	 *     or extending
	 */
	protected PasteChildOperation(PasteChildOperation mainChildPasteProcess) {
		this(mainChildPasteProcess.getParentPasteProcess(),
			mainChildPasteProcess.childObjectInfo);
	}

	/**
	 * Obtains the direct container object, from the deserialized copied elements,
	 * of the object that I am pasting.
	 * 
	 * @return my object's direct container
	 */
	protected EObject getLoadedDirectContainerEObject() {
		if (directContainerEObject == null) {
			directContainerEObject = getLoadedEObject(getChildObjectInfo().containerId);
		}
		return directContainerEObject;
	}

	/**
	 * Obtains the paste operation that created me to paste a child into the
	 * target parent element.
	 * 
	 * @return my parent operation
	 */
	public PasteIntoParentOperation getParentPasteProcess() {
		return (PasteIntoParentOperation) getSpawningPasteOperation();
	}

	/**
	 * Obtains the paste operation that pastes the auxiliary object indicated
	 * by the specified object info.
	 * 
	 * @param auxiliaryChildEObjectInfo the auxiliary object's info
	 * @return the paste operation that pastes the auxiliary object
	 */
	protected PasteChildOperation getAuxiliaryChildPasteProcess(
		ObjectInfo auxiliaryChildEObjectInfo) {
		PasteChildOperation auxiliaryChildPasteProcess = (PasteChildOperation) auxiliaryChildPasteProcessMap
			.get(auxiliaryChildEObjectInfo);
		if (auxiliaryChildPasteProcess == null) {
			auxiliaryChildPasteProcess = makeAuxiliaryChildPasteProcess(auxiliaryChildEObjectInfo);
			if (auxiliaryChildPasteProcess != null) {
				auxiliaryChildPasteProcessMap.put(auxiliaryChildEObjectInfo,
					auxiliaryChildPasteProcess);
			}
		}
		return auxiliaryChildPasteProcess;
	}

	/**
	 * Constructs a paste operation to paste the auxiliary object indicated by
	 * its object info.
	 * 
	 * @param auxiliaryChildEObjectInfo the auxiliary object's info
	 * @return the appropriate paste child operation
	 */
	protected PasteChildOperation makeAuxiliaryChildPasteProcess(
		ObjectInfo auxiliaryChildEObjectInfo) {
		return new PasteChildOperation(this, auxiliaryChildEObjectInfo);
	}

	/**
	 * Retrieves the object that I am pasting from the deserialized clipboard
	 * string into the target parent object.
	 * 
	 * @return the object that I am pasting
	 */
	public EObject getEObject() {
		if (childEObject == null) {
			childEObject = getLoadedEObject(getChildObjectInfo().objId);
		}
		return childEObject;
	}

	/**
	 * After pasting is completed, obtains the element that I pasted.
	 * 
	 * @return the pasted element, or <code>null</code> if I did not succeed
	 *     in pasting
	 */
	public EObject getPastedElement() {
		return pastedElement;
	}

	/**
	 * Looks up an object deserialized from the clipboard string by its ID.
	 *  
	 * @param objId the object ID to look up
	 * @return the corresponding object, or <code>null</code> if not found
	 */
	protected EObject getLoadedEObject(String objId) {
		return getParentPasteProcess().getLoadedEObject(objId);
	}

	/**
	 * Looks up the ID of an object deserialized from the clipboard string.
	 *  
	 * @param eObject the object whose ID we want to look up
	 * @return the corresponding ID, or <code>null</code> if not found
	 */
	protected String getLoadedEObjectID(EObject eObject) {
		return getParentPasteProcess().getLoadedEObjectID(eObject);
	}

	/**
	 * Queries whether the object that I am pasting had its parent object
	 * copied along with it, as an alternative element to try to paste when I
	 * can't be directly pasted into the target element.
	 * 
	 * @return whether my copy object was copied with its parent
	 */
	protected boolean hasCopyParent() {
		return (ResourceInfoProcessor.NONE
			.equals(getChildObjectInfo().copyParentId) == false);
	}

	/**
	 * Queries whether the object that I am pasting was copied because it
	 * is always copied along with an element that was originally selected for
	 * copying.
	 * 
	 * @return whether my copy object is copied because of a "copy always" rule
	 */
	protected boolean isCopyAlways() {
		return (getChildObjectInfo().objCopyType
			.equals(ObjectCopyType.OBJ_COPY_TYPE_ALWAYS));
	}

	/**
	 * Gets the original parent of the object that I am pasting, if it was
	 * copied along with the child.
	 * 
	 * @return the copy parent, or <code>null</code> if it was not copied
	 * 
	 * @see #hasCopyParent()
	 */
	protected EObject getCopyParentEObject() {
		if (copyParentEObject == null) {
			copyParentEObject = getLoadedEObject(getChildObjectInfo().copyParentId);
		}
		return copyParentEObject;
	}

	/**
	 * Looks up an object in the resource to which we are pasting, by its ID.
	 *  
	 * @param objId the object ID to look up
	 * @return the corresponding object, or <code>null</code> if not found
	 */
	protected EObject getEObject(String objId) {
		return getParentPasteProcess().getEObject(objId);
	}

	/**
	 * Looks up the ID of an object in the resource to which we are pasting.
	 *  
	 * @param eObject the object to look up its ID
	 * @return the corresponding ID, or <code>null</code> if not found
	 */
	protected String getEObjectID(EObject eObject) {
		return getParentPasteProcess().getEObjectID(eObject);
	}

	/**
	 * Finds some parent in the containment chain (ancestry) of the parent
	 * element into which I am pasting that my child element can be pasted into.
	 * 
	 * @param preferredTypeName the fully-qualified class name of the preferred
	 *     element type to paste into
	 * @return the suitable parent, if found, otherwise <code>null</code>
	 */
	protected PasteTarget getSuitableParentUsingAncestry(String preferredTypeName) {
		PasteTarget suitableParent = getSuitableParentUsingAncestry(
			getParentTarget(), preferredTypeName, true);
		if (suitableParent == null) {
			suitableParent = getSuitableParentUsingAncestry(getParentTarget(),
				preferredTypeName, false);
		}
		return suitableParent;
	}

	private PasteTarget getSuitableParentUsingAncestry(
			PasteTarget potentialParent, String preferredTypeName,
		boolean strictMatch) {
		PasteTarget suitableParent = checkPotentialParent(potentialParent,
			preferredTypeName, strictMatch);
		if (suitableParent == null && !potentialParent.isResource()) {
			EObject potentialParentObject = (EObject)potentialParent.getObject();
			while ((suitableParent == null)
				&& (potentialParentObject.eContainer() != null)) {
				potentialParentObject = potentialParentObject.eContainer();
				suitableParent = checkPotentialParent(new PasteTarget(potentialParentObject),
					preferredTypeName, strictMatch);
			}
		}
		return suitableParent;
	}

	/**
	 * After pasting has completed, obtains the pasted object corresponding
	 * to the specified originally copied object.
	 * 
	 * @param eObject the originally copied object
	 * @return the corresponding pasted object, or <code>null</code> if the
	 *      <code>eObject</code> was not successfully pasted
	 */
	protected EObject getPastedEObject(EObject eObject) {
		String id = getEObjectID(eObject);
		if (id != null) {
			//it has been pasted as is
			return eObject;
		} else {
			//maybe it has been merged?
			MergedEObjectInfo info = (MergedEObjectInfo) getAllMergedElementsMap()
				.get(eObject);
			if (info != null) {
				if (info.targetEObjects.size() == 1) {
					return (EObject) info.targetEObjects.get(0);
				} else if (info.targetEObjects.size() > 1) {
					//got merged more than once, pick most suitable!
					Iterator it = info.targetEObjects.iterator();
					while (it.hasNext()) {
						EObject mergeTarget = (EObject) it.next();
						if ((getParentTarget().isResource() &&
								getParentTarget().getObject() == mergeTarget.eResource()) ||
								ClipboardSupportUtil.isChild(getParentEObject(), mergeTarget)) {
							return mergeTarget;
						}
					}
					//no suitable one, then pick the first
					return (EObject) info.targetEObjects.get(0);
				}
			}
		}
		return null;
	}

	/**
	 * After pasting has completed, obtains the pasted object corresponding
	 * to the specified originally copied object's parent.
	 * 
	 * @return the corresponding pasted object, or <code>null</code> if the
	 *      copy parent was not successfully pasted
	 */
	protected EObject getPastedDirectCopyParent() {
		return getPastedEObject(getLoadedDirectContainerEObject());
	}

	private EObject doPasteIntoNearestCopyParent(
		EObject topMostCopyParentEObject) throws Exception {
		EObject nearestParent = getLoadedEObject(getChildObjectInfo().containerId);
		while (nearestParent.equals(topMostCopyParentEObject) == false) {
			EObject parentElement = doPasteIntoCopyParent(makeEmbeddedCopyParentObjectInfo(nearestParent));
			if (parentElement != null) {
				return parentElement;
			}
			nearestParent = nearestParent.eContainer();
		}

		return null;
	}

	private EObject doPasteIntoCopyParent(ObjectInfo theCopyParentObjectInfo)
		throws Exception {
		PasteChildOperation copyParentProcess = getAuxiliaryChildPasteProcess(theCopyParentObjectInfo);
		copyParentProcess.paste();
		EObject pastedCopyParent = copyParentProcess.getPastedElement();
		if (pastedCopyParent != null) {
			//the direct copy parent should have been pasted correctly by now
			return doPasteInto(getPastedDirectCopyParent());
		}
		return null;
	}

	private ObjectInfo makeEmbeddedCopyParentObjectInfo(
		EObject embeddedCopyParent) {
		ObjectInfo objectInfo = (ObjectInfo) embeddedCopyParentObjectInfoMap
			.get(embeddedCopyParent);
		if (objectInfo == null) {
			objectInfo = new ObjectInfo();
			objectInfo.objCopyType = ObjectCopyType.OBJ_COPY_TYPE_PARENT;
			objectInfo.objId = getLoadedEObjectID(embeddedCopyParent);
			objectInfo.containerId = getLoadedEObjectID(embeddedCopyParent
				.eContainer());
			objectInfo.containerClass = embeddedCopyParent.eContainer()
				.eClass().getInstanceClassName();
			if (objectInfo.objId.equals(getChildObjectInfo().copyParentId) == false) {
				objectInfo.copyParentId = getChildObjectInfo().copyParentId;
			} else {
				objectInfo.copyParentId = ResourceInfoProcessor.NONE;
			}
			objectInfo.hints = ResourceInfoProcessor.NONE;
			//cache it
			embeddedCopyParentObjectInfoMap.put(embeddedCopyParent, objectInfo);
		}

		return objectInfo;
	}

	private EObject doPasteIntoCopyParent() throws Exception {

		//check if copyParentEObject exists in the target model already
		//try matching direct copy parent ID.
		EObject existingCopyParentEObject = getEObject(getChildObjectInfo().containerId);
		if (existingCopyParentEObject != null) {
			return doPasteInto(existingCopyParentEObject);
		}

		//check if the copy-parent has been
		//pasted already by a sibling paste operation that executed before us?
		EObject pastedDirectCopyParent = getPastedDirectCopyParent();
		if (pastedDirectCopyParent != null) {
			//the direct copy parent should have been pasted correctly already
			return doPasteInto(pastedDirectCopyParent);
		}

		EObject nearestParent = null;
		if (isCopyParentDirectParent() == false) {
			nearestParent = getLoadedEObject(getChildObjectInfo().containerId);
			EObject perent = nearestParent.eContainer();
			EObject root = getCopyParentEObject();
			while ((perent != null) && (perent.equals(root) == false)) {
				existingCopyParentEObject = getPastedEObject(perent);
				if (existingCopyParentEObject != null) {
					break;
				}
				nearestParent = perent;
				perent = nearestParent.eContainer();
			}
			if (existingCopyParentEObject == null) {
				//check the root itself
				existingCopyParentEObject = getPastedEObject(root);
			}
		}

		if (existingCopyParentEObject != null) {
			//the nearestParent copy parent should have been pasted correctly
			// already
			//paste the nearest-parent itself first, the paste the child into
			// it afterwards
			return doPasteIntoCopyParent(makeEmbeddedCopyParentObjectInfo(nearestParent));
		} else {
			//no parent with same ID, and the copy-parent not pasted already,
			//then try other ways to match a parent
			PasteTarget possibleParent = getSuitableParentUsingAncestry(getLoadedDirectContainerEObject()
				.eClass().getInstanceClassName());
			if (possibleParent != null) {
				return doPasteInto(possibleParent);
			} else {
				//no suitable exisiting parent then the copy-parent itself
				//needs to be pasted first
				EObject element = doPasteIntoNearestCopyParent(getCopyParentEObject());
				if (element != null) {
					//found a nearest copy parent and pasted it successfully
					return element;
				}
				//now final try: use the root copy Parent?
				return doPasteIntoCopyParent(getCopyParentObjectInfo());
			}
		}
	}

	/**
	 * Gets the target object into which we are pasting a child.
	 * 
	 * @return the parent (target) object of the paste operation
	 */
	public EObject getParentEObject() {
		return getParentPasteProcess().getEObject();
	}

	/**
	 * Gets the target object into which we are pasting a child.
	 * 
	 * @return the parent (target) object of the paste operation
	 */
	public PasteTarget getParentTarget() {
		return getParentPasteProcess().getPasteTarget();
	}

	/**
	 * Obtains the XML resource into which we are pasting.
	 * 
	 * @return the target resource
	 */
	public XMLResource getParentResource() {
		return getParentPasteProcess().getParentResource();
	}

	/**
	 * Gets an operation to be invoked after I have completed my pasting, to do
	 * some follow-up pasting.  {@link OverridePasteChildOperation}s can
	 * redefine this method to provide custom post-paste behaviour.
	 * <p>
	 * <b>IMPORTANT:</b> This function must be invoked AFTER the paste()
	 * function has been called.
	 * </p>
	 * 
	 * @return an additional operation to do more pasting
	 */
	public PasteChildOperation getPostPasteOperation() {
		return (overrideChildPasteOperation != null) ? overrideChildPasteOperation
			.getPostPasteOperation()
			: doGetPostPasteOperation();
	}

	private PasteChildOperation doGetPostPasteOperation() {
		if ((postPasteOperation == null) && (getPastedElement() != null)
			&& (getAlwaysCopyObjectPasteOperations().isEmpty() == false)) {
			postPasteOperation = new PostPasteChildOperation(this,
				getAlwaysCopyObjectPasteOperations());
		}
		return postPasteOperation;
	}

	public void paste() throws Exception {
		//check if this object has been pasted/merged already for some reason:
		//e.g, copied once because it is a copy-parent, and now we are asked
		//to copy it because it is a copyAlways
		if (getPastedEObject(getEObject()) != null) {
			setPastedElement(getEObject());
			addPastedElement(getPastedElement());
			//set post paste to a NULL operation
			postPasteOperation = PostPasteChildOperation
				.makeNullPostPasteChildOperation(this);
			return;
		}
		//handle diagrams
		if (getClipboardOperationHelper().shouldOverrideChildPasteOperation(
			getParentEObject(), getEObject())) {
			overrideChildPasteOperation = getClipboardOperationHelper()
				.getOverrideChildPasteOperation(this);
			//if the parent was not suitable for pasting a diagram, this
			// happens
			if (overrideChildPasteOperation != null) {
				overrideChildPasteOperation.paste();
				setPastedElement(overrideChildPasteOperation.getPastedElement());
			} else {
				addPasteFailuresObject(getEObject());
			}
			return;
		}

		if (hasCopyParent()) {
			setPastedElement(doPasteIntoCopyParent());
		} else {
			EObject element = null;
			//either it is not a copyAlways, or it is a copyAlways
			// whose
			//original parent didn't resolve, thus, proceed normally
			//by trying to paste in target obj
			element = doPasteInto(getParentTarget());
			
			if (element == null) {
				/*-------------
				 //failed to copy in target parent...then check if it is a copy-always and its
				 // original parent resolves in target model
				 if (isCopyAlways()) {
				 EObject resolvedCopyAlwaysParent = getEObject(getChildObjectInfo().containerId);
				 if (resolvedCopyAlwaysParent != null) {
				 //found original parent for this copyAlways object,
				 // then use it,
				 //instead of user selected parent
				 element = doPasteInto(resolvedCopyAlwaysParent);
				 }
				 }
				 -------------*/
				if ((element == null)
					&& ((getChildObjectInfo()
						.hasHint(ClipboardUtil.PASTE_TO_TARGET_PARENT)) || (isCopyAlways()))) {
					PasteTarget possibleParent = getSuitableParentUsingAncestry(getChildObjectInfo().containerClass);
					if (possibleParent != null) {
						element = doPasteInto(possibleParent);
					}
				}
			}
			setPastedElement(element);
		}

		//did we succeed?
		if (getPastedElement() != null) {
			addPastedElement(getPastedElement());
		} else {
			addPasteFailuresObject(getEObject());
		}
	}

	/**
	 * Pastes my child object into the specified object.
	 * 
	 * @param pasteIntoEObject the object to paste into
	 * @return the newly pasted object, or <code>null</code> if the paste did
	 *     not succeed
	 */
	protected EObject doPasteInto(EObject pasteIntoEObject) {
		if (pasteIntoEObject != null) {
			EReference reference = getPasteContainmentFeature(pasteIntoEObject);
			if (reference != null) {
				return doPasteInto(pasteIntoEObject, reference);
			}
		}
		return null;
	}

	/**
	 * Pastes my child object into the specified object.
	 * 
	 * @param pasteTarget the object to paste into
	 * @return the newly pasted object, or <code>null</code> if the paste did
	 *     not succeed
	 */
	protected EObject doPasteInto(PasteTarget pasteTarget) {
		if (pasteTarget != null) {
			if (pasteTarget.isResource()) {
				return doPasteInto((Resource)pasteTarget.getObject());
			} else {
				return doPasteInto((EObject)pasteTarget.getObject());
			}
		}
		return null;
	}

	/**
	 * Pastes my child object into the specified containment reference of an
	 * object.
	 * 
	 * @param pasteIntoEObject the object to paste into
	 * @param reference the containment reference to paste into
	 * @return the newly pasted object, or <code>null</code> if the paste did
	 *     not succeed
	 */
	protected EObject doPasteInto(EObject pasteIntoEObject, EReference reference) {
		EObject childElement = null;
		Object value = pasteIntoEObject.eGet(reference, true);
		if (FeatureMapUtil.isMany(pasteIntoEObject,reference)) {
			if (handleCollision(reference, (List) value, getEObject(),
				getChildObjectInfo())) {
				childElement = ClipboardSupportUtil.appendEObjectAt(
					pasteIntoEObject, reference, getEObject());
			} else if (getPastedElement() != null) {
				// our pasted element was already assigned by a merge action
				childElement = getPastedElement();
			}
		} else {  // reference is single
			if (handleCollision(reference, (EObject) value, getEObject(),
				getChildObjectInfo())) {
				childElement = ClipboardSupportUtil.setEObject(
					pasteIntoEObject, reference, getEObject());
			} else if (getPastedElement() != null) {
				// our pasted element was already assigned by a merge action
				childElement = getPastedElement();
			}
		}
		return childElement;
	}

	/**
	 * Pastes my child object into the specified resource
	 * 
	 * @param pasteIntoResource the resource to paste into
	 * @return the newly pasted object, or <code>null</code> if the paste did
	 *     not succeed
	 */
	protected EObject doPasteInto(Resource pasteIntoResource) {
		EObject childElement = null;
		if (handleCollision(null, pasteIntoResource.getContents(),
				getEObject(), getChildObjectInfo())) {
			childElement = ClipboardSupportUtil.appendEObject(
				pasteIntoResource, getEObject());
		} else if (getPastedElement() != null) {
			// our pasted element was already assigned by a merge action
			childElement = getPastedElement();
		}

		return childElement;
	}

	/**
	 * Obtains a list of operations to paste the "copy always" objects related
	 * to the object that I am pasting.  By default, these will be executed
	 * as a post-paste operation following me.
	 * 
	 * @return the copy-always object paste operations (which may be empty)
	 * 
	 * @see #getPostPasteOperation()
	 */
	protected List getAlwaysCopyObjectPasteOperations() {
		if (alwaysCopyObjectPasteOperations == null) {
			alwaysCopyObjectPasteOperations = new ArrayList();
			Iterator alwaysCopyEObjectInfoIt = getChildObjectInfo()
				.getCopyAlwaysObjectInfoList().iterator();
			while (alwaysCopyEObjectInfoIt.hasNext()) {
				getProgressMonitor().worked(WORK_UNIT);
				if (isCancelled()) {
					throwCancelException();
				}
				ObjectInfo alwaysCopyObjectInfo = (ObjectInfo) alwaysCopyEObjectInfoIt
					.next();
				if (shouldPasteAlwaysCopyObject(alwaysCopyObjectInfo)) {
					PasteChildOperation pasteOperation = getAuxiliaryChildPasteProcess(alwaysCopyObjectInfo);
					if (pasteOperation != null) {
						alwaysCopyObjectPasteOperations.add(pasteOperation);
					}
				}
			} //while always-copy
		}
		return alwaysCopyObjectPasteOperations;
	}

	/**
	 * Queries whether we should paste the specified "copy always" object
	 * associated with the element we are pasting.  This accounts for the
	 * possibility that the "copy always" object might collide with some element
	 * already in the target resource.
	 * 
	 * @param alwaysCopyObjectInfo info indicating the "copy always" object
	 * @return <code>true</code> if the "copy always" object should be pasted;
	 *      <code>false</code>, otherwise
	 */
	protected boolean shouldPasteAlwaysCopyObject(
		ObjectInfo alwaysCopyObjectInfo) {
		//for a copy always object that exists in the model already, check if
		// this
		//kind of object is "critical", then we need to paste it, note that we
		// are using
		//the exisiting object to query for PasteOption since what matter is
		// the type
		//and not the particular instance itself
		EObject existingObject = getEObject(alwaysCopyObjectInfo.objId);
		EObject loadedEObject = getLoadedEObject(alwaysCopyObjectInfo.objId);
		return ((existingObject == null) || (getClipboardOperationHelper()
			.getPasteCollisionAction(loadedEObject.eClass()) == PasteAction.ADD));

	}

	private PasteTarget checkPotentialParent(PasteTarget potentialParent,
		String preferredTypeName, boolean strictMatch) {
		//match parent on type, if not then try ability to contain the child
		if ((potentialParent.getObject() instanceof EAnnotation) == false) {
			if (potentialParent.isResource()) {
				if (preferredTypeName == null || strictMatch == false) {
					return potentialParent;
				}
			} else {
				EObject potentialParentObject = (EObject)potentialParent.getObject();
				if (potentialParentObject.eClass().getInstanceClassName().equals(
					preferredTypeName)) {
					return potentialParent;
				} else if ((strictMatch == false)
					&& (getPasteContainmentFeature(potentialParentObject) != null)) {
					return potentialParent;
				}
			}
		}
		return null;
	}

	/**
	 * Consults the clipboard support to get the best-match containment feature
	 * of the specified parent object to paste my child object into, according
	 * to the copied object's original containment feature.
	 * 
	 * @param parentEObject the parent to paste into
	 * @return the most appropriate containment feature for the child, or
	 *     <code>null</code> if the parent cannot contain the child at all
	 */
	public EReference getPasteContainmentFeature(EObject parentEObject) {
		return ClipboardSupportUtil.getPasteContainmentFeature(parentEObject,
			getEObject(), getContainmentFeature());
	}

	/**
	 * Handles the collision of an <code>eObject</code> that is to be pasted
	 * into the specified values of a reference, where it collides with one or
	 * more of these existing elements.  This may involve, among other things,
	 * renaming the object to be pasted in order to make its name unique.
	 * 
	 * @param reference the many containment reference into which we want to
	 *     paste the <code>eObject</code>
	 * @param list the current value (list of {@link EObject}s) of the
	 *     containment reference
	 * @param eObject the object that we want to paste, which collides with one
	 *     or more elements in the <code>list</code>
	 * @param eObjectInfo the <code>eObject</code>'s object info meta-data
	 * 
	 * @return <code>true</code> if the collision was resolved so that we
	 *     can go ahead and paste the <code>eObject</code> as intended;
	 *     false, otherwise
	 */
	protected boolean handleCollision(EReference reference, List list,
		EObject eObject, ObjectInfo eObjectInfo) {

		PasteAction pasteCollisionAction = (eObjectInfo.objCopyType
			.equals(ObjectCopyType.OBJ_COPY_TYPE_ALWAYS)) ? PasteAction.CLONE
			: getClipboardOperationHelper().getPasteCollisionAction(
				eObject.eClass());

		if (pasteCollisionAction == PasteAction.DISCARD) {
			//Do not paste. Such elements are typically copied in order to find
			// an appropriate parent
			return false;
		}

		if (list.isEmpty()) {
			return true;
		}

		EObject object = null;
		Iterator it = list.iterator();
		while (it.hasNext()) {
			object = (EObject) it.next();
			if (ClipboardSupportUtil.hasNameCollision(object, eObject)) {
				if (pasteCollisionAction.equals(PasteAction.ADD)) {
					//Create new element with different name
					ClipboardSupportUtil.rename(list, eObject, COPY);
					return true; //insert child
				} else if (pasteCollisionAction.equals(PasteAction.REPLACE)) {
					if (canBeReplaced(object)) {
						//Remove collision element, if any. Create new element
						// in the same location.
						if (reference == null) {
							// paste target is the resouce
							ClipboardSupportUtil.destroyEObjectInResource(object);
						} else {
							ClipboardSupportUtil.destroyEObjectInCollection(object
								.eContainer(), reference, object);
						}
						return true;
					}
					return false; //ignore it since we can't replace the other
				} else if (pasteCollisionAction.equals(PasteAction.IGNORE)) {
					//Leave existing element, if found. Otherwise create new
					// element.
					return false;
				} else if (pasteCollisionAction.equals(PasteAction.MERGE)) {
					mergeEObjects(eObjectInfo
						.hasHint(ClipboardUtil.MERGE_HINT_WEAK), object,
						eObject, eObjectInfo);
					
					// record the existing object that we collided with as the
					//    pasted element, so that we will know that the logical
					//    paste operation succeeded
					setPastedElement(object);
					return false; //don't insert child since we merged it
				} else if (pasteCollisionAction.equals(PasteAction.CLONE)) {
					//Always copy, even if indirectly selected.
					//Y.L. treat it as add???
					ClipboardSupportUtil.rename(list, eObject, COPY);
					return true; //insert child
				}
			} //hasNameCollision
		} //while
		return true; //insert child
	}

	/**
	 * Handles the collision of an <code>eObject</code> that is to be pasted
	 * into the specified scalar reference, where it collides with the
	 * existing element.
	 * 
	 * @param reference the scalar containment reference into which we want to
	 *     paste the <code>eObject</code>
	 * @param object the current value of the containment reference
	 * @param eObject the object that we want to paste, which collides with one
	 *     or more elements in the <code>list</code>
	 * @param eObjectInfo the <code>eObject</code>'s object info meta-data
	 * 
	 * @return <code>true</code> if the collision was resolved so that we
	 *     can go ahead and paste the <code>eObject</code> as intended;
	 *     false, otherwise
	 */
	protected boolean handleCollision(EReference reference, EObject object,
		EObject eObject, ObjectInfo eObjectInfo) {

		PasteAction pasteCollisionAction = (eObjectInfo.objCopyType
			.equals(ObjectCopyType.OBJ_COPY_TYPE_ALWAYS)) ? PasteAction.CLONE
			: getClipboardOperationHelper().getPasteCollisionAction(
				eObject.eClass());

		if (pasteCollisionAction.equals(PasteAction.DISCARD)) {
			//Do not paste. Such elements are typically copied in order to find
			// an appropriate parent
			return false;
		}

		if (object == null) {
			return true;
		}

		if (pasteCollisionAction.equals(PasteAction.ADD)) {
			if (canBeReplaced(object)) {
				//Create new element with different name
				//treat as Replace, since it is a single ref.???
				ClipboardSupportUtil.destroyEObject(object.eContainer(), reference);
				return true;
			}
			return false;
		} else if (pasteCollisionAction.equals(PasteAction.REPLACE)) {
			if (canBeReplaced(object)) {
				//Remove collision element, if any. Create new element in the
				// same location.
				ClipboardSupportUtil.destroyEObject(object.eContainer(), reference);
				return true;
			}
			return false;
		} else if (pasteCollisionAction.equals(PasteAction.IGNORE)) {
			//Leave existing element, if found. Otherwise create new element.
			return false;
		} else if (pasteCollisionAction.equals(PasteAction.MERGE)) {
			mergeEObjects(eObjectInfo.hasHint(ClipboardUtil.MERGE_HINT_WEAK),
				object, eObject, eObjectInfo);
			
			// record the existing object that we collided with as the
			//    pasted element, so that we will know that the logical
			//    paste operation succeeded
			setPastedElement(object);
			return false; //don't insert child since we merged it
		} else if (pasteCollisionAction.equals(PasteAction.CLONE)) {
			if (canBeReplaced(object)) {
				//Always copy, even if indirectly selected.
				//treat as Replace???
				ClipboardSupportUtil.destroyEObject(object.eContainer(), reference);
				return true;
			}
			return false;
		}
		return true; //insert child
	}

	/**
	 * Merges the elements to be pasted into a many containment reference with
	 * those objects already in that reference with which they collide.  This
	 * is used in the resolution of
	 * {@linkplain #handleCollision(EReference, List, EObject, ObjectInfo) collisions}
	 * by {@linkplain PasteAction#MERGE merging}.
	 * 
	 * @param reference the many containment reference to merge objects into
	 * @param targetObjectList the existing objects in the reference collection
	 * @param objectList the objects that we need to merge into the targets
	 * @param objectInfo object info
	 * 
	 * @return the merged lists
	 * 
	 * @see #handleCollision(EReference, List, EObject, ObjectInfo)
	 * @see PasteAction#MERGE
	 */
	protected List mergeLists(EReference reference, List targetObjectList,
		List objectList, ObjectInfo objectInfo) {
		//we did this because the original objectList is unmodifiable
		List mergedList = new ArrayList();
		mergedList.addAll(targetObjectList);
		//Sanity: no point to merge a list into itself
		if (targetObjectList.equals(objectList)) {
			return mergedList;
		}
		EObject eObject = null;
		Iterator childIt = objectList.iterator();
		while (childIt.hasNext()) {
			eObject = (EObject) childIt.next();
			if (handleCollision(reference, mergedList, eObject, objectInfo)) {
				mergedList.add(eObject);
			}
		}
		return mergedList;
	}

	/**
	 * Merges an elements to be pasted with an existing element that collides.
	 * 
	 * @param weakMerge <code>true</code> to perform a
	 *     {@linkplain ClipboardUtil#MERGE_HINT_WEAK weak merge};
	 *     <code>false</code> for a
	 *     {@linkplain ClipboardUtil#MERGE_HINT_STRONG strong merge}
	 * @param targetEObject the existing object to merge into
	 * @param eObject the object that we need to merge into the target
	 * @param objectInfo the <code>eObject</code>'s object info
	 * 
	 * @see #handleCollision(EReference, List, EObject, ObjectInfo)
	 * @see #handleCollision(EReference, EObject, EObject, ObjectInfo)
	 * @see PasteAction#MERGE
	 */
	protected void mergeEObjects(boolean weakMerge, EObject targetEObject,
		EObject eObject, ObjectInfo objectInfo) {
		//Sanity: no point to merge an object into itself
		if (targetEObject.equals(eObject)) {
			return;
		}

		MergedEObjectInfo info = (MergedEObjectInfo) getAllMergedElementsMap()
			.get(eObject);
		//if it has been merged in the very same target, then just return
		if ((info != null) && (info.targetEObjects.contains(targetEObject))) {
			return;
		}

		//no record at all, then create new one
		if (info == null) {
			info = new MergedEObjectInfo();
			info.mergedEObject = eObject;
			info.mergedEObjectID = getLoadedEObjectID(eObject);
			addMergedElementEntry(eObject, info);
		}

		//In the Clipboard Design document this is how it defines Merge types:
		//Weak merges: preserve scalar data in the target element's slots. Only
		// element vector slots are merged.
		//Strong merges: overwrite scalar data in the target element's slots.
		// Element vector slots are also merged.
		//Our interpretation is that scalar == attributes, whereas vector ==
		// references.

		//keep track of what we merged, we need this to resolve refs at the
		// post-paste.
		info.targetEObjects.add(targetEObject);

		//handle refs first
		Iterator it = eObject.eClass().getEAllReferences().iterator();
		EReference reference = null;
		while (it.hasNext()) {
			reference = (EReference) it.next();
			if (reference.isChangeable()) {
				Object unresolvedEObjectValue = eObject.eGet(reference, false);
				if (FeatureMapUtil.isMany(eObject, reference)) {
					List childList = (List) unresolvedEObjectValue;
					if (childList.isEmpty() == false) {
						List targetObjectList = (List) targetEObject.eGet(
							reference, true);
						List mergedList = mergeLists(reference,
							targetObjectList, childList, objectInfo);
						
						// CWD: Don't remove the original -- we're merging!
						// mergedList.removeAll(targetObjectList);
						
						ClipboardSupportUtil.setEObjectList(
							targetEObject, reference, mergedList);
					}
				} else if (unresolvedEObjectValue != null) {
					EObject targetObjectValue = (EObject) targetEObject.eGet(
						reference, true);
					if (handleCollision(reference, targetObjectValue,
						(EObject) unresolvedEObjectValue, objectInfo)) {
						ClipboardSupportUtil.setEObject(
							targetEObject, reference,
							(EObject) unresolvedEObjectValue);
					}
				}
			} //reference.isChangeable()
		} //while

		//now handle attribs if it is a strong merge (default)
		if (weakMerge == false) {
			it = eObject.eClass().getEAllAttributes().iterator();
			EAttribute attribute = null;
			while (it.hasNext()) {
				attribute = (EAttribute) it.next();
				ClipboardSupportUtil.setEAttribute(targetEObject, attribute,
					eObject.eGet(attribute));
			}
		}
	}

	/**
	 * Gets the object info meta-data for the object that I am pasting.
	 * 
	 * @return my child object's meta-data
	 */
	protected ObjectInfo getChildObjectInfo() {
		return childObjectInfo;
	}

	/**
	 * Gets the child paste operation that I am overriding or extending, if I am
	 * an {@linkplain #isAuxiliaryOperation() auxiliary} paste operation.
	 * 
	 * @return my main child paste process, or <code>null</code> if none
	 */
	protected PasteChildOperation getMainChildPasteProcess() {
		return mainChildPasteProcess;
	}

	/**
	 * Queries whether I am an auxiliary operation.
	 * 
	 * @return <code>true</code> if I am an auxiliary paste operation;
	 *      <code>false</code>, otherwise
	 */
	public boolean isAuxiliaryOperation() {
		return (getMainChildPasteProcess() != null);
	}

	/**
	 * Gets the object meta-data for my copy object's parent, if it was
	 * serialized along with the child.
	 * 
	 * @return my copy parent's object info, or <code>null</code> if none
	 */
	protected ObjectInfo getCopyParentObjectInfo() {
		if (copyParentObjectInfo == null) {
			copyParentObjectInfo = (ObjectInfo) getResourceInfo().objects
				.get(getChildObjectInfo().copyParentId);
		}
		return copyParentObjectInfo;
	}

	/**
	 * Queries whether my copy object's parent object that was copied along with
	 * it was a direct container or not.
	 * 
	 * @return <code>true</code> if my copy object's parent was copied and was
	 *    its direct container; <code>false</code>, otherwise
	 */
	protected boolean isCopyParentDirectParent() {
		return getChildObjectInfo().containerId
			.equals(getCopyParentObjectInfo().objId);
	}

	/**
	 * After pasting has completed, records the element that I have successfully
	 * (or not) pasted from the original copy.
	 * 
	 * @param pastedElement the pasted element, or <code>null</code> if pasting
	 *     failed
	 */
	protected void setPastedElement(EObject pastedElement) {
		this.pastedElement = pastedElement;
	}

	/**
	 * Queries whether the specified object that already exists in the target
	 * resource can be replaced by an element being pasted, in case of a
	 * collision that is resolved by
	 * {@linkplain PasteAction#REPLACE replacement}.
	 * 
	 * @param eObject an object in the target model that might be replaced
	 * @return <code>true</code> if it can be replaced;
	 *      <code>false</code>, otherwise
	 * 
	 * @see PasteAction#REPLACE
	 */
	protected boolean canBeReplaced(EObject eObject) {
		if (!getParentTarget().isResource()) {
			// we now know that the target is an EObject
			if (eObject.equals(getParentEObject())) {
				return false;
			}
			if (ClipboardSupportUtil.isChild(eObject, getParentEObject())) {
				return false;
			}
		}
		return true;
	}

}