/*******************************************************************************
 * 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
 *     Stefan Dirix - Bugs 450949, 453218, 460923 and 460675
 *******************************************************************************/
package org.eclipse.emf.compare.diff;

import static org.eclipse.emf.compare.utils.ReferenceUtil.getAsList;
import static org.eclipse.emf.compare.utils.ReferenceUtil.safeEGet;

import com.google.common.base.Optional;

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

import org.apache.log4j.Logger;
import org.eclipse.emf.common.util.Monitor;
import org.eclipse.emf.compare.Comparison;
import org.eclipse.emf.compare.ComparisonCanceledException;
import org.eclipse.emf.compare.DifferenceKind;
import org.eclipse.emf.compare.DifferenceSource;
import org.eclipse.emf.compare.EMFCompareMessages;
import org.eclipse.emf.compare.Match;
import org.eclipse.emf.compare.internal.utils.ComparisonUtil;
import org.eclipse.emf.compare.internal.utils.DiffUtil;
import org.eclipse.emf.compare.utils.IEqualityHelper;
import org.eclipse.emf.ecore.EAttribute;
import org.eclipse.emf.ecore.EObject;
import org.eclipse.emf.ecore.EReference;
import org.eclipse.emf.ecore.EStructuralFeature;
import org.eclipse.emf.ecore.InternalEObject;
import org.eclipse.emf.ecore.resource.Resource;
import org.eclipse.emf.ecore.util.FeatureMap;
import org.eclipse.emf.ecore.util.FeatureMapUtil;

/**
 * The diff engine is in charge of actually computing the differences between the objects mapped by a
 * {@link Match} object.
 * <p>
 * This default implementation aims at being generic enough to be used for any model, whatever the metamodel.
 * However, specific differences, refinements of differences or even higher level differences might be
 * necessary.
 * </p>
 * TODO document available extension possibilities.
 * 
 * @author <a href="mailto:laurent.goubet@obeo.fr">Laurent Goubet</a>
 */
public class DefaultDiffEngine implements IDiffEngine {
	/**
	 * We'll use this "placeholder" to differentiate the unmatched elements from the "null" values that
	 * attributes can legitimately use.
	 */
	protected static final Object UNMATCHED_VALUE = new Object();

	/** The logger. */
	private static final Logger LOGGER = Logger.getLogger(DefaultDiffEngine.class);

	/**
	 * The diff processor that will be used by this engine. Should be passed by the constructor and accessed
	 * by {@link #getDiffProcessor()}.
	 */
	private IDiffProcessor diffProcessor;

	/**
	 * Create the diff engine.
	 */
	public DefaultDiffEngine() {
		this(new DiffBuilder());
	}

	/**
	 * Create the diff engine.
	 * 
	 * @param processor
	 *            this instance will be called for each detected difference.
	 */
	public DefaultDiffEngine(IDiffProcessor processor) {
		this.diffProcessor = processor;
	}

	/**
	 * Checks whether the given {@code iterable} contains the given {@code element} according to the semantics
	 * of {@link IEqualityHelper#matchingValues(Comparison, Object, Object)}.
	 * 
	 * @param comparison
	 *            This will be used in order to retrieve the Match for EObjects when comparing them.
	 * @param iterable
	 *            Iterable which content we are to check.
	 * @param element
	 *            The element we expect to be contained in {@code  iterable}.
	 * @param <E>
	 *            Type of the input iterable's content.
	 * @return {@code true} if the given {@code iterable} contains {@code element}, {@code false} otherwise.
	 */
	protected <E> boolean contains(Comparison comparison, Iterable<E> iterable, E element) {
		final IEqualityHelper equality = comparison.getEqualityHelper();
		for (E candidate : iterable) {
			if (equality.matchingValues(candidate, element)) {
				return true;
			}
		}
		return false;
	}

	/**
	 * {@inheritDoc}
	 * 
	 * @see org.eclipse.emf.compare.diff.IDiffEngine#diff(org.eclipse.emf.compare.Comparison,
	 *      org.eclipse.emf.common.util.Monitor)
	 */
	public void diff(Comparison comparison, Monitor monitor) {
		long start = System.currentTimeMillis();
		if (LOGGER.isDebugEnabled()) {
			LOGGER.debug(String.format("detect differences - START")); //$NON-NLS-1$
		}
		monitor.subTask(EMFCompareMessages.getString("DefaultDiffEngine.monitor.diff")); //$NON-NLS-1$
		for (Match rootMatch : comparison.getMatches()) {
			checkForDifferences(rootMatch, monitor);
		}
		if (LOGGER.isInfoEnabled()) {
			LOGGER.info(String.format("detect differences - END - Took %d ms", Long.valueOf(System //$NON-NLS-1$
					.currentTimeMillis() - start)));
		}
	}

	/**
	 * Checks the given {@link Match}'s sides for potential differences. Will recursively check for
	 * differences on submatches.
	 * 
	 * @param match
	 *            The match that is to be checked.
	 * @param monitor
	 *            The monitor to report progress or to check for cancellation.
	 */
	protected void checkForDifferences(Match match, Monitor monitor) {
		if (monitor.isCanceled()) {
			throw new ComparisonCanceledException();
		}
		checkResourceAttachment(match, monitor);

		final FeatureFilter featureFilter = createFeatureFilter();

		final Iterator<EReference> references = featureFilter.getReferencesToCheck(match);
		while (references.hasNext()) {
			final EReference reference = references.next();
			final boolean considerOrdering = featureFilter.checkForOrderingChanges(reference);
			computeDifferences(match, reference, considerOrdering);
		}

		final Iterator<EAttribute> attributes = featureFilter.getAttributesToCheck(match);
		while (attributes.hasNext()) {
			final EAttribute attribute = attributes.next();
			final boolean considerOrdering = featureFilter.checkForOrderingChanges(attribute);
			computeDifferences(match, attribute, considerOrdering);
		}

		for (Match submatch : match.getSubmatches()) {
			checkForDifferences(submatch, monitor);
		}
	}

	/**
	 * Checks whether the given {@link Match}'s sides have changed resources. This will only be called for
	 * {@link Match} elements referencing the root(s) of an EMF Resource.
	 * 
	 * @param match
	 *            The match that is to be checked.
	 * @param monitor
	 *            The monitor to report progress or to check for cancellation.
	 */
	protected void checkResourceAttachment(Match match, Monitor monitor) {
		final Comparison comparison = match.getComparison();

		if (comparison.getMatchedResources().isEmpty()) {
			// This is a comparison of EObjects, do not go up to the resources
			return;
		}

		final EObject left = match.getLeft();
		final EObject right = match.getRight();
		final EObject origin = match.getOrigin();

		final boolean originIsRoot = isRoot(origin);

		boolean threeWay = comparison.isThreeWay();
		if (threeWay) {
			if (originIsRoot) {
				// Uncontrol or delete, the "resource attachment" is a deletion
				if (!isRoot(left)) {
					final String uri = origin.eResource().getURI().toString();
					getDiffProcessor().resourceAttachmentChange(match, uri, DifferenceKind.DELETE,
							DifferenceSource.LEFT);
				}
				if (!isRoot(right)) {
					final String uri = origin.eResource().getURI().toString();
					getDiffProcessor().resourceAttachmentChange(match, uri, DifferenceKind.DELETE,
							DifferenceSource.RIGHT);
				}
				// Cases where isRoot(left) == true or isRoot(right) == true
				// are handled in org.eclipse.emf.compare.egit by EGitPostProcessor#postDiff
			} else {
				// Control or add, the "resource attachment" is an addition
				if (isRoot(left)) {
					final String uri = left.eResource().getURI().toString();
					getDiffProcessor().resourceAttachmentChange(match, uri, DifferenceKind.ADD,
							DifferenceSource.LEFT);
				}
				if (isRoot(right)) {
					final String uri = right.eResource().getURI().toString();
					getDiffProcessor().resourceAttachmentChange(match, uri, DifferenceKind.ADD,
							DifferenceSource.RIGHT);
				}
			}
		} else {
			final boolean leftIsRoot = isRoot(left);
			final boolean rightIsRoot = isRoot(right);
			if (leftIsRoot && !rightIsRoot) {
				final String uri = left.eResource().getURI().toString();
				getDiffProcessor().resourceAttachmentChange(match, uri, DifferenceKind.ADD,
						DifferenceSource.LEFT);
			} else if (!leftIsRoot && rightIsRoot) {
				final String uri = right.eResource().getURI().toString();
				getDiffProcessor().resourceAttachmentChange(match, uri, DifferenceKind.DELETE,
						DifferenceSource.LEFT);
			}
		}
	}

