/*******************************************************************************
 * Copyright (c) 2012, 2017 Obeo 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:
 *     Obeo - initial API and implementation
 *     Philip Langer - fixes for bug 413520
 *******************************************************************************/
package org.eclipse.emf.compare.merge;

import static com.google.common.collect.Iterators.filter;
import static org.eclipse.emf.compare.merge.IMergeCriterion.NONE;
import static org.eclipse.emf.compare.utils.ReferenceUtil.safeEGet;
import static org.eclipse.emf.compare.utils.ReferenceUtil.safeEIsSet;
import static org.eclipse.emf.compare.utils.ReferenceUtil.safeESet;

import com.google.common.collect.Iterators;

import java.util.Iterator;
import java.util.List;

import org.eclipse.emf.common.util.EList;
import org.eclipse.emf.compare.Comparison;
import org.eclipse.emf.compare.Diff;
import org.eclipse.emf.compare.DifferenceSource;
import org.eclipse.emf.compare.Match;
import org.eclipse.emf.compare.ReferenceChange;
import org.eclipse.emf.compare.internal.utils.DiffUtil;
import org.eclipse.emf.compare.utils.IEqualityHelper;
import org.eclipse.emf.compare.utils.ReferenceUtil;
import org.eclipse.emf.ecore.EObject;
import org.eclipse.emf.ecore.EReference;
import org.eclipse.emf.ecore.EStructuralFeature;
import org.eclipse.emf.ecore.resource.Resource;
import org.eclipse.emf.ecore.util.EcoreUtil;
import org.eclipse.emf.ecore.xmi.XMIResource;

/**
 * This specific implementation of {@link AbstractMerger} will be used to merge reference changes.
 * 
 * @author <a href="mailto:laurent.goubet@obeo.fr">Laurent Goubet</a>
 */
public class ReferenceChangeMerger extends AbstractMerger {
	/**
	 * {@inheritDoc}
	 * 
	 * @see org.eclipse.emf.compare.merge.IMerger#isMergerFor(org.eclipse.emf.compare.Diff)
	 */
	public boolean isMergerFor(Diff target) {
		return target instanceof ReferenceChange;
	}

	@Override
	public boolean apply(IMergeCriterion criterion) {
		return criterion == null || criterion == NONE;
	}

	/**
	 * Merge the given difference rejecting it.
	 * 
	 * @param diff
	 *            The difference to merge.
	 * @param rightToLeft
	 *            The direction of the merge.
	 */
	@Override
	protected void reject(final Diff diff, boolean rightToLeft) {
		ReferenceChange referenceChange = (ReferenceChange)diff;
		DifferenceSource source = referenceChange.getSource();
		switch (referenceChange.getKind()) {
			case ADD:
				// We have a ADD on left, thus nothing in right. We need to revert the addition
				removeFromTarget(referenceChange, rightToLeft);
				break;
			case DELETE:
				// DELETE in the left, thus an element in right. We need to re-create that element
				addInTarget(referenceChange, rightToLeft);
				break;
			case MOVE:
				moveElement(referenceChange, rightToLeft);
				break;
			case CHANGE:
				EObject container = null;
				if (source == DifferenceSource.LEFT) {
					container = referenceChange.getMatch().getLeft();

				} else {
					container = referenceChange.getMatch().getRight();
				}
				// Is it an unset?
				if (container != null) {
					final EObject leftValue = (EObject)safeEGet(container, referenceChange.getReference());
					if (leftValue == null) {
						// Value has been unset in the right, and we are merging towards right.
						// We need to re-add this element
						addInTarget(referenceChange, rightToLeft);
					} else {
						// We'll actually need to "reset" this reference to its original value
						resetInTarget(referenceChange, rightToLeft);
					}
				} else {
					// we have no left, and the source is on the left. Can only be an unset
					addInTarget(referenceChange, rightToLeft);
				}
				break;
			default:
				break;
		}
	}

