diff --git a/dependencymanager/test2/pom.xml b/dependencymanager/test2/pom.xml
new file mode 100644
index 0000000..367812d
--- /dev/null
+++ b/dependencymanager/test2/pom.xml
@@ -0,0 +1,210 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+    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.felix</groupId>
+		<artifactId>felix-parent</artifactId>
+		<version>2.1</version>
+		<relativePath>../../pom/pom.xml</relativePath>
+	</parent>
+
+	<artifactId>org.apache.felix.dependencymanager.test2</artifactId>
+	<version>1.0.0-SNAPSHOT</version>
+	<packaging>bundle</packaging>
+
+	<name>Apache Felix Dependency Manager Integration Tests 2</name>
+
+	<properties>
+		<bundle.build.name>
+			${basedir}/target
+		</bundle.build.name>
+		<bundle.file.name>
+			${bundle.build.name}/${project.build.finalName}.jar
+		</bundle.file.name>
+
+		<felix.build.source>5</felix.build.source>
+		<felix.build.target>5</felix.build.target>
+		<felix.java.signature.artifactId>java15</felix.java.signature.artifactId>
+		<exam.version>3.0.0</exam.version>
+		<url.version>1.5.2</url.version>
+	</properties>
+
+	<dependencies>
+		<dependency>
+			<groupId>org.osgi</groupId>
+			<artifactId>org.osgi.core</artifactId>
+			<version>5.0.0</version>
+			<scope>provided</scope>
+		</dependency>
+		<dependency>
+			<groupId>org.osgi</groupId>
+			<artifactId>org.osgi.compendium</artifactId>
+			<version>5.0.0</version>
+			<scope>provided</scope>
+		</dependency>
+		<dependency>
+			<groupId>org.apache.felix</groupId>
+			<artifactId>org.apache.felix.dependencymanager</artifactId>
+			<version>3.1.1-SNAPSHOT</version>
+			<scope>provided</scope>
+		</dependency>
+		<dependency>
+			<groupId>junit</groupId>
+			<artifactId>junit</artifactId>
+			<version>4.6</version>
+			<scope>provided</scope>
+		</dependency>
+
+		<!-- Integration Testing with Pax Exam -->
+		<dependency>
+			<groupId>org.ops4j.pax.exam</groupId>
+			<artifactId>pax-exam-container-native</artifactId>
+			<version>${exam.version}</version>
+			<scope>test</scope>
+		</dependency>
+
+		<dependency>
+			<groupId>org.ops4j.pax.exam</groupId>
+			<artifactId>pax-exam-junit4</artifactId>
+			<version>${exam.version}</version>
+			<scope>test</scope>
+		</dependency>
+
+		<dependency>
+			<groupId>org.ops4j.pax.exam</groupId>
+			<artifactId>pax-exam-link-mvn</artifactId>
+			<version>${exam.version}</version>
+			<scope>test</scope>
+		</dependency>
+
+		<dependency>
+			<groupId>org.ops4j.pax.url</groupId>
+			<artifactId>pax-url-aether</artifactId>
+			<version>${url.version}</version>
+			<scope>test</scope>
+		</dependency>
+
+		<dependency>
+			<groupId>org.apache.felix</groupId>
+			<artifactId>org.apache.felix.framework</artifactId>
+			<version>4.2.1</version>
+			<scope>test</scope>
+		</dependency>
+
+		<dependency>
+			<groupId>ch.qos.logback</groupId>
+			<artifactId>logback-core</artifactId>
+			<version>0.9.20</version>
+			<scope>test</scope>
+		</dependency>
+
+		<dependency>
+			<groupId>ch.qos.logback</groupId>
+			<artifactId>logback-classic</artifactId>
+			<version>0.9.20</version>
+			<scope>test</scope>
+		</dependency>
+
+		<!-- Dependency Manager Annotations -->
+		<dependency>
+			<groupId>org.apache.felix</groupId>
+			<artifactId>org.apache.felix.dependencymanager.annotation</artifactId>
+			<version>3.1.1-SNAPSHOT</version>
+		</dependency>
+	</dependencies>
+
+	<build>
+		<plugins>
+			<!-- Build the bundle which contains various components used by integration tests -->
+			<plugin>
+				<groupId>org.apache.felix</groupId>
+				<artifactId>maven-bundle-plugin</artifactId>
+				<version>2.3.7</version>
+				<extensions>true</extensions>
+				<configuration>
+					<instructions>
+						<Bundle-Name>Apache Felix Dependency Manager Annotations Tests</Bundle-Name>
+						<Bundle-SymbolicName>org.apache.felix.dependencymanager.test2.components</Bundle-SymbolicName>
+						<Export-Package>org.apache.felix.dependencymanager.test2.components</Export-Package>
+					</instructions>
+				</configuration>
+			</plugin>
+			
+			<!-- java 5 required for annotations support -->
+			<plugin>
+				<artifactId>maven-compiler-plugin</artifactId>
+				<configuration>
+					<source>1.5</source>
+					<target>1.5</target>
+				</configuration>
+			</plugin>
+			
+			<!-- DM annotation plugin used to parse annotations from org.apache.felix.dependencymanager.test2.components artifact -->
+			<plugin>
+				<groupId>org.apache.felix</groupId>
+				<artifactId>org.apache.felix.dependencymanager.annotation</artifactId>
+				<version>3.1.1-SNAPSHOT</version>
+				<executions>
+					<execution>
+						<goals>
+							<goal>scan</goal>
+						</goals>
+						<configuration>
+							<log>debug</log>
+							<!-- generated-output-dir>.</generated-output-dir> -->
+						</configuration>
+					</execution>
+				</executions>
+			</plugin>
+
+			<!-- We have no unit tests, we only have integration tests -->
+			<plugin>
+				<artifactId>maven-surefire-plugin</artifactId>
+				<executions>
+					<execution>
+						<id>surefire-it</id>
+						<phase>integration-test</phase>
+						<goals>
+							<goal>test</goal>
+						</goals>
+						<configuration>
+							<systemProperties>
+								<property>
+									<name>project.bundle.file</name>
+									<value>${bundle.file.name}</value>
+								</property>
+							</systemProperties>
+							<excludes>
+								<exclude>**/components/*</exclude>
+							</excludes>
+							<includes>
+								<include>**/integration/**/*</include>
+							</includes>
+						</configuration>
+					</execution>
+				</executions>
+				<configuration>
+					<excludes>
+						<exclude>**/integration/**</exclude>
+					</excludes>
+				</configuration>
+			</plugin>
+		</plugins>
+	</build>
+</project>
diff --git a/dependencymanager/test2/src/main/java/org/apache/felix/dependencymanager/test2/components/Ensure.java b/dependencymanager/test2/src/main/java/org/apache/felix/dependencymanager/test2/components/Ensure.java
new file mode 100644
index 0000000..0cbdb73
--- /dev/null
+++ b/dependencymanager/test2/src/main/java/org/apache/felix/dependencymanager/test2/components/Ensure.java
@@ -0,0 +1,172 @@
+/*
+ * 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.dependencymanager.test2.components;
+
+import java.io.PrintStream;
+
+import junit.framework.Assert;
+
+/**
+ * Helper class to make sure that steps in a test happen in the correct order. Instantiate
+ * this class and subsequently invoke <code>step(nr)</code> with steps starting at 1. You
+ * can also have threads wait until you arrive at a certain step.
+ */
+public class Ensure {
+    private final boolean DEBUG;
+    private static long INSTANCE = 0;
+    private static final int RESOLUTION = 100;
+    private static PrintStream STREAM = System.out;
+    int step = 0;
+    private Throwable m_throwable;
+    
+    public Ensure() {
+        this(true);
+    }
+    
+    public Ensure(boolean debug) {
+        DEBUG = debug;
+        if (DEBUG) {
+            INSTANCE++;
+        }
+    }
+
+    public void setStream(PrintStream output) {
+        STREAM = output;
+    }
+    
+    /**
+     * Mark this point as step <code>nr</code>.
+     * 
+     * @param nr the step we are in
+     */
+    public synchronized void step(int nr) {
+        step ++;
+        Assert.assertEquals(nr, step);
+        if (DEBUG) {
+            String info = getLineInfo(3);
+            STREAM.println("[Ensure " + INSTANCE + "] step " + step + " [" + currentThread() + "] " + info);
+        }
+        notifyAll();
+    }
+
+    private String getLineInfo(int depth) {
+        StackTraceElement[] trace = Thread.currentThread().getStackTrace();
+        String info = trace[depth].getClassName() + "." + trace[depth].getMethodName() + ":" + trace[depth].getLineNumber();
+        return info;
+    }
+    
+    /**
+     * Mark this point as the next step.
+     */
+    public synchronized void step() {
+        step++;
+        if (DEBUG) {
+            String info = getLineInfo(3);
+            STREAM.println("[Ensure " + INSTANCE + "] next step " + step + " [" + currentThread() + "] " + info);
+        }
+        notifyAll();
+    }
+
+    /**
+     * Wait until we arrive at least at step <code>nr</code> in the process, or fail if that
+     * takes more than <code>timeout</code> milliseconds. If you invoke wait on a thread,
+     * you are effectively assuming some other thread will invoke the <code>step(nr)</code>
+     * method.
+     * 
+     * @param nr the step to wait for
+     * @param timeout the number of milliseconds to wait
+     */
+    public synchronized void waitForStep(int nr, int timeout) {
+        final int initialTimeout = timeout;
+        if (DEBUG) {
+            String info = getLineInfo(3);
+            STREAM.println("[Ensure " + INSTANCE + "] waiting for step " + nr + " [" + currentThread() + "] " + info);
+        }
+        while (step < nr && timeout > 0) {
+            try {
+                wait(RESOLUTION);
+                timeout -= RESOLUTION;
+            }
+            catch (InterruptedException e) {}
+        }
+        if (step < nr) {
+            throw new IllegalStateException("Timed out waiting for " + initialTimeout + " ms for step " + nr + ", we are still at step " + step);
+        }
+        if (DEBUG) {
+            String info = getLineInfo(3);
+            STREAM.println("[Ensure " + INSTANCE + "] arrived at step " + nr + " [" + currentThread() + "] " + info);
+        }
+    }
+    
+    private String currentThread() {
+        Thread thread = Thread.currentThread();
+        return thread.getId() + " " + thread.getName();
+    }
+    
+    public static Runnable createRunnableStep(final Ensure ensure, final int nr) {
+        return new Runnable() { public void run() { ensure.step(nr); }};
+    }
+    
+    public synchronized void steps(Steps steps) {
+        steps.next(this);
+    }
+    
+    /** 
+     * Helper class for naming a list of step numbers. If used with the steps(Steps) method
+     * you can define at which steps in time this point should be passed. That means you can
+     * check methods that will get invoked multiple times during a test.
+     */
+    public static class Steps {
+        private final int[] m_steps;
+        private int m_stepIndex;
+
+        /** 
+         * Create a list of steps and initialize the step counter to zero.
+         */
+        public Steps(int... steps) {
+            m_steps = steps;
+            m_stepIndex = 0;
+        }
+
+        /**
+         * Ensure we're at the right step. Will throw an index out of bounds exception if we enter this step more often than defined.
+         */
+        public void next(Ensure ensure) {
+            ensure.step(m_steps[m_stepIndex++]);
+        }
+    }
+
+    /**
+     * Saves a thrown exception that occurred in a different thread. You can only save one exception
+     * at a time this way.
+     */
+    public synchronized void throwable(Throwable throwable) {
+        m_throwable = throwable;
+    }
+
+    /**
+     * Throws a <code>Throwable</code> if one occurred in a different thread and that thread saved it
+     * using the <code>throwable()</code> method.
+     */
+    public synchronized void ensure() throws Throwable {
+        if (m_throwable != null) {
+            throw m_throwable;
+        }
+    }
+}
diff --git a/dependencymanager/test2/src/main/java/org/apache/felix/dependencymanager/test2/components/SimpleAnnotations.java b/dependencymanager/test2/src/main/java/org/apache/felix/dependencymanager/test2/components/SimpleAnnotations.java
new file mode 100644
index 0000000..e1e2db9
--- /dev/null
+++ b/dependencymanager/test2/src/main/java/org/apache/felix/dependencymanager/test2/components/SimpleAnnotations.java
@@ -0,0 +1,176 @@
+/*
+ * 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.dependencymanager.test2.components;
+
+import org.apache.felix.dm.DependencyManager;
+import org.apache.felix.dm.annotation.api.Component;
+import org.apache.felix.dm.annotation.api.Destroy;
+import org.apache.felix.dm.annotation.api.Init;
+import org.apache.felix.dm.annotation.api.Inject;
+import org.apache.felix.dm.annotation.api.Property;
+import org.apache.felix.dm.annotation.api.Registered;
+import org.apache.felix.dm.annotation.api.ServiceDependency;
+import org.apache.felix.dm.annotation.api.Start;
+import org.apache.felix.dm.annotation.api.Stop;
+import org.apache.felix.dm.annotation.api.Unregistered;
+import org.osgi.framework.Bundle;
+import org.osgi.framework.BundleContext;
+import org.osgi.framework.ServiceRegistration;
+import org.osgi.service.log.LogService;
+
+public class SimpleAnnotations {
+    /**
+     * Provides a <code>Runnable</code> service, which is required by the
+     * {@link Consumer} class.
+     */
+    @Component(properties = {@Property(name = "foo", value = "bar")})
+    public static class Producer implements Runnable {
+        @ServiceDependency(filter = "(name=simple.annotations.producer)")
+        volatile Ensure _ensure;
+
+        @ServiceDependency
+        volatile LogService _logService;
+
+        @Inject
+        volatile BundleContext _ctx;
+
+        @Init
+        protected void init() {
+            _logService.log(LogService.LOG_INFO, "producer.init");
+            // Our component is initializing (at this point: all required
+            // dependencies are injected).
+            _ensure.step(1);
+        }
+
+        @Start
+        protected void start() {
+            // We are about to be registered in the OSGi registry.
+            _ensure.step(2);
+        }
+
+        @Registered
+        protected void registered(ServiceRegistration sr) {
+            _logService.log(LogService.LOG_INFO, "Registered");
+            if (sr == null) {
+                _ensure.throwable(new Exception("ServiceRegistration is null"));
+            }
+            if (!"bar".equals(sr.getReference().getProperty("foo"))) {
+                _ensure.throwable(new Exception("Invalid Service Properties"));
+            }
+            _ensure.step(3);
+        }
+
+        public void run() {
+            _ensure.step(5);
+        }
+
+        @Stop
+        protected void stop() {
+            // We are about to be unregistered from the OSGi registry, and we
+            // must stop.
+            _ensure.step(8);
+        }
+
+        @Unregistered
+        protected void stopped() {
+            // We are unregistered from the OSGi registry.
+            _ensure.step(9);
+        }
+
+        @Destroy
+        public void destroy() {
+            // Our component is shutting down.
+            _ensure.step(10);
+        }
+    }
+
+    /**
+     * Consumes a service which is provided by the {@link Producer} class.
+     */
+    @Component
+    public static class Consumer {
+        @ServiceDependency
+        volatile LogService _logService;
+
+        @ServiceDependency
+        volatile Runnable _runnable;
+
+        @ServiceDependency(filter = "(name=simple.annotations.consumer)")
+        volatile Ensure _ensure;
+
+        @Inject
+        volatile BundleContext _bc;
+        BundleContext _bcNotInjected;
+
+        @Inject
+        volatile DependencyManager _dm;
+        DependencyManager _dmNotInjected;
+
+        @Inject
+        volatile org.apache.felix.dm.Component _component;
+        org.apache.felix.dm.Component _componentNotInjected;
+
+        @Start
+        protected void start() {
+            _logService.log(LogService.LOG_INFO, "Consumer.START: ");
+            checkInjectedFields();
+            _ensure.step(4);
+            _runnable.run();
+        }
+        
+        private void checkInjectedFields() {
+            if (_bc == null) {
+                _ensure.throwable(new Exception("Bundle Context not injected"));
+                return;
+            }
+            if (_bcNotInjected != null) {
+                _ensure.throwable(new Exception("Bundle Context must not be injected"));
+                return;
+            }
+
+            if (_dm == null) {
+                _ensure.throwable(new Exception("DependencyManager not injected"));
+                return;
+            }
+            if (_dmNotInjected != null) {
+                _ensure.throwable(new Exception("DependencyManager must not be injected"));
+                return;
+            }
+
+            if (_component == null) {
+                _ensure.throwable(new Exception("Component not injected"));
+                return;
+            }
+            if (_componentNotInjected != null) {
+                _ensure.throwable(new Exception("Component must not be injected"));
+                return;
+            }
+        }
+
+        @Stop
+        protected void stop() {
+            _ensure.step(6);
+        }
+        
+        @Destroy
+        void destroy() {
+            _ensure.step(7);
+        }
+    }
+}
diff --git a/dependencymanager/test2/src/test/java/org/apache/felix/dependencymanager/test2/integration/annotations/SimpleAnnotationsTest.java b/dependencymanager/test2/src/test/java/org/apache/felix/dependencymanager/test2/integration/annotations/SimpleAnnotationsTest.java
new file mode 100644
index 0000000..2e37f5a
--- /dev/null
+++ b/dependencymanager/test2/src/test/java/org/apache/felix/dependencymanager/test2/integration/annotations/SimpleAnnotationsTest.java
@@ -0,0 +1,51 @@
+/*
+* 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.dependencymanager.test2.integration.annotations;
+
+import org.apache.felix.dependencymanager.test2.components.Ensure;
+import org.apache.felix.dependencymanager.test2.components.SimpleAnnotations;
+import org.apache.felix.dependencymanager.test2.integration.common.TestBase;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.ops4j.pax.exam.junit.PaxExam;
+import org.osgi.framework.ServiceRegistration;
+
+/**
+ * Use case: Ensure that a Provider can be injected into a Consumer, using simple DM annotations.
+ */
+@RunWith(PaxExam.class)
+public class SimpleAnnotationsTest extends TestBase
+{    
+	@Test
+	public void testSimpleAnnotations() throws Throwable
+    {
+	    Ensure e = new Ensure();
+		ServiceRegistration er = register(e, "simple.annotations.producer");        
+        e.waitForStep(3, 10000); // Producer registered
+        ServiceRegistration er2 = register(e, "simple.annotations.consumer"); 
+
+        er2.unregister(); // stop consumer
+        er.unregister(); // stop provider
+
+        // And check if components have been deactivated orderly.
+        e.waitForStep(10, 10000);
+        e.ensure();
+        stopTestComponentsBundle();
+    }        
+}
diff --git a/dependencymanager/test2/src/test/java/org/apache/felix/dependencymanager/test2/integration/api/AspectRaceTest.java b/dependencymanager/test2/src/test/java/org/apache/felix/dependencymanager/test2/integration/api/AspectRaceTest.java
new file mode 100644
index 0000000..72961c8
--- /dev/null
+++ b/dependencymanager/test2/src/test/java/org/apache/felix/dependencymanager/test2/integration/api/AspectRaceTest.java
@@ -0,0 +1,341 @@
+/*
+ * 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.dependencymanager.test2.integration.api;
+
+import java.util.HashSet;
+import java.util.Hashtable;
+import java.util.concurrent.ConcurrentLinkedQueue;
+import java.util.concurrent.CountDownLatch;
+import java.util.concurrent.ExecutorService;
+import java.util.concurrent.Executors;
+import java.util.concurrent.TimeUnit;
+
+import javax.inject.Inject;
+
+import junit.framework.Assert;
+
+import org.apache.felix.dependencymanager.test2.components.Ensure;
+import org.apache.felix.dependencymanager.test2.integration.common.TestBase;
+import org.apache.felix.dm.Component;
+import org.apache.felix.dm.DependencyManager;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.ops4j.pax.exam.junit.PaxExam;
+import org.osgi.framework.BundleContext;
+import org.osgi.framework.InvalidSyntaxException;
+import org.osgi.framework.ServiceReference;
+
+@RunWith(PaxExam.class)
+public class AspectRaceTest extends TestBase {
+	volatile ExecutorService _serviceExec;
+	volatile ExecutorService _aspectExec;
+	volatile DependencyManager _dm;
+	final static int SERVICES = 3;
+	final static int ASPECTS_PER_SERVICE = 10;
+
+	@Inject
+	private static volatile BundleContext _bctx;
+
+	@Test
+	public void testConcurrentAspects() {
+		try {
+			warn("starting aspect race test");
+			int cores = Runtime.getRuntime().availableProcessors();
+			// Used to inject S services
+			_serviceExec = Executors.newFixedThreadPool(cores);
+			// Used to inject S Aspects
+			_aspectExec = Executors.newFixedThreadPool(cores);
+
+			// Setup test components using dependency manager.
+			// We create a Controller which is injected with some S services,
+			// and each S services has some aspects (SAspect).
+
+			_dm = new DependencyManager(_bctx);
+			Controller controller = new Controller();
+			Component c = _dm
+					.createComponent()
+					.setImplementation(controller)
+					.setInterface(Controller.class.getName(), null)
+					.setComposition("getComposition")
+					.add(_dm.createServiceDependency().setService(S.class)
+							.setCallbacks("bind", null, "unbind", "swap")
+							.setRequired(true));
+
+			_dm.add(c);
+
+			for (int loop = 1; loop <= 10000; loop++) {
+				// Perform concurrent injections of "S" service and S aspects
+				// into the Controller component;
+				Factory f = new Factory();
+				f.register();
+
+				controller.check();
+
+				// unregister all services and aspects concurrently
+				f.unregister();
+
+				if ((loop) % 100 == 0) {
+					warn("Performed " + loop + " tests.");
+				}
+			}
+
+			if (super.errorsLogged()) {
+				Assert.assertFalse("Test failed.", false);
+			}
+		}
+
+		catch (Throwable t) {
+			error("Test failed", t);
+			Assert.fail("Test failed: " + t.getMessage());
+		} finally {
+			shutdown(_serviceExec);
+			shutdown(_aspectExec);
+		}
+	}
+
+	void shutdown(ExecutorService exec) {
+		exec.shutdown();
+		try {
+			exec.awaitTermination(5, TimeUnit.SECONDS);
+		} catch (InterruptedException e) {
+		}
+	}
+
+	public interface S {
+		void invoke(Ensure e);
+	}
+
+	public static class SImpl implements S {
+		final int _step;
+
+		SImpl(int step) {
+			_step = step;
+		}
+
+		public void invoke(Ensure e) {
+			e.step(_step);
+		}
+
+		public String toString() {
+			return "SImpl[" + _step + "]";
+		}
+	}
+
+	public static class SAspect implements S {
+		volatile S _next;
+		final int _rank;
+		final int _step;
+
+		SAspect(int rank) {
+			_rank = rank;
+			_step = ASPECTS_PER_SERVICE - rank + 1;
+		}
+
+		public void added(S s) {
+			_next = s;
+		}
+
+		public void swap(S oldS, S newS) {
+			_next = newS;
+		}
+
+		public void invoke(Ensure e) {
+			e.step(_step);
+			_next.invoke(e);
+		}
+
+		public String toString() {
+			return "SAspect[" + _rank + ", " + _step + "]";
+		}
+	}
+
+	class Factory {
+		final ConcurrentLinkedQueue<Component> m_services = new ConcurrentLinkedQueue<Component>();
+		final ConcurrentLinkedQueue<Component> m_aspects = new ConcurrentLinkedQueue<Component>();
+
+		public void register() throws InterruptedException {
+			final CountDownLatch latch = new CountDownLatch(SERVICES
+					+ (ASPECTS_PER_SERVICE * SERVICES));
+
+			for (int i = 1; i <= SERVICES; i++) {
+				final int serviceId = i;
+				_serviceExec.execute(new Runnable() {
+					public void run() {
+						try {
+							Component c = _dm.createComponent();
+							Hashtable<String, String> props = new Hashtable<String, String>();
+							props.put("id", String.valueOf(serviceId));
+							c.setInterface(S.class.getName(), props)
+									.setImplementation(
+											new SImpl(ASPECTS_PER_SERVICE + 1));
+							m_services.add(c);
+							_dm.add(c);
+							latch.countDown();
+						} catch (Throwable e) {
+							error(e);
+						}
+					}
+				});
+
+				for (int j = 1; j <= ASPECTS_PER_SERVICE; j++) {
+					final int rank = j;
+					_aspectExec.execute(new Runnable() {
+						public void run() {
+							try {
+								SAspect sa = new SAspect(rank);
+								Component aspect = _dm.createAspectService(
+										S.class, "(id=" + serviceId + ")",
+										rank, "added", null, null, "swap")
+										.setImplementation(sa);
+								debug("adding aspect " + sa);
+								m_aspects.add(aspect);
+								_dm.add(aspect);
+								latch.countDown();
+							} catch (Throwable e) {
+								error(e);
+							}
+						}
+					});
+				}
+			}
+
+			if (!latch.await(5000, TimeUnit.MILLISECONDS)) {
+				throw new IllegalStateException(
+						"could not register services and aspects timely");
+			}
+
+			debug("all registered: aspects=" + m_aspects);
+			// Thread.sleep(5000);
+		}
+
+		public void unregister() throws InterruptedException,
+				InvalidSyntaxException {
+			final CountDownLatch latch = new CountDownLatch(SERVICES
+					+ (ASPECTS_PER_SERVICE * SERVICES));
+
+			unregisterAspects(latch);
+			unregisterServices(latch);
+
+			if (!latch.await(5000, TimeUnit.MILLISECONDS)) {
+				throw new IllegalStateException(
+						"could not unregister services and aspects timely");
+			}
+
+			if (_bctx.getServiceReference(S.class.getName()) != null) {
+				error("could not unregister some services or aspects !");
+			}
+			debug("unregistered all aspects and services concurrently");
+		}
+
+		public void unregisterAspects(final CountDownLatch latch)
+				throws InterruptedException, InvalidSyntaxException {
+			Component c;
+			debug("unregister: aspects=" + m_aspects);
+
+			while ((c = m_aspects.poll()) != null) {
+				final Component c$ = c;
+				_serviceExec.execute(new Runnable() {
+					public void run() {
+						try {
+							debug("removing service " + c$);
+							_dm.remove(c$);
+							latch.countDown();
+						} catch (Throwable e) {
+							error(e);
+						}
+					}
+				});
+			}
+		}
+
+		public void unregisterServices(final CountDownLatch latch)
+				throws InterruptedException {
+			Component c;
+			debug("unregister: services=" + m_services);
+
+			while ((c = m_services.poll()) != null) {
+				final Component c$ = c;
+				_serviceExec.execute(new Runnable() {
+					public void run() {
+						try {
+							debug("removing service " + c$);
+							_dm.remove(c$);
+							latch.countDown();
+						} catch (Throwable e) {
+							error(e);
+						}
+					}
+				});
+			}
+
+			debug("unregistered all services");
+		}
+	}
+
+	public class Controller {
+		final Composition m_compo = new Composition();
+		final HashSet<S> _services = new HashSet<S>();
+
+		Object[] getComposition() {
+			return new Object[] { this, m_compo };
+		}
+
+		void bind(ServiceReference sr) {
+			S s = (S) sr.getBundle().getBundleContext().getService(sr);
+			if (s == null) {
+				throw new IllegalStateException(
+						"bindA: bundleContext.getService returned null");
+			}
+			debug("bind " + s);
+			synchronized (this) {
+				_services.add(s);
+			}
+		}
+
+		void swap(S previous, S current) {
+			debug("swap: " + previous + "," + current);
+			synchronized (this) {
+				if (!_services.remove(previous)) {
+					error("swap: unknow previous counter: " + previous);
+				}
+				_services.add(current);
+			}
+		}
+
+		void unbind(S a) {
+			debug("unbind " + a);
+			synchronized (this) {
+				_services.remove(a);
+			}
+		}
+
+		void check() {
+			synchronized (this) {
+				for (S s : _services) {
+					debug("checking service: " + s + " ...");
+					Ensure ensure = new Ensure(false);
+					s.invoke(ensure);
+				}
+			}
+		}
+	}
+
+	public static class Composition {
+	}
+}
diff --git a/dependencymanager/test2/src/test/java/org/apache/felix/dependencymanager/test2/integration/common/TestBase.java b/dependencymanager/test2/src/test/java/org/apache/felix/dependencymanager/test2/integration/common/TestBase.java
new file mode 100644
index 0000000..5c01334
--- /dev/null
+++ b/dependencymanager/test2/src/test/java/org/apache/felix/dependencymanager/test2/integration/common/TestBase.java
@@ -0,0 +1,313 @@
+/*
+ * 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.dependencymanager.test2.integration.common;
+
+import static org.ops4j.pax.exam.CoreOptions.bundle;
+import static org.ops4j.pax.exam.CoreOptions.cleanCaches;
+import static org.ops4j.pax.exam.CoreOptions.junitBundles;
+import static org.ops4j.pax.exam.CoreOptions.mavenBundle;
+import static org.ops4j.pax.exam.CoreOptions.options;
+import static org.ops4j.pax.exam.CoreOptions.systemProperty;
+import static org.ops4j.pax.exam.CoreOptions.systemTimeout;
+import static org.ops4j.pax.exam.CoreOptions.vmOption;
+import static org.ops4j.pax.exam.CoreOptions.workingDirectory;
+
+import java.io.File;
+import java.io.PrintWriter;
+import java.io.StringWriter;
+import java.util.Hashtable;
+
+import javax.inject.Inject;
+
+import org.apache.felix.dependencymanager.test2.components.Ensure;
+import org.junit.After;
+import org.junit.Before;
+import org.ops4j.pax.exam.Configuration;
+import org.ops4j.pax.exam.Option;
+import org.ops4j.pax.exam.OptionUtils;
+import org.ops4j.pax.exam.ProbeBuilder;
+import org.ops4j.pax.exam.TestProbeBuilder;
+import org.osgi.framework.Bundle;
+import org.osgi.framework.BundleContext;
+import org.osgi.framework.BundleException;
+import org.osgi.framework.Constants;
+import org.osgi.framework.FrameworkEvent;
+import org.osgi.framework.FrameworkListener;
+import org.osgi.framework.ServiceReference;
+import org.osgi.framework.ServiceRegistration;
+import org.osgi.service.log.LogService;
+
+public abstract class TestBase implements LogService, FrameworkListener {
+    public static final String OSGI_SPEC_VERSION = "4.2.0";
+    private final static int LOG_LEVEL = LogService.LOG_WARNING;
+    private volatile boolean m_errorsLogged;
+
+    // the name of the system property providing the bundle file to be installed
+    // and tested
+    protected static final String BUNDLE_JAR_SYS_PROP = "project.bundle.file";
+
+    // the default bundle jar file name
+    protected static final String BUNDLE_JAR_DEFAULT = "target/org.apache.felix.dependencymanager.test2-3.0.2-SNAPSHOT.jar";
+
+    // the JVM option to set to enable remote debugging
+    protected static final String DEBUG_VM_OPTION = "-Xrunjdwp:transport=dt_socket,server=y,suspend=y,address=30303";
+
+    // the actual JVM option set, extensions may implement a static
+    // initializer overwriting this value to have the configuration()
+    // method include it when starting the OSGi framework JVM
+    protected static String paxRunnerVmOption = null;
+
+    @Inject
+    protected BundleContext context;
+
+    protected ServiceRegistration logService;
+
+    @Configuration
+    public static Option[] configuration() {
+        final String bundleFileName = System.getProperty(BUNDLE_JAR_SYS_PROP, BUNDLE_JAR_DEFAULT);
+        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");
+        }
+
+        final Option[] base = options(
+                workingDirectory("target/paxexam/"),
+                systemProperty("dm.runtime.log").value("false"),
+                systemProperty("org.ops4j.pax.logging.DefaultServiceLog.level").value("WARN"),
+                systemTimeout(5000),
+                cleanCaches(true),
+                junitBundles(),
+                mavenBundle("org.ops4j.pax.tinybundles", "tinybundles", "1.0.0"),
+                mavenBundle("org.apache.felix", "org.apache.felix.dependencymanager",
+                        "3.1.1-SNAPSHOT"),
+                mavenBundle("org.apache.felix", "org.apache.felix.dependencymanager.runtime",
+                        "3.1.1-SNAPSHOT"),
+                mavenBundle("org.apache.felix", "org.apache.felix.configadmin", "1.6.0"),
+                mavenBundle("org.apache.felix", "org.apache.felix.metatype", "1.0.8"),
+                bundle(bundleFile.toURI().toString()));
+        final Option option = (paxRunnerVmOption != null) ? vmOption(paxRunnerVmOption) : null;
+        return OptionUtils.combine(base, option);
+    }
+
+    @ProbeBuilder
+    public TestProbeBuilder buildProbe(TestProbeBuilder builder) {
+        return builder.setHeader(Constants.IMPORT_PACKAGE,
+                "org.apache.felix.dependencymanager.test2.components");
+    }
+
+    @Before
+    public void setUp() {
+        logService = context.registerService(LogService.class.getName(), this, null);
+        context.addFrameworkListener(this);
+    }
+
+    @After
+    public void tearDown() throws BundleException {
+       logService.unregister();
+        context.removeFrameworkListener(this);
+    }
+
+    /**
+     * Create and provide an Ensure object with a name service property.
+     */
+    protected ServiceRegistration register(Ensure e, String name) {
+        Hashtable<String, String> props = new Hashtable<String, String>();
+        props.put("name", name);
+        return context.registerService(Ensure.class.getName(), e, props);
+    }
+
+    /**
+     * Helper method used to stop a given bundle.
+     * 
+     * @param symbolicName
+     *            the symbolic name of the bundle to be stopped.
+     * @param context
+     *            the context used to lookup all installed bundles.
+     */
+    protected void stopBundle(String symbolicName) {
+        // Stop the test.annotation bundle
+        boolean found = false;
+        for (Bundle b : context.getBundles()) {
+            if (b.getSymbolicName().equals(symbolicName)) {
+                try {
+                    found = true;
+                    b.stop();
+                } catch (BundleException e) {
+                    e.printStackTrace();
+                }
+            }
+        }
+        if (!found) {
+            throw new IllegalStateException("bundle " + symbolicName + " not found");
+        }
+    }
+
+    /**
+     * Stops our test components bundle.
+     */
+    protected void stopTestComponentsBundle() {
+        stopBundle("org.apache.felix.dependencymanager.test2.components");
+    }
+
+    /**
+     * Suspend the current thread for a while.
+     * 
+     * @param n
+     *            the number of milliseconds to wait for.
+     */
+    protected void sleep(int ms) {
+        try {
+            Thread.sleep(ms);
+        } catch (InterruptedException e) {
+        }
+    }
+
+    public void log(int level, String message) {
+        checkError(level, null);
+        if (LOG_LEVEL >= level) {
+            System.out.println(getLevel(level) + " - " + Thread.currentThread().getName() + " : " + message);
+        }
+    }
+
+    public void log(int level, String message, Throwable exception) {
+        checkError(level, exception);
+        if (LOG_LEVEL >= level) {
+            StringBuilder sb = new StringBuilder();
+            sb.append(getLevel(level) + " - " + Thread.currentThread().getName() + " : ");
+            sb.append(message);
+            parse(sb, exception);
+            System.out.println(sb.toString());
+        }
+    }
+
+    public void log(ServiceReference sr, int level, String message) {
+        checkError(level, null);
+        if (LOG_LEVEL >= level) {
+            StringBuilder sb = new StringBuilder();
+            sb.append(getLevel(level) + " - " + Thread.currentThread().getName() + " : ");
+            sb.append(message);
+            System.out.println(sb.toString());
+        }
+    }
+
+    public void log(ServiceReference sr, int level, String message, Throwable exception) {
+        checkError(level, exception);
+        if (LOG_LEVEL >= level) {
+            StringBuilder sb = new StringBuilder();
+            sb.append(getLevel(level) + " - " + Thread.currentThread().getName() + " : ");
+            sb.append(message);
+            parse(sb, exception);
+            System.out.println(sb.toString());
+        }
+    }
+
+    protected boolean errorsLogged() {
+        return m_errorsLogged;
+    }
+
+    private void parse(StringBuilder sb, Throwable t) {
+        if (t != null) {
+            sb.append(" - ");
+            StringWriter buffer = new StringWriter();
+            PrintWriter pw = new PrintWriter(buffer);
+            t.printStackTrace(pw);
+            sb.append(buffer.toString());
+            m_errorsLogged = true;
+        }
+    }
+
+    private String getLevel(int level) {
+        switch (level) {
+            case LogService.LOG_DEBUG :
+                return "DEBUG";
+            case LogService.LOG_ERROR :
+                return "ERROR";
+            case LogService.LOG_INFO :
+                return "INFO";
+            case LogService.LOG_WARNING :
+                return "WARN";
+            default :
+                return "";
+        }
+    }
+
+    private void checkError(int level, Throwable exception) {
+        if (level >= LOG_ERROR) {
+            m_errorsLogged = true;
+        }
+        if (exception != null) {
+            m_errorsLogged = true;
+        }
+    }
+
+    public void frameworkEvent(FrameworkEvent event) {
+        int eventType = event.getType();
+        String msg = getFrameworkEventMessage(eventType);
+        int level = (eventType == FrameworkEvent.ERROR) ? LOG_ERROR : LOG_WARNING;
+        if (msg != null) {
+            log(level, msg, event.getThrowable());
+        } else {
+            log(level, "Unknown fwk event: " + event);
+        }
+    }
+
+    private String getFrameworkEventMessage(int event) {
+        switch (event) {
+            case FrameworkEvent.ERROR :
+                return "FrameworkEvent: ERROR";
+            case FrameworkEvent.INFO :
+                return "FrameworkEvent INFO";
+            case FrameworkEvent.PACKAGES_REFRESHED :
+                return "FrameworkEvent: PACKAGE REFRESHED";
+            case FrameworkEvent.STARTED :
+                return "FrameworkEvent: STARTED";
+            case FrameworkEvent.STARTLEVEL_CHANGED :
+                return "FrameworkEvent: STARTLEVEL CHANGED";
+            case FrameworkEvent.WARNING :
+                return "FrameworkEvent: WARNING";
+            default :
+                return null;
+        }
+    }
+
+    protected void warn(String msg) {
+        log(LogService.LOG_WARNING, "[" + Thread.currentThread().getName() + "] " + msg);
+    }
+
+    protected void info(String msg) {
+        log(LogService.LOG_INFO, "[" + Thread.currentThread().getName() + "] " + msg);
+    }
+
+    protected void debug(String msg) {
+        log(LogService.LOG_DEBUG, "[" + Thread.currentThread().getName() + "] " + msg);
+    }
+
+    protected void error(String msg) {
+        log(LogService.LOG_ERROR, "[" + Thread.currentThread().getName() + "] " + msg);
+    }
+
+    protected void error(String msg, Throwable err) {
+        log(LogService.LOG_ERROR, "[" + Thread.currentThread().getName() + "] " + msg, err);
+    }
+
+    protected void error(Throwable err) {
+        log(LogService.LOG_ERROR, "[" + Thread.currentThread().getName() + "] error:", err);
+    }
+}