	/**
	 * Checks whether the given EObject is a root of its resource or not.
	 * 
	 * @param eObj
	 *            The EObject to check.
	 * @return <code>true</code> if this object is a root of its containing resource, <code>false</code>
	 *         otherwise.
	 */
	protected static boolean isRoot(EObject eObj) {
		if (eObj instanceof InternalEObject) {
			return ((InternalEObject)eObj).eDirectResource() != null;
		}

		boolean isRoot = false;
		if (eObj != null) {
			final Resource res = eObj.eResource();
			final EObject container = eObj.eContainer();
			// <root of containment tree> || <root of fragment>
			isRoot = (container == null && res != null)
					|| (container != null && container.eResource() != res);
		}
		return isRoot;
	}

	/**
	 * Delegates the computation of Differences for a given containment reference according to the type of
	 * comparison (two- or three-way), and whether we need to take ordering changes into account.
	 * 
	 * @param match
	 *            The match which sides we need to check for potential differences.
	 * @param reference
	 *            The reference whose values are currently being checked for differences.
	 * @param checkOrdering
	 *            Whether we need to detect ordering changes or ignore them.
	 */
	protected void computeContainmentDifferences(Match match, EReference reference, boolean checkOrdering) {
		Comparison comparison = match.getComparison();

		if (checkOrdering) {
			if (comparison.isThreeWay()) {
				computeContainmentDifferencesThreeWay(match, reference, checkOrdering);
			} else {
				computeContainmentDifferencesTwoWay(match, reference, checkOrdering);
			}
		} else {
			List<Object> leftValues = getAsList(match.getLeft(), reference);
			List<Object> rightValues = getAsList(match.getRight(), reference);
			if (comparison.isThreeWay()) {
				createContainmentDifferencesNoOrdering(match, reference, leftValues, DifferenceSource.LEFT);
				createContainmentDifferencesNoOrdering(match, reference, rightValues, DifferenceSource.RIGHT);

				List<Object> originValues = getAsList(match.getOrigin(), reference);
				for (Object value : originValues) {
					Match valueMatch = comparison.getMatch((EObject)value);
					if (valueMatch.getLeft() == null) {
						featureChange(match, reference, value, DifferenceKind.DELETE, DifferenceSource.LEFT);
					}
					if (valueMatch.getRight() == null) {
						featureChange(match, reference, value, DifferenceKind.DELETE, DifferenceSource.RIGHT);
					}
				}
			} else {
				createContainmentDifferencesNoOrdering(match, reference, leftValues, DifferenceSource.LEFT);

				for (Object value : rightValues) {
					Match valueMatch = comparison.getMatch((EObject)value);
					if (valueMatch.getLeft() == null) {
						featureChange(match, reference, value, DifferenceKind.DELETE, DifferenceSource.LEFT);
					}
				}
			}
		}
	}

	/**
	 * Delegates the computation of Differences for a given muti-valued feature according to the type of
	 * comparison (two- or three-way), and whether we need to take ordering changes into account.
	 * 
	 * @param match
	 *            The match which sides we need to check for potential differences.
	 * @param feature
	 *            The feature whose values are currently being checked for differences.
	 * @param checkOrdering
	 *            Whether we need to detect ordering changes or ignore them.
	 */
	protected void computeMultiValuedFeatureDifferences(Match match, EStructuralFeature feature,
			boolean checkOrdering) {
		Comparison comparison = match.getComparison();

		if (checkOrdering) {
			if (comparison.isThreeWay()) {
				computeMultiValuedFeatureDifferencesThreeWay(match, feature, checkOrdering);
			} else {
				computeMultiValuedFeatureDifferencesTwoWay(match, feature, checkOrdering);
			}
		} else {
			List<Object> leftValues = getAsList(match.getLeft(), feature);
			List<Object> rightValues = getAsList(match.getRight(), feature);
			if (comparison.isThreeWay()) {
				List<Object> originValues = getAsList(match.getOrigin(), feature);
				createMultiValuedFeatureDifferencesNoOrdering(match, feature, leftValues, originValues,
						DifferenceSource.LEFT);
				createMultiValuedFeatureDifferencesNoOrdering(match, feature, rightValues, originValues,
						DifferenceSource.RIGHT);
			} else {
				createMultiValuedFeatureDifferencesNoOrdering(match, feature, leftValues, rightValues,
						DifferenceSource.LEFT);
			}
		}
	}

	/**
	 * Computes the difference between the sides of the given {@code match} for the given containment
	 * {@code reference}.
	 * <p>
	 * This is only meant for three-way comparisons.
	 * </p>
	 * <p>
	 * <b>Note</b> that this is no longer used for references which ordering is not considered, so
	 * {@code checkOrdering} will always be <code>true</code> .
	 * </p>
	 * 
	 * @param match
	 *            The match which sides we need to check for potential differences.
	 * @param reference
	 *            The containment reference which values are to be checked.
	 * @param checkOrdering
	 *            {@code true} if we should consider ordering changes on this reference, {@code false}
	 *            otherwise.
	 */
	protected void computeContainmentDifferencesThreeWay(Match match, EReference reference,
			boolean checkOrdering) {
		final Comparison comparison = match.getComparison();

		// We won't use iterables here since we need random access collections for fast LCS.
		final List<Object> leftValues = getAsList(match.getLeft(), reference);
		final List<Object> rightValues = getAsList(match.getRight(), reference);
		final List<Object> originValues = getAsList(match.getOrigin(), reference);

		final List<Object> lcsOriginLeft = DiffUtil.longestCommonSubsequence(comparison, originValues,
				leftValues);
		final List<Object> lcsOriginRight = DiffUtil.longestCommonSubsequence(comparison, originValues,
				rightValues);

		createContainmentDifferences(match, reference, checkOrdering, leftValues, lcsOriginLeft,
				DifferenceSource.LEFT);
		createContainmentDifferences(match, reference, checkOrdering, rightValues, lcsOriginRight,
				DifferenceSource.RIGHT);

		// deleted from either side
		for (Object diffCandidate : originValues) {
			/*
			 * A value that is in the origin but not in either left or right has been deleted or is a moved
			 * element which previously was in this reference. If the latter, we'll detect it later on when
			 * checking its new reference.
			 */
			final Match candidateMatch = comparison.getMatch((EObject)diffCandidate);
			if (candidateMatch == null) {
				// out of scope
			} else {
				if (candidateMatch.getLeft() == null) {
					featureChange(match, reference, diffCandidate, DifferenceKind.DELETE,
							DifferenceSource.LEFT);
				}
				if (candidateMatch.getRight() == null) {
					featureChange(match, reference, diffCandidate, DifferenceKind.DELETE,
							DifferenceSource.RIGHT);
				}
			}
		}
	}

