diff --git a/karaf/itests/pom.xml b/karaf/itests/pom.xml
index abc44d4..022dfa9 100644
--- a/karaf/itests/pom.xml
+++ b/karaf/itests/pom.xml
@@ -65,6 +65,12 @@
             <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>
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 570f031..fb3d014 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,28 +16,32 @@
  */
 package org.apache.felix.karaf.shell.itests;
 
-import static org.junit.Assert.assertTrue;
-import static org.junit.Assert.fail;
+import java.util.Collections;
+import java.util.Comparator;
+import java.util.Dictionary;
+import java.util.List;
+
+import org.apache.felix.karaf.testing.Helper;
 import org.junit.Test;
 import org.junit.runner.RunWith;
-import static org.ops4j.pax.exam.CoreOptions.bootClasspathLibrary;
-import static org.ops4j.pax.exam.CoreOptions.felix;
-import static org.ops4j.pax.exam.CoreOptions.maven;
-import static org.ops4j.pax.exam.CoreOptions.options;
-import static org.ops4j.pax.exam.CoreOptions.systemPackages;
-import static org.ops4j.pax.exam.CoreOptions.systemProperty;
-import static org.ops4j.pax.exam.CoreOptions.equinox;
-import static org.ops4j.pax.exam.CoreOptions.wrappedBundle;
 import org.ops4j.pax.exam.Option;
-import static org.ops4j.pax.exam.OptionUtils.combine;
 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;
 