	/**
	 * Merge the given difference accepting it.
	 * 
	 * @param diff
	 *            The difference to merge.
	 * @param rightToLeft
	 *            The direction of the merge.
	 */
	@Override
	protected void accept(final Diff diff, boolean rightToLeft) {
		ReferenceChange referenceChange = (ReferenceChange)diff;
		DifferenceSource source = diff.getSource();
		switch (diff.getKind()) {
			case ADD:
				// Create the same element in right
				addInTarget(referenceChange, rightToLeft);
				break;
			case DELETE:
				// Delete that same element from right
				removeFromTarget(referenceChange, rightToLeft);
				break;
			case MOVE:
				moveElement(referenceChange, rightToLeft);
				break;
			case CHANGE:
				EObject container = null;
				if (source == DifferenceSource.LEFT) {
					container = referenceChange.getMatch().getLeft();
				} else {
					container = referenceChange.getMatch().getRight();
				}
				// Is it an unset?
				if (container != null) {
					final EObject leftValue = (EObject)safeEGet(container, referenceChange.getReference());
					if (leftValue == null) {
						removeFromTarget(referenceChange, rightToLeft);
					} else {
						addInTarget(referenceChange, rightToLeft);
					}
				} else {
					// we have no left, and the source is on the left. Can only be an unset
					removeFromTarget(referenceChange, rightToLeft);
				}
				break;
			default:
				break;
		}
	}

	/**
	 * This will be called when trying to copy a "MOVE" diff.
	 * 
	 * @param diff
	 *            The diff we are currently merging.
	 * @param rightToLeft
	 *            Whether we should move the value in the left or right side.
	 */
	protected void moveElement(ReferenceChange diff, boolean rightToLeft) {
		final Comparison comparison = diff.getMatch().getComparison();
		final Match valueMatch = comparison.getMatch(diff.getValue());
		final EReference reference = diff.getReference();

		final EObject expectedContainer;
		if (reference.isContainment()) {
			/*
			 * We cannot "trust" the holding match (getMatch) in this case. However, "valueMatch" cannot be
			 * null : we cannot have detected a move if the moved element is not matched on both sides. Use
			 * that information to retrieve the proper "target" container.
			 */
			final Match targetContainerMatch;
			// If it exists, use the source side's container as reference
			if (rightToLeft && valueMatch.getRight() != null) {
				targetContainerMatch = comparison.getMatch(valueMatch.getRight().eContainer());
			} else if (!rightToLeft && valueMatch.getLeft() != null) {
				targetContainerMatch = comparison.getMatch(valueMatch.getLeft().eContainer());
			} else {
				// Otherwise, the value we're moving on one side has been removed from its source side.
				targetContainerMatch = comparison.getMatch(valueMatch.getOrigin().eContainer());
			}
			if (rightToLeft) {
				expectedContainer = targetContainerMatch.getLeft();
			} else {
				expectedContainer = targetContainerMatch.getRight();
			}
		} else if (rightToLeft) {
			expectedContainer = diff.getMatch().getLeft();
		} else {
			expectedContainer = diff.getMatch().getRight();
		}
		if (expectedContainer == null) {
			throw new IllegalStateException(
					"Couldn't move element because its parent hasn't been merged yet: " + diff); //$NON-NLS-1$
		}

		final EObject expectedValue;
		if (valueMatch == null) {
			// The value being moved is out of the scope
			/*
			 * Note : there should not be a way to end up with a "move" for an out of scope value : a move can
			 * only be detected if the object is matched on both sides, otherwise all we can see is "add" and
			 * "delete"... Is this "fallback" code even reachable? If so, how?
			 */
			// We need to look it up
			if (reference.isMany()) {
				@SuppressWarnings("unchecked")
				final List<EObject> targetList = (List<EObject>)safeEGet(expectedContainer, reference);
				expectedValue = findMatchIn(comparison, targetList, diff.getValue());
			} else {
				expectedValue = (EObject)safeEGet(expectedContainer, reference);
			}
		} else {
			if (rightToLeft) {
				expectedValue = valueMatch.getLeft();
			} else {
				expectedValue = valueMatch.getRight();
			}
		}
		// If expectedValue is null at this point, we have to copy the value from the other side.
		// It can happens with a move between the ancestor and one side, while the other side doesn't has the
		// value.
		if (expectedValue == null) {
			addInTarget(diff, rightToLeft);
		} else {
			// We now know the target container, target reference and target value.
			doMove(diff, comparison, expectedContainer, expectedValue, rightToLeft);
		}
	}