	/**
	 * This will iterate over the given list of values from a containment reference and create the differences
	 * that can be detected from it.
	 * <p>
	 * Ordering changes will not be considered at all from this method. Values that exist in both the given
	 * list of elements and the origin (either ancestor or right side for two-way comparisons), will only have
	 * a Diff if their container or containing reference has changed. If they are still in the same container
	 * and reference, then even if they are not in the same position, we will not try and detect an ordering
	 * change.
	 * </p>
	 * 
	 * @param match
	 *            The match which sides we need to check for potential differences.
	 * @param reference
	 *            The containment reference which values are to be checked.
	 * @param sideValues
	 *            Value of that <code>reference</code> on the given <code>side</code>.
	 * @param side
	 *            The side currently being compared.
	 */
	protected void createContainmentDifferencesNoOrdering(Match match, EReference reference,
			List<Object> sideValues, DifferenceSource side) {
		Comparison comparison = match.getComparison();
		IEqualityHelper equalityHelper = comparison.getEqualityHelper();

		int sizeSide = sideValues.size();

		int currentSide = 0;
		while (currentSide < sizeSide) {
			EObject sideValue = (EObject)sideValues.get(currentSide++);
			Match candidateMatch = comparison.getMatch(sideValue);

			EObject originValue;
			if (comparison.isThreeWay()) {
				originValue = candidateMatch.getOrigin();
			} else {
				originValue = candidateMatch.getRight();
			}

			if (matchingContainment(equalityHelper, sideValue, originValue)) {
				// Object present in both sides, in the same container and same containment feature.
				// We don't care about ordering so there is no change here.
			} else {
				// Object has either changed container or isn't present in the origin
				if (originValue != null) {
					featureChange(match, reference, sideValue, DifferenceKind.MOVE, side);
				} else {
					featureChange(match, reference, sideValue, DifferenceKind.ADD, side);
				}
			}
		}
	}

	/**
	 * Called from {@link #computeContainmentDifferencesThreeWay(Match, EReference, boolean)} once our LCS
	 * have been computed and we know what really changed. It will be used for both the left and right side.
	 * 
	 * @param match
	 *            The match which sides we need to check for potential differences.
	 * @param reference
	 *            The containment reference which values are to be checked.
	 * @param checkOrdering
	 *            {@code true} if we should consider ordering changes on this reference, {@code false}
	 *            otherwise.
	 * @param values
	 *            Value of that <code>reference</code> on the given <code>side</code>.
	 * @param lcsWithOrigin
	 *            LCS between the reference values on the given <code>side</code> and the values in origin.
	 * @param side
	 *            The side currently being compared.
	 */
	protected void createContainmentDifferences(Match match, EReference reference, boolean checkOrdering,
			List<Object> values, List<Object> lcsWithOrigin, DifferenceSource side) {
		final Comparison comparison = match.getComparison();
		final IEqualityHelper equality = comparison.getEqualityHelper();

		int lcsCursor = 0;
		Optional<Match> lcsCurrent = getMatchIfPresent(comparison, lcsWithOrigin, lcsCursor);
		for (Object diffCandidate : values) {
			final Match candidateMatch = comparison.getMatch((EObject)diffCandidate);
			// See bug 405000 for this strange iteration on the LCS
			if (candidateMatch == null || lcsCurrent.orNull() == candidateMatch) {
				lcsCursor++;
				lcsCurrent = getMatchIfPresent(comparison, lcsWithOrigin, lcsCursor);
				continue;
			}

			final EObject value;
			if (side == DifferenceSource.LEFT) {
				value = candidateMatch.getLeft();
			} else {
				value = candidateMatch.getRight();
			}
			final EObject originValue;
			if (comparison.isThreeWay()) {
				originValue = candidateMatch.getOrigin();
			} else {
				originValue = candidateMatch.getRight();
			}

			if (matchingContainment(equality, value, originValue)) {
				/*
				 * Contained in both compared side and the origin, and not part of the LCS. It has moved
				 * within its (containment) reference.
				 */
				if (checkOrdering) {
					featureChange(match, reference, diffCandidate, DifferenceKind.MOVE, side);
				}
			} else {
				/*
				 * This element is in different containers in the compared side and origin (if it is in origin
				 * at all).
				 */
				if (originValue != null) {
					featureChange(match, reference, diffCandidate, DifferenceKind.MOVE, side);
				} else {
					featureChange(match, reference, diffCandidate, DifferenceKind.ADD, side);
				}
			}
		}
	}

	/**
	 * Checks whether the two given EObjects are contained within the same object, under the same reference.
	 * 
	 * @param equalityHelper
	 *            Our current equality helper.
	 * @param o1
	 *            First of the two EObjects to compare.
	 * @param o2
	 *            Second of the two EObjects to compare.
	 * @return <code>true</code> if these two objects are contained within the same container, false
	 *         otherwise.
	 */
	protected boolean matchingContainment(IEqualityHelper equalityHelper, EObject o1, EObject o2) {
		if (o1 == null || o2 == null) {
			return false;
		}

		boolean matchingContainment = false;

		final EObject container1 = o1.eContainer();
		final EObject container2 = o2.eContainer();
		if (container1 != null && container2 != null) {
			final EReference containing1 = o1.eContainmentFeature();
			final EReference containing2 = o2.eContainmentFeature();
			matchingContainment = (containing1 == containing2
					|| containing1.getName().equals(containing2.getName()))
					&& equalityHelper.matchingValues(o1.eContainer(), o2.eContainer());
		}
		return matchingContainment;
	}

	/**
	 * This will be used in order to read the LCS synchronously with the iteration on its target lists'
	 * values. This should be used cautiously since it will work on empty lists, null values and out-of-scope
	 * objects.
	 * 
	 * @param comparison
	 *            The current comparison.
	 * @param list
	 *            A list of EObjects. May be empty or contain out-of-scope values.
	 * @param index
	 *            Index of the object we seek within this list.
	 * @return An optional containing the match of the object at the given index... or
	 *         {@link Optional#absent()}.
	 */
	protected static Optional<Match> getMatchIfPresent(final Comparison comparison, List<Object> list,
			int index) {
		Optional<Match> value = Optional.absent();
		if (list.size() > index) {
			EObject current = (EObject)list.get(index);
			if (current != null) {
				value = Optional.fromNullable(comparison.getMatch(current));
			}
		}
		return value;
	}

