diff --git a/karaf/itests/pom.xml b/karaf/itests/pom.xml
index 022dfa9..20aeea6 100644
--- a/karaf/itests/pom.xml
+++ b/karaf/itests/pom.xml
@@ -56,62 +56,12 @@
             <version>1.2.1</version>
         </dependency>
 
-        <!-- The assembly and all the dependencies -->
-        <dependency>
-            <groupId>org.apache.felix.karaf</groupId>
-            <artifactId>apache-felix-karaf</artifactId>
-            <type>xml</type>
-            <classifier>features</classifier>
-            <scope>test</scope>
-        </dependency>
-
         <dependency>
             <groupId>org.apache.felix.karaf.tooling</groupId>
             <artifactId>org.apache.felix.karaf.tooling.testing</artifactId>
             <scope>test</scope>
         </dependency>
-
-        <!-- Pax EXAM -->
-        <dependency>
-            <groupId>org.ops4j.pax.exam</groupId>
-            <artifactId>pax-exam</artifactId>
-            <scope>test</scope>
-        </dependency>
-        <dependency>
-            <groupId>org.ops4j.pax.exam</groupId>
-            <artifactId>pax-exam-junit</artifactId>
-            <scope>test</scope>
-        </dependency>
-        <dependency>
-            <groupId>org.ops4j.pax.exam</groupId>
-            <artifactId>pax-exam-container-default</artifactId>
-            <scope>test</scope>
-        </dependency>
-        <dependency>
-            <groupId>org.ops4j.pax.exam</groupId>
-            <artifactId>pax-exam-junit-extender-impl</artifactId>
-            <scope>test</scope>
-        </dependency>
-        <dependency>
-            <groupId>junit</groupId>
-            <artifactId>junit</artifactId>
-            <version>4.5</version>
-            <scope>test</scope>
-        </dependency>
-    </dependencies>
-
-    <repositories>
-        <repository>
-            <id>ops4j.releases</id>
-            <url>http://repository.ops4j.org/maven2</url>
-        </repository>
-    </repositories>
-    <pluginRepositories>
-        <pluginRepository>
-            <id>ops4j.releases</id>
-            <url>http://repository.ops4j.org/maven2</url>
-        </pluginRepository>
-    </pluginRepositories>
+   </dependencies>
 
     <build>
         <plugins>
@@ -153,26 +103,6 @@
                 </plugins>
             </build>
         </profile>
-        <!--
-        <profile>
-            <activation>
-                <os>
-                    <family>Windows</family>
-                </os>
-            </activation>
-            <build>
-                <plugins>
-                    <plugin>
-                        <groupId>org.apache.maven.plugins</groupId>
-                        <artifactId>maven-surefire-plugin</artifactId>
-                        <configuration>
-                            <skip>true</skip>
-                        </configuration>
-                    </plugin>
-                </plugins>
-            </build>
-        </profile>
-        -->
     </profiles>
 
 </project>
diff --git a/karaf/itests/src/test/java/org/apache/felix/karaf/shell/itests/CoreTest.java b/karaf/itests/src/test/java/org/apache/felix/karaf/shell/itests/CoreTest.java
index fb3d014..a0f7534 100644
--- a/karaf/itests/src/test/java/org/apache/felix/karaf/shell/itests/CoreTest.java
+++ b/karaf/itests/src/test/java/org/apache/felix/karaf/shell/itests/CoreTest.java
@@ -16,11 +16,7 @@
  */
 package org.apache.felix.karaf.shell.itests;
 
-import java.util.Collections;
-import java.util.Comparator;
-import java.util.Dictionary;
-import java.util.List;
-
+import org.apache.felix.karaf.testing.AbstractIntegrationTest;
 import org.apache.felix.karaf.testing.Helper;
 import org.junit.Test;
 import org.junit.runner.RunWith;
@@ -28,7 +24,6 @@
 import org.ops4j.pax.exam.junit.Configuration;
 import org.ops4j.pax.exam.junit.JUnit4TestRunner;
 import org.osgi.framework.Bundle;
-import org.osgi.framework.Constants;
 import org.osgi.service.command.CommandProcessor;
 import org.osgi.service.command.CommandSession;
 
@@ -36,12 +31,11 @@
 import static org.junit.Assert.fail;
 import static org.ops4j.pax.exam.CoreOptions.equinox;
 import static org.ops4j.pax.exam.CoreOptions.felix;
-import static org.ops4j.pax.exam.CoreOptions.options;
 import static org.ops4j.pax.exam.CoreOptions.systemProperty;
 import static org.ops4j.pax.exam.OptionUtils.combine;
 
 @RunWith(JUnit4TestRunner.class)