	/**
	 * This will do the actual work of moving the element into its reference. All sanity checks were made in
	 * {@link #moveElement(boolean)} and no more verification will be made here.
	 * 
	 * @param diff
	 *            The diff we are currently merging.
	 * @param comparison
	 *            Comparison holding this Diff.
	 * @param expectedContainer
	 *            The container in which we are reorganizing a reference.
	 * @param expectedValue
	 *            The value that is to be moved within its reference.
	 * @param rightToLeft
	 *            Whether we should move the value in the left or right side.
	 */
	@SuppressWarnings("unchecked")
	protected void doMove(ReferenceChange diff, Comparison comparison, EObject expectedContainer,
			EObject expectedValue, boolean rightToLeft) {
		final EReference reference = getMoveTargetReference(comparison, diff, rightToLeft);

		if (reference.isMany()) {
			// Element to move cannot be part of the LCS... or there would not be a MOVE diff
			int insertionIndex = findInsertionIndex(comparison, diff, rightToLeft);

			/*
			 * However, it could still have been located "before" its new index, in which case we need to take
			 * it into account.
			 */
			final List<EObject> targetList = (List<EObject>)safeEGet(expectedContainer, reference);
			final int currentIndex = targetList.indexOf(expectedValue);
			if (insertionIndex > currentIndex && currentIndex >= 0) {
				insertionIndex--;
			}

			if (currentIndex == -1) {
				// happens for container changes for example.
				if (!reference.isContainment()) {
					targetList.remove(expectedValue);
				}
				if (insertionIndex < 0 || insertionIndex > targetList.size()) {
					targetList.add(expectedValue);
				} else {
					targetList.add(insertionIndex, expectedValue);
				}
			} else if (targetList instanceof EList<?>) {
				if (insertionIndex < 0 || insertionIndex >= targetList.size()) {
					((EList<EObject>)targetList).move(targetList.size() - 1, expectedValue);
				} else {
					((EList<EObject>)targetList).move(insertionIndex, expectedValue);
				}
			} else {
				targetList.remove(expectedValue);
				if (insertionIndex < 0 || insertionIndex >= targetList.size()) {
					targetList.add(expectedValue);
				} else {
					targetList.add(insertionIndex, expectedValue);
				}
			}
		} else {
			safeESet(expectedContainer, reference, expectedValue);
		}
	}

	/**
	 * Returns the reference of the target container in case of a MOVE Diff.
	 * 
	 * @param comparison
	 *            the comparison object holding the given Diff.
	 * @param diff
	 *            the given Diff.
	 * @param rightToLeft
	 *            whether we should move the value in the left or right side.
	 * @return the reference of the target container in case of a MOVE Diff.
	 */
	private EReference getMoveTargetReference(Comparison comparison, ReferenceChange diff,
			boolean rightToLeft) {
		final EReference reference;
		final DifferenceSource source = diff.getSource();
		final Match valueMatch = comparison.getMatch(diff.getValue());
		if (!diff.getReference().isContainment() || valueMatch == null) {
			reference = diff.getReference();
		} else if (rightToLeft && source == DifferenceSource.LEFT) {
			EObject sourceValue = valueMatch.getRight();
			if (sourceValue == null) {
				sourceValue = valueMatch.getOrigin();
			}
			EStructuralFeature feature = sourceValue.eContainingFeature();
			if (feature instanceof EReference) {
				reference = (EReference)feature;
			} else {
				// FIXME Manage this case. See javadoc of eContainingFeature. This is possible and will happen
				// with feature maps. http:
				// //download.eclipse.org/modeling/emf/emf/javadoc/2.8.0/org/eclipse/emf/ecore/EObject.html#eContainingFeature%28%29
				reference = diff.getReference();
			}
		} else if (!rightToLeft && source == DifferenceSource.RIGHT) {
			EObject sourceValue = valueMatch.getLeft();
			if (sourceValue == null) {
				sourceValue = valueMatch.getOrigin();
			}
			EStructuralFeature feature = sourceValue.eContainingFeature();
			if (feature instanceof EReference) {
				reference = (EReference)feature;
			} else {
				// FIXME Manage this case. See javadoc of eContainingFeature. This is possible and will happen
				// with feature maps. http:
				// //download.eclipse.org/modeling/emf/emf/javadoc/2.8.0/org/eclipse/emf/ecore/EObject.html#eContainingFeature%28%29
				reference = diff.getReference();
			}
		} else {
			reference = diff.getReference();
		}
		return reference;
	}

