Revert "Bug 528494 - Using the match operator for RequiredCapability"

This reverts commit 72c083ed10a1cca83f00befbefc279af09779df0.
To ensure that today's build failure is not caused by this change.

Change-Id: I3e874183b62a3f6456afa00426f9efb230639b49
diff --git a/bundles/org.eclipse.equinox.p2.metadata/src/org/eclipse/equinox/internal/p2/metadata/RequiredCapability.java b/bundles/org.eclipse.equinox.p2.metadata/src/org/eclipse/equinox/internal/p2/metadata/RequiredCapability.java
index cd8f8da..eee9b32 100644
--- a/bundles/org.eclipse.equinox.p2.metadata/src/org/eclipse/equinox/internal/p2/metadata/RequiredCapability.java
+++ b/bundles/org.eclipse.equinox.p2.metadata/src/org/eclipse/equinox/internal/p2/metadata/RequiredCapability.java
@@ -8,17 +8,12 @@
  *  Contributors:
  *     IBM Corporation - initial API and implementation
  *     EclipseSource - ongoing development
- *     Todor Boev
  *******************************************************************************/
 package org.eclipse.equinox.internal.p2.metadata;
 
-import static org.eclipse.equinox.internal.p2.metadata.InstallableUnit.MEMBER_PROVIDED_CAPABILITIES;
-import static org.eclipse.equinox.internal.p2.metadata.ProvidedCapability.MEMBER_NAME;
-import static org.eclipse.equinox.internal.p2.metadata.ProvidedCapability.MEMBER_NAMESPACE;
-import static org.eclipse.equinox.internal.p2.metadata.ProvidedCapability.MEMBER_VERSION;
-
 import org.eclipse.core.runtime.Assert;
 import org.eclipse.equinox.p2.metadata.IInstallableUnit;
+import org.eclipse.equinox.p2.metadata.Version;
 import org.eclipse.equinox.p2.metadata.VersionRange;
 import org.eclipse.equinox.p2.metadata.expression.ExpressionUtil;
 import org.eclipse.equinox.p2.metadata.expression.IExpression;
@@ -39,26 +34,41 @@
  * @see IInstallableUnit#NAMESPACE_IU_ID
  */
 public class RequiredCapability extends Requirement implements IRequiredCapability {
-	private static final IExpression simpleMatchExpression;
+	private static final IExpression allVersionsExpression;
+	private static final IExpression range_II_Expression;
+	private static final IExpression range_IN_Expression;
+	private static final IExpression range_NI_Expression;
+	private static final IExpression range_NN_Expression;
+	private static final IExpression strictVersionExpression;
+	private static final IExpression openEndedExpression;
+	private static final IExpression openEndedNonInclusiveExpression;
 
 	static {
 		IExpressionFactory factory = ExpressionUtil.getFactory();
+		IExpression xVar = factory.variable("x"); //$NON-NLS-1$
+		IExpression nameEqual = factory.equals(factory.member(xVar, ProvidedCapability.MEMBER_NAME), factory.indexedParameter(0));
+		IExpression namespaceEqual = factory.equals(factory.member(xVar, ProvidedCapability.MEMBER_NAMESPACE), factory.indexedParameter(1));
 
-		IExpression xVar = factory.variable("cap"); //$NON-NLS-1$
+		IExpression versionMember = factory.member(xVar, ProvidedCapability.MEMBER_VERSION);
 
-		IExpression name = factory.member(xVar, MEMBER_NAME);
-		IExpression nameEqual = factory.equals(name, factory.indexedParameter(0));
+		IExpression versionCmpLow = factory.indexedParameter(2);
+		IExpression versionEqual = factory.equals(versionMember, versionCmpLow);
+		IExpression versionGt = factory.greater(versionMember, versionCmpLow);
+		IExpression versionGtEqual = factory.greaterEqual(versionMember, versionCmpLow);
 
-		IExpression namespace = factory.member(xVar, MEMBER_NAMESPACE);
-		IExpression namespaceEqual = factory.equals(namespace, factory.indexedParameter(1));
+		IExpression versionCmpHigh = factory.indexedParameter(3);
+		IExpression versionLt = factory.less(versionMember, versionCmpHigh);
+		IExpression versionLtEqual = factory.lessEqual(versionMember, versionCmpHigh);
 
-		IExpression version = factory.member(xVar, MEMBER_VERSION);
-		IExpression versionInRange = factory.matches(version, factory.indexedParameter(2));
-
-		IExpression pvMember = factory.member(factory.thisVariable(), MEMBER_PROVIDED_CAPABILITIES);
-
-		// Place nameEqual first to eliminate quickly most non-matching candidates
-		simpleMatchExpression = factory.exists(pvMember, factory.lambda(xVar, factory.and(nameEqual, namespaceEqual, versionInRange)));
+		IExpression pvMember = factory.member(factory.thisVariable(), InstallableUnit.MEMBER_PROVIDED_CAPABILITIES);
+		allVersionsExpression = factory.exists(pvMember, factory.lambda(xVar, factory.and(nameEqual, namespaceEqual)));
+		strictVersionExpression = factory.exists(pvMember, factory.lambda(xVar, factory.and(nameEqual, namespaceEqual, versionEqual)));
+		openEndedExpression = factory.exists(pvMember, factory.lambda(xVar, factory.and(nameEqual, namespaceEqual, versionGtEqual)));
+		openEndedNonInclusiveExpression = factory.exists(pvMember, factory.lambda(xVar, factory.and(nameEqual, namespaceEqual, versionGt)));
+		range_II_Expression = factory.exists(pvMember, factory.lambda(xVar, factory.and(nameEqual, namespaceEqual, versionGtEqual, versionLtEqual)));
+		range_IN_Expression = factory.exists(pvMember, factory.lambda(xVar, factory.and(nameEqual, namespaceEqual, versionGtEqual, versionLt)));
+		range_NI_Expression = factory.exists(pvMember, factory.lambda(xVar, factory.and(nameEqual, namespaceEqual, versionGt, versionLtEqual)));
+		range_NN_Expression = factory.exists(pvMember, factory.lambda(xVar, factory.and(nameEqual, namespaceEqual, versionGt, versionLt)));
 	}
 
 	/**
@@ -122,9 +132,28 @@
 	public static IMatchExpression<IInstallableUnit> createMatchExpressionFromRange(String namespace, String name, VersionRange range) {
 		Assert.isNotNull(namespace);
 		Assert.isNotNull(name);
-		Object resolvedRange = (range != null) ? range : VersionRange.emptyRange;
+
+		// Empty range - matches everything
 		IExpressionFactory factory = ExpressionUtil.getFactory();
-		return factory.matchExpression(simpleMatchExpression, name, namespace, resolvedRange);
+		if (range == null || range.equals(VersionRange.emptyRange)) {
+			return factory.matchExpression(allVersionsExpression, name, namespace);
+		}
+
+		// Point range - matches exactly one version
+		if (range.getMinimum().equals(range.getMaximum())) {
+			return factory.matchExpression(strictVersionExpression, name, namespace, range.getMinimum());
+		}
+
+		// Semi-closed ranged - matches a minimum version
+		if (range.getMaximum().equals(Version.MAX_VERSION)) {
+			return factory.matchExpression(range.getIncludeMinimum() ? openEndedExpression : openEndedNonInclusiveExpression, name, namespace, range.getMinimum());
+		}
+
+		// Closed range - matches version between a minimum and a maximum
+		return factory.matchExpression(//
+				range.getIncludeMinimum() ? (range.getIncludeMaximum() ? range_II_Expression : range_IN_Expression) //
+						: (range.getIncludeMaximum() ? range_NI_Expression : range_NN_Expression), //
+				name, namespace, range.getMinimum(), range.getMaximum());
 	}
 
 	public static String extractNamespace(IMatchExpression<IInstallableUnit> matchExpression) {
@@ -138,28 +167,39 @@
 	}
 
 	public static VersionRange extractRange(IMatchExpression<IInstallableUnit> matchExpression) {
-		assertValid(matchExpression);
+		IExpression expr = assertValid(matchExpression);
 		Object[] params = matchExpression.getParameters();
-		return (VersionRange) params[2];
+		if (params.length < 3) {
+			return VersionRange.emptyRange;
+		}
+		Version v = (Version) params[2];
+		if (params.length < 4) {
+			if (expr.equals(strictVersionExpression)) {
+				return new VersionRange(v, true, v, true);
+			}
+			return new VersionRange(v, expr.equals(openEndedExpression), Version.MAX_VERSION, true);
+		}
+		Version h = (Version) params[3];
+		return new VersionRange(v, expr.equals(range_II_Expression) || expr.equals(range_IN_Expression), h, expr.equals(range_II_Expression) || expr.equals(range_NI_Expression));
 	}
 
 	public static boolean isVersionStrict(IMatchExpression<IInstallableUnit> matchExpression) {
-		if (!isSimpleRequirement(matchExpression)) {
-			return false;
-		}
-
-		Object[] params = matchExpression.getParameters();
-		VersionRange range = (VersionRange) params[2];
-		return range.getMinimum().equals(range.getMaximum());
+		return ExpressionUtil.getOperand(matchExpression) == strictVersionExpression;
 	}
 
 	public static boolean isSimpleRequirement(IMatchExpression<IInstallableUnit> matchExpression) {
-		return simpleMatchExpression.equals(ExpressionUtil.getOperand(matchExpression));
+		return isPredefined(ExpressionUtil.getOperand(matchExpression));
 	}
 
-	private static void assertValid(IMatchExpression<IInstallableUnit> matchExpression) {
-		if (!isSimpleRequirement(matchExpression)) {
+	private static IExpression assertValid(IMatchExpression<IInstallableUnit> matchExpression) {
+		IExpression expr = ExpressionUtil.getOperand(matchExpression);
+		if (!isPredefined(expr)) {
 			throw new IllegalArgumentException();
 		}
+		return expr;
+	}
+
+	private static boolean isPredefined(IExpression expr) {
+		return expr.equals(allVersionsExpression) || expr.equals(range_II_Expression) || expr.equals(range_IN_Expression) || expr.equals(range_NI_Expression) || expr.equals(range_NN_Expression) || expr.equals(strictVersionExpression) || expr.equals(openEndedExpression) || expr.equals(openEndedNonInclusiveExpression);
 	}
 }
diff --git a/bundles/org.eclipse.equinox.p2.publisher.eclipse/src/org/eclipse/equinox/p2/publisher/eclipse/BundlesAction.java b/bundles/org.eclipse.equinox.p2.publisher.eclipse/src/org/eclipse/equinox/p2/publisher/eclipse/BundlesAction.java
index b3411b0..95777c8 100644
--- a/bundles/org.eclipse.equinox.p2.publisher.eclipse/src/org/eclipse/equinox/p2/publisher/eclipse/BundlesAction.java
+++ b/bundles/org.eclipse.equinox.p2.publisher.eclipse/src/org/eclipse/equinox/p2/publisher/eclipse/BundlesAction.java
@@ -292,13 +292,12 @@
 		VersionRange versionRange = PublisherHelper.fromOSGiVersionRange(importSpec.getVersionRange());
 		final boolean optional = isOptional(importSpec);
 		final boolean greedy;
-		if (optional) {
+		if (optional)
 			greedy = INSTALLATION_GREEDY.equals(getInstallationDirective(importSpec.getName(), rawImportPackageHeader));
-		} else {
+		else
 			greedy = true;
-		}
 		//TODO this needs to be refined to take into account all the attribute handled by imports
-		reqsDeps.add(MetadataFactory.createRequirement(PublisherHelper.CAPABILITY_NS_JAVA_PACKAGE, importSpec.getName(), versionRange, null, optional, false, greedy));
+		reqsDeps.add(MetadataFactory.createRequirement(PublisherHelper.CAPABILITY_NS_JAVA_PACKAGE, importSpec.getName(), versionRange, null, optional ? 0 : 1, 1, greedy));
 	}
 
 	// TODO Handle all attributes and directives somehow? Especially the "effective" directive.
diff --git a/bundles/org.eclipse.equinox.p2.publisher/src/org/eclipse/equinox/spi/p2/publisher/PublisherHelper.java b/bundles/org.eclipse.equinox.p2.publisher/src/org/eclipse/equinox/spi/p2/publisher/PublisherHelper.java
index 8fc15de..7e462e7 100644
--- a/bundles/org.eclipse.equinox.p2.publisher/src/org/eclipse/equinox/spi/p2/publisher/PublisherHelper.java
+++ b/bundles/org.eclipse.equinox.p2.publisher/src/org/eclipse/equinox/spi/p2/publisher/PublisherHelper.java
@@ -4,7 +4,7 @@
  *  are made available under the terms of the Eclipse Public License v1.0
  *  which accompanies this distribution, and is available at
  *  http://www.eclipse.org/legal/epl-v10.html
- *
+ * 
  *  Contributors:
  *     IBM Corporation - initial API and implementation
  *     Genuitec, LLC - added license support
@@ -46,14 +46,14 @@
 
 	public static final String NAMESPACE_FLAVOR = "org.eclipse.equinox.p2.flavor"; //$NON-NLS-1$"
 	/**
-	 * A capability name in the {@link #NAMESPACE_ECLIPSE_TYPE} namespace
+	 * A capability name in the {@link #NAMESPACE_ECLIPSE_TYPE} namespace 
 	 * representing a feature
 	 * @see IProvidedCapability#getName()
 	 */
 	public static final String TYPE_ECLIPSE_FEATURE = "feature"; //$NON-NLS-1$
 
 	/**
-	 * A capability name in the {@link #NAMESPACE_ECLIPSE_TYPE} namespace
+	 * A capability name in the {@link #NAMESPACE_ECLIPSE_TYPE} namespace 
 	 * representing a source bundle
 	 * @see IProvidedCapability#getName()
 	 */
@@ -214,35 +214,22 @@
 	 * @return The created omni version
 	 */
 	public static Version fromOSGiVersion(org.osgi.framework.Version version) {
-		if (version == null) {
+		if (version == null)
+			return null;
+		if (version.getMajor() == Integer.MAX_VALUE && version.getMicro() == Integer.MAX_VALUE && version.getMicro() == Integer.MAX_VALUE)
 			return Version.MAX_VERSION;
-		}
-		if (version.getMajor() == Integer.MAX_VALUE && version.getMicro() == Integer.MAX_VALUE && version.getMicro() == Integer.MAX_VALUE) {
-			return Version.MAX_VERSION;
-		}
 		return Version.createOSGi(version.getMajor(), version.getMinor(), version.getMicro(), version.getQualifier());
 	}
 
 	public static org.eclipse.osgi.service.resolver.VersionRange toOSGiVersionRange(VersionRange range) {
-		if (range.equals(VersionRange.emptyRange)) {
+		if (range.equals(VersionRange.emptyRange))
 			return org.eclipse.osgi.service.resolver.VersionRange.emptyRange;
-		}
 		return new org.eclipse.osgi.service.resolver.VersionRange(toOSGiVersion(range.getMinimum()), range.getIncludeMinimum(), toOSGiVersion(range.getMaximum()), range.getIncludeMinimum());
 	}
 
 	public static VersionRange fromOSGiVersionRange(org.eclipse.osgi.service.resolver.VersionRange range) {
-		if (range.equals(org.eclipse.osgi.service.resolver.VersionRange.emptyRange)) {
+		if (range.equals(org.eclipse.osgi.service.resolver.VersionRange.emptyRange))
 			return VersionRange.emptyRange;
-		}
-
-		Version min = fromOSGiVersion(range.getLeft());
-		boolean includeMin = range.getIncludeMinimum();
-
-		Version max = fromOSGiVersion(range.getRight());
-		// TODO The OSGi open ended range does not include the max value, where as the p2 does
-		// Fix the p2 range to not include maximum as well (how will this affect the projector)?.
-		boolean includeMax = Version.MAX_VERSION.equals(max) ? true : range.getIncludeMaximum();
-
-		return new VersionRange(min, includeMin, max, includeMax);
+		return new VersionRange(fromOSGiVersion(range.getMinimum()), range.getIncludeMinimum(), fromOSGiVersion(range.getMaximum()), range.getIncludeMaximum());
 	}
 }
