diff --git a/pom.xml b/pom.xml
new file mode 100644
index 0000000..e589dc7
--- /dev/null
+++ b/pom.xml
@@ -0,0 +1,116 @@
+<?xml version="1.0" encoding="ISO-8859-1"?>
+<!--
+    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.
+-->
+<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">
+
+    <modelVersion>4.0.0</modelVersion>
+    <parent>
+        <groupId>org.apache.sling</groupId>
+        <artifactId>sling</artifactId>
+        <version>13</version>
+        <relativePath>../../../parent/pom.xml</relativePath>
+    </parent>
+
+    <artifactId>org.apache.sling.commons.cache.container-test</artifactId>
+    <version>0.1-SNAPSHOT</version>
+    <packaging>jar</packaging>
+
+    <name>Apache Sling OSGi PAX Exam support library</name>
+    <description>
+        This bundle provides a base class for OSGi Container tests. It should be incuded as a dependency with 
+        a scope of test.
+    </description>
+
+    <scm>
+        <connection>scm:svn:http://svn.apache.org/repos/asf/sling/whiteboard/ieb/cache/container-test</connection>
+        <developerConnection>scm:svn:https://svn.apache.org/repos/asf/sling/whiteboard/ieb/cache/container-test</developerConnection>
+        <url>http://svn.apache.org/viewvc/sling/whiteboard/ieb/cache/container-test</url>
+    </scm>
+    
+
+    <dependencies>
+        <dependency>
+            <groupId>org.slf4j</groupId>
+            <artifactId>slf4j-api</artifactId>
+            <scope>provided</scope>
+        </dependency>
+        <dependency>
+            <groupId>junit</groupId>
+            <artifactId>junit</artifactId>
+            <scope>compile</scope>
+        </dependency>
+      <!-- Integration Testing with Pax Exam -->
+        <dependency>
+            <groupId>org.ops4j.pax.exam</groupId>
+            <artifactId>pax-exam-container-forked</artifactId>
+            <version>2.4.0.RC1</version>
+        </dependency>
+        <dependency>
+            <groupId>org.ops4j.pax.exam</groupId>
+            <artifactId>pax-exam-junit4</artifactId>
+            <version>2.4.0.RC1</version>
+        </dependency>
+        <dependency>
+            <groupId>org.ops4j.pax.exam</groupId>
+            <artifactId>pax-exam-link-mvn</artifactId>
+            <version>2.4.0.RC1</version>
+        </dependency>
+        <dependency>
+            <groupId>org.ops4j.pax.url</groupId>
+            <artifactId>pax-url-aether</artifactId>
+            <version>1.4.0.RC1</version>
+        </dependency>
+        <dependency>
+            <groupId>org.ops4j.pax.url</groupId>
+            <artifactId>pax-url-wrap</artifactId>
+            <version>1.4.0.RC1</version>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.geronimo.specs</groupId>
+            <artifactId>geronimo-atinject_1.0_spec</artifactId>
+            <version>1.0</version>
+        </dependency>
+        <dependency>
+            <groupId>org.ops4j.base</groupId>
+            <artifactId>ops4j-base-lang</artifactId>
+            <version>1.2.3</version>
+        </dependency>
+        <dependency>
+            <groupId>org.ops4j.base</groupId>
+            <artifactId>ops4j-base-net</artifactId>
+            <version>1.2.3</version>
+        </dependency>
+        <dependency>
+            <groupId>org.ops4j.pax.tinybundles</groupId>
+            <artifactId>tinybundles</artifactId>
+            <version>1.0.0</version>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.felix</groupId>
+            <artifactId>org.apache.felix.framework</artifactId>
+            <version>4.0.2</version>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.felix</groupId>
+            <artifactId>org.apache.felix.scr</artifactId>
+            <version>1.6.0</version>
+        </dependency>
+
+    </dependencies>
+</project>
diff --git a/src/main/java/org/apache/sling/test/AbstractOSGiRunner.java b/src/main/java/org/apache/sling/test/AbstractOSGiRunner.java
new file mode 100644
index 0000000..771e1a0
--- /dev/null
+++ b/src/main/java/org/apache/sling/test/AbstractOSGiRunner.java
@@ -0,0 +1,267 @@
+/*
+ * 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.sling.test;
+
+import static org.ops4j.pax.exam.Constants.START_LEVEL_SYSTEM_BUNDLES;
+import static org.ops4j.pax.exam.CoreOptions.bundle;
+import static org.ops4j.pax.exam.CoreOptions.composite;
+import static org.ops4j.pax.exam.CoreOptions.mavenBundle;
+import static org.ops4j.pax.exam.CoreOptions.options;
+import static org.ops4j.pax.exam.CoreOptions.provision;
+import static org.ops4j.pax.exam.CoreOptions.systemProperty;
+import static org.ops4j.pax.exam.CoreOptions.wrappedBundle;
+
+import java.io.File;
+import java.io.FilenameFilter;
+import java.net.URL;
+import java.net.URLClassLoader;
+import java.util.Dictionary;
+import java.util.Enumeration;
+
+import org.ops4j.pax.exam.Option;
+import org.ops4j.pax.exam.TestProbeBuilder;
+import org.ops4j.pax.exam.junit.Configuration;
+import org.ops4j.pax.exam.junit.ProbeBuilder;
+import org.ops4j.pax.exam.options.AbstractDelegateProvisionOption;
+import org.osgi.framework.Bundle;
+import org.osgi.framework.BundleContext;
+import org.osgi.framework.Constants;
+import org.osgi.framework.ServiceReference;
+
+/**
+ * Spin the cache up in a container to verify we have a working system.
+ * Parts shamelessly borrowed from the Integration Test class in commons.classloader.
+ */
+public  abstract class AbstractOSGiRunner {
+
+	// the name of the system property providing the bundle file to be installed
+	// and tested
+	private static final String BUNDLE_JAR_SYS_PROP = "project.bundle.file";
+
+
+
+	@ProbeBuilder
+	public TestProbeBuilder _extendProbe(TestProbeBuilder builder) {
+		System.err.println("Parent Builder");
+		
+		String imports = getImports();
+		if ( !imports.startsWith(",")) {
+			imports = ","+imports;
+		}
+		builder.setHeader(Constants.IMPORT_PACKAGE, "org.osgi.framework,org.apache.sling.test"+imports);
+		builder.setHeader(Constants.DYNAMICIMPORT_PACKAGE, "org.ops4j.pax.exam,org.junit,javax.inject,org.ops4j.pax.exam.options");
+		builder.setHeader("Bundle-ManifestVersion", "2");
+		
+		return builder;
+	}
+
+
+	/**
+	 * @return the artifact name to assist determining the correct jar to load from target/
+	 */
+	protected abstract String getArtifactName();
+
+
+
+	/**
+	 * @return a string of additional imports to the builder
+	 */
+	protected String getImports() {
+		return "";
+	}
+
+	protected Option[] getOptions() {
+		return options();
+	}
+
+
+
+	@Configuration
+	public Option[] configuration() {
+
+		String bundleFileName = getBundleFileName();
+		final File bundleFile = new File(bundleFileName);
+		if (!bundleFile.canRead()) {
+			throw new IllegalArgumentException("Cannot read from bundle file "
+					+ bundleFileName + " specified in the "
+					+ BUNDLE_JAR_SYS_PROP + " system property");
+		}
+
+		return options(
+				composite(getOptions()),
+				provision(
+						// url resolution for pax
+						mavenBundle("org.ops4j.pax.url", "pax-url-mvn", "1.3.5"),
+						// to support declarative services
+						mavenBundle("org.apache.felix", "org.apache.felix.scr", "1.6.0"),
+						// bound to need servlet api
+						mavenBundle("org.apache.felix", "javax.servlet","1.0.0"),
+						// standard items.
+						mavenBundle("commons-collections", "commons-collections", "3.2.1"), // 3.2.1 is a bundle, 3.2 is not
+						mavenBundle("commons-io", "commons-io", "1.4"),
+						// export ourselves
+						wrappedBundle(mavenBundle("org.apache.sling","org.apache.sling.commons.cache.container-test")).exports(AbstractOSGiRunner.class.getPackage().getName()),
+						// add the project thats being tested.
+						bundle(bundleFile.toURI().toString())
+				),
+				// below is instead of normal Pax Exam junitBundles() to deal
+				// with build server issue
+				new DirectURLJUnitBundlesOption(),
+				systemProperty("pax.exam.invoker").value("junit"),
+				bundle("link:classpath:META-INF/links/org.ops4j.pax.exam.invoker.junit.link")
+				);
+	}
+
+
+
+
+
+
+
+
+
+
+
+	private String getBundleFileName() {
+		String bundleFileName = System.getProperty(BUNDLE_JAR_SYS_PROP);
+		if (bundleFileName == null) {
+			// are we in an IDE, can we guess the jar name. 
+			File target = new File("target");
+			final String artifactName = getArtifactName();
+			System.err.println("Listing files in "+target.getAbsolutePath()+" looking for "+artifactName);
+			
+			File[] jars = target.listFiles(new FilenameFilter() {
+
+				public boolean accept(File dir, String name) {
+					if (!name.endsWith(".jar")) {
+						return false;
+					}
+					if (name.endsWith("sources.jar")) {
+						return false;
+					}
+					return name
+							.startsWith(artifactName);
+				}
+			});
+			if (jars.length > 0) {
+				bundleFileName = jars[0].getAbsolutePath();
+			}
+		}
+		return bundleFileName;
+	}
+
+
+
+	
+	protected void check() {
+		try {
+			Class<?> t = this.getClass().getClassLoader().loadClass("javax.transaction.TransactionManager");
+			System.err.println("Loaded Class "+t+" from classloader "+t.getClassLoader());
+			ClassLoader cl = t.getClassLoader();
+			if ( cl instanceof URLClassLoader ) {
+				URLClassLoader u = (URLClassLoader) cl;
+				for ( URL url : u.getURLs() ) {
+					System.err.println("Classloadr url"+url);
+				}
+			}
+			
+		} catch (ClassNotFoundException e) {
+			throw new RuntimeException(e);
+		}
+	}
+
+	/**
+	 * Try and load a class from each bundle in turn.
+	 * @param bundleContext
+	 * @param classname
+	 */
+	protected void findClassHome(BundleContext bundleContext, String classname) {
+		System.err.println("Bundle is "+bundleContext);
+		for ( Bundle b : bundleContext.getBundles()) {
+			System.err.println("Bundle is "+bundleContext);
+			if ( classname != null ) {
+				try{
+					Class<?> t = b.loadClass(classname);
+					ClassLoader cl = t.getClassLoader();
+					System.err.println("Loaded  "+t+" "+cl);
+				} catch ( Exception e ) {
+				}
+			}
+		}
+		
+	}
+	
+	/**
+	 * List all the bundles showing services and headers.
+	 * @param bundleContext
+	 */
+	protected void listBundles(BundleContext bundleContext) {
+		System.err.println("Bundle is "+bundleContext);
+		for ( Bundle b : bundleContext.getBundles()) {
+			System.err.println("Bundle is "+bundleContext);
+			Dictionary<String, String> headers = b.getHeaders();
+			for( Enumeration<String> e = headers.keys(); e.hasMoreElements();) {
+				String key = e.nextElement();
+				System.err.println("	Header "+key+" "+headers.get(key));
+			}
+			ServiceReference[] srs = b.getRegisteredServices();
+			if  (srs != null ) {
+				for ( ServiceReference sr: srs) {
+					System.err.println("	Service "+bundleContext);
+				}
+			}
+		}
+	}
+
+	/**
+	 * This code is taken from commons.classloader.it.DynamicClassLoaderIT Clone
+	 * of Pax Exam's JunitBundlesOption which uses a direct URL to the
+	 * SpringSource JUnit bundle to avoid some weird repository issues on the
+	 * Apache build server.
+	 */
+	private static class DirectURLJUnitBundlesOption extends
+			AbstractDelegateProvisionOption<DirectURLJUnitBundlesOption> {
+
+		/**
+		 * Constructor.
+		 */
+		public DirectURLJUnitBundlesOption() {
+			super(
+					bundle("http://repository.springsource.com/ivy/bundles/external/org.junit/com.springsource.org.junit/4.9.0/com.springsource.org.junit-4.9.0.jar"));
+			noUpdate();
+			startLevel(START_LEVEL_SYSTEM_BUNDLES);
+		}
+
+		/**
+		 * {@inheritDoc}
+		 */
+		@Override
+		public String toString() {
+			return String.format("DirectURLJUnitBundlesOption{url=%s}",
+					getURL());
+		}
+
+		/**
+		 * {@inheritDoc}
+		 */
+		protected DirectURLJUnitBundlesOption itself() {
+			return this;
+		}
+	}
+}