	/**
	 * This will be called when we need to create an element in the target side.
	 * <p>
	 * All necessary sanity checks have been made to ensure that the current operation is one that should
	 * create an object in its side or add an objet to a reference. In other words, either :
	 * <ul>
	 * <li>We are copying from right to left and
	 * <ul>
	 * <li>we are copying an addition to the right side (we need to create the same object in the left), or
	 * </li>
	 * <li>we are copying a deletion from the left side (we need to revert the deletion).</li>
	 * </ul>
	 * </li>
	 * <li>We are copying from left to right and
	 * <ul>
	 * <li>we are copying a deletion from the right side (we need to revert the deletion), or</li>
	 * <li>we are copying an addition to the left side (we need to create the same object in the right).</li>
	 * </ul>
	 * </li>
	 * </ul>
	 * </p>
	 * 
	 * @param diff
	 *            The diff we are currently merging.
	 * @param rightToLeft
	 *            Tells us whether we are to add an object on the left or right side.
	 */
	@SuppressWarnings("unchecked")
	protected void addInTarget(ReferenceChange diff, boolean rightToLeft) {
		final Match match = diff.getMatch();
		final EObject expectedContainer;
		if (rightToLeft) {
			expectedContainer = match.getLeft();
		} else {
			expectedContainer = match.getRight();
		}

		if (expectedContainer == null) {
			throw new IllegalStateException(
					"Couldn't add in target because its parent hasn't been merged yet: " + diff); //$NON-NLS-1$
		}

		final Comparison comparison = match.getComparison();
		final EReference reference = diff.getReference();
		final EObject expectedValue;
		final Match valueMatch = comparison.getMatch(diff.getValue());
		boolean needXmiId = false;
		if (valueMatch == null) {
			// This is an out of scope value.
			if (diff.getValue().eIsProxy()) {
				// Copy the proxy
				expectedValue = EcoreUtil.copy(diff.getValue());
			} else {
				// Use the same value.
				expectedValue = diff.getValue();
			}
		} else if (rightToLeft) {
			if (valueMatch.getLeft() == null) {
				expectedValue = createCopy(diff.getValue());
				valueMatch.setLeft(expectedValue);
				needXmiId = true;
			} else {
				expectedValue = valueMatch.getLeft();
			}
		} else {
			if (valueMatch.getRight() == null) {
				expectedValue = createCopy(diff.getValue());
				valueMatch.setRight(expectedValue);
				needXmiId = true;
			} else {
				expectedValue = valueMatch.getRight();
			}
		}

		// We have the container, reference and value. We need to know the insertion index.
		if (reference.isMany()) {
			final int insertionIndex = findInsertionIndex(comparison, diff, rightToLeft);

			final List<EObject> targetList = (List<EObject>)safeEGet(expectedContainer, reference);
			addAt(targetList, expectedValue, insertionIndex);
		} else {
			safeESet(expectedContainer, reference, expectedValue);
		}

		if (needXmiId) {
			// Copy XMI ID when applicable.
			final Resource initialResource = diff.getValue().eResource();
			final Resource targetResource = expectedContainer.eResource();
			if (initialResource instanceof XMIResource && targetResource instanceof XMIResource) {
				((XMIResource)targetResource).setID(expectedValue,
						((XMIResource)initialResource).getID(diff.getValue()));
			}
		}

		checkImpliedDiffsOrdering(diff, rightToLeft);
	}

	/**
	 * This will be called when we need to remove an element from the target side.
	 * <p>
	 * All necessary sanity checks have been made to ensure that the current operation is one that should
	 * delete an object. In other words, we are :
	 * <ul>
	 * <li>Copying from right to left and either
	 * <ul>
	 * <li>we are copying a deletion from the right side (we need to remove the same object in the left) or,
	 * </li>
	 * <li>we are copying an addition to the left side (we need to revert the addition).</li>
	 * </ul>
	 * </li>
	 * <li>Copying from left to right and either
	 * <ul>
	 * <li>we are copying an addition to the right side (we need to revert the addition), or.</li>
	 * <li>we are copying a deletion from the left side (we need to remove the same object in the right).</li>
	 * </ul>
	 * </li>
	 * </ul>
	 * </p>
	 * 
	 * @param diff
	 *            The diff we are currently merging.
	 * @param rightToLeft
	 *            Tells us whether we are to add an object on the left or right side.
	 */
	@SuppressWarnings("unchecked")
	protected void removeFromTarget(ReferenceChange diff, boolean rightToLeft) {
		final Match match = diff.getMatch();
		final EReference reference = diff.getReference();
		final EObject currentContainer;
		if (rightToLeft) {
			currentContainer = match.getLeft();
		} else {
			currentContainer = match.getRight();
		}
		final Comparison comparison = match.getComparison();
		final Match valueMatch = comparison.getMatch(diff.getValue());

		if (currentContainer == null) {
			// Nothing to do, parent already removed
			return;
		}

		final EObject expectedValue;
		if (valueMatch == null) {
			// value is out of the scope... we need to look it up
			if (reference.isMany()) {
				final List<EObject> targetList = (List<EObject>)safeEGet(currentContainer, reference);
				expectedValue = findMatchIn(comparison, targetList, diff.getValue());
			} else {
				// the value will not be needed anyway
				expectedValue = null;
			}
		} else if (rightToLeft) {
			expectedValue = valueMatch.getLeft();
		} else {
			expectedValue = valueMatch.getRight();
		}

		// We have the container, reference and value to remove. Expected value can be null when the
		// deletion was made on both side (i.e. a pseudo delete)
		if (reference.isContainment() && expectedValue != null) {
			EcoreUtil.remove(expectedValue);
			if (rightToLeft && valueMatch != null) {
				valueMatch.setLeft(null);
			} else if (valueMatch != null) {
				valueMatch.setRight(null);
			}
			// TODO remove dangling? remove empty Match?
		} else if (reference.isMany()) {
			/*
			 * TODO if the same value appears twice, should we try and find the one that has actually been
			 * deleted? Can it happen? For now, remove the first occurence we find.
			 */
			final List<EObject> targetList = (List<EObject>)safeEGet(currentContainer, reference);
			targetList.remove(expectedValue);
		} else {
			currentContainer.eUnset(reference);
		}
	}