diff --git a/bundles/org.eclipse.equinox.p2.tests/src/org/eclipse/equinox/p2/tests/metadata/AllTests.java b/bundles/org.eclipse.equinox.p2.tests/src/org/eclipse/equinox/p2/tests/metadata/AllTests.java
index 1c73569..05bf2f2 100644
--- a/bundles/org.eclipse.equinox.p2.tests/src/org/eclipse/equinox/p2/tests/metadata/AllTests.java
+++ b/bundles/org.eclipse.equinox.p2.tests/src/org/eclipse/equinox/p2/tests/metadata/AllTests.java
@@ -39,4 +39,4 @@
 		return suite;
 	}
 
-}
\ No newline at end of file
+}
diff --git a/bundles/org.eclipse.equinox.p2.tests/src/org/eclipse/equinox/p2/tests/publisher/actions/ANYConfigCUsActionTest.java b/bundles/org.eclipse.equinox.p2.tests/src/org/eclipse/equinox/p2/tests/publisher/actions/ANYConfigCUsActionTest.java
index adc767b..6b12e2e 100644
--- a/bundles/org.eclipse.equinox.p2.tests/src/org/eclipse/equinox/p2/tests/publisher/actions/ANYConfigCUsActionTest.java
+++ b/bundles/org.eclipse.equinox.p2.tests/src/org/eclipse/equinox/p2/tests/publisher/actions/ANYConfigCUsActionTest.java
@@ -12,9 +12,7 @@
 import static org.easymock.EasyMock.expect;
 
 import java.io.File;
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.List;
+import java.util.*;
 import org.easymock.EasyMock;
 import org.eclipse.core.runtime.NullProgressMonitor;
 import org.eclipse.equinox.internal.p2.metadata.InstallableUnit;
@@ -22,30 +20,15 @@
 import org.eclipse.equinox.internal.p2.publisher.eclipse.ProductFile;
 import org.eclipse.equinox.internal.provisional.frameworkadmin.ConfigData;
 import org.eclipse.equinox.internal.provisional.frameworkadmin.LauncherData;
