refactored EMF compare 2 integration
diff --git a/plugins/org.eclipse.mylyn.docs.intent.compare/src/org/eclipse/mylyn/docs/intent/compare/match/EditionDistance.java b/plugins/org.eclipse.mylyn.docs.intent.compare/src/org/eclipse/mylyn/docs/intent/compare/match/EditionDistance.java
index c9ca566..b6355fe 100644
--- a/plugins/org.eclipse.mylyn.docs.intent.compare/src/org/eclipse/mylyn/docs/intent/compare/match/EditionDistance.java
+++ b/plugins/org.eclipse.mylyn.docs.intent.compare/src/org/eclipse/mylyn/docs/intent/compare/match/EditionDistance.java
@@ -10,18 +10,11 @@
  *******************************************************************************/

 package org.eclipse.mylyn.docs.intent.compare.match;

 

-import com.google.common.base.Predicate;

-import com.google.common.collect.Iterables;

-import com.google.common.collect.Iterators;

-import com.google.common.collect.Maps;

-import com.google.common.collect.Sets;

-

 import java.util.Iterator;

 import java.util.Map;

 import java.util.Set;

 

 import org.eclipse.emf.common.notify.Notifier;

-import org.eclipse.emf.common.util.URI;

 import org.eclipse.emf.compare.CompareFactory;

 import org.eclipse.emf.compare.Comparison;

 import org.eclipse.emf.compare.DifferenceKind;

@@ -40,6 +33,12 @@
 import org.eclipse.emf.ecore.EReference;

 import org.eclipse.emf.ecore.EStructuralFeature;

 

+import com.google.common.base.Predicate;

+import com.google.common.collect.Iterables;

+import com.google.common.collect.Iterators;

+import com.google.common.collect.Maps;

+import com.google.common.collect.Sets;

+

 /**

  * This distance function implementation will actually compare the given EObject.

  * 

@@ -77,6 +76,11 @@
 	private Set<EStructuralFeature> toBeIgnored;

 

 	/**

+	 * The instance used to compare location of EObjects.

+	 */

+	private URIDistance uriDistance = new URIDistance();

+

+	/**

 	 * The equality helper used to retrieve the URIs through its cache and to instanciate a specific diff

 	 * engine.

 	 */

@@ -97,17 +101,37 @@
 	/**

 	 * Instanciate a new Edition Distance using the given equality helper.

 	 * 

-	 * @param equalityHelper

-	 *            the equality helper to use.

 	 * @param leftRoot

 	 *            the left root of the comparison

 	 * @param rightRoot

 	 *            the right root of the comparison

 	 */

 	// FORK

