Initial commit.
diff --git a/bundles/org.eclipse.equinox.p2.tests.verifier/.classpath b/bundles/org.eclipse.equinox.p2.tests.verifier/.classpath
new file mode 100644
index 0000000..2fbb7a2
--- /dev/null
+++ b/bundles/org.eclipse.equinox.p2.tests.verifier/.classpath
@@ -0,0 +1,7 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<classpath>
+	<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/J2SE-1.4"/>
+	<classpathentry kind="con" path="org.eclipse.pde.core.requiredPlugins"/>
+	<classpathentry kind="src" path="src"/>
+	<classpathentry kind="output" path="bin"/>
+</classpath>
diff --git a/bundles/org.eclipse.equinox.p2.tests.verifier/.project b/bundles/org.eclipse.equinox.p2.tests.verifier/.project
new file mode 100644
index 0000000..26f0241
--- /dev/null
+++ b/bundles/org.eclipse.equinox.p2.tests.verifier/.project
@@ -0,0 +1,28 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<projectDescription>
+	<name>org.eclipse.equinox.p2.tests.verifier</name>
+	<comment></comment>
+	<projects>
+	</projects>
+	<buildSpec>
+		<buildCommand>
+			<name>org.eclipse.jdt.core.javabuilder</name>
+			<arguments>
+			</arguments>
+		</buildCommand>
+		<buildCommand>
+			<name>org.eclipse.pde.ManifestBuilder</name>
+			<arguments>
+			</arguments>
+		</buildCommand>
+		<buildCommand>
+			<name>org.eclipse.pde.SchemaBuilder</name>
+			<arguments>
+			</arguments>
+		</buildCommand>
+	</buildSpec>
+	<natures>
+		<nature>org.eclipse.pde.PluginNature</nature>
+		<nature>org.eclipse.jdt.core.javanature</nature>
+	</natures>
+</projectDescription>
diff --git a/bundles/org.eclipse.equinox.p2.tests.verifier/.settings/org.eclipse.jdt.core.prefs b/bundles/org.eclipse.equinox.p2.tests.verifier/.settings/org.eclipse.jdt.core.prefs
new file mode 100644
index 0000000..016a2a2
--- /dev/null
+++ b/bundles/org.eclipse.equinox.p2.tests.verifier/.settings/org.eclipse.jdt.core.prefs
@@ -0,0 +1,69 @@
+#Thu Sep 10 14:51:49 EDT 2009
+eclipse.preferences.version=1
+org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.2
+org.eclipse.jdt.core.compiler.compliance=1.4
+org.eclipse.jdt.core.compiler.problem.annotationSuperInterface=warning
+org.eclipse.jdt.core.compiler.problem.assertIdentifier=warning
+org.eclipse.jdt.core.compiler.problem.autoboxing=ignore
+org.eclipse.jdt.core.compiler.problem.comparingIdentical=warning
+org.eclipse.jdt.core.compiler.problem.deadCode=warning
+org.eclipse.jdt.core.compiler.problem.deprecation=warning
+org.eclipse.jdt.core.compiler.problem.deprecationInDeprecatedCode=disabled
+org.eclipse.jdt.core.compiler.problem.deprecationWhenOverridingDeprecatedMethod=enabled
+org.eclipse.jdt.core.compiler.problem.discouragedReference=ignore
+org.eclipse.jdt.core.compiler.problem.emptyStatement=warning
+org.eclipse.jdt.core.compiler.problem.enumIdentifier=warning
+org.eclipse.jdt.core.compiler.problem.fallthroughCase=ignore
+org.eclipse.jdt.core.compiler.problem.fatalOptionalError=enabled
+org.eclipse.jdt.core.compiler.problem.fieldHiding=warning
+org.eclipse.jdt.core.compiler.problem.finalParameterBound=warning
+org.eclipse.jdt.core.compiler.problem.finallyBlockNotCompletingNormally=warning
+org.eclipse.jdt.core.compiler.problem.forbiddenReference=error
+org.eclipse.jdt.core.compiler.problem.hiddenCatchBlock=warning
+org.eclipse.jdt.core.compiler.problem.incompatibleNonInheritedInterfaceMethod=warning
+org.eclipse.jdt.core.compiler.problem.incompleteEnumSwitch=ignore
+org.eclipse.jdt.core.compiler.problem.indirectStaticAccess=warning
+org.eclipse.jdt.core.compiler.problem.localVariableHiding=warning
+org.eclipse.jdt.core.compiler.problem.methodWithConstructorName=warning
+org.eclipse.jdt.core.compiler.problem.missingDeprecatedAnnotation=ignore
+org.eclipse.jdt.core.compiler.problem.missingHashCodeMethod=ignore
+org.eclipse.jdt.core.compiler.problem.missingOverrideAnnotation=ignore
+org.eclipse.jdt.core.compiler.problem.missingSerialVersion=warning
+org.eclipse.jdt.core.compiler.problem.missingSynchronizedOnInheritedMethod=ignore
+org.eclipse.jdt.core.compiler.problem.noEffectAssignment=warning
+org.eclipse.jdt.core.compiler.problem.noImplicitStringConversion=warning
+org.eclipse.jdt.core.compiler.problem.nonExternalizedStringLiteral=warning
+org.eclipse.jdt.core.compiler.problem.nullReference=warning
+org.eclipse.jdt.core.compiler.problem.overridingPackageDefaultMethod=warning
+org.eclipse.jdt.core.compiler.problem.parameterAssignment=ignore
+org.eclipse.jdt.core.compiler.problem.possibleAccidentalBooleanAssignment=warning
+org.eclipse.jdt.core.compiler.problem.potentialNullReference=ignore
+org.eclipse.jdt.core.compiler.problem.rawTypeReference=warning
+org.eclipse.jdt.core.compiler.problem.redundantNullCheck=ignore
+org.eclipse.jdt.core.compiler.problem.redundantSuperinterface=ignore
+org.eclipse.jdt.core.compiler.problem.specialParameterHidingField=disabled
+org.eclipse.jdt.core.compiler.problem.staticAccessReceiver=warning
+org.eclipse.jdt.core.compiler.problem.suppressWarnings=enabled
+org.eclipse.jdt.core.compiler.problem.syntheticAccessEmulation=warning
+org.eclipse.jdt.core.compiler.problem.typeParameterHiding=warning
+org.eclipse.jdt.core.compiler.problem.uncheckedTypeOperation=warning
+org.eclipse.jdt.core.compiler.problem.undocumentedEmptyBlock=warning
+org.eclipse.jdt.core.compiler.problem.unhandledWarningToken=warning
+org.eclipse.jdt.core.compiler.problem.unnecessaryElse=warning
+org.eclipse.jdt.core.compiler.problem.unnecessaryTypeCheck=warning
+org.eclipse.jdt.core.compiler.problem.unqualifiedFieldAccess=ignore
+org.eclipse.jdt.core.compiler.problem.unusedDeclaredThrownException=warning
+org.eclipse.jdt.core.compiler.problem.unusedDeclaredThrownExceptionExemptExceptionAndThrowable=enabled
+org.eclipse.jdt.core.compiler.problem.unusedDeclaredThrownExceptionIncludeDocCommentReference=enabled
+org.eclipse.jdt.core.compiler.problem.unusedDeclaredThrownExceptionWhenOverriding=enabled
+org.eclipse.jdt.core.compiler.problem.unusedImport=warning
+org.eclipse.jdt.core.compiler.problem.unusedLabel=warning
+org.eclipse.jdt.core.compiler.problem.unusedLocal=warning
+org.eclipse.jdt.core.compiler.problem.unusedParameter=ignore
+org.eclipse.jdt.core.compiler.problem.unusedParameterIncludeDocCommentReference=enabled
+org.eclipse.jdt.core.compiler.problem.unusedParameterWhenImplementingAbstract=enabled
+org.eclipse.jdt.core.compiler.problem.unusedParameterWhenOverridingConcrete=enabled
+org.eclipse.jdt.core.compiler.problem.unusedPrivateMember=warning
+org.eclipse.jdt.core.compiler.problem.unusedWarningToken=warning
+org.eclipse.jdt.core.compiler.problem.varargsArgumentNeedCast=warning
+org.eclipse.jdt.core.compiler.source=1.3
diff --git a/bundles/org.eclipse.equinox.p2.tests.verifier/META-INF/MANIFEST.MF b/bundles/org.eclipse.equinox.p2.tests.verifier/META-INF/MANIFEST.MF
new file mode 100644
index 0000000..a7619a6
--- /dev/null
+++ b/bundles/org.eclipse.equinox.p2.tests.verifier/META-INF/MANIFEST.MF
@@ -0,0 +1,13 @@
+Manifest-Version: 1.0
+Bundle-ManifestVersion: 2
+Bundle-Name: Test Install Verifier
+Bundle-SymbolicName: org.eclipse.equinox.p2.tests.verifier;singleton:=true
+Bundle-Version: 1.0.0.qualifier
+Bundle-Activator: org.eclipse.equinox.internal.p2.tests.verifier.Activator
+Require-Bundle: org.eclipse.core.runtime
+Bundle-ActivationPolicy: lazy
+Import-Package: org.eclipse.equinox.internal.p2.core.helpers,
+ org.eclipse.equinox.internal.provisional.p2.engine,
+ org.eclipse.equinox.internal.provisional.p2.metadata.query,
+ org.eclipse.equinox.internal.provisional.p2.query
+Bundle-RequiredExecutionEnvironment: J2SE-1.4
diff --git a/bundles/org.eclipse.equinox.p2.tests.verifier/build.properties b/bundles/org.eclipse.equinox.p2.tests.verifier/build.properties
new file mode 100644
index 0000000..e9863e2
--- /dev/null
+++ b/bundles/org.eclipse.equinox.p2.tests.verifier/build.properties
@@ -0,0 +1,5 @@
+source.. = src/
+output.. = bin/
+bin.includes = META-INF/,\
+               .,\
+               plugin.xml
diff --git a/bundles/org.eclipse.equinox.p2.tests.verifier/plugin.xml b/bundles/org.eclipse.equinox.p2.tests.verifier/plugin.xml
new file mode 100644
index 0000000..27d6c0c
--- /dev/null
+++ b/bundles/org.eclipse.equinox.p2.tests.verifier/plugin.xml
@@ -0,0 +1,9 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<?eclipse version="3.4"?>
+<plugin>
+	<extension id="application" point="org.eclipse.core.runtime.applications"> 
+		<application cardinality="singleton-global" thread="main" visible="true"> 
+			<run class="org.eclipse.equinox.internal.p2.tests.verifier.VerifierApplication"/> 
+		</application> 
+	</extension>
+</plugin>
diff --git a/bundles/org.eclipse.equinox.p2.tests.verifier/src/org/eclipse/equinox/internal/p2/tests/verifier/Activator.java b/bundles/org.eclipse.equinox.p2.tests.verifier/src/org/eclipse/equinox/internal/p2/tests/verifier/Activator.java
new file mode 100644
index 0000000..d2a6fd2
--- /dev/null
+++ b/bundles/org.eclipse.equinox.p2.tests.verifier/src/org/eclipse/equinox/internal/p2/tests/verifier/Activator.java
@@ -0,0 +1,55 @@
+/*******************************************************************************
+ * Copyright (c) 2009 IBM Corporation 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:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.equinox.internal.p2.tests.verifier;
+
+import org.osgi.framework.BundleActivator;
+import org.osgi.framework.BundleContext;
+
+/**
+ * The activator class controls the plug-in life cycle
+ */
+public class Activator implements BundleActivator {
+
+	// The plug-in ID
+	public static final String PLUGIN_ID = "org.eclipse.equinox.p2.tests.verifier"; //$NON-NLS-1$
+	private static BundleContext bundleContext;
+
+	/**
+	 * The constructor
+	 */
+	public Activator() {
+		// nothing interesting to do
+	}
+
+	/*
+	 * (non-Javadoc)
+	 * @see org.eclipse.core.runtime.Plugins#start(org.osgi.framework.BundleContext)
+	 */
+	public void start(BundleContext context) throws Exception {
+		bundleContext = context;
+	}
+
+	/*
+	 * (non-Javadoc)
+	 * @see org.eclipse.core.runtime.Plugin#stop(org.osgi.framework.BundleContext)
+	 */
+	public void stop(BundleContext context) throws Exception {
+		bundleContext = null;
+	}
+
+	/*
+	 * Return the bundle context or <code>null</code>.
+	 */
+	public static BundleContext getBundleContext() {
+		return bundleContext;
+	}
+
+}
diff --git a/bundles/org.eclipse.equinox.p2.tests.verifier/src/org/eclipse/equinox/internal/p2/tests/verifier/VerifierApplication.java b/bundles/org.eclipse.equinox.p2.tests.verifier/src/org/eclipse/equinox/internal/p2/tests/verifier/VerifierApplication.java
new file mode 100644
index 0000000..8472d6e
--- /dev/null
+++ b/bundles/org.eclipse.equinox.p2.tests.verifier/src/org/eclipse/equinox/internal/p2/tests/verifier/VerifierApplication.java
@@ -0,0 +1,310 @@
+/*******************************************************************************
+ * Copyright (c) 2009 IBM Corporation 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:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.equinox.internal.p2.tests.verifier;
+
+import java.io.*;
+import java.util.*;
+import org.eclipse.core.runtime.*;
+import org.eclipse.core.runtime.internal.adaptor.EclipseAdaptorMsg;
+import org.eclipse.core.runtime.internal.adaptor.MessageHelper;
+import org.eclipse.equinox.app.IApplication;
+import org.eclipse.equinox.app.IApplicationContext;
+import org.eclipse.equinox.internal.p2.core.helpers.ServiceHelper;
+import org.eclipse.equinox.internal.provisional.p2.engine.IProfile;
+import org.eclipse.equinox.internal.provisional.p2.engine.IProfileRegistry;
+import org.eclipse.equinox.internal.provisional.p2.metadata.query.InstallableUnitQuery;
+import org.eclipse.equinox.internal.provisional.p2.query.Collector;
+import org.eclipse.osgi.framework.internal.core.Constants;
+import org.eclipse.osgi.service.resolver.*;
+import org.eclipse.osgi.util.NLS;
+import org.osgi.framework.Bundle;
+import org.osgi.service.packageadmin.PackageAdmin;
+
+/**
+ * Application which verifies an install.
+ * 
+ * @since 1.0
+ */
+public class VerifierApplication implements IApplication {
+
+	private static final File DEFAULT_PROPERTIES_FILE = new File("verifier.properties"); //$NON-NLS-1$
+	private static final String ARG_PROPERTIES = "-verifier.properties"; //$NON-NLS-1$
+	private Properties properties = null;
+	private List ignoreResolved = null;
+
+	/*
+	 * Create and return an error status with the given message.
+	 */
+	private static IStatus createError(String message) {
+		return new Status(IStatus.ERROR, Activator.PLUGIN_ID, message);
+	}
+
+	/*
+	 * Return the bundle with the given symbolic name, or <code>null</code> if it does not exist.
+	 */
+	public static Bundle getBundle(String symbolicName) {
+		PackageAdmin packageAdmin = (PackageAdmin) ServiceHelper.getService(Activator.getBundleContext(), PackageAdmin.class.getName());
+		if (packageAdmin == null)
+			return null;
+		Bundle[] bundles = packageAdmin.getBundles(symbolicName, null);
+		if (bundles == null)
+			return null;
+		// Return the first bundle that is not installed or uninstalled
+		for (int i = 0; i < bundles.length; i++) {
+			if ((bundles[i].getState() & (Bundle.INSTALLED | Bundle.UNINSTALLED)) == 0) {
+				return bundles[i];
+			}
+		}
+		return null;
+	}
+
+	/* (non-Javadoc)
+	 * @see org.eclipse.equinox.app.IApplication#start(org.eclipse.equinox.app.IApplicationContext)
+	 */
+	public Object start(IApplicationContext context) throws Exception {
+		// start this bundle to registry a bunch of things we need
+		getBundle("org.eclipse.equinox.p2.exemplarysetup").start(Bundle.START_TRANSIENT); //$NON-NLS-1$
+		String[] args = (String[]) context.getArguments().get(IApplicationContext.APPLICATION_ARGS);
+		processArguments(args);
+		return verify();
+	}
+
+	/*
+	 * Go through the command-line args and pull out interesting ones
+	 * for later consumption.
+	 */
+	private void processArguments(String[] args) {
+		if (args == null)
+			return;
+
+		for (int i = 1; i < args.length; i++) {
+			if (ARG_PROPERTIES.equals(args[i - 1])) {
+				String filename = args[i];
+				if (filename.startsWith("-"))
+					continue;
+				try {
+					properties = readProperties(new File(filename));
+				} catch (IOException e) {
+					// TODO
+					e.printStackTrace();
+					// fall through to load default
+				}
+				continue;
+			}
+		}
+
+		// problems loading properties file or none specified so look for a default
+		if (properties == null) {
+			try {
+				if (DEFAULT_PROPERTIES_FILE.exists())
+					properties = readProperties(DEFAULT_PROPERTIES_FILE);
+			} catch (IOException e) {
+				// TODO 
+				e.printStackTrace();
+			}
+		}
+		if (properties == null)
+			properties = new Properties();
+	}
+
+	/*
+	 * Read and return a properties file at the given location.
+	 */
+	private Properties readProperties(File file) throws IOException {
+		Properties result = new Properties();
+		InputStream input = null;
+		try {
+			input = new BufferedInputStream(new FileInputStream(file));
+			result.load(input);
+			return result;
+		} finally {
+			if (input != null)
+				try {
+					input.close();
+				} catch (IOException e) {
+					// ignore
+				}
+		}
+	}
+
+	/* (non-Javadoc)
+	 * @see org.eclipse.equinox.app.IApplication#stop()
+	 */
+	public void stop() {
+		// nothing to do
+	}
+
+	/*
+	 * Return a boolean value indicating whether or not the bundle with the given symbolic name
+	 * should be considered when looking at bundles which are not resolved in the system.
+	 */
+	private boolean shouldCheckResolved(String bundle) {
+		if (ignoreResolved == null) {
+			ignoreResolved = new ArrayList();
+			String list = properties.getProperty("ignore.unresolved");
+			if (list == null)
+				return true;
+			for (StringTokenizer tokenizer = new StringTokenizer(list, ","); tokenizer.hasMoreTokens();)
+				ignoreResolved.add(tokenizer.nextToken().trim());
+		}
+		for (Iterator iter = ignoreResolved.iterator(); iter.hasNext();) {
+			if (bundle.equals(iter.next()))
+				return false;
+		}
+		return true;
+	}
+
+	private List getAllBundles() {
+		PlatformAdmin platformAdmin = (PlatformAdmin) ServiceHelper.getService(Activator.getBundleContext(), PlatformAdmin.class.getName());
+		PackageAdmin packageAdmin = (PackageAdmin) ServiceHelper.getService(Activator.getBundleContext(), PackageAdmin.class.getName());
+		State state = platformAdmin.getState(false);
+		List result = new ArrayList();
+
+		BundleDescription[] bundles = state.getBundles();
+		for (int i = 0; i < bundles.length; i++) {
+			BundleDescription bundle = bundles[i];
+			Bundle[] versions = packageAdmin.getBundles(bundle.getSymbolicName(), bundle.getVersion().toString());
+			for (int j = 0; j < versions.length; j++)
+				result.add(versions[j]);
+		}
+		return result;
+	}
+
+	/*
+	 * Check to ensure all of the bundles in the system are resolved.
+	 * 
+	 * Copied and modified from EclipseStarter#logUnresolvedBundles.
+	 * This method prints out all the reasons while asking the resolver directly
+	 * will only print out the first reason.
+	 */
+	private IStatus checkResolved() {
+		List allProblems = new ArrayList();
+		PlatformAdmin platformAdmin = (PlatformAdmin) ServiceHelper.getService(Activator.getBundleContext(), PlatformAdmin.class.getName());
+		State state = platformAdmin.getState(false);
+		StateHelper stateHelper = platformAdmin.getStateHelper();
+
+		// first lets look for missing leaf constraints (bug 114120)
+		VersionConstraint[] leafConstraints = stateHelper.getUnsatisfiedLeaves(state.getBundles());
+		// hash the missing leaf constraints by the declaring bundles
+		Map missing = new HashMap();
+		for (int i = 0; i < leafConstraints.length; i++) {
+			// only include non-optional and non-dynamic constraint leafs
+			if (leafConstraints[i] instanceof BundleSpecification && ((BundleSpecification) leafConstraints[i]).isOptional())
+				continue;
+			if (leafConstraints[i] instanceof ImportPackageSpecification) {
+				if (ImportPackageSpecification.RESOLUTION_OPTIONAL.equals(((ImportPackageSpecification) leafConstraints[i]).getDirective(Constants.RESOLUTION_DIRECTIVE)))
+					continue;
+				if (ImportPackageSpecification.RESOLUTION_DYNAMIC.equals(((ImportPackageSpecification) leafConstraints[i]).getDirective(Constants.RESOLUTION_DIRECTIVE)))
+					continue;
+			}
+			BundleDescription bundleDesc = leafConstraints[i].getBundle();
+			ArrayList constraints = (ArrayList) missing.get(bundleDesc);
+			if (constraints == null) {
+				constraints = new ArrayList();
+				missing.put(bundleDesc, constraints);
+			}
+			constraints.add(leafConstraints[i]);
+		}
+
+		// found some bundles with missing leaf constraints; log them first 
+		if (missing.size() > 0) {
+			int rootIndex = 0;
+			for (Iterator iter = missing.keySet().iterator(); iter.hasNext(); rootIndex++) {
+				BundleDescription description = (BundleDescription) iter.next();
+				String generalMessage = NLS.bind(EclipseAdaptorMsg.ECLIPSE_STARTUP_ERROR_BUNDLE_NOT_RESOLVED, description.getLocation());
+				ArrayList constraints = (ArrayList) missing.get(description);
+				for (Iterator inner = constraints.iterator(); inner.hasNext();) {
+					String message = generalMessage + " Reason: " + MessageHelper.getResolutionFailureMessage((VersionConstraint) inner.next());
+					allProblems.add(createError(message));
+				}
+			}
+		}
+
+		// There may be some bundles unresolved for other reasons, causing the system to be unresolved
+		// log all unresolved constraints now
+		List allBundles = getAllBundles();
+		for (Iterator i = allBundles.iterator(); i.hasNext();) {
+			Bundle bundle = (Bundle) i.next();
+			if (bundle.getState() == Bundle.INSTALLED) {
+				String generalMessage = NLS.bind(EclipseAdaptorMsg.ECLIPSE_STARTUP_ERROR_BUNDLE_NOT_RESOLVED, bundle);
+				BundleDescription description = state.getBundle(bundle.getBundleId());
+				// for some reason, the state does not know about that bundle
+				if (description == null)
+					continue;
+				VersionConstraint[] unsatisfied = stateHelper.getUnsatisfiedConstraints(description);
+				if (unsatisfied.length > 0) {
+					// the bundle wasn't resolved due to some of its constraints were unsatisfiable
+					for (int j = 0; j < unsatisfied.length; j++)
+						allProblems.add(createError(generalMessage + " Reason: " + MessageHelper.getResolutionFailureMessage(unsatisfied[j])));
+				} else {
+					ResolverError[] resolverErrors = state.getResolverErrors(description);
+					for (int j = 0; j < resolverErrors.length; j++) {
+						if (shouldAdd(resolverErrors[j])) {
+							allProblems.add(createError(generalMessage + " Reason: " + resolverErrors[j].toString()));
+						}
+					}
+				}
+			}
+		}
+		MultiStatus result = new MultiStatus(Activator.PLUGIN_ID, IStatus.OK, "Problems checking resolved bundles.", null);
+		for (Iterator iter = allProblems.iterator(); iter.hasNext();)
+			result.add((IStatus) iter.next());
+		return result;
+	}
+
+	/*
+	 * Return a boolean value indicating whether or not the given resolver error should be 
+	 * added to our results.
+	 */
+	private boolean shouldAdd(ResolverError error) {
+		// ignore EE problems?
+		if (ResolverError.MISSING_EXECUTION_ENVIRONMENT == error.getType() && Boolean.valueOf(properties.getProperty("ignore.ee")).booleanValue())
+			return false;
+		return true;
+	}
+
+	/*
+	 * Ensure we have a profile registry and can access the SELF profile.
+	 */
+	private IStatus checkProfileRegistry() {
+		IProfileRegistry registry = (IProfileRegistry) ServiceHelper.getService(Activator.getBundleContext(), IProfileRegistry.class.getName());
+		if (registry == null)
+			return createError("Profile registry service not available.");
+		IProfile profile = registry.getProfile(IProfileRegistry.SELF);
+		if (profile == null)
+			return createError("SELF profile not available in profile registry.");
+		Collector results = profile.query(new InstallableUnitQuery(Activator.PLUGIN_ID), new Collector(), null);
+		if (results.isEmpty())
+			return createError(NLS.bind("IU for {0} not found in SELF profile.", Activator.PLUGIN_ID));
+		return Status.OK_STATUS;
+	}
+
+	/*
+	 * Perform all of the verification checks.
+	 */
+	public IStatus verify() {
+		String message = "Problems occurred during verification.";
+		MultiStatus result = new MultiStatus(Activator.PLUGIN_ID, IStatus.OK, message, null);
+
+		// ensure all the bundles are resolved
+		IStatus temp = checkResolved();
+		if (!temp.isOK())
+			result.merge(temp);
+
+		// ensure we have a profile registry
+		temp = checkProfileRegistry();
+		if (!temp.isOK())
+			result.merge(temp);
+
+		return result;
+	}
+
+}