-import org.eclipse.equinox.p2.metadata.IInstallableUnit;
-import org.eclipse.equinox.p2.metadata.IInstallableUnitFragment;
-import org.eclipse.equinox.p2.metadata.IProvidedCapability;
-import org.eclipse.equinox.p2.metadata.IRequirement;
-import org.eclipse.equinox.p2.metadata.ITouchpointData;
-import org.eclipse.equinox.p2.metadata.ITouchpointInstruction;
-import org.eclipse.equinox.p2.metadata.MetadataFactory;
+import org.eclipse.equinox.p2.metadata.*;
 import org.eclipse.equinox.p2.metadata.MetadataFactory.InstallableUnitDescription;
-import org.eclipse.equinox.p2.metadata.Version;
-import org.eclipse.equinox.p2.metadata.VersionRange;
 import org.eclipse.equinox.p2.publisher.AbstractPublisherAction;
 import org.eclipse.equinox.p2.publisher.IPublisherResult;
-import org.eclipse.equinox.p2.publisher.eclipse.ConfigAdvice;
-import org.eclipse.equinox.p2.publisher.eclipse.ConfigCUsAction;
-import org.eclipse.equinox.p2.publisher.eclipse.IConfigAdvice;
-import org.eclipse.equinox.p2.publisher.eclipse.IExecutableAdvice;
-import org.eclipse.equinox.p2.publisher.eclipse.LaunchingAdvice;
-import org.eclipse.equinox.p2.publisher.eclipse.ProductFileAdvice;
+import org.eclipse.equinox.p2.publisher.eclipse.*;
 import org.eclipse.equinox.p2.query.IQueryResult;
 import org.eclipse.equinox.p2.query.QueryUtil;
 import org.eclipse.equinox.p2.repository.metadata.IMetadataRepository;