	/**
	 * This will be used in order to read the LCS synchronously with the iteration on its target lists'
	 * values. This should be used cautiously since it will work on empty lists, and null values contained in
	 * the list are treated the same as an empty list and considered to be Optional.absent().
	 * 
	 * @param list
	 *            A list of EObjects. May be empty or contain null or out-of-scope values.
	 * @param index
	 *            Index of the object we seek within this list.
	 * @return An optional containing the object at the given index... or {@link Optional#absent()}.
	 */
	protected static Optional<Object> getIfPresent(List<Object> list, int index) {
		Optional<Object> value = Optional.absent();
		if (list.size() > index) {
			value = Optional.fromNullable(list.get(index));
		}
		return value;
	}

	/**
	 * Computes the difference between the sides of the given {@code match} for the given containment
	 * {@code reference}.
	 * <p>
	 * This is only meant for two-way comparisons.
	 * </p>
	 * <p>
	 * <b>Note</b> that this is no longer used for references which ordering is not considered, so
	 * {@code checkOrdering} will always be <code>true</code> .
	 * </p>
	 * 
	 * @param match
	 *            The match which sides we need to check for potential differences.
	 * @param reference
	 *            The containment reference which values are to be checked.
	 * @param checkOrdering
	 *            {@code true} if we should consider ordering changes on this reference, {@code false}
	 *            otherwise.
	 */
	protected void computeContainmentDifferencesTwoWay(Match match, EReference reference,
			boolean checkOrdering) {
		final Comparison comparison = match.getComparison();

		final List<Object> leftValues = getAsList(match.getLeft(), reference);
		final List<Object> rightValues = getAsList(match.getRight(), reference);

		final List<Object> lcs = DiffUtil.longestCommonSubsequence(comparison, rightValues, leftValues);

		createContainmentDifferences(match, reference, checkOrdering, leftValues, lcs, DifferenceSource.LEFT);

		// deleted
		for (Object diffCandidate : rightValues) {
			/*
			 * A value that is in the right but not in the left either has been deleted or is a moved element
			 * which previously was in this reference. We'll detect the move on its new reference.
			 */
			final Match candidateMatch = comparison.getMatch((EObject)diffCandidate);
			if (candidateMatch == null) {
				// out of scope
			} else if (candidateMatch.getLeft() == null) {
				featureChange(match, reference, diffCandidate, DifferenceKind.DELETE, DifferenceSource.LEFT);
			}
		}
	}

	/**
	 * Computes the difference between the sides of the given <code>match</code> for the given
	 * <code>attribute</code>.
	 * 
	 * @param match
	 *            The match which sides we need to check for potential differences.
	 * @param attribute
	 *            The attribute which values are to be checked.
	 * @param checkOrdering
	 *            <code>true</code> if we should consider ordering changes on this attribute,
	 *            <code>false</code> otherwise.
	 */
	protected void computeDifferences(Match match, EAttribute attribute, boolean checkOrdering) {
		final Comparison comparison = match.getComparison();

		// This default implementation does not care about "attribute" changes on added/removed elements
		boolean shortcut = false;
		if (comparison.isThreeWay()) {
			shortcut = match.getOrigin() == null;
		} else {
			shortcut = match.getLeft() == null || match.getRight() == null;
		}

		// Do not shortcut when multi-valued FeatureMaps are affected to keep their ordering intact
		if (shortcut && FeatureMapUtil.isFeatureMap(attribute)) {
			final EObject owner = getOwner(match);
			if (owner != null && FeatureMapUtil.isMany(owner, attribute)) {
				shortcut = false;
			}
		}

		if (shortcut) {
			return;
		}

		if (attribute.isMany()) {
			if (comparison.isThreeWay()) {
				computeMultiValuedFeatureDifferencesThreeWay(match, attribute, checkOrdering);
			} else {
				computeMultiValuedFeatureDifferencesTwoWay(match, attribute, checkOrdering);
			}
		} else {
			computeSingleValuedAttributeDifferences(match, attribute);
		}
	}

	/**
	 * Returns one side of the match if any exist. The order of the checked sides is Origin, Left and Right.
	 *
	 * @param match
	 *            The match whose sides are checked.
	 * @return Either Origin, Left or Right if one of them exists, {@code null} otherwise.
	 */
	private EObject getOwner(Match match) {
		EObject owner = match.getOrigin();
		if (owner == null) {
			owner = match.getLeft();
			if (owner == null) {
				owner = match.getRight();
			}
		}
		return owner;
	}

	/**
	 * Computes the difference between the sides of the given <code>match</code> for the given
	 * <code>reference</code>.
	 * 
	 * @param match
	 *            The match which sides we need to check for potential differences.
	 * @param reference
	 *            The reference which values are to be checked.
	 * @param checkOrdering
	 *            <code>true</code> if we should consider ordering changes on this reference,
	 *            <code>false</code> otherwise.
	 */
	protected void computeDifferences(Match match, EReference reference, boolean checkOrdering) {
		final Comparison comparison = match.getComparison();

		if (reference.isContainment()) {
			computeContainmentDifferences(match, reference, checkOrdering);
		} else if (reference.isMany()) {
			computeMultiValuedFeatureDifferences(match, reference, checkOrdering);
		} else {
			if (comparison.isThreeWay()) {
				computeSingleValuedReferenceDifferencesThreeWay(match, reference);
			} else {
				computeSingleValuedReferenceDifferencesTwoWay(match, reference);
			}
		}
	}

