Bug 313553 - Requirement: fix comparisons to match OSGi LDAP spec.

The non-constant argument can be a collection in which case the
comparison operation must iterate through it testing each element.

Change-Id: I4105bc9b746c4e5767ecc77f80c93a1cbc82d65e
Signed-off-by: Todor Boev <rinsvind@gmail.com>
diff --git a/bundles/org.eclipse.equinox.p2.metadata/src/org/eclipse/equinox/internal/p2/metadata/expression/Compare.java b/bundles/org.eclipse.equinox.p2.metadata/src/org/eclipse/equinox/internal/p2/metadata/expression/Compare.java
index 7e958e4..5ee16f7 100644
--- a/bundles/org.eclipse.equinox.p2.metadata/src/org/eclipse/equinox/internal/p2/metadata/expression/Compare.java
+++ b/bundles/org.eclipse.equinox.p2.metadata/src/org/eclipse/equinox/internal/p2/metadata/expression/Compare.java
@@ -10,6 +10,7 @@
  *******************************************************************************/
 package org.eclipse.equinox.internal.p2.metadata.expression;
 
+import java.util.Collection;
 import org.eclipse.equinox.p2.metadata.expression.IEvaluationContext;
 
 /**
@@ -31,7 +32,30 @@
 	}
 
 	public Object evaluate(IEvaluationContext context) {
-		int cmpResult = CoercingComparator.coerceAndCompare(lhs.evaluate(context), rhs.evaluate(context));
+		Object lhsVal = lhs.evaluate(context);
+		Object rhsVal = rhs.evaluate(context);
+
+		// Handle collections as per the OSGi LDAP spec
+		if (lhsVal instanceof Collection<?>) {
+			for (Object lhsItem : (Collection<?>) lhsVal) {
+				int cmpResult = CoercingComparator.coerceAndCompare(lhsItem, rhsVal);
+
+				if (cmpResult == 0) {
+					return equalOK;
+				}
+
+				if (cmpResult < 0 && compareLess) {
+					return true;
+				}
+
+				if (!compareLess) {
+					return true;
+				}
+			}
+			return false;
+		}
+
+		int cmpResult = CoercingComparator.coerceAndCompare(lhsVal, rhsVal);
 		return Boolean.valueOf(cmpResult == 0 ? equalOK : (cmpResult < 0 ? compareLess : !compareLess));
 	}
 
diff --git a/bundles/org.eclipse.equinox.p2.metadata/src/org/eclipse/equinox/internal/p2/metadata/expression/Equals.java b/bundles/org.eclipse.equinox.p2.metadata/src/org/eclipse/equinox/internal/p2/metadata/expression/Equals.java
index c318776..4992d79 100644
--- a/bundles/org.eclipse.equinox.p2.metadata/src/org/eclipse/equinox/internal/p2/metadata/expression/Equals.java
+++ b/bundles/org.eclipse.equinox.p2.metadata/src/org/eclipse/equinox/internal/p2/metadata/expression/Equals.java
@@ -10,6 +10,7 @@
  *******************************************************************************/
 package org.eclipse.equinox.internal.p2.metadata.expression;
 
+import java.util.Collection;
 import org.eclipse.equinox.p2.metadata.expression.IEvaluationContext;
 
 /**
@@ -24,10 +25,23 @@
 	}
 
 	public Object evaluate(IEvaluationContext context) {
-		boolean result = CoercingComparator.coerceAndEquals(lhs.evaluate(context), rhs.evaluate(context));
-		if (negate)
-			result = !result;
-		return Boolean.valueOf(result);
+		Object lhsVal = lhs.evaluate(context);
+		Object rhsVal = rhs.evaluate(context);
+
+		// Handle collections as per the OSGi LDAP spec
+		if (lhsVal instanceof Collection<?>) {
+			for (Object lhsItem : (Collection<?>) lhsVal) {
+				boolean eq = CoercingComparator.coerceAndEquals(lhsItem, rhsVal);
+
+				if (eq && !negate) {
+					return true;
+				}
+			}
+			return negate;
+		}
+
+		boolean eq = CoercingComparator.coerceAndEquals(lhsVal, rhsVal);
+		return negate ? !eq : eq;
 	}
 
 	public int getExpressionType() {