	/**
	 * This will be called by the merge operations in order to reset a reference to its original value, be
	 * that the left or right side.
	 * <p>
	 * Should never be called on multi-valued references.
	 * </p>
	 * 
	 * @param diff
	 *            The diff we are currently merging.
	 * @param rightToLeft
	 *            Tells us the direction of this merge operation.
	 */
	protected void resetInTarget(ReferenceChange diff, boolean rightToLeft) {
		final Match match = diff.getMatch();
		final EReference reference = diff.getReference();
		final EObject targetContainer;
		if (rightToLeft) {
			targetContainer = match.getLeft();
		} else {
			targetContainer = match.getRight();
		}

		final EObject originContainer;
		if (match.getComparison().isThreeWay()) {
			originContainer = match.getOrigin();
		} else if (rightToLeft) {
			originContainer = match.getRight();
		} else {
			originContainer = match.getLeft();
		}

		if (originContainer == null || !safeEIsSet(originContainer, reference)) {
			targetContainer.eUnset(reference);
		} else {
			final EObject originalValue = (EObject)safeEGet(originContainer, reference);
			final Match valueMatch = match.getComparison().getMatch(originalValue);
			final EObject expectedValue;
			if (valueMatch == null) {
				// Value is out of the scope, use it as-is
				expectedValue = originalValue;
			} else if (rightToLeft) {
				expectedValue = valueMatch.getLeft();
			} else {
				expectedValue = valueMatch.getRight();
			}
			safeESet(targetContainer, reference, expectedValue);
		}
	}

	/**
	 * In the case of many-to-many eOpposite references, EMF will simply report the difference made on one
	 * side of the equivalence to the other, without considering ordering in any way. In such cases, we'll
	 * iterate over our equivalences after the merge, and double-check the ordering ourselves, fixing it as
	 * needed.
	 * <p>
	 * Note that both implied and equivalent diffs will be double-checked from here.
	 * </p>
	 * 
	 * @param diff
	 *            The diff we are currently merging.
	 * @param rightToLeft
	 *            Direction of the merge.
	 * @since 3.1
	 */
	protected void checkImpliedDiffsOrdering(ReferenceChange diff, boolean rightToLeft) {
		final EReference reference = diff.getReference();
		final List<Diff> mergedImplications;
		if (isAccepting(diff, rightToLeft)) {
			mergedImplications = diff.getImplies();
		} else {
			mergedImplications = diff.getImpliedBy();
		}

		Iterator<Diff> impliedDiffs = mergedImplications.iterator();
		if (reference.isMany() && diff.getEquivalence() != null) {
			impliedDiffs = Iterators.concat(impliedDiffs, diff.getEquivalence().getDifferences().iterator());
		}
		final Iterator<ReferenceChange> impliedReferenceChanges = filter(impliedDiffs, ReferenceChange.class);

		while (impliedReferenceChanges.hasNext()) {
			final ReferenceChange implied = impliedReferenceChanges.next();
			if (implied != diff && isInTerminalState(implied)) {
				if (implied.getReference().isMany() && isAdd(implied, rightToLeft)) {
					internalCheckOrdering(implied, rightToLeft);
					checkImpliedDiffsOrdering(implied, rightToLeft);
				}
			}
		}
	}