	/**
	 * Computes the difference between the sides of the given {@code match} for the given multi-valued
	 * {@code feature}.
	 * <p>
	 * The given {@code feature} cannot be a containment reference.
	 * </p>
	 * <p>
	 * This is only meant for three-way comparisons.
	 * </p>
	 * <p>
	 * <b>Note</b> that this is no longer used for features which ordering is not considered, so
	 * {@code checkOrdering} will always be <code>true</code> .
	 * </p>
	 * 
	 * @param match
	 *            The match which sides we need to check for potential differences.
	 * @param feature
	 *            The feature which values are to be checked.
	 * @param checkOrdering
	 *            {@code true} if we should consider ordering changes on this feature, {@code false}
	 *            otherwise.
	 */
	protected void computeMultiValuedFeatureDifferencesThreeWay(Match match, EStructuralFeature feature,
			boolean checkOrdering) {
		final Comparison comparison = match.getComparison();
		final IEqualityHelper equality = comparison.getEqualityHelper();

		// We won't use iterables here since we need random access collections for fast LCS.
		final List<Object> leftValues = getAsList(match.getLeft(), feature);
		final List<Object> rightValues = getAsList(match.getRight(), feature);
		final List<Object> originValues = getAsList(match.getOrigin(), feature);

		final List<Object> lcsOriginLeft = DiffUtil.longestCommonSubsequence(comparison, originValues,
				leftValues);
		final List<Object> lcsOriginRight = DiffUtil.longestCommonSubsequence(comparison, originValues,
				rightValues);

		// Any value that is _not_ in the LCS has changed.

		int lcsCursor = 0;
		Optional<Object> lcsCurrent = getIfPresent(lcsOriginLeft, lcsCursor);
		for (Object diffCandidate : leftValues) {
			// See bug 405000 for this strange iteration on the LCS
			if (equality.matchingValues(diffCandidate, lcsCurrent.orNull())) {
				lcsCursor++;
				lcsCurrent = getIfPresent(lcsOriginLeft, lcsCursor);
				continue;
			}

			if (contains(comparison, originValues, diffCandidate)) {
				if (checkOrdering) {
					featureChange(match, feature, diffCandidate, DifferenceKind.MOVE, DifferenceSource.LEFT);
				}
			} else if (FeatureMapUtil.isFeatureMap(feature) && diffCandidate instanceof FeatureMap.Entry) {
				// A value of a FeatureMap changed his key
				if (isFeatureMapEntryKeyChange(equality, (FeatureMap.Entry)diffCandidate, originValues)) {
					featureChange(match, feature, diffCandidate, DifferenceKind.CHANGE,
							DifferenceSource.LEFT);
				} else if (isFeatureMapValueMove(comparison, (FeatureMap.Entry)diffCandidate,
						DifferenceSource.LEFT)) {
					featureChange(match, feature, diffCandidate, DifferenceKind.MOVE, DifferenceSource.LEFT);
				} else {
					featureChange(match, feature, diffCandidate, DifferenceKind.ADD, DifferenceSource.LEFT);
				}
			} else {
				featureChange(match, feature, diffCandidate, DifferenceKind.ADD, DifferenceSource.LEFT);
			}
		}

		lcsCursor = 0;
		lcsCurrent = getIfPresent(lcsOriginRight, lcsCursor);
		for (Object diffCandidate : rightValues) {
			// See bug 405000 for this strange iteration on the LCS
			if (equality.matchingValues(diffCandidate, lcsCurrent.orNull())) {
				lcsCursor++;
				lcsCurrent = getIfPresent(lcsOriginRight, lcsCursor);
				continue;
			}

			if (contains(comparison, originValues, diffCandidate)) {
				if (checkOrdering) {
					featureChange(match, feature, diffCandidate, DifferenceKind.MOVE, DifferenceSource.RIGHT);
				}
			} else if (FeatureMapUtil.isFeatureMap(feature) && diffCandidate instanceof FeatureMap.Entry) {
				// A value of a FeatureMap changed his key
				if (isFeatureMapEntryKeyChange(equality, (FeatureMap.Entry)diffCandidate, originValues)) {
					featureChange(match, feature, diffCandidate, DifferenceKind.CHANGE,
							DifferenceSource.RIGHT);
				} else if (isFeatureMapValueMove(comparison, (FeatureMap.Entry)diffCandidate,
						DifferenceSource.RIGHT)) {
					featureChange(match, feature, diffCandidate, DifferenceKind.MOVE, DifferenceSource.RIGHT);
				} else {
					featureChange(match, feature, diffCandidate, DifferenceKind.ADD, DifferenceSource.RIGHT);
				}
			} else {
				featureChange(match, feature, diffCandidate, DifferenceKind.ADD, DifferenceSource.RIGHT);
			}
		}

		// Removed from either side
		for (Object diffCandidate : originValues) {
			// A value that is in the origin but not in one of the side has been deleted.
			// However, we do not want attribute changes on removed elements.
			if (!contains(comparison, leftValues, diffCandidate)) {
				if ((feature instanceof EReference || match.getLeft() != null)
						&& !isFeatureMapChangeOrMove(comparison, feature, diffCandidate, leftValues,
								DifferenceSource.LEFT)) {
					featureChange(match, feature, diffCandidate, DifferenceKind.DELETE,
							DifferenceSource.LEFT);
				}
			}
			if (!contains(comparison, rightValues, diffCandidate)) {
				if ((feature instanceof EReference || match.getRight() != null)
						&& !isFeatureMapChangeOrMove(comparison, feature, diffCandidate, rightValues,
								DifferenceSource.RIGHT)) {
					featureChange(match, feature, diffCandidate, DifferenceKind.DELETE,
							DifferenceSource.RIGHT);
				}
			}
		}
	}

	/**
	 * This will iterate over the given list of values from a multi-valued feature and create the differences
	 * that can be detected from it.
	 * <p>
	 * Ordering changes will not be considered at all from this method. Values that exist in both the given
	 * list of elements and the origin (either ancestor or right side for two-way comparisons), will never
	 * have a Diff even if they are not at the same index in the list of their respective side.
	 * </p>
	 * 
	 * @param match
	 *            The match which sides we need to check for potential differences.
	 * @param feature
	 *            The feature which values are to be checked. Cannot be a containment reference.
	 * @param sideValues
	 *            Value of that <code>reference</code> on the given <code>side</code>.
	 * @param originValues
	 *            Value of that <code>reference</code> on the origin side. Could be the common ancestor or the
	 *            right side in case of two-way comparisons.
	 * @param side
	 *            The side currently being compared.
	 */
	protected void createMultiValuedFeatureDifferencesNoOrdering(Match match, EStructuralFeature feature,
			List<Object> sideValues, List<Object> originValues, DifferenceSource side) {
		Comparison comparison = match.getComparison();
		IEqualityHelper equalityHelper = comparison.getEqualityHelper();

		List<Object> originCopy = new ArrayList<>(originValues);

		int sizeSide = sideValues.size();
		int currentSide = 0;
		while (currentSide < sizeSide) {
			Object sideValue = sideValues.get(currentSide++);

			int currentOrigin = 0;
			int sizeOrigin = originCopy.size();

			boolean matching = false;
			while (currentOrigin < sizeOrigin && !matching) {
				Object originValue = originCopy.get(currentOrigin);
				if (equalityHelper.matchingValues(sideValue, originValue)) {
					originCopy.remove(currentOrigin);
					matching = true;
				}
				currentOrigin++;
			}

			if (!matching) {
				// This object is in the side checked, but not in the origin
				if (FeatureMapUtil.isFeatureMap(feature) && sideValue instanceof FeatureMap.Entry) {
					// A value of a FeatureMap changed its key
					if (isFeatureMapEntryKeyChange(equalityHelper, (FeatureMap.Entry)sideValue,
							originValues)) {
						featureChange(match, feature, sideValue, DifferenceKind.CHANGE, side);
					} else if (isFeatureMapValueMove(comparison, (FeatureMap.Entry)sideValue, side)) {
						featureChange(match, feature, sideValue, DifferenceKind.MOVE, side);
					} else {
						featureChange(match, feature, sideValue, DifferenceKind.ADD, side);
					}
				} else {
					featureChange(match, feature, sideValue, DifferenceKind.ADD, side);
				}
			}
		}

		// Objects that are still present in "originCopy" now have been deleted from the current side.
		// We want all reference changes, but if the current side has been deleted, we do not want to have
		// attribute changes under this deletion.
		boolean sideDeleted;
		if (side == DifferenceSource.LEFT) {
			sideDeleted = match.getLeft() == null;
		} else {
			sideDeleted = match.getRight() == null;
		}
		for (Object originValue : originCopy) {
			if ((feature instanceof EReference || !sideDeleted)
					&& !isFeatureMapChangeOrMove(comparison, feature, originValue, sideValues, side)) {
				featureChange(match, feature, originValue, DifferenceKind.DELETE, side);
			}
		}
	}