+import static org.junit.Assert.assertTrue;
+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 AbstractIntegrationTest {
+public class CoreTest extends org.apache.felix.karaf.testing.AbstractIntegrationTest {
 
     @Test
     public void testHelp() throws Exception {
@@ -108,49 +112,17 @@
 //    }
 //
     @Configuration
-    public static Option[] configuration() {
-        Option[] options = options(
+    public static Option[] configuration() throws Exception {
+        Option[] options = combine(
+            // Default karaf environment
+            Helper.getDefaultOptions(),
             // this is how you set the default log level when using pax logging (logProfile)
             systemProperty("org.ops4j.pax.logging.DefaultServiceLog.level").value("DEBUG"),
-            systemProperty("karaf.name").value("root"),
-            systemProperty("karaf.home").value("target/karaf.home"),
-            systemProperty("karaf.base").value("target/karaf.home"),
-            systemProperty("karaf.startLocalConsole").value("false"),
-            systemProperty("karaf.startRemoteShell").value("false"),
-
-            // hack system packages
-            systemPackages("org.apache.felix.karaf.jaas.boot;version=1.99"),
-            bootClasspathLibrary(mavenBundle("org.apache.felix.karaf.jaas", "org.apache.felix.karaf.jaas.boot")).afterFramework(),
-            bootClasspathLibrary(mavenBundle("org.apache.felix.karaf", "org.apache.felix.karaf.main")).afterFramework(),
-
-            // Log
-            mavenBundle("org.ops4j.pax.logging", "pax-logging-api"),
-            mavenBundle("org.ops4j.pax.logging", "pax-logging-service"),
-            // Felix Config Admin
-            mavenBundle("org.apache.felix", "org.apache.felix.configadmin"),
-            // Blueprint
-            mavenBundle("org.apache.geronimo.blueprint", "geronimo-blueprint"),
-
-            // Bundles
-            mavenBundle("org.apache.mina", "mina-core"),
-            mavenBundle("org.apache.sshd", "sshd-core"),
-            mavenBundle("org.apache.felix.karaf.jaas", "org.apache.felix.karaf.jaas.config"),
-            mavenBundle("org.apache.felix.gogo", "org.apache.felix.gogo.runtime"),
-            mavenBundle("org.apache.felix.karaf.shell", "org.apache.felix.karaf.shell.console"),
-            mavenBundle("org.apache.felix.karaf.shell", "org.apache.felix.karaf.shell.osgi"),
-            mavenBundle("org.apache.felix.karaf.shell", "org.apache.felix.karaf.shell.log").noStart(),
-
+            // Test on both equinox and felix
             equinox(), felix()
         );
-        // 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"))) {
-            Option[] ibmOptions = options(
-                wrappedBundle(maven("org.ops4j.pax.exam", "pax-exam-junit"))
-            );
-            options = combine(ibmOptions, options);
-        }
+        // Stop the shell log bundle 
+        Helper.findMaven(options, "org.apache.felix.karaf.shell", "org.apache.felix.karaf.shell.log").noStart();
         return options;
     }
 
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 ec5d198..49f5fc4 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,28 +16,26 @@
  */
 package org.apache.felix.karaf.shell.itests;
 
-import static org.junit.Assert.assertNotNull;
+import org.apache.felix.karaf.testing.Helper;
 import org.junit.Test;
 import org.junit.runner.RunWith;
-import static org.ops4j.pax.exam.CoreOptions.bootClasspathLibrary;
-import static org.ops4j.pax.exam.CoreOptions.equinox;
-import static org.ops4j.pax.exam.CoreOptions.felix;
-import static org.ops4j.pax.exam.CoreOptions.maven;
-import static org.ops4j.pax.exam.CoreOptions.options;
-import static org.ops4j.pax.exam.CoreOptions.systemPackages;
-import static org.ops4j.pax.exam.CoreOptions.systemProperty;
-import static org.ops4j.pax.exam.CoreOptions.wrappedBundle;
 import org.ops4j.pax.exam.Option;
-import static org.ops4j.pax.exam.OptionUtils.combine;
-import static org.ops4j.pax.exam.container.def.PaxRunnerOptions.scanFeatures;
 import org.ops4j.pax.exam.junit.Configuration;
 import org.ops4j.pax.exam.junit.JUnit4TestRunner;
 import org.osgi.service.blueprint.container.BlueprintContainer;
 import org.osgi.service.command.CommandProcessor;
 import org.osgi.service.command.CommandSession;
 
+import static org.junit.Assert.assertNotNull;
+import static org.ops4j.pax.exam.CoreOptions.equinox;
+import static org.ops4j.pax.exam.CoreOptions.felix;
+import static org.ops4j.pax.exam.CoreOptions.maven;
+import static org.ops4j.pax.exam.CoreOptions.systemProperty;
+import static org.ops4j.pax.exam.OptionUtils.combine;
+import static org.ops4j.pax.exam.container.def.PaxRunnerOptions.scanFeatures;
+
 @RunWith(JUnit4TestRunner.class)
-public class FeaturesTest extends AbstractIntegrationTest {
+public class FeaturesTest extends org.apache.felix.karaf.testing.AbstractIntegrationTest {
 
     @Test
     public void testFeatures() throws Exception {
@@ -53,57 +51,20 @@
     }
 
     @Configuration
-    public static Option[] configuration() {
-        Option[] options = options(
+    public static Option[] configuration() throws Exception{
+        return combine(
+            // Default karaf environment
+            Helper.getDefaultOptions(),
             // this is how you set the default log level when using pax logging (logProfile)
             systemProperty("org.ops4j.pax.logging.DefaultServiceLog.level").value("DEBUG"),
-            systemProperty("karaf.name").value("root"),
-            systemProperty("karaf.home").value("target/karaf.home"),
-            systemProperty("karaf.base").value("target/karaf.home"),
-            systemProperty("karaf.startLocalConsole").value("false"),
-            systemProperty("karaf.startRemoteShell").value("false"),
-
-            // hack system packages
-            systemPackages("org.apache.felix.karaf.jaas.boot;version=1.99"),
-            bootClasspathLibrary(mavenBundle("org.apache.felix.karaf.jaas", "org.apache.felix.karaf.jaas.boot")).afterFramework(),
-            bootClasspathLibrary(mavenBundle("org.apache.felix.karaf", "org.apache.felix.karaf.main")).afterFramework(),
-
-            // Log
-            mavenBundle("org.ops4j.pax.logging", "pax-logging-api"),
-            mavenBundle("org.ops4j.pax.logging", "pax-logging-service"),
-            // Felix Config Admin
-            mavenBundle("org.apache.felix", "org.apache.felix.configadmin"),
-            // Felix Preferences Service
-            mavenBundle("org.apache.felix", "org.apache.felix.prefs"),
-            // Blueprint
-            mavenBundle("org.apache.geronimo.blueprint", "geronimo-blueprint"),
-
-            // Bundles
-            mavenBundle("org.apache.mina", "mina-core"),
-            mavenBundle("org.apache.sshd", "sshd-core"),
-            mavenBundle("org.apache.felix.karaf.jaas", "org.apache.felix.karaf.jaas.config"),
-            mavenBundle("org.apache.felix.karaf.shell", "org.apache.felix.karaf.shell.console"),
-            mavenBundle("org.apache.felix.gogo", "org.apache.felix.gogo.runtime"),
-            mavenBundle("org.apache.felix.karaf.shell", "org.apache.felix.karaf.shell.osgi"),
-            mavenBundle("org.apache.felix.karaf.shell", "org.apache.felix.karaf.shell.log").noStart(),
-
+            // add two features
             scanFeatures(
                     maven().groupId("org.apache.felix.karaf").artifactId("apache-felix-karaf").type("xml").classifier("features").versionAsInProject(),
                     "obr", "wrapper"
             ),
-
+            // Test on both equinox and felix
             equinox(), felix()
         );
-        // 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"))) {
-            Option[] ibmOptions = options(
-                wrappedBundle(maven("org.ops4j.pax.exam", "pax-exam-junit"))
-            );
-            options = combine(ibmOptions, options);
-        }
-        return options;
     }
 
 }
diff --git a/karaf/itests/src/test/java/org/apache/felix/karaf/shell/itests/HeaderParser.java b/karaf/itests/src/test/java/org/apache/felix/karaf/shell/itests/HeaderParser.java
new file mode 100644
index 0000000..a6b6387
--- /dev/null
+++ b/karaf/itests/src/test/java/org/apache/felix/karaf/shell/itests/HeaderParser.java
@@ -0,0 +1,204 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.felix.karaf.shell.itests;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+/**
+ * Utility class to parse a standard OSGi header with paths.
+ *
+ * @author <a href="mailto:dev@geronimo.apache.org">Apache Geronimo Project</a>
+ * @version $Rev: 786132 $, $Date: 2009-06-18 17:47:58 +0200 (Thu, 18 Jun 2009) $
+ */
+public final class HeaderParser  {
+
+    // Private constructor for static final class
+    private HeaderParser() {
+    }
+
+    /**
+     * Parse a given OSGi header into a list of paths
+     *
+     * @param header the OSGi header to parse
+     * @return the list of paths extracted from this header
+     */
+    public static List<PathElement> parseHeader(String header) {
+        List<PathElement> elements = new ArrayList<PathElement>();
+        if (header == null || header.trim().length() == 0) {
+            return elements;
+        }
+        String[] clauses = parseDelimitedString(header, ",");
+        for (String clause : clauses) {
+            String[] tokens = clause.split(";");
+            if (tokens.length < 1) {
+                throw new IllegalArgumentException("Invalid header clause: " + clause);
+            }
+            PathElement elem = new PathElement(tokens[0].trim());
+            elements.add(elem);
+            for (int i = 1; i < tokens.length; i++) {
+                int pos = tokens[i].indexOf('=');
+                if (pos != -1) {
+                    if (pos > 0 && tokens[i].charAt(pos - 1) == ':') {
+                        String name = tokens[i].substring(0, pos - 1).trim();
+                        String value = tokens[i].substring(pos + 1).trim();
+                        if (value.startsWith("\"") && value.endsWith("\"")) {
+                            value = value.substring(1, value.length() - 1);
+                        }
+                        elem.addDirective(name, value);
+                    } else {
+                        String name = tokens[i].substring(0, pos).trim();
+                        String value = tokens[i].substring(pos + 1).trim();
+                        if (value.startsWith("\"") && value.endsWith("\"")) {
+                            value = value.substring(1, value.length() - 1);
+                        }
+                        elem.addAttribute(name, value);
+                    }
+                } else {
+                    elem = new PathElement(tokens[i].trim());
+                    elements.add(elem);
+                }
+            }
+        }
+        return elements;
+    }
+
+    /**
+     * Parses delimited string and returns an array containing the tokens. This
+     * parser obeys quotes, so the delimiter character will be ignored if it is
+     * inside of a quote. This method assumes that the quote character is not
+     * included in the set of delimiter characters.
+     * @param value the delimited string to parse.
+     * @param delim the characters delimiting the tokens.
+     * @return an array of string tokens or null if there were no tokens.
+    **/
+    public static String[] parseDelimitedString(String value, String delim)
+    {
+        if (value == null)
+        {
+           value = "";
+        }
+
+        List list = new ArrayList();
+
+        int CHAR = 1;
+        int DELIMITER = 2;
+        int STARTQUOTE = 4;
+        int ENDQUOTE = 8;
+
+        StringBuffer sb = new StringBuffer();
+
+        int expecting = (CHAR | DELIMITER | STARTQUOTE);
+
+        for (int i = 0; i < value.length(); i++)
+        {
+            char c = value.charAt(i);
+
+            boolean isDelimiter = (delim.indexOf(c) >= 0);
+            boolean isQuote = (c == '"');
+
+            if (isDelimiter && ((expecting & DELIMITER) > 0))
+            {
+                list.add(sb.toString().trim());
+                sb.delete(0, sb.length());
+                expecting = (CHAR | DELIMITER | STARTQUOTE);
+            }
+            else if (isQuote && ((expecting & STARTQUOTE) > 0))
+            {
+                sb.append(c);
+                expecting = CHAR | ENDQUOTE;
+            }
+            else if (isQuote && ((expecting & ENDQUOTE) > 0))
+            {
+                sb.append(c);
+                expecting = (CHAR | STARTQUOTE | DELIMITER);
+            }
+            else if ((expecting & CHAR) > 0)
+            {
+                sb.append(c);
+            }
+            else
+            {
+                throw new IllegalArgumentException("Invalid delimited string: " + value);
+            }
+        }
+
+        if (sb.length() > 0)
+        {
+            list.add(sb.toString().trim());
+        }
+
+        return (String[]) list.toArray(new String[list.size()]);
+    }
+
+    public static class PathElement {
+
+        private String path;
+        private Map<String, String> attributes;
+        private Map<String, String> directives;
+
+        public PathElement(String path) {
+            this.path = path;
+            this.attributes = new HashMap<String, String>();
+            this.directives = new HashMap<String, String>();
+        }
+
+        public String getName() {
+            return this.path;
+        }
+
+        public Map<String, String> getAttributes() {
+            return attributes;
+        }
+
+        public String getAttribute(String name) {
+            return attributes.get(name);
+        }
+
+        public void addAttribute(String name, String value) {
+            attributes.put(name, value);
+        }
+
+        public Map<String, String> getDirectives() {
+            return directives;
+        }
+
+        public String getDirective(String name) {
+            return directives.get(name);
+        }
+
+        public void addDirective(String name, String value) {
+            directives.put(name, value);
+        }
+
+        public String toString() {
+            StringBuilder sb = new StringBuilder(this.path);
+            for (Map.Entry<String,String> directive : this.directives.entrySet()) {
+                sb.append(";").append(directive.getKey()).append(":=").append(directive.getValue());
+            }
+            for (Map.Entry<String,String> attribute : this.attributes.entrySet()) {
+                sb.append(";").append(attribute.getKey()).append("=").append(attribute.getValue());
+            }
+            return sb.toString();
+        }
+
+    }
+}
diff --git a/karaf/pom.xml b/karaf/pom.xml
index 187709a..ae3ff8f 100644
--- a/karaf/pom.xml
+++ b/karaf/pom.xml
@@ -309,6 +309,11 @@
                 <version>${pom.version}</version>
             </dependency>
             <dependency>
+                <groupId>org.apache.felix.karaf.tooling</groupId>
+                <artifactId>org.apache.felix.karaf.tooling.testing</artifactId>
+                <version>${pom.version}</version>
+            </dependency>
+            <dependency>
                 <groupId>org.apache.felix</groupId>
                 <artifactId>org.apache.felix.framework</artifactId>
                 <version>${felix.framework.version}</version>
diff --git a/karaf/tooling/pom.xml b/karaf/tooling/pom.xml
index e42b910..2e3b981 100644
--- a/karaf/tooling/pom.xml
+++ b/karaf/tooling/pom.xml
@@ -34,6 +34,7 @@
 
     <modules>
         <module>features-maven-plugin</module>
+        <module>testing</module>
     </modules>
 
 </project>
diff --git a/karaf/tooling/testing/pom.xml b/karaf/tooling/testing/pom.xml
new file mode 100644
index 0000000..4008c9b
--- /dev/null
+++ b/karaf/tooling/testing/pom.xml
@@ -0,0 +1,176 @@
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
+    <!--
+
+        Licensed to the Apache Software Foundation (ASF) under one or more
+        contributor license agreements.  See the NOTICE file distributed with
+        this work for additional information regarding copyright ownership.
+        The ASF licenses this file to You under the Apache License, Version 2.0
+        (the "License"); you may not use this file except in compliance with
+        the License.  You may obtain a copy of the License at
+
+           http://www.apache.org/licenses/LICENSE-2.0
+
+        Unless required by applicable law or agreed to in writing, software
+        distributed under the License is distributed on an "AS IS" BASIS,
+        WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+        See the License for the specific language governing permissions and
+        limitations under the License.
+    -->
+    <modelVersion>4.0.0</modelVersion>
+
+    <parent>
+      <groupId>org.apache.felix.karaf.tooling</groupId>
+      <artifactId>tooling</artifactId>
+      <version>1.3.0-SNAPSHOT</version>
+    </parent>
+
+    <groupId>org.apache.felix.karaf.tooling</groupId>
+    <artifactId>org.apache.felix.karaf.tooling.testing</artifactId>
+    <packaging>bundle</packaging>
+    <version>1.3.0-SNAPSHOT</version>
+    <name>Apache Felix Karaf :: Testing environment</name>
+
+    <description>
+      A bundle to help using Pax-Exam and Karaf.
+    </description>
+
+    <properties>
+        <appendedResourcesDirectory>${basedir}/../../etc/appended-resources</appendedResourcesDirectory>
+    </properties>
+
+    <dependencies>
+        <!-- Pax EXAM -->
+        <dependency>
+            <groupId>org.ops4j.pax.exam</groupId>
+            <artifactId>pax-exam</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>org.ops4j.pax.exam</groupId>
+            <artifactId>pax-exam-junit</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>org.ops4j.pax.exam</groupId>
+            <artifactId>pax-exam-container-default</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>org.ops4j.pax.exam</groupId>
+            <artifactId>pax-exam-junit-extender-impl</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>junit</groupId>
+            <artifactId>junit</artifactId>
+            <version>4.5</version>
+        </dependency>
+    </dependencies>
+
+    <build>
+        <resources>
+            <resource>
+                <directory>${pom.basedir}/src/main/resources</directory>
+                <includes>
+                    <include>**/*</include>
+                </includes>
+            </resource>
+        </resources>
+        <filters>
+            <filter>target/filter.txt</filter>
+        </filters>
+        <plugins>
+            <plugin>
+                <groupId>org.apache.maven.plugins</groupId>
+                <artifactId>maven-antrun-plugin</artifactId>
+                <executions>
+                    <execution>
+                        <id>create-prop</id>
+                        <phase>initialize</phase>
+                        <configuration>
+                            <tasks>
+                                <taskdef resource="net/sf/antcontrib/antcontrib.properties" classpathref="maven.plugin.classpath" />
+                                <property name="ant.regexp.regexpimpl" value="org.apache.tools.ant.util.regexp.Jdk14RegexpRegexp" />
+                                <property name="mv" value="${project.version}" />
+                                <echo message="Maven version: ${mv}" />
+                                <propertyregex property="ov.p1" input="${mv}" regexp="(\d+)(?:\.(\d+)(?:\.(\d+))?)?(?:[^a-zA-Z0-9](.*))?" replace="\1" defaultValue="0" />
+                                <propertyregex property="ov.p2" input="${mv}" regexp="(\d+)(?:\.(\d+)(?:\.(\d+))?)?(?:[^a-zA-Z0-9](.*))?" replace=".\2" defaultValue=".0" />
+                                <propertyregex property="ov.p3" input="${mv}" regexp="(\d+)(?:\.(\d+)(?:\.(\d+))?)?(?:[^a-zA-Z0-9](.*))?" replace=".\3" defaultValue=".0" />
+                                <propertyregex property="ov.p4" input="${mv}" regexp="(\d+)(?:\.(\d+)(?:\.(\d+))?)?(?:[^a-zA-Z0-9](.*))?" replace=".\4" defaultValue="" />
+                                <propertyregex property="ov.p1a" input="${ov.p1}" regexp="(.+)" replace="\1" defaultValue="0" />
+                                <propertyregex property="ov.p2a" input="${ov.p2}" regexp="(\..+)" replace="\1" defaultValue=".0" />
+                                <propertyregex property="ov.p3a" input="${ov.p3}" regexp="(\..+)" replace="\1" defaultValue=".0" />
+                                <propertyregex property="ov.p4a" input="${ov.p4}" regexp="(\..+)" replace="\1" defaultValue="" />
+                                <property name="ov" value="${ov.p1a}${ov.p2a}${ov.p3a}${ov.p4a}" />
+                                <echo message="OSGi version: ${ov}" />
+                                <mkdir dir="target" />
+                                <echo message="karaf.osgi.version = ${ov}" file="target/filter.txt" />
+                            </tasks>
+                        </configuration>
+                        <goals>
+                            <goal>run</goal>
+                        </goals>
+                    </execution>
+                </executions>
+            </plugin>
+            <plugin>
+                <groupId>org.apache.maven.plugins</groupId>
+                <artifactId>maven-resources-plugin</artifactId>
+                <executions>
+                    <execution>
+                        <id>copy-filtered</id>
+                        <!-- here the phase you need -->
+                        <phase>compile</phase>
+                        <goals>
+                            <goal>copy-resources</goal>
+                        </goals>
+                        <configuration>
+                            <outputDirectory>${basedir}/target/classes/</outputDirectory>
+                            <resources>
+                                <resource>
+                                    <directory>../../assembly/src/main/filtered-resources/etc</directory>
+                                    <filtering>true</filtering>
+                                    <includes>
+                                        <include>config.properties</include>
+                                        <include>startup.properties</include>
+                                    </includes>
+                                </resource>
+                            </resources>
+                        </configuration>
+                    </execution>
+                </executions>
+            </plugin>
+            <!-- generate dependencies versions -->
+            <plugin>
+                <groupId>org.apache.servicemix.tooling</groupId>
+                <artifactId>depends-maven-plugin</artifactId>
+                <version>1.1</version>
+                <executions>
+                    <execution>
+                        <id>generate-depends-file</id>
+                        <goals>
+                            <goal>generate-depends-file</goal>
+                        </goals>
+                    </execution>
+                </executions>
+            </plugin>
+            <plugin>
+                <groupId>org.apache.felix</groupId>
+                <artifactId>maven-bundle-plugin</artifactId>
+                <configuration>
+                    <instructions>
+                        <Bundle-SymbolicName>${pom.artifactId}</Bundle-SymbolicName>
+                        <Export-Package>org.apache.felix.karaf.testing;version=${pom.version}</Export-Package>
+                        <Import-Package>
+                            !org.apache.felix.karaf.testing*,
+                            *
+                        </Import-Package>
+                        <Include-Resource>
+                            {maven-resources},
+                            org/apache/felix/karaf/testing/config.properties=target/classes/config.properties,
+                            org/apache/felix/karaf/testing/startup.properties=target/classes/startup.properties
+                        </Include-Resource>
+                        <_versionpolicy>${bnd.version.policy}</_versionpolicy>
+                    </instructions>
+                </configuration>
+            </plugin>
+        </plugins>
+    </build>
+
+</project>
diff --git a/karaf/itests/src/test/java/org/apache/felix/karaf/shell/itests/AbstractIntegrationTest.java b/karaf/tooling/testing/src/main/java/org/apache/felix/karaf/testing/AbstractIntegrationTest.java
similarity index 94%
rename from karaf/itests/src/test/java/org/apache/felix/karaf/shell/itests/AbstractIntegrationTest.java
rename to karaf/tooling/testing/src/main/java/org/apache/felix/karaf/testing/AbstractIntegrationTest.java
index 950a660..17177b6 100644
--- a/karaf/itests/src/test/java/org/apache/felix/karaf/shell/itests/AbstractIntegrationTest.java
+++ b/karaf/tooling/testing/src/main/java/org/apache/felix/karaf/testing/AbstractIntegrationTest.java
@@ -14,7 +14,7 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
-package org.apache.felix.karaf.shell.itests;
+package org.apache.felix.karaf.testing;
 
 import java.util.Collection;
 import java.util.Dictionary;
@@ -22,7 +22,6 @@
 import java.util.LinkedList;
 import java.util.List;
 
-import org.ops4j.pax.exam.CoreOptions;
 import org.ops4j.pax.exam.Inject;
 import org.ops4j.pax.exam.options.MavenArtifactProvisionOption;
 import org.osgi.framework.Bundle;
@@ -34,6 +33,8 @@
 import org.osgi.framework.ServiceReference;
 import org.osgi.util.tracker.ServiceTracker;
 
+import static org.apache.felix.karaf.testing.Helper.mavenBundle;
+
 public abstract class AbstractIntegrationTest {
 
     public static final long DEFAULT_TIMEOUT = 30000;
@@ -104,10 +105,6 @@
         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
      */
@@ -137,4 +134,4 @@
         return result;
     }
 
-}
+}
\ No newline at end of file
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
new file mode 100644
index 0000000..f41a716
--- /dev/null
+++ b/karaf/tooling/testing/src/main/java/org/apache/felix/karaf/testing/Helper.java
@@ -0,0 +1,706 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.felix.karaf.testing;
+
+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;
+import static org.ops4j.pax.exam.CoreOptions.maven;
+import static org.ops4j.pax.exam.CoreOptions.wrappedBundle;
+import static org.ops4j.pax.exam.OptionUtils.combine;
+
+public final class Helper {
+
+    private Helper() {
+    }
+
+    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(),
+                                       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