-	public EditionDistance(EqualityHelper equalityHelper, Notifier leftRoot, Notifier rightRoot) {

+	public EditionDistance(Notifier leftRoot, Notifier rightRoot) {

 		weights = Maps.newHashMap();

-		this.helper = equalityHelper;

+		this.helper = new EqualityHelper() {

+

+			@Override

+			protected boolean matchingEObjects(Comparison comparison, EObject object1, EObject object2) {

+				final Match match = comparison.getMatch(object1);

+

+				final boolean equal;

+				// Match could be null if the value is out of the scope

+				if (match != null) {

+					equal = match.getLeft() == object2 || match.getRight() == object2

+							|| match.getOrigin() == object2;

+				} else {

+					/*

+					 * use a temporary variable as buffer for the "equal" boolean. We know that the following

+					 * try/catch block can, and will, only initialize it once ... but the compiler does not.

+					 */

+					equal = uriDistance.proximity(object1, object2) == 0;

+				}

+

+				return equal;

+			}

+

+		};

 		this.toBeIgnored = Sets.newLinkedHashSet();

 		this.leftRoot = leftRoot;

 		this.rightRoot = rightRoot;

@@ -116,30 +140,37 @@
 	/**

 	 * {@inheritDoc}

 	 */

-	// FORK

-	public int distance(EObject a, EObject b, int maxDistance) {

-		int distance = maxDistance;

-		if (a.equals(leftRoot) && b.equals(rightRoot) || b.equals(leftRoot) && a.equals(rightRoot)) {

-			distance = 0;

-		} else {

-			distance = new IntentCountingDiffEngine(this, maxDistance).measureDifferences(a, b);

+	public int distance(EObject a, EObject b) {

+		int maxDist = Math.max(getMaxDistance(a), getMaxDistance(b));

+		// FORK

+		int measuredDist = new IntentCountingDiffEngine(this, maxDist).measureDifferences(a, b);

+		if (measuredDist >= maxDist) {

+			return Integer.MAX_VALUE;

 		}

-		return distance;

+		return measuredDist;

+	}

+

+	/**

+	 * {@inheritDoc}

+	 */

+	public boolean areIdentic(EObject a, EObject b) {

+		// FORK

+		return a.equals(leftRoot) && b.equals(rightRoot) || b.equals(leftRoot) && a.equals(rightRoot)

+				|| new IntentCountingDiffEngine(this, 0).measureDifferences(a, b) == 0;

 	}

 

 	/**

 	 * Create a new builder to instanciate and configure an EditionDistance.

 	 * 

-	 * @param helper

-	 *            the equality helper (required to instanciate an EditionDistance).

 	 * @param leftRoot

 	 *            the left root of the comparison

 	 * @param rightRoot

 	 *            the right root of the comparison

 	 * @return a configuration builder.

 	 */

-	public static Builder builder(EqualityHelper helper, Notifier leftRoot, Notifier rightRoot) {

-		return new Builder(helper, leftRoot, rightRoot);

+	// FORK

+	public static Builder builder(Notifier leftRoot, Notifier rightRoot) {

+		return new Builder(leftRoot, rightRoot);

 	}

 

 	/**

@@ -154,16 +185,14 @@
 		/**

 		 * Create the builder.

 		 * 

-		 * @param toBe

-		 *            the equality helper (required to instanciate an EditionDistance).

 		 * @param leftRoot

 		 *            the left root of the comparison

 		 * @param rightRoot

 		 *            the right root of the comparison

 		 */

 		// FORK

-		public Builder(EqualityHelper toBe, Notifier leftRoot, Notifier rightRoot) {

-			this.toBeBuilt = new EditionDistance(toBe, leftRoot, rightRoot);

+		public Builder(Notifier leftRoot, Notifier rightRoot) {

+			this.toBeBuilt = new EditionDistance(leftRoot, rightRoot);

 		}

 

 		/**

@@ -393,13 +422,9 @@
 			Match fakeMatch = CompareFactory.eINSTANCE.createMatch();

 			fakeMatch.setLeft(a);

 			fakeMatch.setRight(b);

-			URI aLocation = helper.getURI(a);

-			URI bLocation = helper.getURI(b);

 			int changes = 0;

-			if (!aLocation.fragment().equals(bLocation.fragment())) {

-				int dist = new URIDistance().proximity(aLocation.fragment(), bLocation.fragment());

-				changes += dist * locationChangeCoef;

-			}

+			int dist = uriDistance.proximity(a, b);

+			changes += dist * locationChangeCoef;

 			if (changes <= maxDistance) {

 				checkForDifferences(fakeMatch);

 				changes += getCounter().getComputedDistance();

@@ -427,7 +452,7 @@
 					return Iterators.filter(super.getReferencesToCheck(match), new Predicate<EReference>() {

 

 						public boolean apply(EReference input) {

-							return toBeIgnored.contains(input) && !input.isContainment();

+							return !toBeIgnored.contains(input) && !input.isContainment();

 						}

 					});

 				}

@@ -466,15 +491,17 @@
 		// assess the quality of further changes.

 		int max = 0;

 		for (EReference feat : Iterables.filter(eObj.eClass().getEAllReferences(), featureFilter)) {

-			if (!feat.isContainer() && eObj.eIsSet(feat)) {

+			if (!feat.isContainer() && !feat.isContainment() && eObj.eIsSet(feat)) {

 				max += getWeight(feat) * referenceChangeCoef;

 			}

 		}

 		for (EAttribute feat : Iterables.filter(eObj.eClass().getEAllAttributes(), featureFilter)) {

-			max += getWeight(feat) * attributeChangeCoef;

+			if (eObj.eIsSet(feat)) {

+				max += getWeight(feat) * attributeChangeCoef;

+			}

 		}

-		max = max + locationChangeCoef * 5 - 1;

-		// System.out.println(eObj.eClass().getName() + ":" + eObj + ":" + max);

-		return max;

+		max = max + locationChangeCoef * 5;

+		return max / 2;

 	}

+

 }

diff --git a/plugins/org.eclipse.mylyn.docs.intent.compare/src/org/eclipse/mylyn/docs/intent/compare/match/IntentCountingDiffEngine.java b/plugins/org.eclipse.mylyn.docs.intent.compare/src/org/eclipse/mylyn/docs/intent/compare/match/IntentCountingDiffEngine.java
index 7b2c8ea..208f975 100644
--- a/plugins/org.eclipse.mylyn.docs.intent.compare/src/org/eclipse/mylyn/docs/intent/compare/match/IntentCountingDiffEngine.java
+++ b/plugins/org.eclipse.mylyn.docs.intent.compare/src/org/eclipse/mylyn/docs/intent/compare/match/IntentCountingDiffEngine.java
@@ -12,6 +12,8 @@
 

 import org.eclipse.emf.ecore.EObject;

 import org.eclipse.mylyn.docs.intent.compare.match.EditionDistance.CountingDiffEngine;

+import org.eclipse.mylyn.docs.intent.compare.utils.LocationDistanceUtils;

+import org.eclipse.mylyn.docs.intent.compare.utils.StringDistanceUtils;

 import org.eclipse.mylyn.docs.intent.core.descriptionunit.DescriptionBloc;

 import org.eclipse.mylyn.docs.intent.core.descriptionunit.DescriptionUnit;

 import org.eclipse.mylyn.docs.intent.core.document.IntentDocument;

@@ -33,9 +35,9 @@
  */

 public class IntentCountingDiffEngine extends CountingDiffEngine {

 

-	private static final double LOCALIZATION_DISTANCE_WEIGHT = 0.2;

+	private static final double LOCALIZATION_DISTANCE_WEIGHT = 0.15;

 

-	private static final double IDENTIFIER_DISTANCE_WEIGHT = 0.8;

+	private static final double IDENTIFIER_DISTANCE_WEIGHT = 0.85;

 

 	/**

 	 * Constructor.

@@ -65,7 +67,7 @@
 		Integer distance = null;

 

 		// the default localization distance

-		Integer uriDistance = getURIDistance(a, b);

+		Integer locationDistance = getLocationDistance(a, b);

 

 		// the semantic distance: in the best case, a title or feature id. If not available, the

 		// element serialization

@@ -74,17 +76,21 @@
 			identifierDistance = getSerializationDistance(a, b);

 		}

 

-		if (identifierDistance != null) {

-			distance = (int)(identifierDistance * IDENTIFIER_DISTANCE_WEIGHT + uriDistance

+		if (identifierDistance != null && locationDistance != null) {

+			distance = (int)(identifierDistance * IDENTIFIER_DISTANCE_WEIGHT + locationDistance

 					* LOCALIZATION_DISTANCE_WEIGHT);

+		} else if (identifierDistance != null) {

+			distance = identifierDistance;

+		} else if (locationDistance != null) {

+			distance = locationDistance;

 		} else {

-			distance = uriDistance;

+			distance = super.measureDifferences(a, b);

 		}

 		return distance;

 	}

 

 	/**

-	 * Returns the distance between document elements by comparing their uris.

+	 * Returns the distance between document elements by comparing their locations.

 	 * 

 	 * @param a

 	 *            the first element

@@ -92,10 +98,10 @@
 	 *            the second element

 	 * @return the distance between two strings

 	 */

-	private Integer getURIDistance(EObject a, EObject b) {

+	private Integer getLocationDistance(EObject a, EObject b) {

 		Integer distance = null;

-		String fragmentA = helper.getURI(a).fragment();

-		String fragmentB = helper.getURI(b).fragment();

+		String fragmentA = LocationDistanceUtils.computeLevel(a);

+		String fragmentB = LocationDistanceUtils.computeLevel(b);

 		if (fragmentA != null && fragmentB != null) {

 			distance = StringDistanceUtils.getStringDistance(fragmentA, fragmentB);

 		}

diff --git a/plugins/org.eclipse.mylyn.docs.intent.compare/src/org/eclipse/mylyn/docs/intent/compare/utils/EMFCompareUtils.java b/plugins/org.eclipse.mylyn.docs.intent.compare/src/org/eclipse/mylyn/docs/intent/compare/utils/EMFCompareUtils.java
index ec7d6a8..9bf12e5 100644
--- a/plugins/org.eclipse.mylyn.docs.intent.compare/src/org/eclipse/mylyn/docs/intent/compare/utils/EMFCompareUtils.java
+++ b/plugins/org.eclipse.mylyn.docs.intent.compare/src/org/eclipse/mylyn/docs/intent/compare/utils/EMFCompareUtils.java
@@ -10,22 +10,21 @@
  *******************************************************************************/

 package org.eclipse.mylyn.docs.intent.compare.utils;

 

-import com.google.common.base.Predicate;

+import static com.google.common.base.Predicates.instanceOf;

+import static com.google.common.base.Predicates.not;

+import static com.google.common.base.Predicates.or;

 

 import org.eclipse.emf.common.notify.Notifier;

 import org.eclipse.emf.compare.Comparison;

 import org.eclipse.emf.compare.EMFCompare;

 import org.eclipse.emf.compare.match.eobject.IEObjectMatcher;

 import org.eclipse.emf.compare.match.eobject.ProximityEObjectMatcher;

-import org.eclipse.emf.compare.utils.EqualityHelper;

 import org.eclipse.emf.compare.utils.UseIdentifiers;

 import org.eclipse.mylyn.docs.intent.compare.scope.IntentComparisonScope;

 import org.eclipse.mylyn.docs.intent.core.compiler.CompilationStatus;

 import org.eclipse.mylyn.docs.intent.core.compiler.SynchronizerCompilationStatus;

 

-import static com.google.common.base.Predicates.instanceOf;

-import static com.google.common.base.Predicates.not;

-import static com.google.common.base.Predicates.or;

+import com.google.common.base.Predicate;

 

 /**

  * Utilities for EMF Compare use.

@@ -55,7 +54,6 @@
 	 */

 	public static Comparison compare(Notifier left, Notifier right) {

 		IntentComparisonScope scope = new IntentComparisonScope(left, right);

-		EqualityHelper helper = new IntentEqualityHelper();

 

 		Predicate<Object> filter = not(or(instanceOf(CompilationStatus.class),

 				instanceOf(SynchronizerCompilationStatus.class)));

@@ -63,8 +61,10 @@
 

 		EMFCompare compare = EMFCompare.newComparator(scope);

 		compare.matchByID(UseIdentifiers.NEVER);

-		compare.setEqualityHelper(helper);

-		return compare.compare();

+		Comparison comparison = compare.compare();

+

+		// IntentPrettyPrinter.printMatch(comparison, System.out);

+		return comparison;

 	}

 

 	/**

@@ -83,20 +83,20 @@
 	 */

 	public static Comparison compareDocuments(Notifier left, Notifier right) {

 		IntentComparisonScope scope = new IntentComparisonScope(left, right);

-		EqualityHelper helper = new IntentEqualityHelper();

 

 		Predicate<Object> filter = not(or(instanceOf(CompilationStatus.class),

 				instanceOf(SynchronizerCompilationStatus.class)));

 		scope.setEObjectContentFilter(filter);

 

 		IEObjectMatcher matcher = ProximityEObjectMatcher.builder(

-				org.eclipse.mylyn.docs.intent.compare.match.EditionDistance.builder(helper, left, right)

-						.build()).build();

+				org.eclipse.mylyn.docs.intent.compare.match.EditionDistance.builder(left, right).build())

+				.build();

 

 		EMFCompare compare = EMFCompare.newComparator(scope);

 		compare.setEObjectMatcher(matcher);

 		compare.matchByID(UseIdentifiers.NEVER);

-		compare.setEqualityHelper(helper);

-		return compare.compare();

+

+		Comparison comparison = compare.compare();

+		return comparison;

 	}

 }

diff --git a/tests/org.eclipse.mylyn.docs.intent.compare.test/src/org/eclipse/mylyn/docs/intent/compare/test/utils/IntentPrettyPrinter.java b/plugins/org.eclipse.mylyn.docs.intent.compare/src/org/eclipse/mylyn/docs/intent/compare/utils/IntentPrettyPrinter.java
similarity index 97%
rename from tests/org.eclipse.mylyn.docs.intent.compare.test/src/org/eclipse/mylyn/docs/intent/compare/test/utils/IntentPrettyPrinter.java
rename to plugins/org.eclipse.mylyn.docs.intent.compare/src/org/eclipse/mylyn/docs/intent/compare/utils/IntentPrettyPrinter.java
index 1f2248d..a8a141a 100644
--- a/tests/org.eclipse.mylyn.docs.intent.compare.test/src/org/eclipse/mylyn/docs/intent/compare/test/utils/IntentPrettyPrinter.java
+++ b/plugins/org.eclipse.mylyn.docs.intent.compare/src/org/eclipse/mylyn/docs/intent/compare/utils/IntentPrettyPrinter.java
@@ -8,7 +8,7 @@
  * Contributors:

  *     Obeo - initial API and implementation

  *******************************************************************************/

-package org.eclipse.mylyn.docs.intent.compare.test.utils;

+package org.eclipse.mylyn.docs.intent.compare.utils;

 

 import java.io.PrintStream;

 import java.util.Arrays;

@@ -23,7 +23,6 @@
 import org.eclipse.emf.compare.MatchResource;

 import org.eclipse.emf.compare.ReferenceChange;

 import org.eclipse.emf.ecore.EObject;

-import org.eclipse.mylyn.docs.intent.compare.utils.IntentEqualityHelper;

 import org.eclipse.mylyn.docs.intent.core.document.IntentDocument;

 import org.eclipse.mylyn.docs.intent.core.modelingunit.StructuralFeatureAffectation;

 import org.eclipse.mylyn.docs.intent.markup.markup.Annotations;

@@ -36,6 +35,7 @@
  * stream.

  * 

  * @author <a href="mailto:laurent.goubet@obeo.fr">Laurent Goubet</a>

+ * @author <a href="mailto:william.piers@obeo.fr">William Piers</a>

  */

 @SuppressWarnings("nls")

 public final class IntentPrettyPrinter {

@@ -455,10 +455,10 @@
 			res = "?";

 		} else {

 			res = element.eClass().getName();

-			String fragment = new IntentEqualityHelper().getURI(element).fragment();

-			if (fragment != null) {

-				res += "[" + fragment + "]";

-			}

+			// String fragment = new IntentEqualityHelper().getURI(element).fragment();

+			// if (fragment != null) {

+			// res += "[" + fragment + "]";

+			// }

 		}

 		if (element instanceof Text) {

 			res = "\"" + ((Text)element).getData() + "\"";

diff --git a/plugins/org.eclipse.mylyn.docs.intent.compare/src/org/eclipse/mylyn/docs/intent/compare/utils/IntentEqualityHelper.java b/plugins/org.eclipse.mylyn.docs.intent.compare/src/org/eclipse/mylyn/docs/intent/compare/utils/LocationDistanceUtils.java
similarity index 70%
rename from plugins/org.eclipse.mylyn.docs.intent.compare/src/org/eclipse/mylyn/docs/intent/compare/utils/IntentEqualityHelper.java
rename to plugins/org.eclipse.mylyn.docs.intent.compare/src/org/eclipse/mylyn/docs/intent/compare/utils/LocationDistanceUtils.java
index 0b9571d..f34636c 100644
--- a/plugins/org.eclipse.mylyn.docs.intent.compare/src/org/eclipse/mylyn/docs/intent/compare/utils/IntentEqualityHelper.java
+++ b/plugins/org.eclipse.mylyn.docs.intent.compare/src/org/eclipse/mylyn/docs/intent/compare/utils/LocationDistanceUtils.java
@@ -10,31 +10,20 @@
  *******************************************************************************/

 package org.eclipse.mylyn.docs.intent.compare.utils;

 

-import org.eclipse.emf.common.util.URI;

-import org.eclipse.emf.compare.utils.EqualityHelper;

 import org.eclipse.emf.ecore.EObject;

 import org.eclipse.mylyn.docs.intent.core.document.IntentStructuredElement;

 

 /**

- * An {@link EqualityHelper} redefinition used to define accurate URIs.

+ * Location distance computation utilities.

  * 

  * @author <a href="mailto:william.piers@obeo.fr">William Piers</a>

  */

-public class IntentEqualityHelper extends EqualityHelper {

+public final class LocationDistanceUtils {

 

 	/**

-	 * {@inheritDoc}

-	 * 

-	 * @see org.eclipse.emf.compare.utils.EqualityHelper#getURI(org.eclipse.emf.ecore.EObject)

+	 * Prevents instantiation.

 	 */

-	@Override

-	public URI getURI(EObject object) {

-		URI uri = super.getURI(object);

-		String level = computeLevel(object);

-		if (level != null) {

-			uri = uri.trimFragment().appendFragment(level);

-		}

-		return uri;

+	private LocationDistanceUtils() {

 	}

 

 	/**

@@ -44,7 +33,7 @@
 	 *            the object

 	 * @return the level of the given object inside of the model tree

 	 */

-	private static String computeLevel(EObject object) {

+	public static String computeLevel(EObject object) {

 		String level = null;

 		if (object instanceof IntentStructuredElement) {

 			level = ((IntentStructuredElement)object).getCompleteLevel();

@@ -63,5 +52,4 @@
 		}

 		return level;

 	}

-

 }

diff --git a/plugins/org.eclipse.mylyn.docs.intent.compare/src/org/eclipse/mylyn/docs/intent/compare/match/StringDistanceUtils.java b/plugins/org.eclipse.mylyn.docs.intent.compare/src/org/eclipse/mylyn/docs/intent/compare/utils/StringDistanceUtils.java
similarity index 97%
rename from plugins/org.eclipse.mylyn.docs.intent.compare/src/org/eclipse/mylyn/docs/intent/compare/match/StringDistanceUtils.java
rename to plugins/org.eclipse.mylyn.docs.intent.compare/src/org/eclipse/mylyn/docs/intent/compare/utils/StringDistanceUtils.java
index 9772783..7cced6b 100644
--- a/plugins/org.eclipse.mylyn.docs.intent.compare/src/org/eclipse/mylyn/docs/intent/compare/match/StringDistanceUtils.java
+++ b/plugins/org.eclipse.mylyn.docs.intent.compare/src/org/eclipse/mylyn/docs/intent/compare/utils/StringDistanceUtils.java
@@ -8,7 +8,7 @@
  * Contributors:

  *     Obeo - initial API and implementation

  *******************************************************************************/

-package org.eclipse.mylyn.docs.intent.compare.match;

+package org.eclipse.mylyn.docs.intent.compare.utils;

 

 import org.eclipse.emf.compare.utils.DiffUtil;

 

diff --git a/tests/org.eclipse.mylyn.docs.intent.compare.test/src/org/eclipse/mylyn/docs/intent/compare/test/unit/MergingIssues.java b/tests/org.eclipse.mylyn.docs.intent.compare.test/src/org/eclipse/mylyn/docs/intent/compare/test/unit/MergingIssues.java
index c24b7ca..d786f81 100644
--- a/tests/org.eclipse.mylyn.docs.intent.compare.test/src/org/eclipse/mylyn/docs/intent/compare/test/unit/MergingIssues.java
+++ b/tests/org.eclipse.mylyn.docs.intent.compare.test/src/org/eclipse/mylyn/docs/intent/compare/test/unit/MergingIssues.java
@@ -16,8 +16,8 @@
 import org.eclipse.emf.compare.Comparison;

 import org.eclipse.emf.compare.Diff;

 import org.eclipse.mylyn.docs.intent.compare.test.utils.AbstractEMFCompareTest;

-import org.eclipse.mylyn.docs.intent.compare.test.utils.IntentPrettyPrinter;

 import org.eclipse.mylyn.docs.intent.compare.utils.EMFCompareUtils;

+import org.eclipse.mylyn.docs.intent.compare.utils.IntentPrettyPrinter;

 import org.eclipse.mylyn.docs.intent.core.document.IntentStructuredElement;

 import org.eclipse.mylyn.docs.intent.parser.modelingunit.ParseException;

 import org.eclipse.mylyn.docs.intent.serializer.IntentSerializer;