	/**
	 * Computes the difference between the sides of the given {@code match} for the given multi-valued
	 * {@code feature}.
	 * <p>
	 * The given {@code feature} cannot be a containment reference.
	 * </p>
	 * <p>
	 * This is only meant for two-way comparisons.
	 * </p>
	 * <p>
	 * <b>Note</b> that this is no longer used for features which ordering is not considered, so
	 * {@code checkOrdering} will always be <code>true</code> .
	 * </p>
	 * 
	 * @param match
	 *            The match which sides we need to check for potential differences.
	 * @param feature
	 *            The feature which values are to be checked.
	 * @param checkOrdering
	 *            {@code true} if we should consider ordering changes on this feature, {@code false}
	 *            otherwise.
	 */
	protected void computeMultiValuedFeatureDifferencesTwoWay(Match match, EStructuralFeature feature,
			boolean checkOrdering) {
		final Comparison comparison = match.getComparison();
		final IEqualityHelper equality = comparison.getEqualityHelper();

		// We won't use iterables here since we need random access collections for fast LCS.
		final List<Object> leftValues = getAsList(match.getLeft(), feature);
		final List<Object> rightValues = getAsList(match.getRight(), feature);

		final List<Object> lcs = DiffUtil.longestCommonSubsequence(comparison, rightValues, leftValues);

		int lcsCursor = 0;
		Optional<Object> lcsCurrent = getIfPresent(lcs, lcsCursor);
		for (Object diffCandidate : leftValues) {
			// See bug 405000 for this strange iteration on the LCS
			if (equality.matchingValues(diffCandidate, lcsCurrent.orNull())) {
				lcsCursor++;
				lcsCurrent = getIfPresent(lcs, lcsCursor);
				continue;
			}

			if (contains(comparison, rightValues, diffCandidate)) {
				if (checkOrdering) {
					featureChange(match, feature, diffCandidate, DifferenceKind.MOVE, DifferenceSource.LEFT);
				}
			} else if (FeatureMapUtil.isFeatureMap(feature) && diffCandidate instanceof FeatureMap.Entry) {
				// A value of a FeatureMap changed his key
				if (isFeatureMapEntryKeyChange(equality, (FeatureMap.Entry)diffCandidate, rightValues)) {
					featureChange(match, feature, diffCandidate, DifferenceKind.CHANGE,
							DifferenceSource.LEFT);
				} else if (isFeatureMapValueMove(comparison, (FeatureMap.Entry)diffCandidate,
						DifferenceSource.LEFT)) {
					featureChange(match, feature, diffCandidate, DifferenceKind.MOVE, DifferenceSource.LEFT);
				} else {
					featureChange(match, feature, diffCandidate, DifferenceKind.ADD, DifferenceSource.LEFT);
				}
			} else {
				featureChange(match, feature, diffCandidate, DifferenceKind.ADD, DifferenceSource.LEFT);
			}
		}

		for (Object diffCandidate : rightValues) {

			if (contains(comparison, leftValues, diffCandidate)) {
				// skip elements which were already looked at earlier
				continue;
			}

			// A value that is in the right but not in the left has been deleted or moved.
			if (isFeatureMapMoveFromNonFeatureMapContainment(comparison, feature, diffCandidate, leftValues,
					DifferenceSource.LEFT)) {
				// add move change if the move originates from a non-feature-map containment.
				featureChange(match, feature, diffCandidate, DifferenceKind.MOVE, DifferenceSource.LEFT);
			} else if (!isFeatureMapChangeOrMove(comparison, feature, diffCandidate, leftValues,
					DifferenceSource.LEFT)) {
				featureChange(match, feature, diffCandidate, DifferenceKind.DELETE, DifferenceSource.LEFT);
			}
		}
	}

	/**
	 * Checks if the given candidate is a FeatureMap change of type DifferenceKind.CHANGE.
	 *
	 * @param comparison
	 *            The comparison object.
	 * @param feature
	 *            The feature which values are to be checked.
	 * @param diffCandidate
	 *            The given candidate for which we search an equivalent value.
	 * @param values
	 *            The entries in which we search.
	 * @param source
	 *            The given DifferenceSource of the entry.
	 * @return true if the given candidate is a FeatureMap change of type DifferenceKind.CHANGE, false
	 *         otherwise.
	 */
	private boolean isFeatureMapChange(final Comparison comparison, final EStructuralFeature feature,
			final Object diffCandidate, final List<Object> values, final DifferenceSource source) {
		return FeatureMapUtil.isFeatureMap(feature)
				&& (isFeatureMapEntryKeyChange(comparison.getEqualityHelper(),
						(FeatureMap.Entry)diffCandidate, values));
	}

	/**
	 * Checks if the given candidate is a FeatureMap change of type DifferenceKind.MOVE.
	 *
	 * @param comparison
	 *            The comparison object.
	 * @param feature
	 *            The feature which values are to be checked.
	 * @param diffCandidate
	 *            The given candidate for which we search an equivalent value.
	 * @param values
	 *            The entries in which we search.
	 * @param source
	 *            The given DifferenceSource of the entry.
	 * @return true if the given candidate is a FeatureMap change of type DifferenceKind.MOVE, false
	 *         otherwise.
	 */
	private boolean isFeatureMapMove(final Comparison comparison, final EStructuralFeature feature,
			final Object diffCandidate, final List<Object> values, final DifferenceSource source) {
		return FeatureMapUtil.isFeatureMap(feature)
				&& isFeatureMapValueMove(comparison, (FeatureMap.Entry)diffCandidate, source);
	}

	/**
	 * Checks if the given candidate is a FeatureMap change of type DifferenceKind.MOVE which originates from
	 * a Non-FeatureMap-Containment.
	 *
	 * @param comparison
	 *            The comparison object.
	 * @param feature
	 *            The feature which values are to be checked.
	 * @param diffCandidate
	 *            The given candidate for which we search an equivalent value.
	 * @param values
	 *            The entries in which we search.
	 * @param source
	 *            The given DifferenceSource of the entry.
	 * @return true if the given candidate is a FeatureMap change of type DifferenceKind.MOVE, false
	 *         otherwise.
	 */
	private boolean isFeatureMapMoveFromNonFeatureMapContainment(final Comparison comparison,
			final EStructuralFeature feature, final Object diffCandidate, final List<Object> values,
			final DifferenceSource source) {
		if (isFeatureMapMove(comparison, feature, diffCandidate, values, source)) {
			final Object entryValue = ((FeatureMap.Entry)diffCandidate).getValue();
			if (entryValue instanceof EObject) {
				final EObject leftObject = comparison.getMatch((EObject)entryValue).getLeft();
				return !ComparisonUtil.isContainedInFeatureMap(leftObject);
			}
		}
		return false;
	}

	/**
	 * Checks if the given candidate is a FeatureMap change of type DifferenceKind.CHANGE or
	 * DifferenceKind.MOVE.
	 * 
	 * @param comparison
	 *            The comparison object.
	 * @param feature
	 *            The feature which values are to be checked.
	 * @param diffCandidate
	 *            The given candidate for which we search an equivalent value.
	 * @param values
	 *            The entries in which we search.
	 * @param source
	 *            The given DifferenceSource of the entry.
	 * @return true if the given candidate is a FeatureMap change of type DifferenceKind.CHANGE or
	 *         DifferenceKind.MOVE, false otherwise.
	 */
	private boolean isFeatureMapChangeOrMove(final Comparison comparison, final EStructuralFeature feature,
			final Object diffCandidate, final List<Object> values, final DifferenceSource source) {
		return isFeatureMapChange(comparison, feature, diffCandidate, values, source)
				|| isFeatureMapMove(comparison, feature, diffCandidate, values, source);
	}