-public class CoreTest extends org.apache.felix.karaf.testing.AbstractIntegrationTest {
+public class CoreTest extends AbstractIntegrationTest {
 
     @Test
     public void testHelp() throws Exception {
diff --git a/karaf/itests/src/test/java/org/apache/felix/karaf/shell/itests/FeaturesTest.java b/karaf/itests/src/test/java/org/apache/felix/karaf/shell/itests/FeaturesTest.java
index 49f5fc4..a3b29c0 100644
--- a/karaf/itests/src/test/java/org/apache/felix/karaf/shell/itests/FeaturesTest.java
+++ b/karaf/itests/src/test/java/org/apache/felix/karaf/shell/itests/FeaturesTest.java
@@ -16,6 +16,7 @@
  */
 package org.apache.felix.karaf.shell.itests;
 
+import org.apache.felix.karaf.testing.AbstractIntegrationTest;
 import org.apache.felix.karaf.testing.Helper;
 import org.junit.Test;
 import org.junit.runner.RunWith;
@@ -35,7 +36,7 @@
 import static org.ops4j.pax.exam.container.def.PaxRunnerOptions.scanFeatures;
 
 @RunWith(JUnit4TestRunner.class)
-public class FeaturesTest extends org.apache.felix.karaf.testing.AbstractIntegrationTest {
+public class FeaturesTest extends AbstractIntegrationTest {
 
     @Test
     public void testFeatures() throws Exception {
diff --git a/karaf/pom.xml b/karaf/pom.xml
index ae3ff8f..ba3a783 100644
--- a/karaf/pom.xml
+++ b/karaf/pom.xml
@@ -87,7 +87,7 @@
         <geronimo.servlet.version>1.1.2</geronimo.servlet.version>
         <jansi.version>1.1</jansi.version>
         <jetty.bundle.version>6.1.14_1</jetty.bundle.version>
-        <junit.version>3.8.2_1</junit.version>
+        <junit.version>4.7_1</junit.version>
         <jline.version>0.9.95-20091026.080844</jline.version>
         <log4j.version>1.2.14</log4j.version>
         <maven.version>2.0.9</maven.version>
diff --git a/karaf/tooling/testing/pom.xml b/karaf/tooling/testing/pom.xml
index 4008c9b..7f29aba 100644
--- a/karaf/tooling/testing/pom.xml
+++ b/karaf/tooling/testing/pom.xml
@@ -39,6 +39,13 @@
     </properties>
 
     <dependencies>
+        <!-- The assembly and all the dependencies -->
+        <dependency>
+            <groupId>org.apache.felix.karaf</groupId>
+            <artifactId>apache-felix-karaf</artifactId>
+            <type>xml</type>
+            <classifier>features</classifier>
+        </dependency>
         <!-- Pax EXAM -->
         <dependency>
             <groupId>org.ops4j.pax.exam</groupId>
@@ -57,9 +64,8 @@
             <artifactId>pax-exam-junit-extender-impl</artifactId>
         </dependency>
         <dependency>
-            <groupId>junit</groupId>
-            <artifactId>junit</artifactId>
-            <version>4.5</version>
+            <groupId>org.apache.servicemix.bundles</groupId>
+            <artifactId>org.apache.servicemix.bundles.junit</artifactId>
         </dependency>
     </dependencies>
 
diff --git a/karaf/tooling/testing/src/main/java/org/apache/felix/karaf/testing/Helper.java b/karaf/tooling/testing/src/main/java/org/apache/felix/karaf/testing/Helper.java
index f41a716..1243eb9 100644
--- a/karaf/tooling/testing/src/main/java/org/apache/felix/karaf/testing/Helper.java
+++ b/karaf/tooling/testing/src/main/java/org/apache/felix/karaf/testing/Helper.java
@@ -16,31 +16,20 @@
  */
 package org.apache.felix.karaf.testing;
 
+import java.io.IOException;
 import java.io.InputStream;
 import java.net.URL;
 import java.util.ArrayList;
-import java.util.Collection;
-import java.util.Dictionary;
 import java.util.Enumeration;
 import java.util.HashMap;
-import java.util.LinkedList;
 import java.util.List;
 import java.util.Map;
 import java.util.Properties;
 
 import org.ops4j.pax.exam.CoreOptions;
-import org.ops4j.pax.exam.Inject;
 import org.ops4j.pax.exam.Option;
 import org.ops4j.pax.exam.options.MavenArtifactProvisionOption;
 import org.ops4j.pax.exam.options.SystemPropertyOption;
-import org.osgi.framework.Bundle;
-import org.osgi.framework.BundleContext;
-import org.osgi.framework.Constants;
-import org.osgi.framework.Filter;
-import org.osgi.framework.FrameworkUtil;
-import org.osgi.framework.InvalidSyntaxException;
-import org.osgi.framework.ServiceReference;
-import org.osgi.util.tracker.ServiceTracker;
 
 import static org.ops4j.pax.exam.CoreOptions.bootClasspathLibrary;
 import static org.ops4j.pax.exam.CoreOptions.frameworkStartLevel;
@@ -48,42 +37,222 @@
 import static org.ops4j.pax.exam.CoreOptions.wrappedBundle;
 import static org.ops4j.pax.exam.OptionUtils.combine;
 
+/**
+ * Helper class for setting up a pax-exam test environment for karaf.
+ *
+ * A simple configuration for pax-exam can be create using the following
+ * code:
+ * <pre>
+ *   @Configuration
+ *   public static Option[] configuration() throws Exception{
+ *       return combine(
+ *           // Default karaf environment
+ *           Helper.getDefaultOptions(),
+ *           // Test on both equinox and felix
+ *           equinox(), felix()
+ *       );
+ *   }
+ * </pre>
+ *
+ */
 public final class Helper {
 
     private Helper() {
     }
 
+    /**
+     *  Create an provisioning option for the specified maven artifact
+     * (groupId and artifactId), using the version found in the list
+     * of dependencies of this maven project.
+     *
+     * @param groupId the groupId of the maven bundle
+     * @param artifactId the artifactId of the maven bundle
+     * @return the provisioning option for the given bundle
+     */
     public static MavenArtifactProvisionOption mavenBundle(String groupId, String artifactId) {
-        return CoreOptions.mavenBundle().groupId(groupId).artifactId(artifactId).versionAsInProject();
+        return CoreOptions.mavenBundle(groupId, artifactId).versionAsInProject();
     }
 
-    /*
-     * Explode the dictionary into a ,-delimited list of key=value pairs
+    /**
+     * Return a map of system properties for karaf.
+     * The default karaf home directory is "target/karaf.home".
+     *
+     * @return a list of system properties for karaf
      */
-    private static String explode(Dictionary dictionary) {
-        Enumeration keys = dictionary.keys();
-        StringBuffer result = new StringBuffer();
-        while (keys.hasMoreElements()) {
-            Object key = keys.nextElement();
-            result.append(String.format("%s=%s", key, dictionary.get(key)));
-            if (keys.hasMoreElements()) {
-                result.append(", ");
-            }
-        }
-        return result.toString();
+    public static Properties getDefaultSystemOptions() {
+        return getDefaultSystemOptions("target/karaf.home");
     }
 
-    /*
-     * Provides an iterable collection of references, even if the original array is null
+    /**
+     * Return a map of system properties for karaf,
+     * using the specified folder for the karaf home directory.
+     *
+     * @param karafHome the karaf home directory
+     * @return a list of system properties for karaf
      */
-    private static final Collection<ServiceReference> asCollection(ServiceReference[] references) {
-        List<ServiceReference> result = new LinkedList<ServiceReference>();
-        if (references != null) {
-            for (ServiceReference reference : references) {
-                result.add(reference);
+    public static Properties getDefaultSystemOptions(String karafHome) {
+        Properties sysProps = new Properties();
+        sysProps.setProperty("karaf.name", "root");
+        sysProps.setProperty("karaf.home", karafHome);
+        sysProps.setProperty("karaf.base", karafHome);
+        sysProps.setProperty("karaf.startLocalConsole", "false");
+        sysProps.setProperty("karaf.startRemoteShell", "false");
+        sysProps.setProperty("org.osgi.framework.startlevel.beginning", "100");
+        return sysProps;
+    }
+
+    /**
+     * Return an array of pax-exam options to correctly configure the osgi
+     * framework for karaf.
+     *
+     * @return default pax-exam options for karaf osgi framework
+     */
+    public static Option[] getDefaultConfigOptions() {
+        return getDefaultConfigOptions(getDefaultSystemOptions(),
+                                       getResource("/org/apache/felix/karaf/testing/config.properties"));
+    }
+
+    /**
+     * Return an array of pax-exam options to configure the osgi
+     * framework for karaf, given the system properties and the
+     * location of the osgi framework properties file.
+     *
+     * @param sysProps karaf system properties
+     * @param configProperties the URL to load the osgi framework properties from
+     * @return pax-exam options for karaf osgi framework
+     */
+    public static Option[] getDefaultConfigOptions(Properties sysProps, URL configProperties) {
+        // Load props
+        Properties configProps = loadProperties(configProperties);
+        // Set system props
+        for (Enumeration e = sysProps.propertyNames(); e.hasMoreElements();) {
+            String key = (String) e.nextElement();
+            configProps.setProperty(key, sysProps.getProperty(key));
+        }
+        // Perform variable substitution for system properties.
+        for (Enumeration e = configProps.propertyNames(); e.hasMoreElements();) {
+            String name = (String) e.nextElement();
+            configProps.setProperty(name, substVars(configProps.getProperty(name), name, null, configProps));
+        }
+        // Transform to sys props options
+        List<Option> options = new ArrayList<Option>();
+        for (Enumeration e = configProps.propertyNames(); e.hasMoreElements();) {
+            String name = (String) e.nextElement();
+            String value = configProps.getProperty(name);
+            value = value.replaceAll("\r", "").replaceAll("\n", "").replaceAll(" ", "");
+            options.add(new SystemPropertyOption(name).value(value));
+        }
+        if (configProps.getProperty("org.osgi.framework.startlevel.beginning") != null) {
+            options.add(frameworkStartLevel(Integer.parseInt(configProps.getProperty("org.osgi.framework.startlevel.beginning"))));
+        }
+        return options.toArray(new Option[options.size()]);
+    }
+
+    /**
+     * Return an array of pax-exam options for the provisioning of karaf system bundles.
+     *
+     * @return an array of pax-exam options for provisioning karaf system bundles
+     */
+    public static Option[] getDefaultProvisioningOptions() {
+        return getDefaultProvisioningOptions(getDefaultSystemOptions(),
+                                            getResource("/org/apache/felix/karaf/testing/startup.properties"));
+    }
+
+    /**
+     * Return an array of pax-exam options for the provisioning of karaf system bundles,
+     * given the karaf system properties and the location of the startup bundles config file.
+     *
+     * @param sysProps karaf system properties
+     * @param startupProperties the URL to load the system bundles from
+     * @return an array of pax-exam options for provisioning karaf system bundles
+     */
+    public static Option[] getDefaultProvisioningOptions(Properties sysProps, URL startupProperties) {
+        Properties startupProps = loadProperties(startupProperties);
+        // Perform variable substitution for system properties.
+        for (Enumeration e = startupProps.propertyNames(); e.hasMoreElements();) {
+            String name = (String) e.nextElement();
+            startupProps.setProperty(name, substVars(startupProps.getProperty(name), name, null, sysProps));
+        }
+        // Transform to sys props options
+        List<Option> options = new ArrayList<Option>();
+        options.add(bootClasspathLibrary(mavenBundle("org.apache.felix.karaf.jaas", "org.apache.felix.karaf.jaas.boot")).afterFramework());
+        options.add(bootClasspathLibrary(mavenBundle("org.apache.felix.karaf", "org.apache.felix.karaf.main")).afterFramework());
+        for (Enumeration e = startupProps.propertyNames(); e.hasMoreElements();) {
+            String name = (String) e.nextElement();
+            String value = startupProps.getProperty(name);
+            MavenArtifactProvisionOption opt = convertToMaven(name);
+            if (opt.getURL().contains("org.apache.felix.karaf.features")) {
+                opt.noStart();
+            }
+            opt.startLevel(Integer.parseInt(value));
+            options.add(opt);
+        }
+        options.add(mavenBundle("org.apache.felix.karaf.tooling", "org.apache.felix.karaf.tooling.testing"));
+        // We need to add pax-exam-junit here when running with the ibm
+        // jdk to avoid the following exception during the test run:
+        // ClassNotFoundException: org.ops4j.pax.exam.junit.Configuration
+        if ("IBM Corporation".equals(System.getProperty("java.vendor"))) {
+            options.add(wrappedBundle(maven("org.ops4j.pax.exam", "pax-exam-junit")));
+        }
+        return options.toArray(new Option[options.size()]);
+    }
+
+    /**
+     * Return an array of options for setting up a pax-exam test environment for karaf.
+     *
+     * @return an array of pax-exam options
+     */
+    public static Option[] getDefaultOptions() {
+        return combine(getDefaultConfigOptions(), getDefaultProvisioningOptions());
+    }
+
+    /**
+     * Retrieve the pax-exam option for provisioning the given maven bundle.
+     *
+     * @param options the list of pax-exam options
+     * @param groupId the maven group id
+     * @param artifactId the maven artifact id
+     * @return the pax-exam provisioning option for the bundle or <code>null</code> if not found
+     */
+    public static MavenArtifactProvisionOption findMaven(Option[] options, String groupId, String artifactId) {
+        for (Option option : options) {
+            if (option instanceof MavenArtifactProvisionOption) {
+                MavenArtifactProvisionOption mvn = (MavenArtifactProvisionOption) option;
+                if (mvn.getURL().startsWith("mvn:" + groupId + "/" + artifactId + "/")) {
+                    return mvn;
+                }
             }
         }
-        return result;
+        return null;
+    }
+
+    private static Properties loadProperties(URL location) {
+        try {
+            Properties props = new Properties();
+            InputStream is = location.openStream();
+            try {
+                props.load(is);
+            } finally {
+                is.close();
+            }
+            return props;
+        } catch (IOException e) {
+            throw new RuntimeException("Unable to load properties from " + location, e);
+        }
+    }
+
+    private static URL getResource(String location) {
+        URL url = null;
+        if (Thread.currentThread().getContextClassLoader() != null) {
+            url = Thread.currentThread().getContextClassLoader().getResource(location);
+        }
+        if (url == null) {
+            url = Helper.class.getResource(location);
+        }
+        if (url == null) {
+            throw new RuntimeException("Unable to find resource " + location);
+        }
+        return url;
     }
 
     private static final String DELIM_START = "${";
@@ -226,481 +395,4 @@
         }
     }
 
-    public static Properties getDefaultSystemOptions() {
-        return getDefaultSystemOptions("target/karaf.home");
-    }
-
-    public static Properties getDefaultSystemOptions(String karafHome) {
-        Properties sysProps = new Properties();
-        sysProps.setProperty("karaf.name", "root");
-        sysProps.setProperty("karaf.home", karafHome);
-        sysProps.setProperty("karaf.base", karafHome);
-        sysProps.setProperty("karaf.startLocalConsole", "false");
-        sysProps.setProperty("karaf.startRemoteShell", "false");
-        sysProps.setProperty("org.osgi.framework.startlevel.beginning", "100");
-        return sysProps;
-    }
-
-    public static Option[] getDefaultConfigOptions() throws Exception {
-        return getDefaultConfigOptions(getDefaultSystemOptions(),
-                                       getResource("/org/apache/felix/karaf/testing/config.properties"));
-    }
-
-    public static Option[] getDefaultConfigOptions(Properties sysProps, URL configProperties) throws Exception {
-        // Load props
-        Properties configProps = new Properties();
-        InputStream is = configProperties.openStream();
-        try {
-            configProps.load(is);
-        } finally {
-            is.close();
-        }
-        // Set system props
-        for (Enumeration e = sysProps.propertyNames(); e.hasMoreElements();) {
-            String key = (String) e.nextElement();
-            configProps.setProperty(key, sysProps.getProperty(key));
-        }
-        // Perform variable substitution for system properties.
-        for (Enumeration e = configProps.propertyNames(); e.hasMoreElements();) {
-            String name = (String) e.nextElement();
-            configProps.setProperty(name, substVars(configProps.getProperty(name), name, null, configProps));
-        }
-        // Transform to sys props options
-        List<Option> options = new ArrayList<Option>();
-        for (Enumeration e = configProps.propertyNames(); e.hasMoreElements();) {
-            String name = (String) e.nextElement();
-            String value = configProps.getProperty(name);
-            value = value.replaceAll("\r", "").replaceAll("\n", "").replaceAll(" ", "");
-            options.add(new SystemPropertyOption(name).value(value));
-            System.err.println("sysprop: " + name + " = " + value);
-        }
-        if (configProps.getProperty("org.osgi.framework.startlevel.beginning") != null) {
-            options.add(frameworkStartLevel(Integer.parseInt(configProps.getProperty("org.osgi.framework.startlevel.beginning"))));
-        }
-        return options.toArray(new Option[options.size()]);
-    }
-
-    public static Option[] getDefaultProvisioningOptions() throws Exception {
-        return getDefaultProvisioningOptions(getDefaultSystemOptions(),
-                                            getResource("/org/apache/felix/karaf/testing/startup.properties"));
-    }
-
-    private static URL getResource(String location) throws Exception {
-        URL url = null;
-        if (Thread.currentThread().getContextClassLoader() != null) {
-            url = Thread.currentThread().getContextClassLoader().getResource(location);
-        }
-        if (url == null) {
-            url = Helper.class.getResource(location);
-        }
-        System.err.println("Trying to load resource: " + location + ". Found: " + url);
-        return url;
-    }
-
-    public static Option[] getDefaultProvisioningOptions(Properties sysProps, URL configProperties) throws Exception {
-        Properties startupProps = new Properties();
-        InputStream is = configProperties.openStream();
-        try {
-            startupProps.load(is);
-        } finally {
-            is.close();
-        }
-        // Perform variable substitution for system properties.
-        for (Enumeration e = startupProps.propertyNames(); e.hasMoreElements();) {
-            String name = (String) e.nextElement();
-            startupProps.setProperty(name, substVars(startupProps.getProperty(name), name, null, sysProps));
-        }
-        // Transform to sys props options
-        List<Option> options = new ArrayList<Option>();
-        options.add(bootClasspathLibrary(mavenBundle("org.apache.felix.karaf.jaas", "org.apache.felix.karaf.jaas.boot")).afterFramework());
-        options.add(bootClasspathLibrary(mavenBundle("org.apache.felix.karaf", "org.apache.felix.karaf.main")).afterFramework());
-        for (Enumeration e = startupProps.propertyNames(); e.hasMoreElements();) {
-            String name = (String) e.nextElement();
-            String value = startupProps.getProperty(name);
-            MavenArtifactProvisionOption opt = convertToMaven(name);
-            if (opt.getURL().contains("org.apache.felix.karaf.features")) {
-                opt.noStart();
-            }
-            opt.startLevel(Integer.parseInt(value));
-            options.add(opt);
-        }
-        options.add(mavenBundle("org.apache.felix.karaf.tooling", "org.apache.felix.karaf.tooling.testing"));
-        // We need to add pax-exam-junit here when running with the ibm
-        // jdk to avoid the following exception during the test run:
-        // ClassNotFoundException: org.ops4j.pax.exam.junit.Configuration
-        if ("IBM Corporation".equals(System.getProperty("java.vendor"))) {
-            options.add(wrappedBundle(maven("org.ops4j.pax.exam", "pax-exam-junit")));
-        }
-        return options.toArray(new Option[options.size()]);
-    }
-
-    public static Option[] getDefaultOptions() throws Exception {
-        return combine(getDefaultConfigOptions(), getDefaultProvisioningOptions());
-    }
-
-    public static MavenArtifactProvisionOption findMaven(Option[] options, String groupId, String artifactId) {
-        for (Option option : options) {
-            if (option instanceof MavenArtifactProvisionOption) {
-                MavenArtifactProvisionOption mvn = (MavenArtifactProvisionOption) option;
-                if (mvn.getURL().startsWith("mvn:" + groupId + "/" + artifactId + "/")) {
-                    return mvn;
-                }
-            }
-        }
-        return null;
-    }
-
-    public abstract static class AbstractIntegrationTest {
-
-        public static final long DEFAULT_TIMEOUT = 30000;
-
-        @Inject
-        protected BundleContext bundleContext;
-
-        protected <T> T getOsgiService(Class<T> type, long timeout) {
-            return getOsgiService(type, null, timeout);
-        }
-
-        protected <T> T getOsgiService(Class<T> type) {
-            return getOsgiService(type, null, DEFAULT_TIMEOUT);
-        }
-
-        protected <T> T getOsgiService(Class<T> type, String filter, long timeout) {
-            ServiceTracker tracker = null;
-            try {
-                String flt;
-                if (filter != null) {
-                    if (filter.startsWith("(")) {
-                        flt = "(&(" + Constants.OBJECTCLASS + "=" + type.getName() + ")" + filter + ")";
-                    } else {
-                        flt = "(&(" + Constants.OBJECTCLASS + "=" + type.getName() + ")(" + filter + "))";
-                    }
-                } else {
-                    flt = "(" + Constants.OBJECTCLASS + "=" + type.getName() + ")";
-                }
-                Filter osgiFilter = FrameworkUtil.createFilter(flt);
-                tracker = new ServiceTracker(bundleContext, osgiFilter, null);
-                tracker.open(true);
-                // Note that the tracker is not closed to keep the reference
-                // This is buggy, as the service reference may change i think
-                Object svc = type.cast(tracker.waitForService(timeout));
-                if (svc == null) {
-                    Dictionary dic = bundleContext.getBundle().getHeaders();
-                    System.err.println("Test bundle headers: " + explode(dic));
-
-                    for (ServiceReference ref : asCollection(bundleContext.getAllServiceReferences(null, null))) {
-                        System.err.println("ServiceReference: " + ref);
-                    }
-
-                    for (ServiceReference ref : asCollection(bundleContext.getAllServiceReferences(null, flt))) {
-                        System.err.println("Filtered ServiceReference: " + ref);
-                    }
-
-                    throw new RuntimeException("Gave up waiting for service " + flt);
-                }
-                return type.cast(svc);
-            } catch (InvalidSyntaxException e) {
-                throw new IllegalArgumentException("Invalid filter", e);
-            } catch (InterruptedException e) {
-                throw new RuntimeException(e);
-            }
-        }
-
-        protected Bundle installBundle(String groupId, String artifactId) throws Exception {
-            MavenArtifactProvisionOption mvnUrl = mavenBundle(groupId, artifactId);
-            return bundleContext.installBundle(mvnUrl.getURL());
-        }
-
-        protected Bundle getInstalledBundle(String symbolicName) {
-            for (Bundle b : bundleContext.getBundles()) {
-                if (b.getSymbolicName().equals(symbolicName)) {
-                    return b;
-                }
-            }
-            return null;
-        }
-
-        public static MavenArtifactProvisionOption mavenBundle(String groupId, String artifactId) {
-            return CoreOptions.mavenBundle().groupId(groupId).artifactId(artifactId).versionAsInProject();
-        }
-
-        /*
-         * Explode the dictionary into a ,-delimited list of key=value pairs
-         */
-        private static String explode(Dictionary dictionary) {
-            Enumeration keys = dictionary.keys();
-            StringBuffer result = new StringBuffer();
-            while (keys.hasMoreElements()) {
-                Object key = keys.nextElement();
-                result.append(String.format("%s=%s", key, dictionary.get(key)));
-                if (keys.hasMoreElements()) {
-                    result.append(", ");
-                }
-            }
-            return result.toString();
-        }
-
-        /*
-         * Provides an iterable collection of references, even if the original array is null
-         */
-        private static final Collection<ServiceReference> asCollection(ServiceReference[] references) {
-            List<ServiceReference> result = new LinkedList<ServiceReference>();
-            if (references != null) {
-                for (ServiceReference reference : references) {
-                    result.add(reference);
-                }
-            }
-            return result;
-        }
-
-        private static final String DELIM_START = "${";
-        private static final String DELIM_STOP = "}";
-
-        /**
-         * <p>
-         * This method performs property variable substitution on the
-         * specified value. If the specified value contains the syntax
-         * <tt>${&lt;prop-name&gt;}</tt>, where <tt>&lt;prop-name&gt;</tt>
-         * refers to either a configuration property or a system property,
-         * then the corresponding property value is substituted for the variable
-         * placeholder. Multiple variable placeholders may exist in the
-         * specified value as well as nested variable placeholders, which
-         * are substituted from inner most to outer most. Configuration
-         * properties override system properties.
-         * </p>
-         *
-         * @param val         The string on which to perform property substitution.
-         * @param currentKey  The key of the property being evaluated used to
-         *                    detect cycles.
-         * @param cycleMap    Map of variable references used to detect nested cycles.
-         * @param configProps Set of configuration properties.
-         * @return The value of the specified string after system property substitution.
-         * @throws IllegalArgumentException If there was a syntax error in the
-         *                                  property placeholder syntax or a recursive variable reference.
-         */
-        private static String substVars(String val, String currentKey,
-                                        Map<String, String> cycleMap, Properties configProps)
-                throws IllegalArgumentException {
-            // If there is currently no cycle map, then create
-            // one for detecting cycles for this invocation.
-            if (cycleMap == null) {
-                cycleMap = new HashMap<String, String>();
-            }
-
-            // Put the current key in the cycle map.
-            cycleMap.put(currentKey, currentKey);
-
-            // Assume we have a value that is something like:
-            // "leading ${foo.${bar}} middle ${baz} trailing"
-
-            // Find the first ending '}' variable delimiter, which
-            // will correspond to the first deepest nested variable
-            // placeholder.
-            int stopDelim = val.indexOf(DELIM_STOP);
-
-            // Find the matching starting "${" variable delimiter
-            // by looping until we find a start delimiter that is
-            // greater than the stop delimiter we have found.
-            int startDelim = val.indexOf(DELIM_START);
-            while (stopDelim >= 0) {
-                int idx = val.indexOf(DELIM_START, startDelim + DELIM_START.length());
-                if ((idx < 0) || (idx > stopDelim)) {
-                    break;
-                } else if (idx < stopDelim) {
-                    startDelim = idx;
-                }
-            }
-
-            // If we do not have a start or stop delimiter, then just
-            // return the existing value.
-            if ((startDelim < 0) && (stopDelim < 0)) {
-                return val;
-            }
-            // At this point, we found a stop delimiter without a start,
-            // so throw an exception.
-            else if (((startDelim < 0) || (startDelim > stopDelim))
-                    && (stopDelim >= 0)) {
-                throw new IllegalArgumentException(
-                        "stop delimiter with no start delimiter: "
-                                + val);
-            }
-
-            // At this point, we have found a variable placeholder so
-            // we must perform a variable substitution on it.
-            // Using the start and stop delimiter indices, extract
-            // the first, deepest nested variable placeholder.
-            String variable =
-                    val.substring(startDelim + DELIM_START.length(), stopDelim);
-
-            // Verify that this is not a recursive variable reference.
-            if (cycleMap.get(variable) != null) {
-                throw new IllegalArgumentException(
-                        "recursive variable reference: " + variable);
-            }
-
-            // Get the value of the deepest nested variable placeholder.
-            // Try to configuration properties first.
-            String substValue = (configProps != null)
-                    ? configProps.getProperty(variable, null)
-                    : null;
-            if (substValue == null) {
-                // Ignore unknown property values.
-                substValue = System.getProperty(variable, "");
-            }
-
-            // Remove the found variable from the cycle map, since
-            // it may appear more than once in the value and we don't
-            // want such situations to appear as a recursive reference.
-            cycleMap.remove(variable);
-
-            // Append the leading characters, the substituted value of
-            // the variable, and the trailing characters to get the new
-            // value.
-            val = val.substring(0, startDelim)
-                    + substValue
-                    + val.substring(stopDelim + DELIM_STOP.length(), val.length());
-
-            // Now perform substitution again, since there could still
-            // be substitutions to make.
-            val = substVars(val, currentKey, cycleMap, configProps);
-
-            // Return the value.
-            return val;
-        }
-
-        private static MavenArtifactProvisionOption convertToMaven(String location) {
-            String[] p = location.split("/");
-            if (p.length >= 4 && p[p.length-1].startsWith(p[p.length-3] + "-" + p[p.length-2])) {
-                MavenArtifactProvisionOption opt = new MavenArtifactProvisionOption();
-                int artifactIdVersionLength = p[p.length-3].length() + 1 + p[p.length-2].length(); // (artifactId + "-" + version).length
-                if (p[p.length-1].charAt(artifactIdVersionLength) == '-') {
-                    opt.classifier((p[p.length-1].substring(artifactIdVersionLength + 1, p[p.length-1].lastIndexOf('.'))));
-                }
-                StringBuffer sb = new StringBuffer();
-                for (int j = 0; j < p.length - 3; j++) {
-                    if (j > 0) {
-                        sb.append('.');
-                    }
-                    sb.append(p[j]);
-                }
-                opt.groupId(sb.toString());
-                opt.artifactId(p[p.length-3]);
-                opt.version(p[p.length-2]);
-                opt.type(p[p.length-1].substring(p[p.length-1].lastIndexOf('.') + 1));
-                return opt;
-            } else {
-                throw new IllegalArgumentException("Unable to extract maven information from " + location);
-            }
-        }
-
-        public static Properties getDefaultSystemOptions() {
-            return getDefaultSystemOptions("target/karaf.home");
-        }
-
-        public static Properties getDefaultSystemOptions(String karafHome) {
-            Properties sysProps = new Properties();
-            sysProps.setProperty("karaf.name", "root");
-            sysProps.setProperty("karaf.home", karafHome);
-            sysProps.setProperty("karaf.base", karafHome);
-            sysProps.setProperty("karaf.startLocalConsole", "false");
-            sysProps.setProperty("karaf.startRemoteShell", "false");
-            sysProps.setProperty("org.osgi.framework.startlevel.beginning", "100");
-            return sysProps;
-        }
-
-        public static Option[] getDefaultConfigOptions() throws Exception {
-            return getDefaultConfigOptions(getDefaultSystemOptions(),
-                                           Helper.class.getResource("/config.properties"));
-        }
-
-        public static Option[] getDefaultConfigOptions(Properties sysProps, URL configProperties) throws Exception {
-            // Load props
-            Properties configProps = new Properties();
-            InputStream is = configProperties.openStream();
-            try {
-                configProps.load(is);
-            } finally {
-                is.close();
-            }
-            // Set system props
-            for (Enumeration e = sysProps.propertyNames(); e.hasMoreElements();) {
-                String key = (String) e.nextElement();
-                configProps.setProperty(key, sysProps.getProperty(key));
-            }
-            // Perform variable substitution for system properties.
-            for (Enumeration e = configProps.propertyNames(); e.hasMoreElements();) {
-                String name = (String) e.nextElement();
-                configProps.setProperty(name, substVars(configProps.getProperty(name), name, null, configProps));
-            }
-            // Transform to sys props options
-            List<Option> options = new ArrayList<Option>();
-            for (Enumeration e = configProps.propertyNames(); e.hasMoreElements();) {
-                String name = (String) e.nextElement();
-                String value = configProps.getProperty(name);
-                value = value.replaceAll("\r", "").replaceAll("\n", "").replaceAll(" ", "");
-                options.add(new SystemPropertyOption(name).value(value));
-            }
-            if (configProps.getProperty("org.osgi.framework.startlevel.beginning") != null) {
-                options.add(frameworkStartLevel(Integer.parseInt(configProps.getProperty("org.osgi.framework.startlevel.beginning"))));
-            }
-            return options.toArray(new Option[options.size()]);
-        }
-
-        public static Option[] getDefaultProvisioningOptions() throws Exception {
-            return getDefaultProvisioningOptions(getDefaultSystemOptions(),
-                                                 Helper.class.getResource("/startup.properties"));
-        }
-
-        public static Option[] getDefaultProvisioningOptions(Properties sysProps, URL configProperties) throws Exception {
-            Properties startupProps = new Properties();
-            InputStream is = configProperties.openStream();
-            try {
-                startupProps.load(is);
-            } finally {
-                is.close();
-            }
-            // Perform variable substitution for system properties.
-            for (Enumeration e = startupProps.propertyNames(); e.hasMoreElements();) {
-                String name = (String) e.nextElement();
-                startupProps.setProperty(name, substVars(startupProps.getProperty(name), name, null, sysProps));
-            }
-            // Transform to sys props options
-            List<Option> options = new ArrayList<Option>();
-            options.add(bootClasspathLibrary(mavenBundle("org.apache.felix.karaf.jaas", "org.apache.felix.karaf.jaas.boot")).afterFramework());
-            options.add(bootClasspathLibrary(mavenBundle("org.apache.felix.karaf", "org.apache.felix.karaf.main")).afterFramework());
-            for (Enumeration e = startupProps.propertyNames(); e.hasMoreElements();) {
-                String name = (String) e.nextElement();
-                String value = startupProps.getProperty(name);
-                MavenArtifactProvisionOption opt = convertToMaven(name);
-                if (opt.getURL().contains("org.apache.felix.karaf.features")) {
-                    opt.noStart();
-                }
-                opt.startLevel(Integer.parseInt(value));
-                options.add(opt);
-            }
-            // We need to add pax-exam-junit here when running with the ibm
-            // jdk to avoid the following exception during the test run:
-            // ClassNotFoundException: org.ops4j.pax.exam.junit.Configuration
-            if ("IBM Corporation".equals(System.getProperty("java.vendor"))) {
-                options.add(wrappedBundle(maven("org.ops4j.pax.exam", "pax-exam-junit")));
-            }
-            return options.toArray(new Option[options.size()]);
-        }
-
-        public static Option[] getDefaultOptions() throws Exception {
-            return combine(getDefaultConfigOptions(), getDefaultProvisioningOptions());
-        }
-
-        public static MavenArtifactProvisionOption findMaven(Option[] options, String groupId, String artifactId) {
-            for (Option option : options) {
-                if (option instanceof MavenArtifactProvisionOption) {
-                    MavenArtifactProvisionOption mvn = (MavenArtifactProvisionOption) option;
-                    if (mvn.getURL().startsWith("mvn:" + groupId + "/" + artifactId + "/")) {
-                        return mvn;
-                    }
-                }
-            }
-            return null;
-        }
-    }
 }
\ No newline at end of file