-import org.eclipse.equinox.p2.tests.TestActivator;
-import org.eclipse.equinox.p2.tests.TestData;
-import org.eclipse.equinox.p2.tests.TestMetadataRepository;
+import org.eclipse.equinox.p2.tests.*;
 
 public class ANYConfigCUsActionTest extends ActionTest {
 	private static final String BUNDLE_VERSION = "5.0.0"; //$NON-NLS-1$
@@ -89,9 +72,9 @@
 		//verify RequiredCapabilities
 		List<IRequirement> requiredCapability = iu.getRequirements();
 		assertTrue(requiredCapability.size() == 3);
-		verifyRequirement(requiredCapability, IInstallableUnit.NAMESPACE_IU_ID, flavor + id + ".config." + configSpec, new VersionRange(version, true, version, true)); //$NON-NLS-1$
-		verifyRequirement(requiredCapability, IInstallableUnit.NAMESPACE_IU_ID, flavor + id + ".ini." + configSpec, new VersionRange(version, true, version, true)); //$NON-NLS-1$
-		verifyRequirement(requiredCapability, IInstallableUnit.NAMESPACE_IU_ID, flavor + configSpec + ORG_ECLIPSE_CORE_COMMANDS, new VersionRange(version, true, version, true));
+		verifyRequiredCapability(requiredCapability, IInstallableUnit.NAMESPACE_IU_ID, flavor + id + ".config." + configSpec, new VersionRange(version, true, version, true)); //$NON-NLS-1$
+		verifyRequiredCapability(requiredCapability, IInstallableUnit.NAMESPACE_IU_ID, flavor + id + ".ini." + configSpec, new VersionRange(version, true, version, true)); //$NON-NLS-1$
+		verifyRequiredCapability(requiredCapability, IInstallableUnit.NAMESPACE_IU_ID, flavor + configSpec + ORG_ECLIPSE_CORE_COMMANDS, new VersionRange(version, true, version, true));
 
 		//verify non root IUs
 		verifyFragment("ini"); //$NON-NLS-1$
@@ -149,8 +132,8 @@
 		assertEquals(0, fragment.getRequirements().size());
 
 		final Collection<IRequirement> hostRequirements = fragment.getHost();
-		verifyRequirement(hostRequirements, "osgi.bundle", ORG_ECLIPSE_CORE_COMMANDS, new VersionRange(BUNDLE_VERSION)); //$NON-NLS-1$
-		verifyRequirement(hostRequirements, "org.eclipse.equinox.p2.eclipse.type", "bundle", new VersionRange(Version.create("1.0.0"), true, Version.create("2.0.0"), false), null, 1, 1, false); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$
+		verifyRequiredCapability(hostRequirements, "osgi.bundle", ORG_ECLIPSE_CORE_COMMANDS, new VersionRange(BUNDLE_VERSION)); //$NON-NLS-1$
+		verifyRequiredCapability(hostRequirements, "org.eclipse.equinox.p2.eclipse.type", "bundle", new VersionRange(Version.create("1.0.0"), true, Version.create("2.0.0"), false), 1, 1, false); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$
 		assertTrue(hostRequirements.size() == 2);
 
 		final Collection<ITouchpointData> touchpointData = fragment.getTouchpointData();
diff --git a/bundles/org.eclipse.equinox.p2.tests/src/org/eclipse/equinox/p2/tests/publisher/actions/ActionTest.java b/bundles/org.eclipse.equinox.p2.tests/src/org/eclipse/equinox/p2/tests/publisher/actions/ActionTest.java
index 058cca7..06302d9 100644
--- a/bundles/org.eclipse.equinox.p2.tests/src/org/eclipse/equinox/p2/tests/publisher/actions/ActionTest.java
+++ b/bundles/org.eclipse.equinox.p2.tests/src/org/eclipse/equinox/p2/tests/publisher/actions/ActionTest.java
@@ -9,44 +9,21 @@
  ******************************************************************************/
 package org.eclipse.equinox.p2.tests.publisher.actions;
 
-import static org.easymock.EasyMock.createMock;
-import static org.easymock.EasyMock.expect;
-import static org.easymock.EasyMock.replay;
+import static org.easymock.EasyMock.*;
 import static org.junit.Assert.assertThat;
 
-import java.io.ByteArrayOutputStream;
-import java.io.File;
-import java.io.FileInputStream;
-import java.io.IOException;
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.List;
-import java.util.Map;
-import java.util.StringTokenizer;
-import org.eclipse.core.runtime.IPath;
-import org.eclipse.core.runtime.NullProgressMonitor;
-import org.eclipse.core.runtime.Path;
+import java.io.*;
+import java.util.*;
+import org.eclipse.core.runtime.*;
 import org.eclipse.equinox.internal.p2.core.helpers.FileUtils;
-import org.eclipse.equinox.p2.metadata.IInstallableUnit;
-import org.eclipse.equinox.p2.metadata.IProvidedCapability;
-import org.eclipse.equinox.p2.metadata.IRequirement;
-import org.eclipse.equinox.p2.metadata.MetadataFactory;
-import org.eclipse.equinox.p2.metadata.Version;
-import org.eclipse.equinox.p2.metadata.VersionRange;
-import org.eclipse.equinox.p2.metadata.expression.ExpressionUtil;
-import org.eclipse.equinox.p2.metadata.expression.IExpression;
-import org.eclipse.equinox.p2.metadata.expression.IMatchExpression;
-import org.eclipse.equinox.p2.publisher.AbstractPublisherAction;
-import org.eclipse.equinox.p2.publisher.IPublisherInfo;
-import org.eclipse.equinox.p2.publisher.IPublisherResult;
-import org.eclipse.equinox.p2.publisher.PublisherResult;
-import org.eclipse.equinox.p2.query.IQuery;
-import org.eclipse.equinox.p2.query.IQueryResult;
-import org.eclipse.equinox.p2.query.QueryUtil;
+import org.eclipse.equinox.internal.p2.metadata.IRequiredCapability;
+import org.eclipse.equinox.internal.p2.metadata.InstallableUnit;
+import org.eclipse.equinox.p2.metadata.*;
+import org.eclipse.equinox.p2.metadata.expression.*;
+import org.eclipse.equinox.p2.publisher.*;
+import org.eclipse.equinox.p2.query.*;
 import org.eclipse.equinox.p2.tests.AbstractProvisioningTest;
-import org.hamcrest.Description;
-import org.hamcrest.Matcher;
-import org.hamcrest.TypeSafeMatcher;
+import org.hamcrest.*;
 import org.junit.Assert;
 
 public abstract class ActionTest extends AbstractProvisioningTest {
@@ -88,33 +65,39 @@
 		Assert.fail("Missing ProvidedCapability: " + name + version.toString()); //$NON-NLS-1$
 	}
 
-	protected void verifyRequirement(Collection<IRequirement> actual, String namespace, String name, VersionRange range) {
-		verifyRequirement(actual, namespace, name, range, null, 1, 1, true);
+	protected void verifyRequiredCapability(Collection<IRequirement> requirement, String namespace, String name, VersionRange range) {
+		verifyRequiredCapability(requirement, namespace, name, range, 1, 1, true);
 	}
 
-	protected void verifyRequirement(Collection<IRequirement> actual, String namespace, String name, VersionRange range, String filterStr, int minCard, int maxCard, boolean greedy) {
-		IRequirement expected = MetadataFactory.createRequirement(namespace, name, range, null, minCard, maxCard, greedy);
-		verifyRequirement(actual, expected);
-	}
-
-	protected void verifyRequirement(Collection<IRequirement> actual, String matchExpr, int minCard, int maxCard, boolean greedy) {
-		IExpression expr = ExpressionUtil.parse(matchExpr);
-		IMatchExpression<IInstallableUnit> matcher = ExpressionUtil.getFactory().matchExpression(expr);
-		IRequirement expected = MetadataFactory.createRequirement(matcher, null, minCard, maxCard, greedy);
-		verifyRequirement(actual, expected);
-	}
-
-	protected void verifyRequirement(Collection<IRequirement> actual, IRequirement expected) {
-		for (IRequirement act : actual) {
-			if (expected.getMatches().equals(act.getMatches())) {
-				String descr = "IRequirement " + expected.getMatches();
-				Assert.assertEquals("Min of " + descr, expected.getMin(), act.getMin());
-				Assert.assertEquals("Max of " + descr, expected.getMax(), act.getMax());
-				Assert.assertEquals("Greedy of " + descr, expected.isGreedy(), act.isGreedy());
+	protected void verifyRequiredCapability(Collection<IRequirement> requirement, String namespace, String name, VersionRange range, int min, int max, boolean greedy) {
+		for (Iterator<IRequirement> iterator = requirement.iterator(); iterator.hasNext();) {
+			IRequiredCapability required = (IRequiredCapability) iterator.next();
+			if (required.getName().equalsIgnoreCase(name) && required.getNamespace().equalsIgnoreCase(namespace) && required.getRange().equals(range)) {
+				String requirementDescr = "RequiredCapability " + name + " " + range.toString();
+				Assert.assertEquals("Min of " + requirementDescr, min, required.getMin());
+				Assert.assertEquals("Max of " + requirementDescr, max, required.getMax());
+				Assert.assertEquals("Greedy of " + requirementDescr, greedy, required.isGreedy());
 				return;
 			}
 		}
-		Assert.fail("Missing IRequirement: " + expected); //$NON-NLS-1$
+		Assert.fail("Missing RequiredCapability: " + name + " " + range.toString()); //$NON-NLS-1$
+	}
+
+	protected void verifyRequirement(Collection<IRequirement> requirement, String filter, int min, int max, boolean greedy) {
+		IExpression expr = ExpressionUtil.parse(filter);
+		IMatchExpression<IInstallableUnit> matchExpr = ExpressionUtil.getFactory().matchExpression(expr);
+
+		for (Iterator iterator = requirement.iterator(); iterator.hasNext();) {
+			IRequirement required = (IRequirement) iterator.next();
+			if (required.getMatches().equals(matchExpr)) {
+				String requirementDescr = "IRequirement " + filter;
+				Assert.assertEquals("Min of " + requirementDescr, min, required.getMin());
+				Assert.assertEquals("Max of " + requirementDescr, max, required.getMax());
+				Assert.assertEquals("Greedy of " + requirementDescr, greedy, required.isGreedy());
+				return;
+			}
+		}
+		Assert.fail("Missing IRequirement: " + filter); //$NON-NLS-1$
 	}
 
 	protected IInstallableUnit mockIU(String id, Version version) {
@@ -152,6 +135,36 @@
 		return map;
 	}
 
+	protected void contains(Collection<IProvidedCapability> capabilities, String namespace, String name, Version version) {
+		for (IProvidedCapability capability : capabilities) {
+			if (capability.getNamespace().equals(namespace) && capability.getName().equals(name) && capability.getVersion().equals(version))
+				return;
+		}
+		fail();
+	}
+
+	protected void contains(Collection<IRequirement> capabilities, String namespace, String name, VersionRange range, String filterStr, boolean optional, boolean multiple) {
+		IMatchExpression<IInstallableUnit> filter = InstallableUnit.parseFilter(filterStr);
+		for (Iterator<IRequirement> iterator = capabilities.iterator(); iterator.hasNext();) {
+			IRequiredCapability capability = (IRequiredCapability) iterator.next();
+			if (filter == null) {
+				if (capability.getFilter() != null)
+					continue;
+			} else if (!filter.equals(capability.getFilter()))
+				continue;
+			if (!name.equals(capability.getName()))
+				continue;
+			if (!namespace.equals(capability.getNamespace()))
+				continue;
+			if (optional != (capability.getMin() == 0))
+				continue;
+			if (!range.equals(capability.getRange()))
+				continue;
+			return;
+		}
+		fail();
+	}
+
 	public void setupPublisherResult() {
 		publisherResult = new PublisherResult();
 	}
diff --git a/bundles/org.eclipse.equinox.p2.tests/src/org/eclipse/equinox/p2/tests/publisher/actions/BundlesActionTest.java b/bundles/org.eclipse.equinox.p2.tests/src/org/eclipse/equinox/p2/tests/publisher/actions/BundlesActionTest.java
index af99bfe..f943a78 100644
--- a/bundles/org.eclipse.equinox.p2.tests/src/org/eclipse/equinox/p2/tests/publisher/actions/BundlesActionTest.java
+++ b/bundles/org.eclipse.equinox.p2.tests/src/org/eclipse/equinox/p2/tests/publisher/actions/BundlesActionTest.java
@@ -11,59 +11,23 @@
  ******************************************************************************/
 package org.eclipse.equinox.p2.tests.publisher.actions;
 
-import static org.easymock.EasyMock.and;
-import static org.easymock.EasyMock.capture;
-import static org.easymock.EasyMock.expect;
+import static org.easymock.EasyMock.*;
 import static org.eclipse.equinox.p2.tests.publisher.actions.StatusMatchers.errorStatus;
 import static org.eclipse.equinox.p2.tests.publisher.actions.StatusMatchers.statusWithMessageWhich;
-import static org.hamcrest.CoreMatchers.containsString;
-import static org.hamcrest.CoreMatchers.hasItem;
-import static org.hamcrest.CoreMatchers.is;
+import static org.hamcrest.CoreMatchers.*;
 import static org.junit.Assert.assertThat;
 
-import java.io.BufferedInputStream;
-import java.io.File;
-import java.io.FileInputStream;
-import java.io.InputStream;
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.Collection;
-import java.util.Collections;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Locale;
-import java.util.Map;
+import java.io.*;
+import java.util.*;
 import java.util.zip.ZipInputStream;
 import org.easymock.EasyMock;
-import org.eclipse.core.runtime.IStatus;
-import org.eclipse.core.runtime.NullProgressMonitor;
-import org.eclipse.core.runtime.Path;
-import org.eclipse.core.runtime.Status;
+import org.eclipse.core.runtime.*;
 import org.eclipse.equinox.internal.p2.director.QueryableArray;
-import org.eclipse.equinox.internal.p2.metadata.ArtifactKey;
-import org.eclipse.equinox.internal.p2.metadata.RequiredCapability;
-import org.eclipse.equinox.internal.p2.metadata.TranslationSupport;
-import org.eclipse.equinox.p2.metadata.IArtifactKey;
-import org.eclipse.equinox.p2.metadata.IInstallableUnit;
-import org.eclipse.equinox.p2.metadata.IProvidedCapability;
-import org.eclipse.equinox.p2.metadata.IRequirement;
-import org.eclipse.equinox.p2.metadata.ITouchpointData;
-import org.eclipse.equinox.p2.metadata.ITouchpointInstruction;
-import org.eclipse.equinox.p2.metadata.IUpdateDescriptor;
+import org.eclipse.equinox.internal.p2.metadata.*;
+import org.eclipse.equinox.p2.metadata.*;
 import org.eclipse.equinox.p2.metadata.MetadataFactory.InstallableUnitDescription;
-import org.eclipse.equinox.p2.metadata.Version;
-import org.eclipse.equinox.p2.metadata.VersionRange;
-import org.eclipse.equinox.p2.publisher.AbstractPublisherApplication;
-import org.eclipse.equinox.p2.publisher.AdviceFileAdvice;
-import org.eclipse.equinox.p2.publisher.IPublisherInfo;
-import org.eclipse.equinox.p2.publisher.IPublisherResult;
-import org.eclipse.equinox.p2.publisher.PublisherInfo;
-import org.eclipse.equinox.p2.publisher.PublisherResult;
-import org.eclipse.equinox.p2.publisher.actions.IAdditionalInstallableUnitAdvice;
-import org.eclipse.equinox.p2.publisher.actions.ICapabilityAdvice;
-import org.eclipse.equinox.p2.publisher.actions.IPropertyAdvice;
-import org.eclipse.equinox.p2.publisher.actions.ITouchpointAdvice;
-import org.eclipse.equinox.p2.publisher.actions.IUpdateDescriptorAdvice;
+import org.eclipse.equinox.p2.publisher.*;
+import org.eclipse.equinox.p2.publisher.actions.*;
 import org.eclipse.equinox.p2.publisher.eclipse.BundlesAction;
 import org.eclipse.equinox.p2.publisher.eclipse.IBundleShapeAdvice;
 import org.eclipse.equinox.p2.query.IQueryResult;
@@ -118,21 +82,21 @@
 	private static final String TEST2_PROV_X_NAMESPACE = JAVA_PACKAGE;
 	private static final String TEST1_PROV_Z_NAMESPACE = JAVA_PACKAGE;
 
-	private static final Version BUNDLE1_VERSION = Version.create("0.1.0");//$NON-NLS-1$
-	private static final Version BUNDLE2_VERSION = Version.create("1.0.0.qualifier");//$NON-NLS-1$
-	private static final Version BUNDLE3_VERSION = Version.create("0.1.0.qualifier");//$NON-NLS-1$
-	private static final Version BUNDLE4_VERSION = Version.create("2.0.1");//$NON-NLS-1$
-	private static final Version BUNDLE5_VERSION = Version.create("0.1.0.qualifier");//$NON-NLS-1$
+	private final Version BUNDLE1_VERSION = Version.create("0.1.0");//$NON-NLS-1$
+	private final Version BUNDLE2_VERSION = Version.create("1.0.0.qualifier");//$NON-NLS-1$
+	private final Version BUNDLE3_VERSION = Version.create("0.1.0.qualifier");//$NON-NLS-1$
+	private final Version BUNDLE4_VERSION = Version.create("2.0.1");//$NON-NLS-1$
+	private final Version BUNDLE5_VERSION = Version.create("0.1.0.qualifier");//$NON-NLS-1$
 
-	private static final VersionRange DEFAULT_VERSION_RANGE = VersionRange.emptyRange;
-	private static final Version PROVBUNDLE2_VERSION = BUNDLE2_VERSION;
-	private static final Version TEST2_PROVZ_VERSION = Version.emptyVersion;
-	private static final Version TEST2_PROVY_VERSION = Version.emptyVersion;
-	private static final Version TEST2_PROVX_VERSION = Version.emptyVersion;
-	private static final VersionRange TEST2_IU_A_VERSION_RANGE = VersionRange.emptyRange;
-	private static final VersionRange TEST2_IU_B_VERSION_RANGE = VersionRange.emptyRange;
-	private static final VersionRange TEST2_IU_C_VERSION_RANGE = VersionRange.create("1.0.0");//$NON-NLS-1$
-	private static final VersionRange TEST1_IU_D_VERSION_RANGE = VersionRange.create("1.3.0");//$NON-NLS-1$
+	private final VersionRange DEFAULT_VERSION_RANGE = VersionRange.emptyRange;
+	private final Version PROVBUNDLE2_VERSION = BUNDLE2_VERSION;
+	private final Version TEST2_PROVZ_VERSION = Version.emptyVersion;
+	private final Version TEST2_PROVY_VERSION = Version.emptyVersion;
+	private final Version TEST2_PROVX_VERSION = Version.emptyVersion;
+	private final VersionRange TEST2_IUA_VERSION_RANGE = VersionRange.emptyRange;
+	private final VersionRange TEST2_IUB_VERSION_RANGE = VersionRange.emptyRange;
+	private final VersionRange TEST2_IUC_VERSION_RANGE = new VersionRange(Version.create("1.0.0"), true, Version.MAX_VERSION, true);//$NON-NLS-1$
+	private final VersionRange TEST1_IUD_VERSION_RANGE = new VersionRange(Version.create("1.3.0"), true, Version.MAX_VERSION, true);//$NON-NLS-1$
 
 	protected TestArtifactRepository artifactRepository = new TestArtifactRepository(getAgent());
 
@@ -253,7 +217,7 @@
 
 		// check required capabilities
 		Collection<IRequirement> requiredCapability = bundle1IU.getRequirements();
-		verifyRequirement(requiredCapability, TEST1_IU_D_NAMESPACE, TEST1_IUD_NAME, TEST1_IU_D_VERSION_RANGE);
+		verifyRequiredCapability(requiredCapability, TEST1_IU_D_NAMESPACE, TEST1_IUD_NAME, TEST1_IUD_VERSION_RANGE);
 		verifyRequirement(requiredCapability, TEST1_REQ_EE_FILTER, 0, 1, true);
 		assertEquals("2.0", 2, requiredCapability.size());
 
@@ -290,9 +254,9 @@
 
 		// check required capabilities
 		Collection<IRequirement> requirements = bundle2IU.getRequirements();
-		verifyRequirement(requirements, TEST2_IU_A_NAMESPACE, TEST2_REQ_A_NAME, TEST2_IU_A_VERSION_RANGE);
-		verifyRequirement(requirements, TEST2_IU_B_NAMESPACE, TEST2_REQ_B_NAME, TEST2_IU_B_VERSION_RANGE);
-		verifyRequirement(requirements, TEST2_IU_C_NAMESPACE, TEST2_REQ_C_NAME, TEST2_IU_C_VERSION_RANGE);
+		verifyRequiredCapability(requirements, TEST2_IU_A_NAMESPACE, TEST2_REQ_A_NAME, TEST2_IUA_VERSION_RANGE);
+		verifyRequiredCapability(requirements, TEST2_IU_B_NAMESPACE, TEST2_REQ_B_NAME, TEST2_IUB_VERSION_RANGE);
+		verifyRequiredCapability(requirements, TEST2_IU_C_NAMESPACE, TEST2_REQ_C_NAME, TEST2_IUC_VERSION_RANGE);
 		verifyRequirement(requirements, TEST2_REQ_EE_FILTER, 0, 1, true);
 		assertTrue(requirements.size() == 4 /*number of tested elements*/);
 
@@ -357,10 +321,10 @@
 
 		// check required capabilities
 		Collection<IRequirement> requirements = bundle4IU.getRequirements();
-		verifyRequirement(requirements, JAVA_PACKAGE, TEST4_REQ_PACKAGE_OPTIONAL_NAME, DEFAULT_VERSION_RANGE, null, 0, 1, false);
-		verifyRequirement(requirements, JAVA_PACKAGE, TEST4_REQ_PACKAGE_OPTGREEDY_NAME, DEFAULT_VERSION_RANGE, null, 0, 1, true);
-		verifyRequirement(requirements, OSGI, TEST4_REQ_BUNDLE_OPTIONAL_NAME, DEFAULT_VERSION_RANGE, null, 0, 1, false);
-		verifyRequirement(requirements, OSGI, TEST4_REQ_BUNDLE_OPTGREEDY_NAME, DEFAULT_VERSION_RANGE, null, 0, 1, true);
+		verifyRequiredCapability(requirements, JAVA_PACKAGE, TEST4_REQ_PACKAGE_OPTIONAL_NAME, DEFAULT_VERSION_RANGE, 0, 1, false);
+		verifyRequiredCapability(requirements, JAVA_PACKAGE, TEST4_REQ_PACKAGE_OPTGREEDY_NAME, DEFAULT_VERSION_RANGE, 0, 1, true);
+		verifyRequiredCapability(requirements, OSGI, TEST4_REQ_BUNDLE_OPTIONAL_NAME, DEFAULT_VERSION_RANGE, 0, 1, false);
+		verifyRequiredCapability(requirements, OSGI, TEST4_REQ_BUNDLE_OPTGREEDY_NAME, DEFAULT_VERSION_RANGE, 0, 1, true);
 		assertEquals("2.0", 4, requirements.size());
 	}
 
diff --git a/bundles/org.eclipse.equinox.p2.tests/src/org/eclipse/equinox/p2/tests/publisher/actions/ConfigCUsActionTest.java b/bundles/org.eclipse.equinox.p2.tests/src/org/eclipse/equinox/p2/tests/publisher/actions/ConfigCUsActionTest.java
index 542dced..5364a25 100644
--- a/bundles/org.eclipse.equinox.p2.tests/src/org/eclipse/equinox/p2/tests/publisher/actions/ConfigCUsActionTest.java
+++ b/bundles/org.eclipse.equinox.p2.tests/src/org/eclipse/equinox/p2/tests/publisher/actions/ConfigCUsActionTest.java
@@ -13,9 +13,7 @@
 import static org.easymock.EasyMock.expect;
 
 import java.io.File;
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.List;
+import java.util.*;
 import org.easymock.EasyMock;
 import org.eclipse.core.runtime.NullProgressMonitor;
 import org.eclipse.equinox.internal.p2.metadata.InstallableUnit;
@@ -23,24 +21,11 @@
 import org.eclipse.equinox.internal.p2.publisher.eclipse.ProductFile;
 import org.eclipse.equinox.internal.provisional.frameworkadmin.ConfigData;
 import org.eclipse.equinox.internal.provisional.frameworkadmin.LauncherData;
-import org.eclipse.equinox.p2.metadata.IInstallableUnit;
-import org.eclipse.equinox.p2.metadata.IProvidedCapability;
-import org.eclipse.equinox.p2.metadata.IRequirement;
-import org.eclipse.equinox.p2.metadata.ITouchpointData;
-import org.eclipse.equinox.p2.metadata.ITouchpointInstruction;
-import org.eclipse.equinox.p2.metadata.Version;
-import org.eclipse.equinox.p2.metadata.VersionRange;
+import org.eclipse.equinox.p2.metadata.*;
 import org.eclipse.equinox.p2.publisher.IPublisherResult;
-import org.eclipse.equinox.p2.publisher.eclipse.ConfigAdvice;
-import org.eclipse.equinox.p2.publisher.eclipse.ConfigCUsAction;
-import org.eclipse.equinox.p2.publisher.eclipse.IConfigAdvice;
-import org.eclipse.equinox.p2.publisher.eclipse.IExecutableAdvice;
-import org.eclipse.equinox.p2.publisher.eclipse.LaunchingAdvice;
-import org.eclipse.equinox.p2.publisher.eclipse.ProductFileAdvice;
+import org.eclipse.equinox.p2.publisher.eclipse.*;
 import org.eclipse.equinox.p2.repository.metadata.IMetadataRepository;
-import org.eclipse.equinox.p2.tests.TestActivator;
-import org.eclipse.equinox.p2.tests.TestData;
-import org.eclipse.equinox.p2.tests.TestMetadataRepository;
+import org.eclipse.equinox.p2.tests.*;
 
 public class ConfigCUsActionTest extends ActionTest {
 	private static File configLocation = new File(TestActivator.getTestDataFolder(), "ConfigCUsActionTest/level1/level2/config.ini"); //$NON-NLS-1$
@@ -78,8 +63,8 @@
 
 		//verify RequiredCapabilities
 		List<IRequirement> requiredCapability = iu.getRequirements();
-		verifyRequirement(requiredCapability, IInstallableUnit.NAMESPACE_IU_ID, flavor + id + ".config." + configSpec, new VersionRange(version, true, version, true)); //$NON-NLS-1$
-		verifyRequirement(requiredCapability, IInstallableUnit.NAMESPACE_IU_ID, flavor + id + ".ini." + configSpec, new VersionRange(version, true, version, true)); //$NON-NLS-1$
+		verifyRequiredCapability(requiredCapability, IInstallableUnit.NAMESPACE_IU_ID, flavor + id + ".config." + configSpec, new VersionRange(version, true, version, true)); //$NON-NLS-1$
+		verifyRequiredCapability(requiredCapability, IInstallableUnit.NAMESPACE_IU_ID, flavor + id + ".ini." + configSpec, new VersionRange(version, true, version, true)); //$NON-NLS-1$
 		assertTrue(requiredCapability.size() == 2);
 
 		//verify non root IUs
diff --git a/bundles/org.eclipse.equinox.p2.tests/src/org/eclipse/equinox/p2/tests/publisher/actions/EquinoxExecutableActionTest.java b/bundles/org.eclipse.equinox.p2.tests/src/org/eclipse/equinox/p2/tests/publisher/actions/EquinoxExecutableActionTest.java
index dbca937..ddd7d48 100644
--- a/bundles/org.eclipse.equinox.p2.tests/src/org/eclipse/equinox/p2/tests/publisher/actions/EquinoxExecutableActionTest.java
+++ b/bundles/org.eclipse.equinox.p2.tests/src/org/eclipse/equinox/p2/tests/publisher/actions/EquinoxExecutableActionTest.java
@@ -10,21 +10,10 @@
  ******************************************************************************/
 package org.eclipse.equinox.p2.tests.publisher.actions;
 
-import static org.easymock.EasyMock.anyBoolean;
-import static org.easymock.EasyMock.anyObject;
-import static org.easymock.EasyMock.expect;
+import static org.easymock.EasyMock.*;
 
-import java.io.File;
-import java.io.FileInputStream;
-import java.io.FileOutputStream;
-import java.io.IOException;
-import java.io.InputStream;
-import java.io.InputStreamReader;
-import java.io.Reader;
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.Enumeration;
-import java.util.LinkedList;
+import java.io.*;
+import java.util.*;
 import java.util.regex.Matcher;
 import java.util.regex.Pattern;
 import java.util.zip.ZipEntry;
@@ -34,16 +23,8 @@
 import org.eclipse.equinox.internal.p2.core.helpers.FileUtils;
 import org.eclipse.equinox.internal.p2.metadata.InstallableUnit;
 import org.eclipse.equinox.internal.p2.publisher.eclipse.ExecutablesDescriptor;
-import org.eclipse.equinox.p2.metadata.IArtifactKey;
-import org.eclipse.equinox.p2.metadata.IInstallableUnit;
-import org.eclipse.equinox.p2.metadata.IInstallableUnitFragment;
-import org.eclipse.equinox.p2.metadata.IProvidedCapability;
-import org.eclipse.equinox.p2.metadata.IRequirement;
-import org.eclipse.equinox.p2.metadata.Version;
-import org.eclipse.equinox.p2.metadata.VersionRange;
-import org.eclipse.equinox.p2.publisher.AbstractPublisherAction;
-import org.eclipse.equinox.p2.publisher.IPublisherInfo;
-import org.eclipse.equinox.p2.publisher.IPublisherResult;
+import org.eclipse.equinox.p2.metadata.*;
+import org.eclipse.equinox.p2.publisher.*;
 import org.eclipse.equinox.p2.publisher.eclipse.EquinoxExecutableAction;
 import org.eclipse.equinox.p2.publisher.eclipse.IBrandingAdvice;
 import org.eclipse.equinox.p2.repository.artifact.IArtifactDescriptor;
@@ -142,7 +123,7 @@
 				verifyProvidedCapability(providedCapability, IInstallableUnit.NAMESPACE_IU_ID, flavorArg + idBase + ".executable." + confSpec, version); //$NON-NLS-1$
 				assertTrue(providedCapability.size() == 1);
 				Collection<IRequirement> requiredCapability = fragment.getHost();
-				verifyRequirement(requiredCapability, IInstallableUnit.NAMESPACE_IU_ID, idBase + ".executable." + confSpec, new VersionRange(version, true, version, true)); //$NON-NLS-1$
+				verifyRequiredCapability(requiredCapability, IInstallableUnit.NAMESPACE_IU_ID, idBase + ".executable." + confSpec, new VersionRange(version, true, version, true)); //$NON-NLS-1$
 				assertTrue(requiredCapability.size() == 1);
 
 				assertTrue(fragment.getFilter().getParameters()[0].toString().indexOf("(osgi.ws=" + _ws + ")") != -1);
@@ -191,7 +172,7 @@
 				assertTrue(providedCapabilities.size() == 2);
 
 				Collection<IRequirement> requiredCapability = possibleExec.getRequirements();
-				verifyRequirement(requiredCapability, IInstallableUnit.NAMESPACE_IU_ID, "org.eclipse.equinox.launcher." + (idBase.equals("mac") || idBase.equals("macCocoa") ? confSpec.substring(0, confSpec.lastIndexOf(".")) : confSpec), VersionRange.emptyRange); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
+				verifyRequiredCapability(requiredCapability, IInstallableUnit.NAMESPACE_IU_ID, "org.eclipse.equinox.launcher." + (idBase.equals("mac") || idBase.equals("macCocoa") ? confSpec.substring(0, confSpec.lastIndexOf(".")) : confSpec), VersionRange.emptyRange); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
 				assertTrue(requiredCapability.size() == 1);
 
 				try {
diff --git a/bundles/org.eclipse.equinox.p2.tests/src/org/eclipse/equinox/p2/tests/publisher/actions/EquinoxLauncherCUActionTest.java b/bundles/org.eclipse.equinox.p2.tests/src/org/eclipse/equinox/p2/tests/publisher/actions/EquinoxLauncherCUActionTest.java
index 3b78232..8c89140 100644
--- a/bundles/org.eclipse.equinox.p2.tests/src/org/eclipse/equinox/p2/tests/publisher/actions/EquinoxLauncherCUActionTest.java
+++ b/bundles/org.eclipse.equinox.p2.tests/src/org/eclipse/equinox/p2/tests/publisher/actions/EquinoxLauncherCUActionTest.java
@@ -10,19 +10,12 @@
  ******************************************************************************/
 package org.eclipse.equinox.p2.tests.publisher.actions;
 
-import static org.easymock.EasyMock.createMock;
-import static org.easymock.EasyMock.expect;
-import static org.easymock.EasyMock.replay;
+import static org.easymock.EasyMock.*;
 
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.Map;
+import java.util.*;
 import org.eclipse.core.runtime.NullProgressMonitor;
 import org.eclipse.equinox.internal.p2.metadata.InstallableUnitFragment;
-import org.eclipse.equinox.p2.metadata.IInstallableUnit;
-import org.eclipse.equinox.p2.metadata.IProvidedCapability;
-import org.eclipse.equinox.p2.metadata.Version;
-import org.eclipse.equinox.p2.metadata.VersionRange;
+import org.eclipse.equinox.p2.metadata.*;
 import org.eclipse.equinox.p2.publisher.IPublisherResult;
 import org.eclipse.equinox.p2.publisher.PublisherResult;
 import org.eclipse.equinox.p2.publisher.actions.IVersionAdvice;
@@ -69,8 +62,8 @@
 			if (iu.getId().equals(flavorArg + EquinoxLauncherCUAction.ORG_ECLIPSE_EQUINOX_LAUNCHER)) {
 				assertTrue(iu instanceof InstallableUnitFragment);
 				//verify required capability
-				verifyRequirement(((InstallableUnitFragment) iu).getHost(), PublisherHelper.OSGI_BUNDLE_CLASSIFIER, EquinoxLauncherCUAction.ORG_ECLIPSE_EQUINOX_LAUNCHER, VersionRange.emptyRange);
-				verifyRequirement(((InstallableUnitFragment) iu).getHost(), PublisherHelper.NAMESPACE_ECLIPSE_TYPE, "bundle", new VersionRange(Version.create("1.0.0"), true, Version.create("2.0.0"), false), null, 1, 1, false); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
+				verifyRequiredCapability(((InstallableUnitFragment) iu).getHost(), PublisherHelper.OSGI_BUNDLE_CLASSIFIER, EquinoxLauncherCUAction.ORG_ECLIPSE_EQUINOX_LAUNCHER, VersionRange.emptyRange);
+				verifyRequiredCapability(((InstallableUnitFragment) iu).getHost(), PublisherHelper.NAMESPACE_ECLIPSE_TYPE, "bundle", new VersionRange(Version.create("1.0.0"), true, Version.create("2.0.0"), false), 1, 1, false); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
 				assertEquals(2, (((InstallableUnitFragment) iu).getHost().size()));
 
 				Collection<IProvidedCapability> cap = iu.getProvidedCapabilities();
diff --git a/bundles/org.eclipse.equinox.p2.tests/src/org/eclipse/equinox/p2/tests/publisher/actions/FeaturesActionTest.java b/bundles/org.eclipse.equinox.p2.tests/src/org/eclipse/equinox/p2/tests/publisher/actions/FeaturesActionTest.java
index 4b6203f..eabb75f 100644
--- a/bundles/org.eclipse.equinox.p2.tests/src/org/eclipse/equinox/p2/tests/publisher/actions/FeaturesActionTest.java
+++ b/bundles/org.eclipse.equinox.p2.tests/src/org/eclipse/equinox/p2/tests/publisher/actions/FeaturesActionTest.java
@@ -10,18 +10,11 @@
  ******************************************************************************/
 package org.eclipse.equinox.p2.tests.publisher.actions;
 
-import static org.easymock.EasyMock.and;
-import static org.easymock.EasyMock.capture;
-import static org.easymock.EasyMock.expect;
-import static org.easymock.EasyMock.isA;
+import static org.easymock.EasyMock.*;
 
 import java.io.File;
 import java.io.IOException;
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.Collections;
-import java.util.HashMap;
-import java.util.Map;
+import java.util.*;
 import java.util.zip.ZipInputStream;
 import org.easymock.Capture;
 import org.easymock.EasyMock;
@@ -29,32 +22,15 @@
 import org.eclipse.core.runtime.Path;
 import org.eclipse.equinox.internal.p2.metadata.ArtifactKey;
 import org.eclipse.equinox.internal.p2.metadata.IRequiredCapability;
-import org.eclipse.equinox.p2.metadata.IArtifactKey;
-import org.eclipse.equinox.p2.metadata.IInstallableUnit;
-import org.eclipse.equinox.p2.metadata.IInstallableUnitPatch;
-import org.eclipse.equinox.p2.metadata.IProvidedCapability;
-import org.eclipse.equinox.p2.metadata.IRequirement;
-import org.eclipse.equinox.p2.metadata.ITouchpointData;
-import org.eclipse.equinox.p2.metadata.ITouchpointInstruction;
-import org.eclipse.equinox.p2.metadata.MetadataFactory;
+import org.eclipse.equinox.p2.metadata.*;
 import org.eclipse.equinox.p2.metadata.MetadataFactory.InstallableUnitDescription;
-import org.eclipse.equinox.p2.metadata.Version;
-import org.eclipse.equinox.p2.metadata.VersionRange;
 import org.eclipse.equinox.p2.metadata.expression.ExpressionUtil;
-import org.eclipse.equinox.p2.publisher.IPublisherInfo;
-import org.eclipse.equinox.p2.publisher.IPublisherResult;
-import org.eclipse.equinox.p2.publisher.PublisherInfo;
-import org.eclipse.equinox.p2.publisher.actions.IAdditionalInstallableUnitAdvice;
-import org.eclipse.equinox.p2.publisher.actions.ICapabilityAdvice;
-import org.eclipse.equinox.p2.publisher.actions.IFeatureRootAdvice;
-import org.eclipse.equinox.p2.publisher.actions.IPropertyAdvice;
-import org.eclipse.equinox.p2.publisher.actions.ITouchpointAdvice;
-import org.eclipse.equinox.p2.publisher.actions.IUpdateDescriptorAdvice;
+import org.eclipse.equinox.p2.metadata.expression.IMatchExpression;
+import org.eclipse.equinox.p2.publisher.*;
+import org.eclipse.equinox.p2.publisher.actions.*;
 import org.eclipse.equinox.p2.publisher.eclipse.FeaturesAction;
 import org.eclipse.equinox.p2.repository.artifact.IArtifactDescriptor;
-import org.eclipse.equinox.p2.tests.TestActivator;
-import org.eclipse.equinox.p2.tests.TestData;
-import org.eclipse.equinox.p2.tests.TestMetadataRepository;
+import org.eclipse.equinox.p2.tests.*;
 import org.eclipse.equinox.p2.tests.publisher.TestArtifactRepository;
 import org.eclipse.equinox.spi.p2.publisher.PublisherHelper;
 
@@ -108,9 +84,11 @@
 		IRequirement[][] applicabilityScope = iu.getApplicabilityScope();
 		assertEquals(1, applicabilityScope.length);
 		IRequiredCapability require = (IRequiredCapability) applicabilityScope[0][0];
-
-		IRequirement expected = MetadataFactory.createRequirement(IInstallableUnit.NAMESPACE_IU_ID, "org.foo.feature.group", VersionRange.create("[1.0.0, 2.0.0)"), null, false, false, true);
-		verifyRequirement(Collections.singleton(expected), require);
+		assertEquals("org.foo.feature.group", require.getName());
+		IMatchExpression<IInstallableUnit> matches = require.getMatches();
+		assertEquals("providedCapabilities.exists(x | x.name == $0 && x.namespace == $1 && x.version >= $2 && x.version < $3)", matches.toString());
+		assertEquals(Version.parseVersion("1.0.0"), matches.getParameters()[2]);
+		assertEquals(Version.parseVersion("2.0.0"), matches.getParameters()[3]);
 	}
 
 	public void testMatchRange() throws Exception {
@@ -133,14 +111,16 @@
 		Collection<IRequirement> requires = iu.getRequirements();
 		assertEquals(3, requires.size());
 		for (IRequirement require : requires) {
-			String requireName = ((IRequiredCapability) require).getName();
-
-			if (requireName.equals("org.foo.feature.group")) {
-				IRequirement expected = MetadataFactory.createRequirement(IInstallableUnit.NAMESPACE_IU_ID, "org.foo.feature.group", VersionRange.create("[1.0.0, 2.0.0)"), null, false, false, true);
-				verifyRequirement(Collections.singleton(expected), require);
-			} else if (requireName.equals("org.plug")) {
-				IRequirement expected = MetadataFactory.createRequirement(IInstallableUnit.NAMESPACE_IU_ID, "org.plug", VersionRange.create("[1.0.0, 2.0.0)"), null, false, false, true);
-				verifyRequirement(Collections.singleton(expected), require);
+			if (((IRequiredCapability) require).getName().equals("org.foo.feature.group")) {
+				IMatchExpression<IInstallableUnit> matches = require.getMatches();
+				assertEquals("providedCapabilities.exists(x | x.name == $0 && x.namespace == $1 && x.version >= $2 && x.version < $3)", matches.toString());
+				assertEquals(Version.parseVersion("1.0.0"), matches.getParameters()[2]);
+				assertEquals(Version.parseVersion("2.0.0"), matches.getParameters()[3]);
+			} else if (((IRequiredCapability) require).getName().equals("org.plug")) {
+				IMatchExpression<IInstallableUnit> matches = require.getMatches();
+				assertEquals("providedCapabilities.exists(x | x.name == $0 && x.namespace == $1 && x.version >= $2 && x.version < $3)", matches.toString());
+				assertEquals(Version.parseVersion("1.0.0"), matches.getParameters()[2]);
+				assertEquals(Version.parseVersion("2.0.0"), matches.getParameters()[3]);
 			}
 		}
 	}
@@ -165,14 +145,14 @@
 		Collection<IRequirement> requires = iu.getRequirements();
 		assertEquals(3, requires.size());
 		for (IRequirement require : requires) {
-			String requireName = ((IRequiredCapability) require).getName();
-
-			if (requireName.equals("org.foo.feature.group")) {
-				IRequirement expected = MetadataFactory.createRequirement(IInstallableUnit.NAMESPACE_IU_ID, "org.foo.feature.group", VersionRange.create("1.0.0"), null, false, false, true);
-				verifyRequirement(Collections.singleton(expected), require);
-			} else if (requireName.equals("org.plug")) {
-				IRequirement expected = MetadataFactory.createRequirement(IInstallableUnit.NAMESPACE_IU_ID, "org.plug", VersionRange.create("1.0.0"), null, false, false, true);
-				verifyRequirement(Collections.singleton(expected), require);
+			if (((IRequiredCapability) require).getName().equals("org.foo.feature.group")) {
+				IMatchExpression<IInstallableUnit> matches = require.getMatches();
+				assertEquals("providedCapabilities.exists(x | x.name == $0 && x.namespace == $1 && x.version >= $2)", matches.toString());
+				assertEquals(Version.parseVersion("1.0.0"), matches.getParameters()[2]);
+			} else if (((IRequiredCapability) require).getName().equals("org.plug")) {
+				IMatchExpression<IInstallableUnit> matches = require.getMatches();
+				assertEquals("providedCapabilities.exists(x | x.name == $0 && x.namespace == $1 && x.version >= $2)", matches.toString());
+				assertEquals(Version.parseVersion("1.0.0"), matches.getParameters()[2]);
 			}
 		}
 	}
@@ -245,9 +225,9 @@
 		assertTrue(fooRequiredCapabilities.size() == 0);
 
 		Collection<IProvidedCapability> fooProvidedCapabilities = foo.getProvidedCapabilities();
-		verifyProvidedCapability(fooProvidedCapabilities, IInstallableUnit.NAMESPACE_IU_ID, "foo.feature.jar", fooVersion); //$NON-NLS-1$
-		verifyProvidedCapability(fooProvidedCapabilities, PublisherHelper.NAMESPACE_ECLIPSE_TYPE, "feature", fooVersion); //$NON-NLS-1$
-		verifyProvidedCapability(fooProvidedCapabilities, "org.eclipse.update.feature", FOO, fooVersion); //$NON-NLS-1$
+		contains(fooProvidedCapabilities, IInstallableUnit.NAMESPACE_IU_ID, "foo.feature.jar", fooVersion); //$NON-NLS-1$
+		contains(fooProvidedCapabilities, PublisherHelper.NAMESPACE_ECLIPSE_TYPE, "feature", fooVersion); //$NON-NLS-1$
+		contains(fooProvidedCapabilities, "org.eclipse.update.feature", FOO, fooVersion); //$NON-NLS-1$
 		assertTrue(fooProvidedCapabilities.size() == 3);
 
 		//feature group IU for foo
@@ -280,8 +260,8 @@
 		IInstallableUnit barGroup = barIUs.get(0);
 		Collection<IRequirement> barRequiredCapabilities = barGroup.getRequirements();
 		//contains(barRequiredCapabilities, IInstallableUnit.NAMESPACE_IU_ID, "bar_root", new VersionRange(barVersion, true, barVersion, true), null, false /*multiple*/, false /*optional*/); //$NON-NLS-1$//$NON-NLS-2$
-		verifyRequirement(barRequiredCapabilities, IInstallableUnit.NAMESPACE_IU_ID, "bar.feature.jar", new VersionRange(barVersion, true, barVersion, true), "(org.eclipse.update.install.features=true)", 1, 1, true); //$NON-NLS-1$//$NON-NLS-2$
-		verifyRequirement(barRequiredCapabilities, IInstallableUnit.NAMESPACE_IU_ID, "org.bar.feature.feature.group", VersionRange.emptyRange, "(&(|(osgi.nl=de)(osgi.nl=en)(osgi.nl=fr)))", 1, 1, true); //$NON-NLS-1$//$NON-NLS-2$
+		contains(barRequiredCapabilities, IInstallableUnit.NAMESPACE_IU_ID, "bar.feature.jar", new VersionRange(barVersion, true, barVersion, true), "(org.eclipse.update.install.features=true)", false /*multiple*/, false /*optional*/); //$NON-NLS-1$//$NON-NLS-2$
+		contains(barRequiredCapabilities, IInstallableUnit.NAMESPACE_IU_ID, "org.bar.feature.feature.group", VersionRange.emptyRange, "(&(|(osgi.nl=de)(osgi.nl=en)(osgi.nl=fr)))", false /*multiple*/, false /*optional*/); //$NON-NLS-1$//$NON-NLS-2$
 		assertEquals(barGroup.getFilter().getParameters()[0], ExpressionUtil.parseLDAP("(&(|(osgi.os=macosx)(osgi.os=win32))(|(osgi.ws=carbon)(osgi.ws=win32))(|(osgi.arch=ppc)(osgi.arch=x86))(osgi.nl=en))"));
 
 		//check zipped=true in touchpointData
@@ -297,9 +277,9 @@
 		assertTrue(barRequiredCapabilities.size() == 0);
 
 		Collection<IProvidedCapability> barProvidedCapabilities = bar.getProvidedCapabilities();
-		verifyProvidedCapability(barProvidedCapabilities, IInstallableUnit.NAMESPACE_IU_ID, "bar.feature.jar", barVersion); //$NON-NLS-1$
-		verifyProvidedCapability(barProvidedCapabilities, PublisherHelper.NAMESPACE_ECLIPSE_TYPE, "feature", fooVersion); //$NON-NLS-1$
-		verifyProvidedCapability(barProvidedCapabilities, "org.eclipse.update.feature", BAR, barVersion); //$NON-NLS-1$
+		contains(barProvidedCapabilities, IInstallableUnit.NAMESPACE_IU_ID, "bar.feature.jar", barVersion); //$NON-NLS-1$
+		contains(barProvidedCapabilities, PublisherHelper.NAMESPACE_ECLIPSE_TYPE, "feature", fooVersion); //$NON-NLS-1$
+		contains(barProvidedCapabilities, "org.eclipse.update.feature", BAR, barVersion); //$NON-NLS-1$
 		assertTrue(barProvidedCapabilities.size() == 3);
 	}
 
diff --git a/bundles/org.eclipse.equinox.p2.tests/src/org/eclipse/equinox/p2/tests/publisher/actions/JREActionTest.java b/bundles/org.eclipse.equinox.p2.tests/src/org/eclipse/equinox/p2/tests/publisher/actions/JREActionTest.java
index 0fdb648..7595578 100644
--- a/bundles/org.eclipse.equinox.p2.tests/src/org/eclipse/equinox/p2/tests/publisher/actions/JREActionTest.java
+++ b/bundles/org.eclipse.equinox.p2.tests/src/org/eclipse/equinox/p2/tests/publisher/actions/JREActionTest.java
@@ -12,44 +12,22 @@
 package org.eclipse.equinox.p2.tests.publisher.actions;
 
 import static org.easymock.EasyMock.expect;
-import static org.eclipse.equinox.p2.tests.publisher.actions.StatusMatchers.errorStatus;
-import static org.eclipse.equinox.p2.tests.publisher.actions.StatusMatchers.okStatus;
-import static org.eclipse.equinox.p2.tests.publisher.actions.StatusMatchers.statusWithMessageWhich;
-import static org.hamcrest.CoreMatchers.containsString;
-import static org.hamcrest.CoreMatchers.hasItem;
-import static org.hamcrest.CoreMatchers.is;
-import static org.hamcrest.CoreMatchers.not;
+import static org.eclipse.equinox.p2.tests.publisher.actions.StatusMatchers.*;
+import static org.hamcrest.CoreMatchers.*;
 import static org.junit.Assert.assertThat;
 
-import java.io.ByteArrayOutputStream;
-import java.io.File;
-import java.io.FileFilter;
-import java.io.FileInputStream;
-import java.io.IOException;
-import java.util.Arrays;
-import java.util.Collection;
-import java.util.HashMap;
-import java.util.Map;
+import java.io.*;
+import java.util.*;
 import java.util.zip.ZipInputStream;
 import org.eclipse.core.runtime.IStatus;
 import org.eclipse.core.runtime.NullProgressMonitor;
 import org.eclipse.equinox.internal.p2.core.helpers.FileUtils;
 import org.eclipse.equinox.internal.p2.metadata.ArtifactKey;
-import org.eclipse.equinox.p2.metadata.IArtifactKey;
-import org.eclipse.equinox.p2.metadata.IInstallableUnit;
-import org.eclipse.equinox.p2.metadata.IInstallableUnitFragment;
-import org.eclipse.equinox.p2.metadata.IProvidedCapability;
-import org.eclipse.equinox.p2.metadata.IRequirement;
-import org.eclipse.equinox.p2.metadata.ITouchpointInstruction;
-import org.eclipse.equinox.p2.metadata.MetadataFactory;
-import org.eclipse.equinox.p2.metadata.Version;
-import org.eclipse.equinox.p2.metadata.VersionRange;
+import org.eclipse.equinox.p2.metadata.*;
 import org.eclipse.equinox.p2.publisher.IPublisherInfo;
 import org.eclipse.equinox.p2.publisher.IPublisherResult;
 import org.eclipse.equinox.p2.publisher.actions.JREAction;
-import org.eclipse.equinox.p2.tests.TestActivator;
-import org.eclipse.equinox.p2.tests.TestData;
-import org.eclipse.equinox.p2.tests.TestMetadataRepository;
+import org.eclipse.equinox.p2.tests.*;
 import org.eclipse.equinox.p2.tests.publisher.TestArtifactRepository;
 import org.eclipse.equinox.spi.p2.publisher.PublisherHelper;
 
@@ -210,7 +188,7 @@
 		assertTrue(((ITouchpointInstruction) instructions.get("uninstall")).getBody().equals("cleanupzip(source:@artifact, target:${installFolder});")); //$NON-NLS-1$ //$NON-NLS-2$
 		assertTrue(bar instanceof IInstallableUnitFragment);
 		Collection<IRequirement> requiredCapability = ((IInstallableUnitFragment) bar).getHost();
-		verifyRequirement(requiredCapability, IInstallableUnit.NAMESPACE_IU_ID, id, new VersionRange(jreVersion, true, Version.MAX_VERSION, true));
+		verifyRequiredCapability(requiredCapability, IInstallableUnit.NAMESPACE_IU_ID, id, new VersionRange(jreVersion, true, Version.MAX_VERSION, true));
 		assertTrue(requiredCapability.size() == 1);
 
 		Collection<IProvidedCapability> providedCapability = bar.getProvidedCapabilities();