	/**
	 * Checks if the entry has its value equivalent in the list of entries, with a different key.
	 * 
	 * @param equality
	 *            Use to compare objects by the org.eclipse.emf.compare.match.IMatchEngine.
	 * @param entry
	 *            The given FeatureMap.Entry for which we search an equivalent value.
	 * @param entries
	 *            The entries in which we search.
	 * @return true if the entry has its value equivalent in the list of entries, with a different key, false
	 *         otherwise.
	 */
	private boolean isFeatureMapEntryKeyChange(final IEqualityHelper equality, final FeatureMap.Entry entry,
			final List<Object> entries) {
		final Object entryValue = entry.getValue();
		final EStructuralFeature entryKey = entry.getEStructuralFeature();
		if (DiffUtil.isContainmentReference(entryKey)) {
			for (Object object : entries) {
				if (object instanceof FeatureMap.Entry) {
					final FeatureMap.Entry featureMapEntry = (FeatureMap.Entry)object;
					if (equality.matchingValues(entryValue, featureMapEntry.getValue())) {
						return !entryKey.equals(featureMapEntry.getEStructuralFeature());
					}
				}
			}
		}
		return false;
	}

	/**
	 * Checks if the entry's value has its equivalent in the opposite side, and thus is a DifferenceKind.MOVE
	 * difference. If the FeatureMapEntry is non-contained the method will return {@code false}.
	 * 
	 * @param comparison
	 *            The comparison object.
	 * @param entry
	 *            The FeatureMap.Entry which contains the value for which we try to find its equivalent.
	 * @param side
	 *            The given DifferenceSource of the entry.
	 * @return {@code true} if the entry's value has its equivalent in the opposite side and is contained
	 *         within the feature map, {@code false} otherwise.
	 */
	private boolean isFeatureMapValueMove(final Comparison comparison, FeatureMap.Entry entry,
			DifferenceSource side) {
		final boolean move;
		final Object entryValue = entry.getValue();
		final EStructuralFeature structuralFeature = entry.getEStructuralFeature();

		if (entryValue instanceof EObject && DiffUtil.isContainmentReference(structuralFeature)) {
			final Match candidateMatch = comparison.getMatch((EObject)entryValue);

			if (candidateMatch == null) {
				move = false;
			} else {
				final EObject value;
				if (side == DifferenceSource.LEFT) {
					value = candidateMatch.getLeft();
				} else {
					value = candidateMatch.getRight();
				}
				final EObject oppositeValue;
				if (comparison.isThreeWay()) {
					oppositeValue = candidateMatch.getOrigin();
				} else {
					oppositeValue = candidateMatch.getRight();
				}

				if (value != null && oppositeValue != null) {
					move = !comparison.getEqualityHelper().matchingValues(value.eContainer(),
							oppositeValue.eContainer());
				} else {
					move = false;
				}
			}
		} else {
			move = false;
		}
		return move;

	}

	/**
	 * Computes the difference between the sides of the given <code>match</code> for the given single-valued
	 * <code>attribute</code>.
	 * 
	 * @param match
	 *            The match which sides we need to check for potential differences.
	 * @param attribute
	 *            The attribute which values are to be checked.
	 */
	protected void computeSingleValuedAttributeDifferences(Match match, EAttribute attribute) {
		final Comparison comparison = match.getComparison();

		final EObject left = match.getLeft();
		Object leftValue = UNMATCHED_VALUE;
		if (left != null) {
			leftValue = safeEGet(left, attribute);
		}
		final EObject right = match.getRight();
		Object rightValue = UNMATCHED_VALUE;
		if (right != null) {
			rightValue = safeEGet(right, attribute);
		}

		final IEqualityHelper helper = comparison.getEqualityHelper();
		final EObject origin = match.getOrigin();
		if (helper.matchingValues(leftValue, rightValue)) {
			// Identical values in left and right. The only problematic case is if they do not match the
			// origin (and left and right are defined, i.e don't detect attribute change on unmatched)
			if (leftValue != UNMATCHED_VALUE && comparison.isThreeWay()) {
				final Object originValue;
				if (origin == null) {
					originValue = null;
				} else {
					originValue = safeEGet(origin, attribute);
				}
				final boolean matchingLO = helper.matchingValues(leftValue, originValue);

				// if !matchingLO, the same change has been made on both side. This is actually a
				// pseudo-conflict.
				if (!matchingLO && !isNullOrEmptyString(leftValue)) {
					// The same value has been SET or CHANGED on both sides
					// (depending on whether origin is null or not)
					getDiffProcessor().attributeChange(match, attribute, leftValue, DifferenceKind.CHANGE,
							DifferenceSource.LEFT);
					getDiffProcessor().attributeChange(match, attribute, rightValue, DifferenceKind.CHANGE,
							DifferenceSource.RIGHT);
				} else if (!matchingLO) {
					// The same value has been UNSET from both sides
					getDiffProcessor().attributeChange(match, attribute, originValue, DifferenceKind.CHANGE,
							DifferenceSource.LEFT);
					getDiffProcessor().attributeChange(match, attribute, originValue, DifferenceKind.CHANGE,
							DifferenceSource.RIGHT);
				}
			}
		} else if (origin != null) {
			final Object originValue = safeEGet(origin, attribute);

			if (helper.matchingValues(leftValue, originValue)) {
				Object changedValue = rightValue;
				if (isNullOrEmptyString(rightValue)) {
					changedValue = originValue;
				}

				if (rightValue != UNMATCHED_VALUE) {
					// Value is in left and origin, but not in the right
					getDiffProcessor().attributeChange(match, attribute, changedValue, DifferenceKind.CHANGE,
							DifferenceSource.RIGHT);
				} else {
					// Right is unmatched, left is the same as in the origin. No diff here : the diff is on
					// the match itself, not on one of its attributes.
				}
			} else if (helper.matchingValues(rightValue, originValue)) {
				Object changedValue = leftValue;
				if (isNullOrEmptyString(leftValue)) {
					changedValue = originValue;
				}

				if (leftValue != UNMATCHED_VALUE) {
					// Value is in right and origin, but not in left
					getDiffProcessor().attributeChange(match, attribute, changedValue, DifferenceKind.CHANGE,
							DifferenceSource.LEFT);
				} else {
					// Left is unmatched, right is the same as in the origin. No diff here : the diff is on
					// the match itself, not on one of its attributes.
				}
			} else {
				/*
				 * Left and right are different. None match what's in the origin. Those of the two that are
				 * not unmatched are thus a "change" difference, with a possible conflict.
				 */
				Object leftChange = leftValue;
				if (isNullOrEmptyString(leftValue)) {
					leftChange = originValue;
				}
				Object rightChange = rightValue;
				if (isNullOrEmptyString(rightValue)) {
					rightChange = originValue;
				}

				if (leftValue != UNMATCHED_VALUE) {
					getDiffProcessor().attributeChange(match, attribute, leftChange, DifferenceKind.CHANGE,
							DifferenceSource.LEFT);
				}
				if (rightValue != UNMATCHED_VALUE) {
					getDiffProcessor().attributeChange(match, attribute, rightChange, DifferenceKind.CHANGE,
							DifferenceSource.RIGHT);
				}
			}
		} else {
			// Left and right values are different, and we have no origin.
			if (leftValue != UNMATCHED_VALUE) {
				if (isNullOrEmptyString(leftValue)) {
					getDiffProcessor().attributeChange(match, attribute, rightValue, DifferenceKind.CHANGE,
							DifferenceSource.LEFT);
				} else {
					getDiffProcessor().attributeChange(match, attribute, leftValue, DifferenceKind.CHANGE,
							DifferenceSource.LEFT);
				}
			}
			if (comparison.isThreeWay() && rightValue != UNMATCHED_VALUE) {
				if (isNullOrEmptyString(rightValue)) {
					getDiffProcessor().attributeChange(match, attribute, leftValue, DifferenceKind.CHANGE,
							DifferenceSource.RIGHT);
				} else {
					getDiffProcessor().attributeChange(match, attribute, rightValue, DifferenceKind.CHANGE,
							DifferenceSource.RIGHT);
				}
			}
		}
	}