	/**
	 * Checks a particular difference for the ordering of its target values. This will be used to double-check
	 * that equivalent differences haven't been "broken" by EMF by not preserving their value order.
	 * <p>
	 * Should only be used on <u>merged</u> differences which target <u>many-valued</u> references.
	 * </p>
	 * 
	 * @param diff
	 *            The diff that is to be checked.
	 * @param rightToLeft
	 *            Direction of the merge that took place.
	 */
	private void internalCheckOrdering(ReferenceChange diff, boolean rightToLeft) {
		final EStructuralFeature feature = diff.getReference();
		final EObject value = diff.getValue();
		final Match match = diff.getMatch();
		final Comparison comparison = match.getComparison();
		final Match valueMatch = comparison.getMatch(value);

		final EObject sourceContainer;
		final EObject targetContainer;
		final EObject newValue;
		if (rightToLeft) {
			sourceContainer = match.getRight();
			targetContainer = match.getLeft();
			newValue = valueMatch.getLeft();
		} else {
			sourceContainer = match.getLeft();
			targetContainer = match.getRight();
			newValue = valueMatch.getRight();
		}

		final List<Object> sourceList = ReferenceUtil.getAsList(sourceContainer, feature);
		final List<Object> targetList = ReferenceUtil.getAsList(targetContainer, feature);

		final List<Object> lcs = DiffUtil.longestCommonSubsequence(comparison, sourceList, targetList);
		if (lcs.contains(valueMatch.getLeft()) || lcs.contains(valueMatch.getRight())) {
			// Ordering is correct on this one
			return;
		}

		int insertionIndex = DiffUtil.findInsertionIndex(comparison, sourceList, targetList, value);
		if (insertionIndex >= 0) {
			/*
			 * We've used unresolving views of the eobject lists since we didn't know whether there was
			 * actually any work to do. Use the real list now.
			 */
			@SuppressWarnings("unchecked")
			final List<EObject> changedList = (List<EObject>)safeEGet(targetContainer, feature);
			if (changedList.size() > 1) {
				if (changedList instanceof EList<?>) {
					if (insertionIndex > changedList.size()) {
						((EList<EObject>)changedList).move(changedList.size() - 1, newValue);
					} else {
						((EList<EObject>)changedList).move(insertionIndex, newValue);
					}
				} else {
					changedList.remove(newValue);
					if (insertionIndex > changedList.size()) {
						changedList.add(newValue);
					} else {
						changedList.add(insertionIndex, newValue);
					}
				}
			}
		}
	}

	/**
	 * Seeks a match of the given {@code element} in the given list, using the equality helper to find it.
	 * This is only used when moving or deleting proxies for now.
	 * 
	 * @param comparison
	 *            The comparison which Diff we are currently merging.
	 * @param list
	 *            The list from which we seek a value.
	 * @param element
	 *            The value for which we need a match in {@code list}.
	 * @return The match of {@code element} in {@code list}, {@code null} if none.
	 */
	protected EObject findMatchIn(Comparison comparison, List<EObject> list, EObject element) {
		final IEqualityHelper helper = comparison.getEqualityHelper();
		final Iterator<EObject> it = list.iterator();
		while (it.hasNext()) {
			final EObject next = it.next();
			if (helper.matchingValues(next, element)) {
				return next;
			}
		}
		return null;
	}

	/**
	 * This will be used by the distinct merge actions in order to find the index at which a value should be
	 * inserted in its target list. See {@link DiffUtil#findInsertionIndex(Comparison, Diff, boolean)} for
	 * more on this.
	 * <p>
	 * Sub-classes can override this if the insertion order is irrelevant. A return value of {@code -1} will
	 * be considered as "no index" and the value will be inserted at the end of its target list.
	 * </p>
	 * 
	 * @param comparison
	 *            This will be used in order to retrieve the Match for EObjects when comparing them.
	 * @param diff
	 *            The diff which merging will trigger the need for an insertion index in its target list.
	 * @param rightToLeft
	 *            {@code true} if the merging will be done into the left list, so that we should consider the
	 *            right model as the source and the left as the target.
	 * @return The index at which this {@code diff}'s value should be inserted into the 'target' list, as
	 *         inferred from {@code rightToLeft}. {@code -1} if the value should be inserted at the end of its
	 *         target list.
	 * @see DiffUtil#findInsertionIndex(Comparison, Diff, boolean)
	 */
	protected int findInsertionIndex(Comparison comparison, Diff diff, boolean rightToLeft) {
		return DiffUtil.findInsertionIndex(comparison, diff, rightToLeft);
	}
}