	/**
	 * Returns {@code true} if the given {@code object} is {@code null} or the empty String.
	 * 
	 * @param object
	 *            The object we need to test.
	 * @return {@code true} if the given {@code object} is {@code null} or the empty String.
	 */
	private boolean isNullOrEmptyString(Object object) {
		return object == null || "".equals(object); //$NON-NLS-1$
	}

	/**
	 * Returns {@code true} if the given {@code object} is {@code null} or the {@link #UNMATCHED_VALUE}.
	 * 
	 * @param object
	 *            The object we need to test.
	 * @return {@code true} if the given {@code object} is {@code null} or the {@link #UNMATCHED_VALUE}.
	 */
	private boolean isNullOrUnmatched(Object object) {
		return object == null || object == UNMATCHED_VALUE;
	}

	/**
	 * Computes the difference between the sides of the given <code>match</code> for the given single-valued
	 * <code>reference</code>.
	 * <p>
	 * The given {@code reference} cannot be a containment reference.
	 * </p>
	 * <p>
	 * This is only meant for three-way comparisons.
	 * </p>
	 * 
	 * @param match
	 *            The match which sides we need to check for potential differences.
	 * @param reference
	 *            The reference which values are to be checked.
	 */
	protected void computeSingleValuedReferenceDifferencesThreeWay(Match match, EReference reference) {
		final Comparison comparison = match.getComparison();

		final EObject left = match.getLeft();
		Object leftValue = UNMATCHED_VALUE;
		if (left != null) {
			leftValue = safeEGet(left, reference);
		}
		final EObject right = match.getRight();
		Object rightValue = UNMATCHED_VALUE;
		if (right != null) {
			rightValue = safeEGet(right, reference);
		}
		final EObject origin = match.getOrigin();
		Object originValue = UNMATCHED_VALUE;
		if (origin != null) {
			originValue = safeEGet(origin, reference);
		}

		boolean distinctValueLO = !comparison.getEqualityHelper().matchingValues(leftValue, originValue);
		// consider null and unmatched as the same
		distinctValueLO = distinctValueLO
				&& !(isNullOrUnmatched(leftValue) && isNullOrUnmatched(originValue));

		if (distinctValueLO) {
			// Left and origin are distinct
			if (leftValue == null || leftValue == UNMATCHED_VALUE) {
				// Left has been removed
				getDiffProcessor().referenceChange(match, reference, (EObject)originValue,
						DifferenceKind.CHANGE, DifferenceSource.LEFT);
			} else {
				// Left has been set to a new value, or left has been added altogether
				getDiffProcessor().referenceChange(match, reference, (EObject)leftValue,
						DifferenceKind.CHANGE, DifferenceSource.LEFT);
			}
		}

		boolean distinctValueRO = !comparison.getEqualityHelper().matchingValues(rightValue, originValue);
		// consider null and unmatched as the same
		distinctValueRO = distinctValueRO
				&& !(isNullOrUnmatched(rightValue) && isNullOrUnmatched(originValue));

		if (distinctValueRO) {
			// Right and origin are distinct
			if (rightValue == null || rightValue == UNMATCHED_VALUE) {
				// right value is unset, or right has been removed
				getDiffProcessor().referenceChange(match, reference, (EObject)originValue,
						DifferenceKind.CHANGE, DifferenceSource.RIGHT);
			} else {
				// Right has been set to a new value, or right has been added altogether
				getDiffProcessor().referenceChange(match, reference, (EObject)rightValue,
						DifferenceKind.CHANGE, DifferenceSource.RIGHT);
			}
		}
	}

	/**
	 * Computes the difference between the sides of the given <code>match</code> for the given single-valued
	 * <code>reference</code>.
	 * <p>
	 * The given {@code reference} cannot be a containment reference.
	 * </p>
	 * <p>
	 * This is only meant for two-way comparisons.
	 * </p>
	 * 
	 * @param match
	 *            The match which sides we need to check for potential differences.
	 * @param reference
	 *            The reference which values are to be checked.
	 */
	protected void computeSingleValuedReferenceDifferencesTwoWay(Match match, EReference reference) {
		final Comparison comparison = match.getComparison();

		final EObject left = match.getLeft();
		Object leftValue = UNMATCHED_VALUE;
		if (left != null) {
			leftValue = safeEGet(left, reference);
		}
		final EObject right = match.getRight();
		Object rightValue = UNMATCHED_VALUE;
		if (right != null) {
			rightValue = safeEGet(right, reference);
		}

		boolean distinctValue = !comparison.getEqualityHelper().matchingValues(leftValue, rightValue);
		// consider null and unmatched as the same
		distinctValue = distinctValue && !(isNullOrUnmatched(leftValue) && isNullOrUnmatched(rightValue));

		if (distinctValue) {
			if (leftValue == null || leftValue == UNMATCHED_VALUE) {
				// left value is unset, or left has been removed
				getDiffProcessor().referenceChange(match, reference, (EObject)rightValue,
						DifferenceKind.CHANGE, DifferenceSource.LEFT);
			} else {
				// Left has been set to a new value, or left has been added altogether
				getDiffProcessor().referenceChange(match, reference, (EObject)leftValue,
						DifferenceKind.CHANGE, DifferenceSource.LEFT);
			}
		}
	}

	/**
	 * This will be used in order to create the {@link FeatureFilter} that should be used by this engine to
	 * determine the structural features on which it is to try and detect differences.
	 * 
	 * @return The newly created feature filter.
	 */
	protected FeatureFilter createFeatureFilter() {
		return new FeatureFilter();
	}

	/**
	 * Delegates to the diff processor to create the specified feature change.
	 * 
	 * @param match
	 *            The match on which values we detected a diff.
	 * @param feature
	 *            The exact feature on which a diff was detected.
	 * @param value
	 *            The value for which we detected a changed.
	 * @param kind
	 *            The kind of difference to create.
	 * @param source
	 *            The source from which originates that diff.
	 */
	protected void featureChange(Match match, EStructuralFeature feature, Object value, DifferenceKind kind,
			DifferenceSource source) {
		if (FeatureMapUtil.isFeatureMap(feature)) {
			getDiffProcessor().featureMapChange(match, (EAttribute)feature, value, kind, source);
		} else if (feature instanceof EAttribute) {
			getDiffProcessor().attributeChange(match, (EAttribute)feature, value, kind, source);
		} else if (value instanceof EObject) {
			getDiffProcessor().referenceChange(match, (EReference)feature, (EObject)value, kind, source);
		}
	}

	/**
	 * This will return the diff processor that has been created through {@link #createDiffProcessor()} for
	 * this differencing process.
	 * 
	 * @return The diff processor to notify of difference detections.
	 */
	protected final IDiffProcessor getDiffProcessor() {
		return diffProcessor;
	}
}
