Merge pull request #5 from apache/rotty3000/cdi-spi

Rotty3000/cdi spi
diff --git a/.gitignore b/.gitignore
index beef00d..dddad45 100644
--- a/.gitignore
+++ b/.gitignore
@@ -2,3 +2,5 @@
 .project
 .settings
 target
+*.iml
+.idea
diff --git a/README.md b/README.md
index bd7fd8f..892535d 100644
--- a/README.md
+++ b/README.md
@@ -78,15 +78,23 @@
 
 In bnd `4.3.0+` you can rely purely on the discovery mode calculated from existing `beans.xml` files in your project. This grants even less configuration friction for existing projects migrating to OSGi CDI.
 
-## Pre-built runtime
+## Pre-built runtimes
 
-This repository provides an example for how to assemble an executable jar providing a complete runtime for you to just drop in your CDI bundles. It comes complete with logging, Gogo shell, Config Admin, Http Whiteboard support, and OSGi Promises.
+This repository provides two examples for how to assemble an executable jar providing a complete runtime for you to just drop in your CDI bundles. These come complete with logging, Gogo shell, Config Admin, Http Whiteboard support, and OSGi Promises.
 
-Once you've completed a successfull build, you should be able to execute the command:
+Once you've completed a successful build, you should be able to execute the commands:
 
-`java -jar cdi-executable/target/executable.jar`
+#### OpenWebBeans
 
-and be presented with a gogo shell prompt ready for you to install a CDI bundle.
+`java -jar cdi-executable/target/weld-executable.jar`
+
+and be presented a gogo shell prompt running in a framework that uses Aries CDI over **Apache OpenWebBeans** ready for you to install a CDI bundle.
+
+#### Weld
+
+`java -jar cdi-executable/target/owb-executable.jar`
+
+and be presented with a gogo shell prompt running in a framework that uses Aries CDI over **JBoss Weld** ready for you to install a CDI bundle.
 
 ## Architecture Overview
 
@@ -172,4 +180,16 @@
          - `@BeforeDestroy(ComponentScoped.class)`
          - `@Destroyed(ComponentScoped.class)`
 
+## Aries CDI SPI
+
+Aries CDI now has an SPI for enabling it to be used with any CDI container impl.
+
+The requirements to satisfy this SPI are quite simple:
+
+- Aries CDI Extender requires:
+
+  -  a **prototype scoped** service that implements `org.apache.aries.cdi.spi.CDIContainerInitializer`
+
+  - The behaviour of this container should be to start the `@ApplicationScoped` context immediately. This allows for services from the container component to be published right away.
+
 Check out the many questions and answers in the [FAQ](faq.md).
\ No newline at end of file
diff --git a/cdi-bom/pom.xml b/cdi-bom/pom.xml
index e3a9ce5..29f8f16 100644
--- a/cdi-bom/pom.xml
+++ b/cdi-bom/pom.xml
@@ -71,11 +71,35 @@
 			</dependency>
 			<dependency>
 				<groupId>org.apache.aries.cdi</groupId>
+				<artifactId>org.apache.aries.cdi.extension.mp-config</artifactId>
+				<version>${project.version}</version>
+				<scope>compile</scope>
+			</dependency>
+			<dependency>
+				<groupId>org.apache.aries.cdi</groupId>
 				<artifactId>org.apache.aries.cdi.extra</artifactId>
 				<version>${project.version}</version>
 				<scope>compile</scope>
 			</dependency>
 			<dependency>
+				<groupId>org.apache.aries.cdi</groupId>
+				<artifactId>org.apache.aries.cdi.spi</artifactId>
+				<version>${project.version}</version>
+				<scope>compile</scope>
+			</dependency>
+			<dependency>
+				<groupId>org.apache.aries.cdi</groupId>
+				<artifactId>org.apache.aries.cdi.owb</artifactId>
+				<version>${project.version}</version>
+				<scope>runtime</scope>
+			</dependency>
+			<dependency>
+				<groupId>org.apache.aries.cdi</groupId>
+				<artifactId>org.apache.aries.cdi.weld</artifactId>
+				<version>${project.version}</version>
+				<scope>runtime</scope>
+			</dependency>
+			<dependency>
 				<groupId>org.apache.aries.spifly</groupId>
 				<artifactId>org.apache.aries.spifly.dynamic.framework.extension</artifactId>
 				<version>1.2</version>
diff --git a/cdi-executable/executable.bndrun b/cdi-executable/owb-executable.bndrun
similarity index 67%
copy from cdi-executable/executable.bndrun
copy to cdi-executable/owb-executable.bndrun
index 02b26d4..46820c6 100644
--- a/cdi-executable/executable.bndrun
+++ b/cdi-executable/owb-executable.bndrun
@@ -24,12 +24,6 @@
 	osgi.console=
 
 -resolve.effective: resolve, active
--runrequires: \
-	osgi.identity;filter:='(osgi.identity=javax.ejb-api)',\
-	osgi.identity;filter:='(osgi.identity=javax.transaction-api)',\
-	osgi.identity;filter:='(osgi.identity=org.apache.aries.cdi.extension.http)',\
-	osgi.identity;filter:='(osgi.identity=org.apache.aries.cdi.extra)',\
-	osgi.identity;filter:='(osgi.identity=org.apache.felix.gogo.command)'
 
 -runpath: \
 	ch.qos.logback.classic,\
@@ -38,32 +32,43 @@
 	slf4j.api
 
 -runsystempackages: \
-	org.slf4j;version=1.7.25,\
-	org.slf4j.helpers;version=1.7.25,\
-	org.slf4j.spi;version=1.7.25,\
+	org.slf4j;version=1.7.28,\
+	org.slf4j.event;version=1.7.28,\
+	org.slf4j.helpers;version=1.7.28,\
+	org.slf4j.spi;version=1.7.28,\
 	sun.misc
 
+-runrequires: \
+	osgi.identity;filter:='(osgi.identity=org.apache.aries.cdi.owb)',\
+	osgi.identity;filter:='(osgi.identity=org.apache.felix.gogo.command)'
+
+-runblacklist: \
+	osgi.identity;filter:='(osgi.identity=org.apache.aries.cdi.weld)',\
+	osgi.identity;filter:='(osgi.identity=org.jboss.spec.*)'
+
 -runbundles: \
-	javax.ejb-api;version='[3.2.0,3.2.1)',\
-	javax.transaction-api;version='[1.2.0,1.2.1)',\
-	jboss-classfilewriter;version='[1.2.3,1.2.4)',\
-	org.apache.aries.cdi.extender;version='[1.0.3,1.0.4)',\
-	org.apache.aries.cdi.extension.http;version='[1.0.3,1.0.4)',\
-	org.apache.aries.cdi.extra;version='[1.0.3,1.0.4)',\
+	javax.servlet.jsp-api;version='[2.3.3,2.3.4)',\
+	openwebbeans-impl;version='[2.0.13,2.0.14)',\
+	openwebbeans-spi;version='[2.0.13,2.0.14)',\
+	openwebbeans-web;version='[2.0.13,2.0.14)',\
+	org.apache.aries.cdi.extender;version='[1.1.0,1.1.1)',\
+	org.apache.aries.cdi.extra;version='[1.1.0,1.1.1)',\
+	org.apache.aries.cdi.owb;version='[1.1.0,1.1.1)',\
+	org.apache.aries.cdi.spi;version='[1.1.0,1.1.1)',\
 	org.apache.aries.spifly.dynamic.framework.extension;version='[1.2.0,1.2.1)',\
 	org.apache.felix.configadmin;version='[1.9.10,1.9.11)',\
 	org.apache.felix.gogo.command;version='[1.1.0,1.1.1)',\
 	org.apache.felix.gogo.runtime;version='[1.1.2,1.1.3)',\
 	org.apache.felix.gogo.shell;version='[1.1.2,1.1.3)',\
-	org.apache.felix.http.jetty;version='[4.0.6,4.0.7)',\
 	org.apache.felix.http.servlet-api;version='[1.1.2,1.1.3)',\
 	org.apache.geronimo.specs.geronimo-annotation_1.3_spec;version='[1.1.0,1.1.1)',\
 	org.apache.geronimo.specs.geronimo-atinject_1.0_spec;version='[1.1.0,1.1.1)',\
 	org.apache.geronimo.specs.geronimo-el_2.2_spec;version='[1.1.0,1.1.1)',\
 	org.apache.geronimo.specs.geronimo-interceptor_1.2_spec;version='[1.1.0,1.1.1)',\
 	org.apache.geronimo.specs.geronimo-jcdi_2.0_spec;version='[1.1.0,1.1.1)',\
-	org.jboss.logging.jboss-logging;version='[3.3.2,3.3.3)',\
-	org.jboss.weld.osgi-bundle;version='[3.0.5,3.0.6)',\
+	org.apache.xbean.asm7-shaded;version='[4.13.0,4.13.1)',\
+	org.apache.xbean.bundleutils;version='[4.15.0,4.15.1)',\
+	org.apache.xbean.finder-shaded;version='[4.13.0,4.13.1)',\
 	org.osgi.service.cdi;version='[1.0.0,1.0.1)',\
 	org.osgi.util.function;version='[1.1.0,1.1.1)',\
-	org.osgi.util.promise;version='[1.1.0,1.1.1)',\
+	org.osgi.util.promise;version='[1.1.0,1.1.1)'
diff --git a/cdi-executable/pom.xml b/cdi-executable/pom.xml
index df95188..57e17d0 100644
--- a/cdi-executable/pom.xml
+++ b/cdi-executable/pom.xml
@@ -78,30 +78,80 @@
 				<groupId>biz.aQute.bnd</groupId>
 				<artifactId>bnd-resolver-maven-plugin</artifactId>
 				<configuration>
-					<bndruns>
-						<bndrun>executable.bndrun</bndrun>
-					</bndruns>
 					<includeDependencyManagement>true</includeDependencyManagement>
 				</configuration>
+				<executions>
+					<execution>
+						<id>owb-resolve</id>
+						<phase>package</phase>
+						<goals>
+							<goal>resolve</goal>
+						</goals>
+						<configuration>
+							<bndruns>
+								<bndrun>owb-executable.bndrun</bndrun>
+							</bndruns>
+						</configuration>
+					</execution>
+					<execution>
+						<id>weld-resolve</id>
+						<phase>package</phase>
+						<goals>
+							<goal>resolve</goal>
+						</goals>
+						<configuration>
+							<bndruns>
+								<bndrun>weld-executable.bndrun</bndrun>
+							</bndruns>
+						</configuration>
+					</execution>
+				</executions>
 			</plugin>
 			<plugin>
 				<groupId>biz.aQute.bnd</groupId>
 				<artifactId>bnd-export-maven-plugin</artifactId>
 				<configuration>
-					<bndruns>
-						<bndrun>executable.bndrun</bndrun>
-					</bndruns>
 					<includeDependencyManagement>true</includeDependencyManagement>
 				</configuration>
+				<executions>
+					<execution>
+						<id>owb-export</id>
+						<goals>
+							<goal>export</goal>
+						</goals>
+						<configuration>
+							<bndruns>
+								<bndrun>owb-executable.bndrun</bndrun>
+							</bndruns>
+						</configuration>
+					</execution>
+					<execution>
+						<id>weld-export</id>
+						<goals>
+							<goal>export</goal>
+						</goals>
+						<configuration>
+							<bndruns>
+								<bndrun>weld-executable.bndrun</bndrun>
+							</bndruns>
+						</configuration>
+					</execution>
+				</executions>
 			</plugin>
 			<plugin>
 				<groupId>biz.aQute.bnd</groupId>
 				<artifactId>bnd-run-maven-plugin</artifactId>
 				<executions>
 					<execution>
-						<id>executable</id>
+						<id>owb-executable</id>
 						<configuration>
-							<bndrun>executable.bndrun</bndrun>
+							<bndrun>owb-executable.bndrun</bndrun>
+						</configuration>
+					</execution>
+					<execution>
+						<id>weld-executable</id>
+						<configuration>
+							<bndrun>weld-executable.bndrun</bndrun>
 						</configuration>
 					</execution>
 				</executions>
diff --git a/cdi-executable/executable.bndrun b/cdi-executable/weld-executable.bndrun
similarity index 80%
rename from cdi-executable/executable.bndrun
rename to cdi-executable/weld-executable.bndrun
index 02b26d4..242c842 100644
--- a/cdi-executable/executable.bndrun
+++ b/cdi-executable/weld-executable.bndrun
@@ -24,12 +24,6 @@
 	osgi.console=
 
 -resolve.effective: resolve, active
--runrequires: \
-	osgi.identity;filter:='(osgi.identity=javax.ejb-api)',\
-	osgi.identity;filter:='(osgi.identity=javax.transaction-api)',\
-	osgi.identity;filter:='(osgi.identity=org.apache.aries.cdi.extension.http)',\
-	osgi.identity;filter:='(osgi.identity=org.apache.aries.cdi.extra)',\
-	osgi.identity;filter:='(osgi.identity=org.apache.felix.gogo.command)'
 
 -runpath: \
 	ch.qos.logback.classic,\
@@ -38,25 +32,34 @@
 	slf4j.api
 
 -runsystempackages: \
-	org.slf4j;version=1.7.25,\
-	org.slf4j.helpers;version=1.7.25,\
-	org.slf4j.spi;version=1.7.25,\
+	org.slf4j;version=1.7.28,\
+	org.slf4j.event;version=1.7.28,\
+	org.slf4j.helpers;version=1.7.28,\
+	org.slf4j.spi;version=1.7.28,\
 	sun.misc
 
+-runrequires: \
+	osgi.identity;filter:='(osgi.identity=javax.ejb-api)',\
+	osgi.identity;filter:='(osgi.identity=javax.transaction-api)',\
+	osgi.identity;filter:='(osgi.identity=org.apache.aries.cdi.weld)',\
+	osgi.identity;filter:='(osgi.identity=org.apache.felix.gogo.command)'
+
+-runblacklist: \
+	osgi.identity;filter:='(osgi.identity=org.apache.aries.cdi.owb)',\
+	osgi.identity;filter:='(osgi.identity=org.jboss.spec.*)'
+
 -runbundles: \
 	javax.ejb-api;version='[3.2.0,3.2.1)',\
 	javax.transaction-api;version='[1.2.0,1.2.1)',\
 	jboss-classfilewriter;version='[1.2.3,1.2.4)',\
-	org.apache.aries.cdi.extender;version='[1.0.3,1.0.4)',\
-	org.apache.aries.cdi.extension.http;version='[1.0.3,1.0.4)',\
-	org.apache.aries.cdi.extra;version='[1.0.3,1.0.4)',\
+	org.apache.aries.cdi.extender;version='[1.1.0,1.1.1)',\
+	org.apache.aries.cdi.spi;version='[1.1.0,1.1.1)',\
+	org.apache.aries.cdi.weld;version='[1.1.0,1.1.1)',\
 	org.apache.aries.spifly.dynamic.framework.extension;version='[1.2.0,1.2.1)',\
 	org.apache.felix.configadmin;version='[1.9.10,1.9.11)',\
 	org.apache.felix.gogo.command;version='[1.1.0,1.1.1)',\
 	org.apache.felix.gogo.runtime;version='[1.1.2,1.1.3)',\
 	org.apache.felix.gogo.shell;version='[1.1.2,1.1.3)',\
-	org.apache.felix.http.jetty;version='[4.0.6,4.0.7)',\
-	org.apache.felix.http.servlet-api;version='[1.1.2,1.1.3)',\
 	org.apache.geronimo.specs.geronimo-annotation_1.3_spec;version='[1.1.0,1.1.1)',\
 	org.apache.geronimo.specs.geronimo-atinject_1.0_spec;version='[1.1.0,1.1.1)',\
 	org.apache.geronimo.specs.geronimo-el_2.2_spec;version='[1.1.0,1.1.1)',\
@@ -66,4 +69,4 @@
 	org.jboss.weld.osgi-bundle;version='[3.0.5,3.0.6)',\
 	org.osgi.service.cdi;version='[1.0.0,1.0.1)',\
 	org.osgi.util.function;version='[1.1.0,1.1.1)',\
-	org.osgi.util.promise;version='[1.1.0,1.1.1)',\
+	org.osgi.util.promise;version='[1.1.0,1.1.1)'
diff --git a/cdi-extender/pom.xml b/cdi-extender/pom.xml
index 7131fc6..e849995 100644
--- a/cdi-extender/pom.xml
+++ b/cdi-extender/pom.xml
@@ -53,6 +53,7 @@
 					<bnd><![CDATA[
 						-cdiannotations:
 						-conditionalpackage: \
+							aQute.lib.exceptions,\
 							org.apache.felix.utils.extender,\
 							org.osgi.util.converter
 					]]></bnd>
@@ -63,6 +64,11 @@
 
 	<dependencies>
 		<dependency>
+			<groupId>org.apache.aries.cdi</groupId>
+			<artifactId>org.apache.aries.cdi.spi</artifactId>
+			<version>${project.version}</version>
+		</dependency>
+		<dependency>
 			<groupId>org.apache.felix</groupId>
 			<artifactId>org.apache.felix.converter</artifactId>
 		</dependency>
@@ -87,10 +93,6 @@
 			<artifactId>geronimo-jcdi_2.0_spec</artifactId>
 		</dependency>
 		<dependency>
-			<groupId>org.jboss.weld</groupId>
-			<artifactId>weld-osgi-bundle</artifactId>
-		</dependency>
-		<dependency>
 			<groupId>org.osgi</groupId>
 			<artifactId>osgi.annotation</artifactId>
 		</dependency>
@@ -130,6 +132,12 @@
 			<groupId>org.osgi</groupId>
 			<artifactId>osgi.core</artifactId>
 		</dependency>
+		<dependency>
+			<groupId>biz.aQute.bnd</groupId>
+			<artifactId>biz.aQute.bndlib</artifactId>
+			<version>${bnd.version}</version>
+			<scope>provided</scope>
+		</dependency>
 
 		<dependency>
 			<groupId>ch.qos.logback</groupId>
diff --git a/cdi-extender/src/main/java/org/apache/aries/cdi/container/internal/Activator.java b/cdi-extender/src/main/java/org/apache/aries/cdi/container/internal/Activator.java
index b0c7881..02cd5c0 100644
--- a/cdi-extender/src/main/java/org/apache/aries/cdi/container/internal/Activator.java
+++ b/cdi-extender/src/main/java/org/apache/aries/cdi/container/internal/Activator.java
@@ -27,7 +27,7 @@
 import java.util.concurrent.CopyOnWriteArrayList;
 import java.util.concurrent.ExecutorService;
 import java.util.concurrent.Executors;
-import java.util.concurrent.ThreadFactory;
+import java.util.concurrent.TimeUnit;
 
 import org.apache.aries.cdi.container.internal.command.CDICommand;
 import org.apache.aries.cdi.container.internal.container.CDIBundle;
@@ -41,15 +41,18 @@
 import org.apache.aries.cdi.container.internal.model.FactoryComponent;
 import org.apache.aries.cdi.container.internal.model.SingleActivator;
 import org.apache.aries.cdi.container.internal.model.SingleComponent;
+import org.apache.aries.cdi.container.internal.spi.ContainerListener;
 import org.apache.aries.cdi.container.internal.util.Logs;
+import org.apache.aries.cdi.spi.CDIContainerInitializer;
 import org.apache.felix.utils.extender.AbstractExtender;
 import org.apache.felix.utils.extender.Extension;
 import org.osgi.annotation.bundle.Header;
 import org.osgi.framework.Bundle;
 import org.osgi.framework.BundleContext;
 import org.osgi.framework.Constants;
-import org.osgi.framework.FrameworkUtil;
 import org.osgi.framework.ServiceFactory;
+import org.osgi.framework.ServiceObjects;
+import org.osgi.framework.ServiceReference;
 import org.osgi.framework.ServiceRegistration;
 import org.osgi.framework.wiring.BundleRequirement;
 import org.osgi.framework.wiring.BundleWire;
@@ -61,6 +64,7 @@
 import org.osgi.service.log.LoggerFactory;
 import org.osgi.util.promise.PromiseFactory;
 import org.osgi.util.tracker.ServiceTracker;
+import org.osgi.util.tracker.ServiceTrackerCustomizer;
 
 @Header(
 	name = Constants.BUNDLE_ACTIVATOR,
@@ -69,24 +73,13 @@
 @RequireConfigurationAdmin
 public class Activator extends AbstractExtender {
 
-	private static final Logs _logs = new Logs.Builder(FrameworkUtil.getBundle(Activator.class).getBundleContext()).build();
-	private static final Logger _log = _logs.getLogger(Activator.class);
-	private static final ThreadGroup _threadGroup = new ThreadGroup("Apache Aries CCR - CDI");
-	private static final ExecutorService _executorService = Executors.newFixedThreadPool(
-		1,
-		new ThreadFactory() {
-
-			@Override
-			public Thread newThread(Runnable r) {
-				Thread t = new Thread(_threadGroup, r, "Aries CCR Thread");
-				t.setDaemon(true);
-				return t;
-			}
-
-		}
-	);
-	private static final PromiseFactory _promiseFactory = new PromiseFactory(_executorService);
-	public static final CCR ccr = new CCR(_promiseFactory, _logs);
+	private volatile CCR _ccr;
+	private volatile ExecutorService _executorService;
+	private volatile Logger _log;
+	private volatile Logs _logs;
+	private volatile PromiseFactory _promiseFactory;
+	private volatile ServiceTracker<CDIContainerInitializer, ServiceObjects<CDIContainerInitializer>> _containerTracker;
+	private volatile ServiceTracker<ContainerListener, ContainerListener> _containerListeners;
 
 	public Activator() {
 		setSynchronous(true);
@@ -94,12 +87,48 @@
 
 	@Override
 	public void start(BundleContext bundleContext) throws Exception {
+		_logs = new Logs.Builder(bundleContext).build();
+		_log = _logs.getLogger(Activator.class);
+		_containerTracker = new ServiceTracker<>(
+			bundleContext, CDIContainerInitializer.class,
+			new ServiceTrackerCustomizer<CDIContainerInitializer, ServiceObjects<CDIContainerInitializer>>() {
+
+				@Override
+				public ServiceObjects<CDIContainerInitializer> addingService(
+					ServiceReference<CDIContainerInitializer> reference) {
+
+					return bundleContext.getServiceObjects(reference);
+				}
+
+				@Override
+				public void modifiedService(ServiceReference<CDIContainerInitializer> reference,
+					ServiceObjects<CDIContainerInitializer> service) {
+				}
+
+				@Override
+				public void removedService(ServiceReference<CDIContainerInitializer> reference,
+					ServiceObjects<CDIContainerInitializer> service) {
+				}
+			}
+		);
+		_containerTracker.open();
+
+		_containerListeners = new ServiceTracker<>(bundleContext, ContainerListener.class, null);
+		_containerListeners.open();
+
+		_executorService = Executors.newSingleThreadExecutor(worker -> {
+			Thread t = new Thread(new ThreadGroup("Apache Aries CCR - CDI"), worker, "Aries CCR Thread (" + hashCode() + ")");
+			t.setDaemon(false);
+			return t;
+		});
+		_promiseFactory = new PromiseFactory(_executorService);
+		_ccr = new CCR(_promiseFactory, _logs);
+		_command = new CDICommand(_ccr);
+
 		if (_log.isDebugEnabled()) {
 			_log.debug("CCR starting {}", bundleContext.getBundle());
 		}
 
-		_command = new CDICommand(ccr);
-
 		_bundleContext = bundleContext;
 
 		registerCCR();
@@ -150,6 +179,11 @@
 		if (_log.isDebugEnabled()) {
 			_log.debug("CCR stoped {}", bundleContext.getBundle());
 		}
+		_executorService.shutdownNow();
+		_executorService.awaitTermination(2, TimeUnit.SECONDS); // not important but just to avoid to quit too fast
+
+		_containerTracker.close();
+		_containerListeners.close();
 	}
 
 	@Override
@@ -172,7 +206,7 @@
 			bundle, _bundleContext.getBundle(), _ccrChangeCount, _promiseFactory, caTracker, _logs);
 
 		// the CDI bundle
-		return new CDIBundle(ccr, containerState,
+		return new CDIBundle(_ccr, containerState,
 			// handle extensions
 			new ExtensionPhase(containerState,
 				// listen for configurations of the container component
@@ -183,14 +217,15 @@
 						new ContainerActivator.Builder(containerState,
 							// when the active container bootstraps CDI
 							new ContainerBootstrap(
-								containerState,
+								containerState, _containerTracker,
 								// when CDI is bootstrapping is complete and is up and running
 								// activate the configuration listeners for single and factory components
 								new ConfigurationListener.Builder(containerState),
 								new SingleComponent.Builder(containerState,
 									new SingleActivator.Builder(containerState)),
 								new FactoryComponent.Builder(containerState,
-									new FactoryActivator.Builder(containerState))
+									new FactoryActivator.Builder(containerState)),
+								_containerListeners
 							)
 						)
 					).build()
@@ -264,7 +299,7 @@
 
 			_registrations.add(registration);
 
-			return ccr;
+			return _ccr;
 		}
 
 		@Override
diff --git a/cdi-extender/src/main/java/org/apache/aries/cdi/container/internal/annotated/AnnotatedCallableImpl.java b/cdi-extender/src/main/java/org/apache/aries/cdi/container/internal/annotated/AnnotatedCallableImpl.java
new file mode 100644
index 0000000..82fb02f
--- /dev/null
+++ b/cdi-extender/src/main/java/org/apache/aries/cdi/container/internal/annotated/AnnotatedCallableImpl.java
@@ -0,0 +1,45 @@
+/**
+ * Licensed 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.aries.cdi.container.internal.annotated;
+
+import java.lang.reflect.AnnotatedElement;
+import java.lang.reflect.Executable;
+import java.lang.reflect.Type;
+import java.util.List;
+import java.util.stream.Collectors;
+import java.util.stream.IntStream;
+
+import javax.enterprise.inject.spi.AnnotatedCallable;
+import javax.enterprise.inject.spi.AnnotatedParameter;
+import javax.enterprise.inject.spi.AnnotatedType;
+
+public class AnnotatedCallableImpl<X> extends AnnotatedMemberImpl<X> implements AnnotatedCallable<X> {
+
+	private final List<AnnotatedParameter<X>> _parameters;
+
+	public AnnotatedCallableImpl(final Type baseType, final AnnotatedElement annotatedElement, final AnnotatedType<X> declaringType, final Executable executable) {
+		super(baseType, annotatedElement, declaringType, executable);
+
+		_parameters = IntStream.range(0, executable.getParameterCount())
+			.mapToObj(i -> new AnnotatedParameterImpl<X>(executable.getAnnotatedParameterTypes()[i].getType(), executable.getParameterAnnotations()[i], this, i))
+			.collect(Collectors.toList());
+	}
+
+	@Override
+	public List<AnnotatedParameter<X>> getParameters() {
+		return _parameters;
+	}
+
+}
diff --git a/cdi-extender/src/main/java/org/apache/aries/cdi/container/internal/annotated/AnnotatedConstructorImpl.java b/cdi-extender/src/main/java/org/apache/aries/cdi/container/internal/annotated/AnnotatedConstructorImpl.java
new file mode 100644
index 0000000..90924cc
--- /dev/null
+++ b/cdi-extender/src/main/java/org/apache/aries/cdi/container/internal/annotated/AnnotatedConstructorImpl.java
@@ -0,0 +1,34 @@
+/**
+ * Licensed 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.aries.cdi.container.internal.annotated;
+
+import java.lang.reflect.Constructor;
+
+import javax.enterprise.inject.spi.AnnotatedConstructor;
+import javax.enterprise.inject.spi.AnnotatedType;
+
+public class AnnotatedConstructorImpl<X> extends AnnotatedCallableImpl<X> implements AnnotatedConstructor<X> {
+
+	public AnnotatedConstructorImpl(final AnnotatedType<X> declaringType, final Constructor<X> constructor) {
+		super(constructor.getAnnotatedReturnType().getType(), constructor, declaringType, constructor);
+	}
+
+	@Override
+	@SuppressWarnings("unchecked")
+	public Constructor<X> getJavaMember() {
+		return (Constructor<X>)super.getJavaMember();
+	}
+
+}
diff --git a/cdi-extender/src/main/java/org/apache/aries/cdi/container/internal/annotated/AnnotatedFieldImpl.java b/cdi-extender/src/main/java/org/apache/aries/cdi/container/internal/annotated/AnnotatedFieldImpl.java
new file mode 100644
index 0000000..73099b7
--- /dev/null
+++ b/cdi-extender/src/main/java/org/apache/aries/cdi/container/internal/annotated/AnnotatedFieldImpl.java
@@ -0,0 +1,33 @@
+/**
+ * Licensed 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.aries.cdi.container.internal.annotated;
+
+import java.lang.reflect.Field;
+
+import javax.enterprise.inject.spi.AnnotatedField;
+import javax.enterprise.inject.spi.AnnotatedType;
+
+public class AnnotatedFieldImpl<X> extends AnnotatedMemberImpl<X> implements AnnotatedField<X> {
+
+	public AnnotatedFieldImpl(final AnnotatedType<X> declaringType, final Field field) {
+		super(field.getGenericType(), field, declaringType, field);
+	}
+
+	@Override
+	public Field getJavaMember() {
+		return (Field)super.getJavaMember();
+	}
+
+}
diff --git a/cdi-extender/src/main/java/org/apache/aries/cdi/container/internal/annotated/AnnotatedImpl.java b/cdi-extender/src/main/java/org/apache/aries/cdi/container/internal/annotated/AnnotatedImpl.java
new file mode 100644
index 0000000..62d54d5
--- /dev/null
+++ b/cdi-extender/src/main/java/org/apache/aries/cdi/container/internal/annotated/AnnotatedImpl.java
@@ -0,0 +1,71 @@
+/**
+ * Licensed 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.aries.cdi.container.internal.annotated;
+
+import static java.util.stream.Collectors.*;
+
+import java.lang.annotation.Annotation;
+import java.lang.reflect.AnnotatedElement;
+import java.lang.reflect.Type;
+import java.util.Arrays;
+import java.util.Set;
+
+import javax.enterprise.inject.spi.Annotated;
+
+import org.apache.aries.cdi.container.internal.util.Reflection;
+
+public class AnnotatedImpl<X> implements Annotated {
+
+	private final Type _baseType;
+	private final AnnotatedElement _annotatedElement;
+	private final Set<Type> _typeClosure;
+
+	public AnnotatedImpl(final Type baseType, final AnnotatedElement annotatedElement) {
+		_baseType = baseType;
+		_annotatedElement = annotatedElement;
+		_typeClosure = Reflection.getTypes(_baseType);
+	}
+
+	@Override
+	public Type getBaseType() {
+		return _baseType;
+	}
+
+	@Override
+	public Set<Type> getTypeClosure() {
+		return _typeClosure;
+	}
+
+	@Override
+	public <T extends Annotation> T getAnnotation(Class<T> annotationType) {
+		return _annotatedElement.getAnnotation(annotationType);
+	}
+
+	@Override
+	public <T extends Annotation> Set<T> getAnnotations(Class<T> annotationType) {
+		return Arrays.stream(_annotatedElement.getAnnotationsByType(annotationType)).collect(toSet());
+	}
+
+	@Override
+	public Set<Annotation> getAnnotations() {
+		return Arrays.stream(_annotatedElement.getAnnotations()).collect(toSet());
+	}
+
+	@Override
+	public boolean isAnnotationPresent(Class<? extends Annotation> annotationType) {
+		return _annotatedElement.isAnnotationPresent(annotationType);
+	}
+
+}
diff --git a/cdi-extender/src/main/java/org/apache/aries/cdi/container/internal/annotated/AnnotatedMemberImpl.java b/cdi-extender/src/main/java/org/apache/aries/cdi/container/internal/annotated/AnnotatedMemberImpl.java
new file mode 100644
index 0000000..e621667
--- /dev/null
+++ b/cdi-extender/src/main/java/org/apache/aries/cdi/container/internal/annotated/AnnotatedMemberImpl.java
@@ -0,0 +1,52 @@
+/**
+ * Licensed 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.aries.cdi.container.internal.annotated;
+
+import java.lang.reflect.AnnotatedElement;
+import java.lang.reflect.Member;
+import java.lang.reflect.Modifier;
+import java.lang.reflect.Type;
+
+import javax.enterprise.inject.spi.AnnotatedMember;
+import javax.enterprise.inject.spi.AnnotatedType;
+
+public class AnnotatedMemberImpl<X> extends AnnotatedImpl<X> implements AnnotatedMember<X> {
+
+	private final Member _member;
+	private final AnnotatedType<X> _declaringType;
+
+	public AnnotatedMemberImpl(final Type baseType, final AnnotatedElement annotatedElement, final AnnotatedType<X> declaringType, final Member member) {
+		super(baseType, annotatedElement);
+
+		_declaringType = declaringType;
+		_member = member;
+	}
+
+	@Override
+	public Member getJavaMember() {
+		return _member;
+	}
+
+	@Override
+	public boolean isStatic() {
+		return Modifier.isStatic(_member.getModifiers());
+	}
+
+	@Override
+	public AnnotatedType<X> getDeclaringType() {
+		return _declaringType;
+	}
+
+}
diff --git a/cdi-extender/src/main/java/org/apache/aries/cdi/container/internal/annotated/AnnotatedMethodImpl.java b/cdi-extender/src/main/java/org/apache/aries/cdi/container/internal/annotated/AnnotatedMethodImpl.java
new file mode 100644
index 0000000..ddde40b
--- /dev/null
+++ b/cdi-extender/src/main/java/org/apache/aries/cdi/container/internal/annotated/AnnotatedMethodImpl.java
@@ -0,0 +1,33 @@
+/**
+ * Licensed 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.aries.cdi.container.internal.annotated;
+
+import java.lang.reflect.Method;
+
+import javax.enterprise.inject.spi.AnnotatedMethod;
+import javax.enterprise.inject.spi.AnnotatedType;
+
+public class AnnotatedMethodImpl<X> extends AnnotatedCallableImpl<X> implements AnnotatedMethod<X> {
+
+	public AnnotatedMethodImpl(final AnnotatedType<X> declaringType, final Method method) {
+		super(method.getGenericReturnType(), method, declaringType, method);
+	}
+
+	@Override
+	public Method getJavaMember() {
+		return (Method)super.getJavaMember();
+	}
+
+}
diff --git a/cdi-extender/src/main/java/org/apache/aries/cdi/container/internal/annotated/AnnotatedParameterImpl.java b/cdi-extender/src/main/java/org/apache/aries/cdi/container/internal/annotated/AnnotatedParameterImpl.java
new file mode 100644
index 0000000..a4388b1
--- /dev/null
+++ b/cdi-extender/src/main/java/org/apache/aries/cdi/container/internal/annotated/AnnotatedParameterImpl.java
@@ -0,0 +1,68 @@
+/**
+ * Licensed 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.aries.cdi.container.internal.annotated;
+
+import java.lang.annotation.Annotation;
+import java.lang.reflect.AnnotatedElement;
+import java.lang.reflect.Type;
+import java.util.Arrays;
+
+import javax.enterprise.inject.spi.AnnotatedCallable;
+import javax.enterprise.inject.spi.AnnotatedParameter;
+
+public class AnnotatedParameterImpl<X> extends AnnotatedImpl<X> implements AnnotatedParameter<X> {
+
+	private final AnnotatedCallable<X> _annotatedCallable;
+	private final int _position;
+
+	public AnnotatedParameterImpl(final Type baseType, final Annotation[] parameterAnnotations, final AnnotatedCallable<X> annotatedCallable, final int position) {
+		super(baseType, newAnnotatedElement(parameterAnnotations));
+
+		_annotatedCallable = annotatedCallable;
+		_position = position;
+	}
+
+	@Override
+	public int getPosition() {
+		return _position;
+	}
+
+	@Override
+	public AnnotatedCallable<X> getDeclaringCallable() {
+		return _annotatedCallable;
+	}
+
+	private static AnnotatedElement newAnnotatedElement(final Annotation[] parameterAnnotations) {
+		return new AnnotatedElement() {
+
+			@Override
+			public Annotation[] getDeclaredAnnotations() {
+				return parameterAnnotations;
+			}
+
+			@Override
+			public Annotation[] getAnnotations() {
+				return parameterAnnotations;
+			}
+
+			@Override
+			public <T extends Annotation> T getAnnotation(Class<T> annotationType) {
+				return Arrays.stream(parameterAnnotations).filter(annotationType::isInstance).map(annotationType::cast).findFirst().orElse(null);
+			}
+
+		};
+	}
+
+}
diff --git a/cdi-extender/src/main/java/org/apache/aries/cdi/container/internal/annotated/AnnotatedTypeImpl.java b/cdi-extender/src/main/java/org/apache/aries/cdi/container/internal/annotated/AnnotatedTypeImpl.java
new file mode 100644
index 0000000..e5de340
--- /dev/null
+++ b/cdi-extender/src/main/java/org/apache/aries/cdi/container/internal/annotated/AnnotatedTypeImpl.java
@@ -0,0 +1,66 @@
+/**
+ * Licensed 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.aries.cdi.container.internal.annotated;
+
+import static java.util.stream.Collectors.*;
+import static org.apache.aries.cdi.container.internal.util.Reflection.*;
+
+import java.lang.reflect.Constructor;
+import java.util.Set;
+
+import javax.enterprise.inject.spi.AnnotatedConstructor;
+import javax.enterprise.inject.spi.AnnotatedField;
+import javax.enterprise.inject.spi.AnnotatedMethod;
+import javax.enterprise.inject.spi.AnnotatedType;
+
+public class AnnotatedTypeImpl<X> extends AnnotatedImpl<X> implements AnnotatedType<X> {
+
+	private final Class<X> _declaringClass;
+	private final Set<AnnotatedConstructor<X>> _constructors;
+	private final Set<AnnotatedField<? super X>> _fields;
+	private final Set<AnnotatedMethod<? super X>> _methods;
+
+	@SuppressWarnings("unchecked")
+	public AnnotatedTypeImpl(final Class<X> declaringClass) {
+		super(declaringClass, declaringClass);
+
+		_declaringClass = declaringClass;
+
+		_constructors = allConstructors(_declaringClass).map(c -> new AnnotatedConstructorImpl<>(this, (Constructor<X>)c)).collect(toSet());
+		_fields = allFields(_declaringClass).map(f -> new AnnotatedFieldImpl<>(this, f)).collect(toSet());
+		_methods = allMethods(_declaringClass).map(m -> new AnnotatedMethodImpl<>(this, m)).collect(toSet());
+	}
+
+	@Override
+	public Class<X> getJavaClass() {
+		return _declaringClass;
+	}
+
+	@Override
+	public Set<AnnotatedConstructor<X>> getConstructors() {
+		return _constructors;
+	}
+
+	@Override
+	public Set<AnnotatedMethod<? super X>> getMethods() {
+		return _methods;
+	}
+
+	@Override
+	public Set<AnnotatedField<? super X>> getFields() {
+		return _fields;
+	}
+
+}
diff --git a/cdi-extender/src/main/java/org/apache/aries/cdi/container/internal/bean/ComponentPropertiesBean.java b/cdi-extender/src/main/java/org/apache/aries/cdi/container/internal/bean/ComponentPropertiesBean.java
index 8155ac9..db9d8d5 100644
--- a/cdi-extender/src/main/java/org/apache/aries/cdi/container/internal/bean/ComponentPropertiesBean.java
+++ b/cdi-extender/src/main/java/org/apache/aries/cdi/container/internal/bean/ComponentPropertiesBean.java
@@ -21,7 +21,7 @@
 import java.util.Objects;
 import java.util.Set;
 
-import javax.enterprise.context.ApplicationScoped;
+import javax.enterprise.context.Dependent;
 import javax.enterprise.context.spi.CreationalContext;
 import javax.enterprise.inject.Default;
 import javax.enterprise.inject.spi.Bean;
@@ -98,7 +98,7 @@
 		ExtendedActivationDTO current = ComponentContext.With.current();
 
 		if (current == null) {
-			return ApplicationScoped.class;
+			return Dependent.class;
 		}
 
 		return ComponentScoped.class;
diff --git a/cdi-extender/src/main/java/org/apache/aries/cdi/container/internal/bean/ReferenceBean.java b/cdi-extender/src/main/java/org/apache/aries/cdi/container/internal/bean/ReferenceBean.java
index c1ac4b8..c6d7a76 100644
--- a/cdi-extender/src/main/java/org/apache/aries/cdi/container/internal/bean/ReferenceBean.java
+++ b/cdi-extender/src/main/java/org/apache/aries/cdi/container/internal/bean/ReferenceBean.java
@@ -149,26 +149,7 @@
 
 //		TODO do we want to support decorators/interceptors on in-bound services one day???
 //		==================================================================================
-
-//		if (s == null) return null;
-//
-//		List<javax.enterprise.inject.spi.Decorator<?>> decorators = _bm.resolveDecorators(
-//			Collections.singleton(_template.serviceClass),
-//			new Annotation[0]);
-//
-//		if (decorators.isEmpty()) {
-//			return s;
-//		}
-//
-//		org.jboss.weld.manager.BeanManagerImpl bmi =
-//			((org.jboss.weld.bean.builtin.BeanManagerProxy)_bm).delegate();
-//		org.jboss.weld.injection.CurrentInjectionPoint cip = bmi.getServices().get(
-//			org.jboss.weld.injection.CurrentInjectionPoint.class);
-//		InjectionPoint ip = cip.peek();
-//		return org.jboss.weld.util.Decorators.getOuterDelegate(
-//			(Bean<S>)this, s, c, (Class<S>)_template.serviceClass,
-//			(org.jboss.weld.injection.EmptyInjectionPoint.INSTANCE.equals(ip) ? null : ip),
-//			bmi, decorators);
+//  	If so, use InterceptionFactory instead of doing it manually
 	}
 
 	@Override
diff --git a/cdi-extender/src/main/java/org/apache/aries/cdi/container/internal/command/CDICommand.java b/cdi-extender/src/main/java/org/apache/aries/cdi/container/internal/command/CDICommand.java
index 8631e3a..4a642b0 100644
--- a/cdi-extender/src/main/java/org/apache/aries/cdi/container/internal/command/CDICommand.java
+++ b/cdi-extender/src/main/java/org/apache/aries/cdi/container/internal/command/CDICommand.java
@@ -14,7 +14,8 @@
 
 package org.apache.aries.cdi.container.internal.command;
 
-import static java.util.stream.Collectors.*;
+import static java.util.stream.Collectors.partitioningBy;
+import static java.util.stream.Collectors.toList;
 
 import java.util.Collection;
 import java.util.Formatter;
@@ -33,10 +34,12 @@
 import org.osgi.service.cdi.runtime.dto.ComponentInstanceDTO;
 import org.osgi.service.cdi.runtime.dto.ConfigurationDTO;
 import org.osgi.service.cdi.runtime.dto.ContainerDTO;
+import org.osgi.service.cdi.runtime.dto.ExtensionDTO;
 import org.osgi.service.cdi.runtime.dto.ReferenceDTO;
 import org.osgi.service.cdi.runtime.dto.template.ActivationTemplateDTO;
 import org.osgi.service.cdi.runtime.dto.template.ComponentTemplateDTO;
 import org.osgi.service.cdi.runtime.dto.template.ConfigurationTemplateDTO;
+import org.osgi.service.cdi.runtime.dto.template.ExtensionTemplateDTO;
 import org.osgi.service.cdi.runtime.dto.template.ReferenceTemplateDTO;
 
 public class CDICommand {
@@ -93,10 +96,34 @@
 			containerDTO.bundle.symbolicName,
 			containerDTO.bundle.id);
 
+		if (!containerDTO.template.extensions.isEmpty()) {
+			f.format(
+				"%s%sEXTENSIONS%n",
+				(hasNext ? PSSS : SSSS),
+				TLLS);
+
+			for (Iterator<ExtensionTemplateDTO> itr1 = containerDTO.template.extensions.iterator(); itr1.hasNext();) {
+				ExtensionTemplateDTO templateDTO = itr1.next();
+				ExtensionDTO extensionDTO = containerDTO.extensions.stream().filter(extInstance -> templateDTO == extInstance.template).findFirst().orElse(null);
+
+				f.format(
+					"%s%sFILTER: %s%n",
+					(hasNext ? PSSS : SSSS) + PSSS,
+					(itr1.hasNext() ? TLLS : CLLS),
+					templateDTO.serviceFilter);
+				f.format(
+					"%s%s%sMATCH: %s%n",
+					(hasNext ? PSSS : SSSS) + PSSS,
+					(itr1.hasNext() ? PSSS : SSSS),
+					CLLS,
+					(extensionDTO == null) ? "null*" : extensionDTO.service);
+			}
+		}
+
 		f.format(
 			"%s%sCOMPONENTS%n",
 			(hasNext ? PSSS : SSSS),
-			curb);
+			CLLS);
 
 		Map<Boolean, List<ComponentTemplateDTO>> componentTemplateDTOs = containerDTO.template.components.stream().collect(
 			partitioningBy(c -> c.type == ComponentType.CONTAINER)
@@ -160,20 +187,35 @@
 			c -> c.template.name.equals(componentTemplateDTO.name)
 		).findFirst().orElse(null);
 
-		if ((componentDTO != null) && !componentDTO.instances.isEmpty()) {
-			Iterator<ComponentInstanceDTO> itr3 = componentDTO.instances.iterator();
+		if (componentDTO != null) {
+			if (!componentDTO.instances.isEmpty()) {
+				Iterator<ComponentInstanceDTO> itr3 = componentDTO.instances.iterator();
 
-			for (;itr3.hasNext();) {
-				ComponentInstanceDTO instanceDTO = itr3.next();
+				for (;itr3.hasNext();) {
+					ComponentInstanceDTO instanceDTO = itr3.next();
 
+					formatInstance(
+						f,
+						prefix,
+						componentDTO,
+						componentTemplateDTO,
+						instanceDTO,
+						pids(instanceDTO, configMap),
+						hasNext,
+						itr3.hasNext(),
+						verbose);
+				}
+			}
+			else {
 				formatInstance(
 					f,
 					prefix,
 					componentDTO,
-					instanceDTO,
-					pids(instanceDTO, configMap),
+					componentTemplateDTO,
+					null,
+					configMap.get(Boolean.FALSE).stream().map(c -> c.pid).collect(toList()).toString(),
 					hasNext,
-					itr3.hasNext(),
+					false,
 					verbose);
 			}
 		}
@@ -182,6 +224,7 @@
 				f,
 				prefix,
 				componentDTO,
+				componentTemplateDTO,
 				null,
 				configMap.get(Boolean.FALSE).stream().map(c -> c.pid).collect(toList()).toString(),
 				hasNext,
@@ -191,7 +234,7 @@
 	}
 
 	private void formatInstance(
-		Formatter f, String prefix, ComponentDTO componentDTO,
+		Formatter f, String prefix, ComponentDTO componentDTO, ComponentTemplateDTO templateDTO,
 		ComponentInstanceDTO instanceDTO, String pids,
 		boolean hasNext, boolean hasNext2, boolean verbose) {
 
@@ -201,7 +244,7 @@
 				prefix,
 				(hasNext ? PSSS : SSSS),
 				TLLS,
-				componentDTO.template.beans.toString());
+				templateDTO.beans.toString());
 
 			f.format(
 				"%s%s%sCONFIGURATIONS%n",
@@ -209,7 +252,7 @@
 				(hasNext ? PSSS : SSSS),
 				TLLS);
 
-			for (Iterator<ConfigurationTemplateDTO> itr = componentDTO.template.configurations.iterator();itr.hasNext();) {
+			for (Iterator<ConfigurationTemplateDTO> itr = templateDTO.configurations.iterator();itr.hasNext();) {
 				ConfigurationTemplateDTO conf = itr.next();
 
 				ConfigurationDTO configurationDTO = null;
@@ -266,14 +309,14 @@
 				}
 			}
 
-			if (!componentDTO.template.references.isEmpty()) {
+			if (!templateDTO.references.isEmpty()) {
 				f.format(
 					"%s%s%sREFERENCES%n",
 					prefix,
 					(hasNext ? PSSS : SSSS),
 					TLLS);
 
-				for (Iterator<ReferenceTemplateDTO> itr = componentDTO.template.references.iterator(); itr.hasNext();) {
+				for (Iterator<ReferenceTemplateDTO> itr = templateDTO.references.iterator(); itr.hasNext();) {
 					ReferenceTemplateDTO dto = itr.next();
 
 					ReferenceDTO referenceDTO = null;
@@ -345,14 +388,14 @@
 				}
 			}
 
-			if (!componentDTO.template.activations.isEmpty()) {
+			if (!templateDTO.activations.isEmpty()) {
 				f.format(
 					"%s%s%sACTIVATIONS%n",
 					prefix,
 					(hasNext ? PSSS : SSSS),
 					TLLS);
 
-				for (Iterator<ActivationTemplateDTO> itr = componentDTO.template.activations.iterator(); itr.hasNext();) {
+				for (Iterator<ActivationTemplateDTO> itr = templateDTO.activations.iterator(); itr.hasNext();) {
 					ActivationTemplateDTO dto = itr.next();
 
 					ActivationDTO activationDTO = null;
diff --git a/cdi-extender/src/main/java/org/apache/aries/cdi/container/internal/container/CDIBundle.java b/cdi-extender/src/main/java/org/apache/aries/cdi/container/internal/container/CDIBundle.java
index c9816bd..3c58d88 100644
--- a/cdi-extender/src/main/java/org/apache/aries/cdi/container/internal/container/CDIBundle.java
+++ b/cdi-extender/src/main/java/org/apache/aries/cdi/container/internal/container/CDIBundle.java
@@ -31,23 +31,25 @@
 	@Override
 	public boolean close() {
 		try (Syncro open = syncro.open()) {
+			if (!running) return false;
+
 			containerState.closing();
 
 			return next.map(
-					next -> {
-						submit(next.closeOp(), next::close).onFailure(
-								f -> {
-									_log.error(l -> l.error("CCR Error in cdibundle CLOSE on {}", bundle(), f));
+				next -> {
+					submit(next.closeOp(), next::close).onFailure(
+						f -> {
+							_log.error(l -> l.error("CCR Error in cdibundle CLOSE on {}", bundle(), f));
 
-									error(f);
-								}
-								);
+							error(f);
+						}
+					);
 
-						_ccr.remove(bundle());
+					_ccr.remove(bundle());
 
-						return true;
-					}
-					).orElse(true);
+					return true;
+				}
+			).orElse(true);
 		}
 	}
 
@@ -64,7 +66,7 @@
 	@Override
 	public boolean open() {
 		try (Syncro open = syncro.open()) {
-			return next.map(
+			return running = next.map(
 				next -> {
 					_ccr.add(containerState.bundle(), containerState);
 
@@ -94,5 +96,6 @@
 
 	private final CCR _ccr;
 	private final Logger _log;
+	private volatile boolean running = false;
 
 }
diff --git a/cdi-extender/src/main/java/org/apache/aries/cdi/container/internal/container/ConfigurationListener.java b/cdi-extender/src/main/java/org/apache/aries/cdi/container/internal/container/ConfigurationListener.java
index 9a89301..494de1c 100644
--- a/cdi-extender/src/main/java/org/apache/aries/cdi/container/internal/container/ConfigurationListener.java
+++ b/cdi-extender/src/main/java/org/apache/aries/cdi/container/internal/container/ConfigurationListener.java
@@ -29,7 +29,6 @@
 import org.apache.aries.cdi.container.internal.util.Predicates;
 import org.apache.aries.cdi.container.internal.util.Syncro;
 import org.apache.aries.cdi.container.internal.util.Throw;
-import org.jboss.weld.exceptions.IllegalArgumentException;
 import org.osgi.framework.Constants;
 import org.osgi.framework.ServiceRegistration;
 import org.osgi.service.cdi.ConfigurationPolicy;
diff --git a/cdi-extender/src/main/java/org/apache/aries/cdi/container/internal/container/ContainerBootstrap.java b/cdi-extender/src/main/java/org/apache/aries/cdi/container/internal/container/ContainerBootstrap.java
index c67a26e..e0dc3c5 100644
--- a/cdi-extender/src/main/java/org/apache/aries/cdi/container/internal/container/ContainerBootstrap.java
+++ b/cdi-extender/src/main/java/org/apache/aries/cdi/container/internal/container/ContainerBootstrap.java
@@ -14,54 +14,87 @@
 
 package org.apache.aries.cdi.container.internal.container;
 
-import java.util.List;
-import java.util.concurrent.CopyOnWriteArrayList;
+import static java.util.Objects.requireNonNull;
+
+import java.net.URL;
+import java.util.ServiceLoader;
+import java.util.concurrent.atomic.AtomicInteger;
+import java.util.function.Consumer;
+import java.util.stream.Stream;
 
 import javax.enterprise.inject.spi.Extension;
 
 import org.apache.aries.cdi.container.internal.container.Op.Mode;
 import org.apache.aries.cdi.container.internal.container.Op.Type;
-import org.apache.aries.cdi.container.internal.loader.BundleResourcesLoader;
+import org.apache.aries.cdi.container.internal.loader.BundleClassLoader;
 import org.apache.aries.cdi.container.internal.model.ExtendedExtensionDTO;
 import org.apache.aries.cdi.container.internal.model.FactoryComponent;
+import org.apache.aries.cdi.container.internal.model.OSGiBean;
 import org.apache.aries.cdi.container.internal.model.SingleComponent;
+import org.apache.aries.cdi.container.internal.spi.ContainerListener;
+import org.apache.aries.cdi.container.internal.util.Maps;
 import org.apache.aries.cdi.container.internal.util.Syncro;
-import org.jboss.weld.bootstrap.WeldBootstrap;
-import org.jboss.weld.bootstrap.spi.BeanDeploymentArchive;
-import org.jboss.weld.bootstrap.spi.Deployment;
-import org.jboss.weld.bootstrap.spi.Metadata;
-import org.jboss.weld.util.ServiceLoader;
+import org.apache.aries.cdi.spi.CDIContainerInitializer;
+import org.osgi.framework.Bundle;
+import org.osgi.framework.BundleContext;
+import org.osgi.framework.Constants;
+import org.osgi.framework.ServiceObjects;
+import org.osgi.framework.ServiceReference;
+import org.osgi.service.cdi.runtime.dto.ExtensionDTO;
 import org.osgi.service.log.Logger;
+import org.osgi.util.tracker.ServiceTracker;
 
 public class ContainerBootstrap extends Phase {
 
 	public ContainerBootstrap(
-		ContainerState containerState,
-		ConfigurationListener.Builder configurationBuilder,
-		SingleComponent.Builder singleBuilder,
-		FactoryComponent.Builder factoryBuilder) {
+			ContainerState containerState,
+			ServiceTracker<CDIContainerInitializer, ServiceObjects<CDIContainerInitializer>> containerTracker,
+			ConfigurationListener.Builder configurationBuilder,
+			SingleComponent.Builder singleBuilder,
+			FactoryComponent.Builder factoryBuilder,
+			ServiceTracker<ContainerListener, ContainerListener> listeners) {
 
 		super(containerState, null);
 
 		_configurationBuilder = configurationBuilder;
+		_containerTracker = containerTracker;
+		_listeners = listeners;
 		_singleBuilder = singleBuilder;
 		_factoryBuilder = factoryBuilder;
 		_log = containerState.containerLogs().getLogger(getClass());
+
+		_serviceObjects = requireNonNull(
+			_containerTracker.getService(),
+			"A prototype scope org.apache.aries.cdi.spi.CDIContainerInitializer service must be available.");
 	}
 
 	@Override
 	public boolean close() {
 		try (Syncro syncro = _lock.open()) {
-			if (_bootstrap != null) {
-				_log.debug(l -> l.debug("CCR container bootstrap shutdown on {}", _bootstrap));
-				_bootstrap.shutdown();
-				_bootstrap = null;
+			if (_containerInstance != null) {
+				_log.debug(l -> l.debug("CCR container shutdown for {}", bundle()));
+				try {
+					_containerInstance.close();
+					withListeners(ContainerListener::onStopSuccess);
+				} catch (final RuntimeException re) {
+					withListeners(listener -> listener.onStopError(re));
+					throw re;
+				} finally {
+					_containerInstance = null;
+					try {
+						_serviceObjects.ungetService(_initializer);
+						_initializer = null;
+					}
+					catch (Throwable t) {
+						_log.trace(l -> l.trace("CCR Failure in returning initializer instance on {}", bundle(), t));
+					}
+				}
 			}
 
 			return true;
 		}
 		catch (Throwable t) {
-			_log.error(l -> l.error("CCR Failure in container bootstrap shutdown on {}", _bootstrap, t));
+			_log.error(l -> l.error("CCR Failure in container bootstrap shutdown on {}", bundle(), t));
 
 			return false;
 		}
@@ -80,7 +113,7 @@
 				return false;
 			}
 
-			if (_bootstrap != null) {
+			if (_containerInstance != null) {
 				return true;
 			}
 
@@ -88,61 +121,29 @@
 				return false;
 			}
 
-			List<Metadata<Extension>> extensions = new CopyOnWriteArrayList<>();
-
-			// Add the internal extensions
-			extensions.add(
-				new ExtensionMetadata(
-					new BundleContextExtension(containerState.bundleContext()),
-					containerState.id()));
-			extensions.add(
-				new ExtensionMetadata(
-					new RuntimeExtension(containerState, _configurationBuilder, _singleBuilder, _factoryBuilder),
-					containerState.id()));
-			extensions.add(
-				new ExtensionMetadata(
-					new LoggerExtension(containerState),
-					containerState.id()));
-
-			Thread currentThread = Thread.currentThread();
-			ClassLoader current = currentThread.getContextClassLoader();
-			BundleResourcesLoader.Builder builder = new BundleResourcesLoader.Builder(containerState.bundle(), containerState.extenderBundle());
+			_log.debug(log -> log.debug("CCR container startup for {}", bundle()));
 
 			try {
-				currentThread.setContextClassLoader(containerState.classLoader());
+				// always use a new class loader
+				BundleClassLoader loader = new BundleClassLoader(containerState.bundle(), containerState.extenderBundle());
 
-				// Add extensions found from the bundle's class loader, such as those in the Bundle-ClassPath
-				ServiceLoader.load(Extension.class, containerState.classLoader()).forEach(extensions::add);
+				_initializer = _serviceObjects.getService();
 
-				// Add external extensions
-				containerState.containerDTO().extensions.stream().map(
-					ExtendedExtensionDTO.class::cast
-				).map(
-					e -> {
-						builder.add(e.serviceReference.getBundle());
-						return new ExtensionMetadata(e.extension.getService(), e.template.serviceFilter);
-					}
-				).forEach(extensions::add);
+				processExtensions(loader, _initializer);
 
-				_bootstrap = new WeldBootstrap();
+				containerState.containerComponentTemplateDTO().properties.forEach(_initializer::addProperty);
 
-				BeanDeploymentArchive beanDeploymentArchive = new ContainerDeploymentArchive(
-					builder.build(),
-					containerState.id(),
-					containerState.beansModel().getBeanClassNames(),
-					containerState.beansModel().getBeansXml());
+				_containerInstance = _initializer
+						.addBeanClasses(containerState.beansModel().getOSGiBeans().stream().map(OSGiBean::getBeanClass).toArray(Class<?>[]::new))
+						.addBeanXmls(containerState.beansModel().getBeansXml().toArray(new URL[0]))
+						.setBundleContext(bundle().getBundleContext())
+						.setClassLoader(loader)
+						.initialize();
 
-				Deployment deployment = new ContainerDeployment(extensions, beanDeploymentArchive);
-
-				_bootstrap.startExtensions(extensions);
-				_bootstrap.startContainer(containerState.id(), new ContainerEnvironment(), deployment);
-				_bootstrap.startInitialization();
-				_bootstrap.deployBeans();
-				_bootstrap.validateBeans();
-				_bootstrap.endInitialization();
-			}
-			finally {
-				currentThread.setContextClassLoader(current);
+				withListeners(ContainerListener::onStartSuccess);
+			} catch (final RuntimeException re) {
+				withListeners(listener -> listener.onStartError(re));
+				throw re;
 			}
 
 			return true;
@@ -154,12 +155,73 @@
 		return Op.of(Mode.OPEN, Type.CONTAINER_BOOTSTRAP, containerState.id());
 	}
 
+	protected void processExtensions(BundleClassLoader loader, CDIContainerInitializer initializer) {
+		AtomicInteger counter = new AtomicInteger();
 
-	private volatile WeldBootstrap _bootstrap;
+		// Add the internal extensions
+		initializer.addExtension(
+			new BundleContextExtension(containerState.bundleContext()),
+			Maps.of(Constants.SERVICE_ID, counter.decrementAndGet(),
+					Constants.SERVICE_DESCRIPTION, "Aries CDI BundleContextExtension"));
+		initializer.addExtension(
+			new RuntimeExtension(containerState, _configurationBuilder, _singleBuilder, _factoryBuilder),
+			Maps.of(Constants.SERVICE_ID, counter.decrementAndGet(),
+					Constants.SERVICE_DESCRIPTION, "Aries CDI RuntimeExtension"));
+		initializer.addExtension(
+			new LoggerExtension(containerState),
+			Maps.of(Constants.SERVICE_ID, counter.decrementAndGet(),
+					Constants.SERVICE_DESCRIPTION, "Aries CDI LoggerExtension"));
+
+		// Add extensions found from the bundle's class loader, such as those in the Bundle-ClassPath
+		ServiceLoader.load(Extension.class, containerState.classLoader()).forEach(extension ->
+			initializer.addExtension(
+				extension,
+				Maps.of(Constants.SERVICE_ID, counter.decrementAndGet(),
+						Constants.SERVICE_DESCRIPTION, "ClassLoader Extension from " + containerState.bundle()))
+		);
+
+		// Add external extensions
+		for (ExtensionDTO extensionDTO : containerState.containerDTO().extensions) {
+			ExtendedExtensionDTO extendedExtensionDTO = (ExtendedExtensionDTO)extensionDTO;
+
+			initializer.addExtension(
+				extendedExtensionDTO.extension.getService(),
+				Maps.of(extendedExtensionDTO.extension.getServiceReference().getProperties()));
+
+			Bundle extensionBundle = extendedExtensionDTO.extension.getServiceReference().getBundle();
+
+			if (!loader.getBundles().contains(extensionBundle)) {
+				loader.getBundles().add(extensionBundle);
+			}
+		}
+	}
+
+	private void withListeners(final Consumer<ContainerListener> action) {
+		final ServiceReference<ContainerListener>[] refs = _listeners.getServiceReferences();
+		if (refs != null && refs.length > 0) {
+			final BundleContext bundleContext = bundle().getBundleContext();
+			Stream.of(refs).forEach(ref -> {
+				final ContainerListener service = bundleContext.getService(ref);
+				if (service != null) {
+					try {
+						action.accept(service);
+					} finally {
+						bundleContext.ungetService(ref);
+					}
+				}
+			});
+		}
+	}
+
+	private volatile AutoCloseable _containerInstance;
+	private final ServiceTracker<CDIContainerInitializer, ServiceObjects<CDIContainerInitializer>> _containerTracker;
 	private final ConfigurationListener.Builder _configurationBuilder;
 	private final FactoryComponent.Builder _factoryBuilder;
+	private CDIContainerInitializer _initializer;
+	private final ServiceObjects<CDIContainerInitializer> _serviceObjects;
 	private final SingleComponent.Builder _singleBuilder;
 	private final Syncro _lock = new Syncro(true);
 	private final Logger _log;
+	private final ServiceTracker<ContainerListener, ContainerListener> _listeners;
 
 }
\ No newline at end of file
diff --git a/cdi-extender/src/main/java/org/apache/aries/cdi/container/internal/container/ContainerDiscovery.java b/cdi-extender/src/main/java/org/apache/aries/cdi/container/internal/container/ContainerDiscovery.java
deleted file mode 100644
index ecaa8d1..0000000
--- a/cdi-extender/src/main/java/org/apache/aries/cdi/container/internal/container/ContainerDiscovery.java
+++ /dev/null
@@ -1,56 +0,0 @@
-/**
- * Licensed 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.aries.cdi.container.internal.container;
-
-import java.util.Collections;
-import java.util.List;
-
-import javax.enterprise.inject.spi.Extension;
-
-import org.apache.aries.cdi.container.internal.model.BeansModel;
-import org.jboss.weld.bootstrap.WeldBootstrap;
-import org.jboss.weld.bootstrap.spi.BeanDeploymentArchive;
-import org.jboss.weld.bootstrap.spi.Deployment;
-import org.jboss.weld.bootstrap.spi.Metadata;
-
-public class ContainerDiscovery {
-
-	public ContainerDiscovery(ContainerState containerState) {
-		String id = containerState.id() + "-discovery";
-
-		BeansModel beansModel = containerState.beansModel();
-
-		BeanDeploymentArchive beanDeploymentArchive = new ContainerDeploymentArchive(
-			containerState.loader(), id, beansModel.getBeanClassNames(),
-			beansModel.getBeansXml());
-
-		ExtensionMetadata extension = new ExtensionMetadata(
-			new DiscoveryExtension(containerState), id);
-
-		List<Metadata<Extension>> extensions = Collections.singletonList(extension);
-
-		Deployment deployment = new ContainerDeployment(
-			Collections.singletonList(extension), beanDeploymentArchive);
-
-		WeldBootstrap _bootstrap = new WeldBootstrap();
-
-		_bootstrap.startExtensions(extensions);
-		_bootstrap.startContainer(id, new ContainerEnvironment(), deployment);
-		_bootstrap.startInitialization();
-		_bootstrap.deployBeans();
-		_bootstrap.shutdown();
-	}
-
-}
\ No newline at end of file
diff --git a/cdi-extender/src/main/java/org/apache/aries/cdi/container/internal/container/ContainerState.java b/cdi-extender/src/main/java/org/apache/aries/cdi/container/internal/container/ContainerState.java
index a6c072f..2a9d130 100644
--- a/cdi-extender/src/main/java/org/apache/aries/cdi/container/internal/container/ContainerState.java
+++ b/cdi-extender/src/main/java/org/apache/aries/cdi/container/internal/container/ContainerState.java
@@ -32,26 +32,20 @@
 import java.util.concurrent.CopyOnWriteArrayList;
 import java.util.concurrent.atomic.AtomicBoolean;
 
-import javax.enterprise.inject.Any;
 import javax.enterprise.inject.spi.BeanManager;
-import javax.enterprise.util.AnnotationLiteral;
 
 import org.apache.aries.cdi.container.internal.ChangeCount;
 import org.apache.aries.cdi.container.internal.loader.BundleClassLoader;
-import org.apache.aries.cdi.container.internal.loader.BundleResourcesLoader;
 import org.apache.aries.cdi.container.internal.model.BeansModel;
 import org.apache.aries.cdi.container.internal.model.BeansModelBuilder;
 import org.apache.aries.cdi.container.internal.model.ExtendedConfigurationTemplateDTO;
 import org.apache.aries.cdi.container.internal.model.ExtendedExtensionTemplateDTO;
 import org.apache.aries.cdi.container.internal.util.Logs;
 import org.apache.aries.cdi.container.internal.util.Throw;
-import org.jboss.weld.resources.spi.ResourceLoader;
-import org.jboss.weld.serialization.spi.ProxyServices;
 import org.osgi.framework.Bundle;
 import org.osgi.framework.BundleContext;
 import org.osgi.framework.Constants;
 import org.osgi.framework.dto.BundleDTO;
-import org.osgi.framework.namespace.PackageNamespace;
 import org.osgi.framework.wiring.BundleCapability;
 import org.osgi.framework.wiring.BundleRequirement;
 import org.osgi.framework.wiring.BundleWire;
@@ -73,10 +67,6 @@
 
 public class ContainerState {
 
-	public static final AnnotationLiteral<Any> ANY = new AnnotationLiteral<Any>() {
-		private static final long serialVersionUID = 1L;
-	};
-
 	public ContainerState(
 		Bundle bundle,
 		Bundle extenderBundle,
@@ -193,14 +183,12 @@
 
 		_containerDTO.template.components.add(_containerComponentTemplateDTO);
 
-		_aggregateClassLoader = new BundleClassLoader(getBundles(_bundle, _extenderBundle));
+		_aggregateClassLoader = new BundleClassLoader(_bundle, _extenderBundle);
 
 		_beansModel = new BeansModelBuilder(this, _aggregateClassLoader, bundleWiring, cdiAttributes).build();
 
-		_bundleClassLoader = bundleWiring.getClassLoader();
-
 		try {
-			new ContainerDiscovery(this);
+			new Discovery(this).discover();
 		}
 		catch (Exception e) {
 			_log.error(l -> l.error("CCR Discovery resulted in errors on {}", bundle, e));
@@ -240,10 +228,6 @@
 		return _bundle;
 	}
 
-	public ClassLoader bundleClassLoader() {
-		return _bundleClassLoader;
-	}
-
 	public BundleContext bundleContext() {
 		return _bundleContext;
 	}
@@ -256,7 +240,7 @@
 		return _ccrLogs;
 	}
 
-	public ClassLoader classLoader() {
+	public BundleClassLoader classLoader() {
 		return _aggregateClassLoader;
 	}
 
@@ -330,11 +314,6 @@
 		_changeCount.incrementAndGet();
 	}
 
-	@SuppressWarnings("unchecked")
-	public <T extends ResourceLoader & ProxyServices> T loader() {
-		return (T)new BundleResourcesLoader.Builder(_bundle, _extenderBundle).build();
-	}
-
 	public PromiseFactory promiseFactory() {
 		return _promiseFactory;
 	}
@@ -380,39 +359,11 @@
 		return promise;
 	}
 
-	private static Bundle[] getBundles(Bundle bundle, Bundle extenderBundle) {
-		List<Bundle> bundles = new ArrayList<>();
-
-		bundles.add(bundle);
-		bundles.add(extenderBundle);
-
-		BundleWiring extenderWiring = extenderBundle.adapt(BundleWiring.class);
-
-		List<BundleWire> requiredWires = extenderWiring.getRequiredWires(PackageNamespace.PACKAGE_NAMESPACE);
-
-		for (BundleWire bundleWire : requiredWires) {
-			BundleCapability capability = bundleWire.getCapability();
-			Map<String, Object> attributes = capability.getAttributes();
-			String packageName = (String)attributes.get(PackageNamespace.PACKAGE_NAMESPACE);
-			if (!packageName.startsWith("org.jboss.weld.")) {
-				continue;
-			}
-
-			Bundle wireBundle = bundleWire.getProvider().getBundle();
-			if (!bundles.contains(wireBundle)) {
-				bundles.add(wireBundle);
-			}
-		}
-
-		return bundles.toArray(new Bundle[0]);
-	}
-
-	private final ClassLoader _aggregateClassLoader;
+	private final BundleClassLoader _aggregateClassLoader;
 	private volatile Deferred<BeanManager> _beanManagerDeferred;
 	private final BeansModel _beansModel;
 	private final Bundle _bundle;
 	private final BundleContext _bundleContext;
-	private final ClassLoader _bundleClassLoader;
 	private final Map<CheckedCallback<?, ?>, Deferred<?>> _callbacks = new ConcurrentHashMap<>();
 	private final ServiceTracker<ConfigurationAdmin, ConfigurationAdmin> _caTracker;
 	private final Logger _log;
diff --git a/cdi-extender/src/main/java/org/apache/aries/cdi/container/internal/container/Discovery.java b/cdi-extender/src/main/java/org/apache/aries/cdi/container/internal/container/Discovery.java
new file mode 100644
index 0000000..bd1cb97
--- /dev/null
+++ b/cdi-extender/src/main/java/org/apache/aries/cdi/container/internal/container/Discovery.java
@@ -0,0 +1,397 @@
+/**
+ * Licensed 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.aries.cdi.container.internal.container;
+
+import java.lang.annotation.Annotation;
+import java.lang.reflect.Type;
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Map;
+import java.util.Optional;
+import java.util.Set;
+import java.util.concurrent.CopyOnWriteArrayList;
+
+import javax.enterprise.context.ApplicationScoped;
+import javax.enterprise.context.Dependent;
+import javax.enterprise.event.Observes;
+import javax.enterprise.event.ObservesAsync;
+import javax.enterprise.inject.Disposes;
+import javax.enterprise.inject.Produces;
+import javax.enterprise.inject.spi.Annotated;
+import javax.enterprise.inject.spi.AnnotatedMember;
+import javax.enterprise.inject.spi.AnnotatedMethod;
+import javax.enterprise.inject.spi.AnnotatedParameter;
+import javax.enterprise.inject.spi.AnnotatedType;
+import javax.inject.Inject;
+import javax.inject.Named;
+
+import org.apache.aries.cdi.container.internal.annotated.AnnotatedTypeImpl;
+import org.apache.aries.cdi.container.internal.model.BeansModel;
+import org.apache.aries.cdi.container.internal.model.ComponentPropertiesModel;
+import org.apache.aries.cdi.container.internal.model.ExtendedActivationTemplateDTO;
+import org.apache.aries.cdi.container.internal.model.ExtendedComponentTemplateDTO;
+import org.apache.aries.cdi.container.internal.model.ExtendedConfigurationTemplateDTO;
+import org.apache.aries.cdi.container.internal.model.OSGiBean;
+import org.apache.aries.cdi.container.internal.model.ReferenceModel;
+import org.apache.aries.cdi.container.internal.model.ReferenceModel.Builder;
+import org.apache.aries.cdi.container.internal.util.Annotates;
+import org.apache.aries.cdi.container.internal.util.Reflection;
+import org.osgi.service.cdi.ComponentType;
+import org.osgi.service.cdi.ConfigurationPolicy;
+import org.osgi.service.cdi.MaximumCardinality;
+import org.osgi.service.cdi.ServiceScope;
+import org.osgi.service.cdi.annotations.ComponentProperties;
+import org.osgi.service.cdi.annotations.ComponentScoped;
+import org.osgi.service.cdi.annotations.FactoryComponent;
+import org.osgi.service.cdi.annotations.PID;
+import org.osgi.service.cdi.annotations.Reference;
+import org.osgi.service.cdi.annotations.SingleComponent;
+import org.osgi.service.cdi.reference.BindBeanServiceObjects;
+import org.osgi.service.cdi.reference.BindService;
+import org.osgi.service.cdi.reference.BindServiceReference;
+import org.osgi.service.cdi.runtime.dto.template.ComponentTemplateDTO;
+
+public class Discovery {
+
+	private static final List<Type> BIND_TYPES = Arrays.asList(BindService.class, BindBeanServiceObjects.class, BindServiceReference.class);
+
+	public Discovery(ContainerState containerState) {
+		_containerState = containerState;
+		_beansModel = _containerState.beansModel();
+		_containerTemplate = _containerState.containerDTO().template.components.get(0);
+	}
+
+	public void discover() {
+		_beansModel.getOSGiBeans().stream().forEach(osgiBean -> {
+			osgiBean.found(true);
+
+			AnnotatedType<?> annotatedType = new AnnotatedTypeImpl<>(osgiBean.getBeanClass());
+
+			try {
+				String beanName = Annotates.beanName(annotatedType);
+				Class<? extends Annotation> beanScope = Annotates.beanScope(annotatedType);
+				Map<String, Object> componentProperties = Annotates.componentProperties(annotatedType);
+				ServiceScope serviceScope = Annotates.serviceScope(annotatedType);
+				List<String> serviceTypes = Annotates.serviceClassNames(annotatedType);
+
+				if (annotatedType.isAnnotationPresent(SingleComponent.class)) {
+					doFactoryOrSingleComponent(osgiBean, osgiBean.getBeanClass(), annotatedType, beanName, serviceTypes, serviceScope, componentProperties, ComponentType.SINGLE);
+				}
+				else if (annotatedType.isAnnotationPresent(FactoryComponent.class)) {
+					doFactoryOrSingleComponent(osgiBean, osgiBean.getBeanClass(), annotatedType, beanName, serviceTypes, serviceScope, componentProperties, ComponentType.FACTORY);
+				}
+				else if (annotatedType.isAnnotationPresent(ComponentScoped.class)) {
+					_componentScoped.add(osgiBean);
+				}
+				else {
+					discoverActivations(osgiBean, osgiBean.getBeanClass(), annotatedType, null, beanScope, serviceTypes, serviceScope, componentProperties);
+				}
+			}
+			catch (Exception e) {
+				_containerState.error(e);
+
+				return;
+			}
+
+			annotatedType.getConstructors().stream().filter(this::isInject).flatMap(annotatedConstructor -> annotatedConstructor.getParameters().stream()).forEach(
+				annotatedParameter ->
+					processAnnotated(annotatedParameter, annotatedParameter.getBaseType(), Annotates.qualifiers(annotatedParameter), osgiBean)
+			);
+
+			annotatedType.getFields().stream().filter(this::isInject).forEach(
+				annotatedField ->
+					processAnnotated(annotatedField, annotatedField.getBaseType(), Annotates.qualifiers(annotatedField), osgiBean)
+			);
+
+			annotatedType.getFields().stream().filter(this::isProduces).forEach(
+				annotatedField -> {
+					Class<? extends Annotation> beanScope = Annotates.beanScope(annotatedField);
+					Map<String, Object> componentProperties = Annotates.componentProperties(annotatedField);
+					ServiceScope serviceScope = Annotates.serviceScope(annotatedField);
+					List<String> serviceTypes = Annotates.serviceClassNames(annotatedField);
+
+					discoverActivations(osgiBean, osgiBean.getBeanClass(), annotatedField, annotatedField, beanScope, serviceTypes, serviceScope, componentProperties);
+				}
+			);
+
+			annotatedType.getMethods().stream().forEach(annotatedMethod -> {
+				if (isInjectOrProduces(annotatedMethod)) {
+					annotatedMethod.getParameters().stream().forEach(
+						annotatedParameter -> processAnnotated(annotatedParameter, annotatedParameter.getBaseType(), Annotates.qualifiers(annotatedParameter), osgiBean)
+					);
+
+					if (isProduces(annotatedMethod)) {
+						Class<? extends Annotation> beanScope = Annotates.beanScope(annotatedMethod);
+						Map<String, Object> componentProperties = Annotates.componentProperties(annotatedMethod);
+						ServiceScope serviceScope = Annotates.serviceScope(annotatedMethod);
+						List<String> serviceTypes = Annotates.serviceClassNames(annotatedMethod);
+
+						discoverActivations(osgiBean, osgiBean.getBeanClass(), annotatedMethod, annotatedMethod, beanScope, serviceTypes, serviceScope, componentProperties);
+					}
+				}
+				else if (isDisposeOrObserves(annotatedMethod)) {
+					annotatedMethod.getParameters().subList(1, annotatedMethod.getParameters().size()).stream().forEach(
+						annotatedParameter -> processAnnotated(annotatedParameter, annotatedParameter.getBaseType(), Annotates.qualifiers(annotatedParameter), osgiBean)
+					);
+				}
+			});
+		});
+
+		postProcessComponentScopedBeans();
+	}
+
+	<X> boolean isInject(AnnotatedMember<X> annotatedMember) {
+		return (annotatedMember.isAnnotationPresent(Inject.class) && !annotatedMember.isStatic());
+	}
+
+	<X> boolean isInjectOrProduces(AnnotatedMember<X> annotatedMember) {
+		return (annotatedMember.isAnnotationPresent(Inject.class) && !annotatedMember.isStatic()) ||
+			annotatedMember.isAnnotationPresent(Produces.class);
+	}
+
+	<X> boolean isProduces(AnnotatedMember<X> annotatedMember) {
+		return annotatedMember.isAnnotationPresent(Produces.class);
+	}
+
+	<X> boolean isDisposeOrObserves(AnnotatedMethod<X> annotatedMethod) {
+		return !annotatedMethod.getParameters().isEmpty() && (annotatedMethod.getParameters().get(0).isAnnotationPresent(Disposes.class) ||
+			annotatedMethod.getParameters().get(0).isAnnotationPresent(Observes.class) ||
+			annotatedMethod.getParameters().get(0).isAnnotationPresent(ObservesAsync.class));
+	}
+
+	<X> void processAnnotated(Annotated annotated, Type injectionPointType, Set<Annotation> qualifiers, OSGiBean osgiBean) {
+		if (BIND_TYPES.contains(Reflection.getRawType(annotated.getBaseType()))) {
+			Builder builder = new ReferenceModel.Builder(annotated);
+
+			try {
+				ReferenceModel referenceModel = builder.type(injectionPointType).build();
+
+				osgiBean.addReference(referenceModel.toDTO());
+			}
+			catch (Exception e) {
+				_containerState.error(e);
+			}
+		}
+		else {
+			Reference reference = annotated.getAnnotation(Reference.class);
+			ComponentProperties componentProperties = annotated.getAnnotation(ComponentProperties.class);
+
+			if (reference != null) {
+				doReference(osgiBean, annotated, injectionPointType, reference, componentProperties);
+			}
+			else if (componentProperties != null) {
+				doComponentProperties(osgiBean, injectionPointType, qualifiers);
+			}
+		}
+	}
+
+	void postProcessComponentScopedBeans() {
+		_containerState.containerDTO().template.components.stream().filter(
+			template -> template.type != ComponentType.CONTAINER
+		).map(
+			template -> (ExtendedComponentTemplateDTO)template
+		).forEach(
+			template -> {
+
+				_componentScoped.forEach(
+					osgiBean -> {
+						if (osgiBean.getComponent() == null) {
+							osgiBean.setComponent(_containerState, template);
+						}
+
+						String className = osgiBean.getBeanClass().getName();
+						if (!template.beans.contains(className)) {
+							template.beans.add(className);
+						}
+					}
+				);
+			}
+		);
+	}
+
+	void doComponentProperties(OSGiBean osgiBean, Type injectionPointType, Set<Annotation> qualifiers) {
+		try {
+			ComponentPropertiesModel configurationModel = new ComponentPropertiesModel.Builder(
+				injectionPointType
+			).declaringClass(
+				osgiBean.getBeanClass()
+			).qualifiers(
+				qualifiers
+			).build();
+
+			osgiBean.addConfiguration(_containerState, configurationModel.toDTO());
+		}
+		catch (Exception e) {
+			_containerState.error(e);
+		}
+	}
+
+	void discoverActivations(OSGiBean osgiBean, Class<?> declaringClass, Annotated annotated, AnnotatedMember<?> producer, Class<? extends Annotation> scope, List<String> serviceTypeNames, ServiceScope serviceScope, Map<String, Object> componentProperties) {
+		String className = declaringClass.getName();
+
+		if (!_containerTemplate.beans.contains(className)) {
+			_containerTemplate.beans.add(className);
+		}
+
+		if (!serviceTypeNames.isEmpty()) {
+			if (!scope.equals(ApplicationScoped.class) &&
+				!scope.equals(Dependent.class)) {
+
+				_containerState.error(
+					new IllegalStateException(
+						String.format(
+							"@Service can only be used on @ApplicationScoped, @Dependent, @SingleComponent, and @FactoryComponent: %s",
+							osgiBean.getBeanClass())));
+
+				return;
+			}
+
+			ExtendedActivationTemplateDTO activationTemplate = new ExtendedActivationTemplateDTO();
+			activationTemplate.cdiScope = scope;
+			activationTemplate.declaringClass = declaringClass;
+			activationTemplate.producer = producer;
+			activationTemplate.properties = componentProperties;
+			activationTemplate.scope = serviceScope;
+			activationTemplate.serviceClasses = serviceTypeNames;
+
+			_containerTemplate.activations.add(activationTemplate);
+		}
+
+		osgiBean.setComponent(_containerState, _containerTemplate);
+	}
+
+	void doFactoryOrSingleComponent(
+			OSGiBean osgiBean, Class<?> declaringClass, Annotated annotated, String beanName,
+			List<String> serviceTypes, ServiceScope serviceScope,
+			Map<String, Object> componentProperties, ComponentType componentType) {
+
+		Set<Annotation> qualifiers = Annotates.qualifiers(annotated);
+		qualifiers.removeIf(Named.class::isInstance);
+
+		ExtendedComponentTemplateDTO componentTemplate = new ExtendedComponentTemplateDTO();
+		componentTemplate.activations = new CopyOnWriteArrayList<>();
+
+		ExtendedActivationTemplateDTO activationTemplate = new ExtendedActivationTemplateDTO();
+		activationTemplate.declaringClass = declaringClass;
+		activationTemplate.properties = Collections.emptyMap();
+		activationTemplate.scope = serviceScope;
+		activationTemplate.serviceClasses = serviceTypes;
+
+		componentTemplate.activations.add(activationTemplate);
+
+		componentTemplate.beanClass = declaringClass;
+		componentTemplate.qualifiers = qualifiers;
+		componentTemplate.beans = new CopyOnWriteArrayList<>();
+		componentTemplate.configurations = new CopyOnWriteArrayList<>();
+		componentTemplate.name = beanName;
+		componentTemplate.properties = componentProperties;
+		componentTemplate.references = new CopyOnWriteArrayList<>();
+		componentTemplate.type = componentType;
+
+		annotated.getAnnotations(PID.class).stream().forEach(
+			PID -> {
+				String pid = PID.value();
+
+				ExtendedConfigurationTemplateDTO configurationTemplate = new ExtendedConfigurationTemplateDTO();
+
+				configurationTemplate.declaringClass = declaringClass;
+				configurationTemplate.maximumCardinality = MaximumCardinality.ONE;
+				configurationTemplate.pid = Optional.of(pid).map(
+					s -> (s.equals("$") || s.equals("")) ? componentTemplate.name : s
+				).orElse(componentTemplate.name);
+
+				if (componentType == ComponentType.SINGLE) {
+					configurationTemplate.pid = (pid.equals("$") || pid.equals("")) ? componentTemplate.name : pid;
+				}
+
+				configurationTemplate.policy = PID.policy();
+
+				componentTemplate.configurations.add(configurationTemplate);
+			}
+		);
+
+		if (componentType == ComponentType.SINGLE) {
+			if (componentTemplate.configurations.isEmpty()) {
+				ExtendedConfigurationTemplateDTO configurationTemplate = new ExtendedConfigurationTemplateDTO();
+
+				configurationTemplate.declaringClass = declaringClass;
+				configurationTemplate.maximumCardinality = MaximumCardinality.ONE;
+				configurationTemplate.pid = componentTemplate.name;
+				configurationTemplate.policy = ConfigurationPolicy.OPTIONAL;
+
+				componentTemplate.configurations.add(configurationTemplate);
+			}
+		}
+		else {
+			ExtendedConfigurationTemplateDTO configurationTemplate = new ExtendedConfigurationTemplateDTO();
+
+			configurationTemplate.declaringClass = declaringClass;
+			configurationTemplate.maximumCardinality = MaximumCardinality.MANY;
+			configurationTemplate.pid = Optional.ofNullable(
+				annotated.getAnnotation(FactoryComponent.class)
+			).map(FactoryComponent::value).map(
+				v -> (v.equals("$") || v.equals("")) ? componentTemplate.name : v
+			).orElse(componentTemplate.name);
+			configurationTemplate.policy = ConfigurationPolicy.REQUIRED;
+
+			componentTemplate.configurations.add(configurationTemplate);
+		}
+
+		componentTemplate.beans.add(declaringClass.getName());
+
+		_containerState.containerDTO().template.components.add(componentTemplate);
+
+		osgiBean.setComponent(_containerState, componentTemplate);
+	}
+
+	void doReference(OSGiBean osgiBean, Annotated annotated, Type injectionPointType, Reference reference, ComponentProperties componentProperties) {
+		if (componentProperties != null) {
+			_containerState.error(
+				new IllegalArgumentException(
+					String.format(
+						"Cannot use @Reference and @Configuration on the same injection point {}",
+						injectionPointType))
+			);
+
+			return;
+		}
+
+		Builder builder = null;
+
+		if (annotated instanceof AnnotatedParameter) {
+			builder = new ReferenceModel.Builder(annotated);
+		}
+		else {
+			builder = new ReferenceModel.Builder(annotated);
+		}
+
+		try {
+			ReferenceModel referenceModel = builder.type(injectionPointType).build();
+
+			osgiBean.addReference(referenceModel.toDTO());
+		}
+		catch (Exception e) {
+			_containerState.error(e);
+		}
+	}
+
+	private final BeansModel _beansModel;
+	private final Set<OSGiBean> _componentScoped = new HashSet<>();
+	private final ComponentTemplateDTO _containerTemplate;
+	private final ContainerState _containerState;
+
+}
diff --git a/cdi-extender/src/main/java/org/apache/aries/cdi/container/internal/container/DiscoveryExtension.java b/cdi-extender/src/main/java/org/apache/aries/cdi/container/internal/container/DiscoveryExtension.java
deleted file mode 100644
index a4fa150..0000000
--- a/cdi-extender/src/main/java/org/apache/aries/cdi/container/internal/container/DiscoveryExtension.java
+++ /dev/null
@@ -1,496 +0,0 @@
-/**
- * Licensed 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.aries.cdi.container.internal.container;
-
-import java.lang.annotation.Annotation;
-import java.lang.reflect.Type;
-import java.util.Collections;
-import java.util.HashSet;
-import java.util.List;
-import java.util.Map;
-import java.util.Optional;
-import java.util.Set;
-import java.util.concurrent.CopyOnWriteArrayList;
-
-import javax.enterprise.context.ApplicationScoped;
-import javax.enterprise.context.Dependent;
-import javax.enterprise.event.Observes;
-import javax.enterprise.inject.spi.AfterBeanDiscovery;
-import javax.enterprise.inject.spi.Annotated;
-import javax.enterprise.inject.spi.AnnotatedField;
-import javax.enterprise.inject.spi.AnnotatedParameter;
-import javax.enterprise.inject.spi.Bean;
-import javax.enterprise.inject.spi.BeanManager;
-import javax.enterprise.inject.spi.DefinitionException;
-import javax.enterprise.inject.spi.Extension;
-import javax.enterprise.inject.spi.InjectionPoint;
-import javax.enterprise.inject.spi.ProcessAnnotatedType;
-import javax.enterprise.inject.spi.ProcessBean;
-import javax.enterprise.inject.spi.ProcessInjectionPoint;
-import javax.enterprise.inject.spi.ProcessProducerField;
-import javax.enterprise.inject.spi.ProcessProducerMethod;
-
-import org.apache.aries.cdi.container.internal.model.BeansModel;
-import org.apache.aries.cdi.container.internal.model.ComponentPropertiesModel;
-import org.apache.aries.cdi.container.internal.model.ExtendedActivationTemplateDTO;
-import org.apache.aries.cdi.container.internal.model.ExtendedComponentTemplateDTO;
-import org.apache.aries.cdi.container.internal.model.ExtendedConfigurationTemplateDTO;
-import org.apache.aries.cdi.container.internal.model.OSGiBean;
-import org.apache.aries.cdi.container.internal.model.ReferenceModel;
-import org.apache.aries.cdi.container.internal.model.ReferenceModel.Builder;
-import org.apache.aries.cdi.container.internal.util.Annotates;
-import org.osgi.service.cdi.ComponentType;
-import org.osgi.service.cdi.ConfigurationPolicy;
-import org.osgi.service.cdi.MaximumCardinality;
-import org.osgi.service.cdi.ServiceScope;
-import org.osgi.service.cdi.annotations.ComponentProperties;
-import org.osgi.service.cdi.annotations.ComponentScoped;
-import org.osgi.service.cdi.annotations.FactoryComponent;
-import org.osgi.service.cdi.annotations.PID;
-import org.osgi.service.cdi.annotations.Reference;
-import org.osgi.service.cdi.annotations.SingleComponent;
-import org.osgi.service.cdi.reference.BindBeanServiceObjects;
-import org.osgi.service.cdi.reference.BindService;
-import org.osgi.service.cdi.reference.BindServiceReference;
-import org.osgi.service.cdi.runtime.dto.template.ComponentTemplateDTO;
-
-public class DiscoveryExtension implements Extension {
-
-	public DiscoveryExtension(ContainerState containerState) {
-		_containerState = containerState;
-		_beansModel = _containerState.beansModel();
-		_containerTemplate = _containerState.containerDTO().template.components.get(0);
-	}
-
-	<X> void processAnnotatedType(@Observes ProcessAnnotatedType<X> pat) {
-		Class<X> declaringClass = Annotates.declaringClass(pat.getAnnotatedType());
-
-		final String className = declaringClass.getName();
-
-		OSGiBean osgiBean = _beansModel.getOSGiBean(className);
-
-		if (osgiBean == null) {
-			return;
-		}
-
-		osgiBean.found(true);
-	}
-
-	<X> void processBindObject(@Observes ProcessInjectionPoint<X, BindService<?>> pip) {
-		processInjectionPoint0(pip, true);
-	}
-
-	<X> void processBindServiceObjects(@Observes ProcessInjectionPoint<X, BindBeanServiceObjects<?>> pip) {
-		processInjectionPoint0(pip, true);
-	}
-
-	<X> void processBindServiceReference(@Observes ProcessInjectionPoint<X, BindServiceReference<?>> pip) {
-		processInjectionPoint0(pip, true);
-	}
-
-	<X, T> void processInjectionPoint(@Observes ProcessInjectionPoint<X, T> pip) {
-		processInjectionPoint0(pip, false);
-	}
-
-	<X, T> void processInjectionPoint0(ProcessInjectionPoint<X, T> pip, boolean special) {
-		InjectionPoint injectionPoint = pip.getInjectionPoint();
-
-		Annotated annotated = injectionPoint.getAnnotated();
-
-		Class<X> declaringClass = Annotates.declaringClass(annotated);
-
-		String className = declaringClass.getName();
-
-		OSGiBean osgiBean = _beansModel.getOSGiBean(className);
-
-		if (osgiBean == null) {
-			return;
-		}
-
-		if (special) {
-			doSpecial(osgiBean, annotated, injectionPoint.getType());
-		}
-		else {
-			doOther(osgiBean, declaringClass, annotated, injectionPoint);
-		}
-	}
-
-	<X> void processBean(@Observes ProcessBean<X> pb) {
-		final Class<X> declaringClass = Annotates.declaringClass(pb);
-
-		String className = declaringClass.getName();
-
-		OSGiBean osgiBean = _beansModel.getOSGiBean(className);
-
-		if (osgiBean == null) {
-			return;
-		}
-
-		osgiBean.found(true);
-
-		final Annotated annotated = pb.getAnnotated();
-
-		try {
-			List<String> serviceTypes = Annotates.serviceClassNames(annotated);
-			Map<String, Object> componentProperties = Annotates.componentProperties(annotated);
-			ServiceScope serviceScope = Annotates.serviceScope(annotated);
-
-			if (annotated.isAnnotationPresent(SingleComponent.class)) {
-				doSingleComponent(osgiBean, declaringClass, annotated, pb.getBean(), serviceTypes, serviceScope, componentProperties);
-			}
-			else if (annotated.isAnnotationPresent(FactoryComponent.class)) {
-				doFactoryComponent(osgiBean, declaringClass, annotated, pb.getBean(), serviceTypes, serviceScope, componentProperties);
-			}
-			else if (annotated.isAnnotationPresent(ComponentScoped.class)) {
-				// Explicitly ignore this case
-			}
-			else {
-				doContainerBean(osgiBean, declaringClass, annotated, pb, pb.getBean().getScope(), serviceTypes, serviceScope, componentProperties);
-			}
-		}
-		catch (Exception e) {
-			pb.addDefinitionError(e);
-		}
-	}
-
-	void afterBeanDiscovery(@Observes AfterBeanDiscovery abd, BeanManager beanManager) {
-		_containerState.containerDTO().template.components.stream().filter(
-			template -> template.type != ComponentType.CONTAINER
-		).map(
-			template -> (ExtendedComponentTemplateDTO)template
-		).forEach(
-			template -> {
-				Set<Bean<?>> visited = new HashSet<>();
-				scanComponentBean(template, template.bean, beanManager, visited);
-			}
-		);
-
-		_beansModel.getOSGiBeans().stream().forEach(
-			osgiBean -> {
-				if (!osgiBean.found()) {
-					abd.addDefinitionError(
-						new DefinitionException(
-							String.format(
-								"Did not find bean for %s",
-								osgiBean.getBeanClass())));
-				}
-			}
-		);
-	}
-
-	void doComponentProperties(OSGiBean osgiBean, Class<?> declaringClass, InjectionPoint injectionPoint) {
-		try {
-			ComponentPropertiesModel configurationModel = new ComponentPropertiesModel.Builder(
-				injectionPoint.getType()
-			).declaringClass(
-				declaringClass
-			).injectionPoint(
-				injectionPoint
-			).build();
-
-			osgiBean.addConfiguration(_containerState, configurationModel.toDTO());
-		}
-		catch (Exception e) {
-			_containerState.error(e);
-		}
-	}
-
-	void doContainerBean(OSGiBean osgiBean, Class<?> declaringClass, Annotated annotated, ProcessBean<?> pb, Class<? extends Annotation> scope, List<String> serviceTypeNames, ServiceScope serviceScope, Map<String, Object> componentProperties) {
-		String className = declaringClass.getName();
-
-		if (!_containerTemplate.beans.contains(className)) {
-			_containerTemplate.beans.add(className);
-		}
-
-		if (!serviceTypeNames.isEmpty()) {
-			if (!scope.equals(ApplicationScoped.class) &&
-				!scope.equals(Dependent.class)) {
-
-				pb.addDefinitionError(
-					new IllegalStateException(
-						String.format(
-							"@Service can only be used on @ApplicationScoped, @Dependent, @SingleComponent, and @FactoryComponent: %s",
-							pb.getBean())));
-				return;
-			}
-
-			ExtendedActivationTemplateDTO activationTemplate = new ExtendedActivationTemplateDTO();
-			activationTemplate.cdiScope = scope;
-			activationTemplate.declaringClass = declaringClass;
-			if (pb instanceof ProcessProducerField) {
-				activationTemplate.producer = ((ProcessProducerField<?, ?>) pb).getAnnotatedProducerField();
-			}
-			else if (pb instanceof ProcessProducerMethod) {
-				activationTemplate.producer = ((ProcessProducerMethod<?, ?>) pb).getAnnotatedProducerMethod();
-			}
-			activationTemplate.properties = componentProperties;
-			activationTemplate.scope = serviceScope;
-			activationTemplate.serviceClasses = serviceTypeNames;
-
-			_containerTemplate.activations.add(activationTemplate);
-		}
-
-		osgiBean.setComponent(_containerState, _containerTemplate);
-	}
-
-	void doFactoryComponent(OSGiBean osgiBean, Class<?> declaringClass, Annotated annotated, Bean<?> bean, List<String> serviceTypeNames, ServiceScope serviceScope, Map<String, Object> componentProperties) {
-		ExtendedComponentTemplateDTO componentTemplate = new ExtendedComponentTemplateDTO();
-		componentTemplate.activations = new CopyOnWriteArrayList<>();
-
-		ExtendedActivationTemplateDTO activationTemplate = new ExtendedActivationTemplateDTO();
-		activationTemplate.declaringClass = declaringClass;
-		activationTemplate.properties = Collections.emptyMap();
-		activationTemplate.scope = serviceScope;
-		activationTemplate.serviceClasses = serviceTypeNames;
-
-		componentTemplate.activations.add(activationTemplate);
-
-		componentTemplate.bean = bean;
-		componentTemplate.beans = new CopyOnWriteArrayList<>();
-		componentTemplate.configurations = new CopyOnWriteArrayList<>();
-		componentTemplate.name = bean.getName();
-		componentTemplate.properties = componentProperties;
-		componentTemplate.references = new CopyOnWriteArrayList<>();
-		componentTemplate.type = ComponentType.FACTORY;
-
-		annotated.getAnnotations(PID.class).stream().forEach(
-			PID -> {
-				ExtendedConfigurationTemplateDTO configurationTemplate = new ExtendedConfigurationTemplateDTO();
-
-				configurationTemplate.declaringClass = declaringClass;
-				configurationTemplate.maximumCardinality = MaximumCardinality.ONE;
-				configurationTemplate.pid = Optional.of(PID.value()).map(
-					s -> {
-						if (s.equals("$") || s.equals("")) {
-							return componentTemplate.name;
-						}
-						return s;
-					}
-				).orElse(componentTemplate.name);
-
-				configurationTemplate.policy = PID.policy();
-
-				componentTemplate.configurations.add(configurationTemplate);
-			}
-		);
-
-		ExtendedConfigurationTemplateDTO configurationTemplate = new ExtendedConfigurationTemplateDTO();
-
-		configurationTemplate.declaringClass = declaringClass;
-		configurationTemplate.maximumCardinality = MaximumCardinality.MANY;
-		configurationTemplate.pid = Optional.ofNullable(
-			annotated.getAnnotation(FactoryComponent.class)
-		).map(fc -> {
-			if (fc.value().equals("$") || fc.value().equals("")) {
-				return componentTemplate.name;
-			}
-			return fc.value();
-		}).orElse(componentTemplate.name);
-		configurationTemplate.policy = ConfigurationPolicy.REQUIRED;
-
-		componentTemplate.configurations.add(configurationTemplate);
-		componentTemplate.beans.add(declaringClass.getName());
-
-		_containerState.containerDTO().template.components.add(componentTemplate);
-
-		osgiBean.setComponent(_containerState, componentTemplate);
-	}
-
-	void doOther(OSGiBean osgiBean, Class<?> declaringClass, Annotated annotated, InjectionPoint injectionPoint) {
-		Reference reference = annotated.getAnnotation(Reference.class);
-		ComponentProperties componentProperties = annotated.getAnnotation(ComponentProperties.class);
-
-		if (reference != null) {
-			doReference(osgiBean, annotated, injectionPoint, reference, componentProperties);
-		}
-		else if (componentProperties != null) {
-			doComponentProperties(osgiBean, declaringClass, injectionPoint);
-		}
-	}
-
-	void doReference(OSGiBean osgiBean, Annotated annotated, InjectionPoint injectionPoint, Reference reference, ComponentProperties componentProperties) {
-		if (componentProperties != null) {
-			_containerState.error(
-				new IllegalArgumentException(
-					String.format(
-						"Cannot use @Reference and @Configuration on the same injection point {}",
-						injectionPoint))
-			);
-
-			return;
-		}
-
-		Builder builder = null;
-
-		if (annotated instanceof AnnotatedParameter) {
-			builder = new ReferenceModel.Builder((AnnotatedParameter<?>)annotated);
-		}
-		else {
-			builder = new ReferenceModel.Builder((AnnotatedField<?>)annotated);
-		}
-
-		try {
-			ReferenceModel referenceModel = builder.type(injectionPoint.getType()).build();
-
-			osgiBean.addReference(referenceModel.toDTO());
-		}
-		catch (Exception e) {
-			_containerState.error(e);
-		}
-	}
-
-	void doSingleComponent(OSGiBean osgiBean, Class<?> declaringClass, Annotated annotated, Bean<?> bean, List<String> serviceTypes, ServiceScope serviceScope, Map<String, Object> componentProperties) {
-		ExtendedComponentTemplateDTO componentTemplate = new ExtendedComponentTemplateDTO();
-		componentTemplate.activations = new CopyOnWriteArrayList<>();
-
-		ExtendedActivationTemplateDTO activationTemplate = new ExtendedActivationTemplateDTO();
-		activationTemplate.declaringClass = declaringClass;
-		activationTemplate.properties = Collections.emptyMap();
-		activationTemplate.scope = serviceScope;
-		activationTemplate.serviceClasses = serviceTypes;
-
-		componentTemplate.activations.add(activationTemplate);
-
-		componentTemplate.bean = bean;
-		componentTemplate.beans = new CopyOnWriteArrayList<>();
-		componentTemplate.configurations = new CopyOnWriteArrayList<>();
-		componentTemplate.name = bean.getName();
-		componentTemplate.properties = componentProperties;
-		componentTemplate.references = new CopyOnWriteArrayList<>();
-		componentTemplate.type = ComponentType.SINGLE;
-
-		annotated.getAnnotations(PID.class).stream().forEach(
-			PID -> {
-				ExtendedConfigurationTemplateDTO configurationTemplate = new ExtendedConfigurationTemplateDTO();
-
-				configurationTemplate.declaringClass = declaringClass;
-				configurationTemplate.maximumCardinality = MaximumCardinality.ONE;
-				configurationTemplate.pid = Optional.of(PID.value()).map(
-					s -> {
-						if (s.equals("$") || s.equals("")) {
-							return componentTemplate.name;
-						}
-						return s;
-					}
-				).orElse(componentTemplate.name);
-
-				if (PID.value().equals("$") || PID.value().equals("")) {
-					configurationTemplate.pid = componentTemplate.name;
-				}
-				else {
-					configurationTemplate.pid = PID.value();
-				}
-
-				configurationTemplate.policy = PID.policy();
-
-				componentTemplate.configurations.add(configurationTemplate);
-			}
-		);
-
-		if (componentTemplate.configurations.isEmpty()) {
-			ExtendedConfigurationTemplateDTO configurationTemplate = new ExtendedConfigurationTemplateDTO();
-
-			configurationTemplate.declaringClass = declaringClass;
-			configurationTemplate.maximumCardinality = MaximumCardinality.ONE;
-			configurationTemplate.pid = componentTemplate.name;
-			configurationTemplate.policy = ConfigurationPolicy.OPTIONAL;
-
-			componentTemplate.configurations.add(configurationTemplate);
-		}
-
-		componentTemplate.beans.add(declaringClass.getName());
-
-		_containerState.containerDTO().template.components.add(componentTemplate);
-
-		osgiBean.setComponent(_containerState, componentTemplate);
-	}
-
-	void doSpecial(OSGiBean osgiBean, Annotated annotated, Type injectionPointType) {
-		Builder builder = null;
-
-		if (annotated instanceof AnnotatedParameter) {
-			builder = new ReferenceModel.Builder((AnnotatedParameter<?>)annotated);
-		}
-		else {
-			builder = new ReferenceModel.Builder((AnnotatedField<?>)annotated);
-		}
-
-		try {
-			ReferenceModel referenceModel = builder.type(injectionPointType).build();
-
-			osgiBean.addReference(referenceModel.toDTO());
-		}
-		catch (Exception e) {
-			_containerState.error(e);
-		}
-	}
-
-	void scanComponentBean(
-		ExtendedComponentTemplateDTO template,
-		Bean<?> bean,
-		BeanManager beanManager,
-		Set<Bean<?>> visited) {
-
-		if (visited.contains(bean)) {
-			return;
-		}
-
-		visited.add(bean);
-
-		Class<?> beanClass = bean.getBeanClass();
-
-		String className = beanClass.getName();
-
-		OSGiBean osgiBean = _beansModel.getOSGiBean(className);
-
-		ComponentTemplateDTO currentTemplate = osgiBean.getComponent();
-
-		if (currentTemplate == null) {
-			osgiBean.setComponent(_containerState, template);
-		}
-		else if (!currentTemplate.equals(template)) {
-			throw new IllegalStateException("Something is wrong here");
-		}
-
-		if (!template.beans.contains(className)) {
-			template.beans.add(className);
-		}
-
-		for (InjectionPoint injectionPoint : bean.getInjectionPoints()) {
-			if (injectionPoint.getAnnotated().isAnnotationPresent(ComponentProperties.class) ||
-				injectionPoint.getAnnotated().isAnnotationPresent(Reference.class)) {
-
-				continue;
-			}
-
-			Set<Bean<?>> beans = beanManager.getBeans(
-				injectionPoint.getType(),
-				injectionPoint.getQualifiers().toArray(new Annotation[0]));
-
-			Bean<?> next = beanManager.resolve(beans);
-
-			if ((next == null) || next.getScope() != ComponentScoped.class) {
-				continue;
-			}
-
-			scanComponentBean(template, next, beanManager, visited);
-		}
-	}
-
-	private final BeansModel _beansModel;
-	private final ComponentTemplateDTO _containerTemplate;
-	private final ContainerState _containerState;
-
-}
diff --git a/cdi-extender/src/main/java/org/apache/aries/cdi/container/internal/container/MarkedInjectionPoint.java b/cdi-extender/src/main/java/org/apache/aries/cdi/container/internal/container/MarkedInjectionPoint.java
deleted file mode 100644
index 0433f2e..0000000
--- a/cdi-extender/src/main/java/org/apache/aries/cdi/container/internal/container/MarkedInjectionPoint.java
+++ /dev/null
@@ -1,58 +0,0 @@
-/**
- * Licensed 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.aries.cdi.container.internal.container;
-
-import java.lang.annotation.Annotation;
-import java.util.Set;
-import java.util.concurrent.atomic.AtomicInteger;
-
-import javax.enterprise.inject.spi.InjectionPoint;
-
-import org.apache.aries.cdi.container.internal.util.Sets;
-import org.jboss.weld.injection.ForwardingInjectionPoint;
-
-public class MarkedInjectionPoint extends ForwardingInjectionPoint {
-
-	public MarkedInjectionPoint(InjectionPoint injectionPoint) {
-		_delegate = injectionPoint;
-		_mark = Mark.Literal.from(counter.incrementAndGet());
-		_qualifiers = Sets.hashSet(injectionPoint.getQualifiers(), _mark);
-	}
-
-	@Override
-	protected InjectionPoint delegate() {
-		return _delegate;
-	}
-
-	public InjectionPoint getDelegate() {
-		return delegate();
-	}
-
-	public Mark getMark() {
-		return _mark;
-	}
-
-	@Override
-	public Set<Annotation> getQualifiers() {
-		return _qualifiers;
-	}
-
-	private static final AtomicInteger counter = new AtomicInteger();
-
-	private final InjectionPoint _delegate;
-	private final Mark _mark;
-	private final Set<Annotation> _qualifiers;
-
-}
\ No newline at end of file
diff --git a/cdi-extender/src/main/java/org/apache/aries/cdi/container/internal/container/Op.java b/cdi-extender/src/main/java/org/apache/aries/cdi/container/internal/container/Op.java
index 48c0380..5ff43cd 100644
--- a/cdi-extender/src/main/java/org/apache/aries/cdi/container/internal/container/Op.java
+++ b/cdi-extender/src/main/java/org/apache/aries/cdi/container/internal/container/Op.java
@@ -28,7 +28,7 @@
 		CONTAINER_COMPONENT,
 		CONTAINER_FIRE_EVENTS,
 		CONTAINER_INSTANCE,
-		CONTAINER_PUBLISH_SERVICES,
+		CONTAINER_INIT_COMPONENTS,
 		REFERENCES,
 		EXTENSION,
 		FACTORY_ACTIVATOR,
diff --git a/cdi-extender/src/main/java/org/apache/aries/cdi/container/internal/container/RuntimeExtension.java b/cdi-extender/src/main/java/org/apache/aries/cdi/container/internal/container/RuntimeExtension.java
index 51e795e..777ac6a 100644
--- a/cdi-extender/src/main/java/org/apache/aries/cdi/container/internal/container/RuntimeExtension.java
+++ b/cdi-extender/src/main/java/org/apache/aries/cdi/container/internal/container/RuntimeExtension.java
@@ -23,6 +23,7 @@
 import java.util.Map;
 import java.util.Objects;
 import java.util.concurrent.CopyOnWriteArrayList;
+import java.util.concurrent.atomic.AtomicInteger;
 import java.util.stream.Collectors;
 
 import javax.annotation.Priority;
@@ -37,7 +38,6 @@
 import javax.enterprise.inject.spi.AnnotatedField;
 import javax.enterprise.inject.spi.AnnotatedMember;
 import javax.enterprise.inject.spi.AnnotatedMethod;
-import javax.enterprise.inject.spi.AnnotatedParameter;
 import javax.enterprise.inject.spi.Bean;
 import javax.enterprise.inject.spi.BeanManager;
 import javax.enterprise.inject.spi.BeforeBeanDiscovery;
@@ -182,7 +182,9 @@
 
 				for (ActivationTemplateDTO at : _containerTemplate.activations) {
 					ExtendedActivationTemplateDTO extended = (ExtendedActivationTemplateDTO)at;
-					if (extended.declaringClass.equals(declaringClass) && Objects.equals(extended.producer, producer)) {
+					if (extended.declaringClass.equals(declaringClass) &&
+							equals(extended.producer, producer)) {
+
 						activationTemplate = extended;
 						break;
 					}
@@ -224,11 +226,11 @@
 
 		ComponentDTO componentDTO = _containerState.containerDTO().components.get(0);
 
+		registerServices(componentDTO, bm);
+
 		_containerState.submit(
-			Op.of(Mode.OPEN, Type.CONTAINER_PUBLISH_SERVICES, _containerState.id()),
-			() -> registerServices(componentDTO, bm)
-		).then(
-			s -> initComponents()
+			Op.of(Mode.OPEN, Type.CONTAINER_INIT_COMPONENTS, _containerState.id()),
+			this::initComponents
 		).then(s -> {
 			Dictionary<String, Object> properties = new Hashtable<>();
 			properties.put(CDIConstants.CDI_CONTAINER_ID, _containerState.id());
@@ -241,6 +243,8 @@
 
 			registerService(serviceTypes, bm, properties);
 
+			_log.debug(l -> l.debug("CCR Container READY for {}", _containerState.bundle()));
+
 			return s;
 		});
 	}
@@ -288,7 +292,7 @@
 					).findFirst().map(
 						ExtendedReferenceDTO.class::cast
 					).ifPresent(
-						r -> bean.setReferenceDTO(r)
+						bean::setReferenceDTO
 					);
 				}
 
@@ -325,6 +329,18 @@
 		return producerFactory.createProducer(bean);
 	}
 
+	// Objects.equals(producer, producer1) is not expected to work so impl it as expected there
+	private boolean equals(AnnotatedMember<?> producerA, AnnotatedMember<?> producerB) {
+		if ((producerA == null) && (producerB == null)) return true;
+		if (!Objects.equals(producerA.getJavaMember(), producerB.getJavaMember())) {
+			return false;
+		}
+		if (!Objects.equals(producerA.getAnnotations(), producerB.getAnnotations())) {
+			return false;
+		}
+		return true;
+	}
+
 	private Promise<Boolean> initComponents() {
 		_containerState.containerDTO().template.components.stream().filter(
 			t -> t.type != ComponentType.CONTAINER
@@ -364,33 +380,29 @@
 		return _containerState.submit(cl.openOp(), cl::open);
 	}
 
-	private boolean matchConfiguration(OSGiBean osgiBean, ProcessInjectionPoint<?, ?> pip) {
+	private void processConfiguration(OSGiBean osgiBean, ProcessInjectionPoint<?, ?> pip) {
 		InjectionPoint injectionPoint = pip.getInjectionPoint();
 
 		Class<?> declaringClass = Annotates.declaringClass(injectionPoint.getAnnotated());
 
 		ConfigurationTemplateDTO current = new ComponentPropertiesModel.Builder(injectionPoint.getType()).declaringClass(
 			declaringClass
-		).injectionPoint(
-			injectionPoint
+		).qualifiers(
+			injectionPoint.getQualifiers()
 		).build().toDTO();
 
-		return osgiBean.getComponent().configurations.stream().map(
+		osgiBean.getComponent().configurations.stream().map(
 			t -> (ExtendedConfigurationTemplateDTO)t
 		).filter(
 			t -> current.equals(t)
-		).findFirst().map(
+		).findFirst().ifPresent(
 			t -> {
-				MarkedInjectionPoint markedInjectionPoint = new MarkedInjectionPoint(injectionPoint);
+				final Mark mark = Mark.Literal.from(MARK_IP_COUNTER.incrementAndGet());
+				pip.configureInjectionPoint().addQualifiers(mark);
 
-				pip.setInjectionPoint(markedInjectionPoint);
-
-				t.bean.setInjectionPoint(injectionPoint);
-				t.bean.setMark(markedInjectionPoint.getMark());
-
-				return true;
+				t.bean.setMark(mark);
 			}
-		).orElse(false);
+		);
 	}
 
 	private boolean matchReference(OSGiBean osgiBean, ProcessInjectionPoint<?, ?> pip) {
@@ -398,19 +410,9 @@
 
 		Annotated annotated = injectionPoint.getAnnotated();
 
-		ReferenceModel.Builder builder = null;
+		ReferenceModel.Builder builder = new ReferenceModel.Builder(annotated);
 
-		if (annotated instanceof AnnotatedField) {
-			builder = new ReferenceModel.Builder((AnnotatedField<?>)annotated);
-		}
-		else if (annotated instanceof AnnotatedMethod) {
-			builder = new ReferenceModel.Builder((AnnotatedMethod<?>)annotated);
-		}
-		else {
-			builder = new ReferenceModel.Builder((AnnotatedParameter<?>)annotated);
-		}
-
-		ReferenceModel referenceModel = builder.injectionPoint(injectionPoint).build();
+		ReferenceModel referenceModel = builder.type(injectionPoint.getType()).build();
 
 		ExtendedReferenceTemplateDTO current = referenceModel.toDTO();
 
@@ -420,11 +422,10 @@
 			t -> current.equals(t)
 		).findFirst().map(
 			t -> {
-				MarkedInjectionPoint markedInjectionPoint = new MarkedInjectionPoint(injectionPoint);
+				final Mark mark = Mark.Literal.from(MARK_IP_COUNTER.incrementAndGet());
+				pip.configureInjectionPoint().addQualifier(mark);
 
-				pip.setInjectionPoint(markedInjectionPoint);
-
-				t.bean.setMark(markedInjectionPoint.getMark());
+				t.bean.setMark(mark);
 
 				_log.debug(l -> l.debug("CCR maping InjectionPoint {} to reference template {}", injectionPoint, t));
 
@@ -455,7 +456,20 @@
 		}
 
 		if (componentProperties != null) {
-			matchConfiguration(osgiBean, pip);
+			processConfiguration(osgiBean, pip);
+		}
+	}
+
+	private void registerServiceHandleFailure(
+		ExtendedComponentInstanceDTO componentInstance,
+		ExtendedActivationTemplateDTO activationTemplate,
+		BeanManager bm) {
+
+		try {
+			registerService(componentInstance, activationTemplate, bm);
+		}
+		catch (Throwable t) {
+			_log.error("CDI - An error occured", t);
 		}
 	}
 
@@ -559,7 +573,7 @@
 		componentDTO.template.activations.stream().map(
 			ExtendedActivationTemplateDTO.class::cast
 		).forEach(
-			a -> registerService((ExtendedComponentInstanceDTO)componentDTO.instances.get(0), a, bm)
+			a -> registerServiceHandleFailure((ExtendedComponentInstanceDTO)componentDTO.instances.get(0), a, bm)
 		);
 
 		return true;
@@ -574,4 +588,5 @@
 	private final List<ServiceRegistration<?>> _registrations = new CopyOnWriteArrayList<>();
 	private final SingleComponent.Builder _singleBuilder;
 
+	private static final AtomicInteger MARK_IP_COUNTER = new AtomicInteger();
 }
diff --git a/cdi-extender/src/main/java/org/apache/aries/cdi/container/internal/loader/BundleClassLoader.java b/cdi-extender/src/main/java/org/apache/aries/cdi/container/internal/loader/BundleClassLoader.java
index 9246c04..404681a 100644
--- a/cdi-extender/src/main/java/org/apache/aries/cdi/container/internal/loader/BundleClassLoader.java
+++ b/cdi-extender/src/main/java/org/apache/aries/cdi/container/internal/loader/BundleClassLoader.java
@@ -14,32 +14,36 @@
 
 package org.apache.aries.cdi.container.internal.loader;
 
+import static java.util.Objects.requireNonNull;
+
 import java.io.IOException;
 import java.net.URL;
-import java.net.URLClassLoader;
+import java.security.ProtectionDomain;
 import java.util.Collections;
 import java.util.Enumeration;
+import java.util.List;
 import java.util.concurrent.ConcurrentHashMap;
 import java.util.concurrent.ConcurrentMap;
+import java.util.concurrent.CopyOnWriteArrayList;
+import java.util.function.Function;
+import java.util.function.Predicate;
 
+import org.apache.aries.cdi.spi.loader.SpiLoader;
 import org.osgi.framework.Bundle;
 
-public class BundleClassLoader extends URLClassLoader {
+public final class BundleClassLoader extends SpiLoader {
 
-	public BundleClassLoader(Bundle[] bundles) {
-		super(new URL[0]);
-
-		if (bundles.length == 0) {
-			throw new IllegalArgumentException(
-				"At least one bundle is required");
-		}
-
-		_bundles = bundles;
+	public BundleClassLoader(Bundle cdiBundle, Bundle extenderBundle) {
+		_bundles.add(requireNonNull(cdiBundle));
+		_bundles.add(requireNonNull(extenderBundle));
 	}
 
 	@Override
 	public URL findResource(String name) {
 		for (Bundle bundle : _bundles) {
+			if ((bundle.getState() & Bundle.UNINSTALLED) == Bundle.UNINSTALLED) {
+				continue;
+			}
 			URL url = bundle.getResource(name);
 
 			if (url != null) {
@@ -53,6 +57,9 @@
 	@Override
 	public Enumeration<URL> findResources(String name) {
 		for (Bundle bundle : _bundles) {
+			if ((bundle.getState() & Bundle.UNINSTALLED) == Bundle.UNINSTALLED) {
+				continue;
+			}
 			try {
 				Enumeration<URL> enumeration = bundle.getResources(name);
 
@@ -62,12 +69,17 @@
 			}
 			catch (IOException ioe) {
 			}
+
+			if (resourcePredicate != null && resourcePredicate.test(name)) {
+				return resourceFunction.apply(name);
+			}
 		}
 
 		return Collections.emptyEnumeration();
 	}
 
-	public Bundle[] getBundles() {
+	@Override
+	public List<Bundle> getBundles() {
 		return _bundles;
 	}
 
@@ -82,11 +94,34 @@
 	}
 
 	@Override
+	public BundleClassLoader handleResources(
+		Predicate<String> predicate, Function<String, Enumeration<URL>> function) {
+
+		resourcePredicate = requireNonNull(predicate);
+		resourceFunction = requireNonNull(function);
+
+		return this;
+	}
+
+	@Override
+	public BundleClassLoader findClass(
+		Predicate<String> predicate, Function<String, Class<?>> function) {
+
+		classPredicate = requireNonNull(predicate);
+		classFunction = requireNonNull(function);
+
+		return this;
+	}
+
+	@Override
 	protected Class<?> findClass(String name) throws ClassNotFoundException {
 		Object classLoadingLock = getClassLoadingLock(name);
 
 		synchronized (classLoadingLock) {
 			for (Bundle bundle : _bundles) {
+				if ((bundle.getState() & Bundle.UNINSTALLED) == Bundle.UNINSTALLED) {
+					continue;
+				}
 				try {
 					return bundle.loadClass(name);
 				}
@@ -95,6 +130,10 @@
 				}
 			}
 
+			if (classPredicate != null && classPredicate.test(name)) {
+				return classFunction.apply(name);
+			}
+
 			throw new ClassNotFoundException(name);
 		}
 	}
@@ -122,7 +161,62 @@
 		}
 	}
 
-	private final Bundle[] _bundles;
+	@Override
+	public Class<?> getOrRegister(final String proxyClassName, final byte[] proxyBytes,
+								final Package pck, final ProtectionDomain protectionDomain) {
+		final String key = proxyClassName.replace('/', '.');
+		Class<?> existing = _cache.get(key);
+		if (existing == null) {
+			Object classLoadingLock = getClassLoadingLock(key);
+			synchronized (classLoadingLock) {
+				existing = _cache.get(key);
+				if (existing == null) {
+					definePackageFor(pck, protectionDomain);
+					existing = super.defineClass(proxyClassName, proxyBytes, 0, proxyBytes.length);
+					resolveClass(existing);
+					_cache.put(key, existing);
+				}
+			}
+		}
+		return existing;
+	}
+
+	private void definePackageFor(final Package model, final ProtectionDomain protectionDomain) {
+		if (model == null) {
+			return;
+		}
+		if (getPackage(model.getName()) == null) {
+			if (model.isSealed() && protectionDomain != null &&
+					protectionDomain.getCodeSource() != null &&
+					protectionDomain.getCodeSource().getLocation() != null) {
+				definePackage(
+						model.getName(),
+						model.getSpecificationTitle(),
+						model.getSpecificationVersion(),
+						model.getSpecificationVendor(),
+						model.getImplementationTitle(),
+						model.getImplementationVersion(),
+						model.getImplementationVendor(),
+						protectionDomain.getCodeSource().getLocation());
+			} else {
+				definePackage(
+						model.getName(),
+						model.getSpecificationTitle(),
+						model.getSpecificationVersion(),
+						model.getSpecificationVendor(),
+						model.getImplementationTitle(),
+						model.getImplementationVersion(),
+						model.getImplementationVendor(),
+						null);
+			}
+		}
+	}
+
+	private final List<Bundle> _bundles = new CopyOnWriteArrayList<>();
 	private final ConcurrentMap<String, Class<?>> _cache = new ConcurrentHashMap<>();
+	private volatile Predicate<String> classPredicate;
+	private volatile Function<String, Class<?>> classFunction;
+	private volatile Function<String, Enumeration<URL>> resourceFunction;
+	private volatile Predicate<String> resourcePredicate;
 
 }
\ No newline at end of file
diff --git a/cdi-extender/src/main/java/org/apache/aries/cdi/container/internal/model/BeansModel.java b/cdi-extender/src/main/java/org/apache/aries/cdi/container/internal/model/BeansModel.java
index 4933d14..f39a5ff 100644
--- a/cdi-extender/src/main/java/org/apache/aries/cdi/container/internal/model/BeansModel.java
+++ b/cdi-extender/src/main/java/org/apache/aries/cdi/container/internal/model/BeansModel.java
@@ -18,9 +18,6 @@
 import java.util.Collection;
 import java.util.Map;
 
-import org.jboss.weld.bootstrap.spi.BeansXml;
-import org.jboss.weld.xml.BeansXmlParser;
-
 public class BeansModel {
 
 	public BeansModel(
@@ -28,22 +25,14 @@
 		Collection<URL> beanDescriptorURLs) {
 
 		_beans = beans;
-
-		BeansXml beansXml = BeansXml.EMPTY_BEANS_XML;
-
-		if (!beanDescriptorURLs.isEmpty()) {
-			BeansXmlParser beansXmlParser = new BeansXmlParser();
-			beansXml = beansXmlParser.parse(beanDescriptorURLs);
-		}
-
-		_beansXml = beansXml;
+		_beansXml = beanDescriptorURLs;
 	}
 
 	public Collection<String> getBeanClassNames() {
 		return _beans.keySet();
 	}
 
-	public BeansXml getBeansXml() {
+	public Collection<URL> getBeansXml() {
 		return _beansXml;
 	}
 
@@ -60,6 +49,6 @@
 	}
 
 	private final Map<String, OSGiBean> _beans;
-	private final BeansXml _beansXml;
+	private final Collection<URL> _beansXml;
 
 }
\ No newline at end of file
diff --git a/cdi-extender/src/main/java/org/apache/aries/cdi/container/internal/model/BeansModelBuilder.java b/cdi-extender/src/main/java/org/apache/aries/cdi/container/internal/model/BeansModelBuilder.java
index 0ec959b..9e8b9c8 100644
--- a/cdi-extender/src/main/java/org/apache/aries/cdi/container/internal/model/BeansModelBuilder.java
+++ b/cdi-extender/src/main/java/org/apache/aries/cdi/container/internal/model/BeansModelBuilder.java
@@ -14,9 +14,8 @@
 
 package org.apache.aries.cdi.container.internal.model;
 
-import static org.apache.aries.cdi.container.internal.util.Reflection.cast;
-import static org.osgi.service.cdi.CDIConstants.REQUIREMENT_BEANS_ATTRIBUTE;
-import static org.osgi.service.cdi.CDIConstants.REQUIREMENT_DESCRIPTOR_ATTRIBUTE;
+import static org.apache.aries.cdi.container.internal.util.Reflection.*;
+import static org.osgi.service.cdi.CDIConstants.*;
 
 import java.net.URL;
 import java.util.ArrayList;
diff --git a/cdi-extender/src/main/java/org/apache/aries/cdi/container/internal/model/ComponentPropertiesModel.java b/cdi-extender/src/main/java/org/apache/aries/cdi/container/internal/model/ComponentPropertiesModel.java
index 8530ca3..2b7deb3 100644
--- a/cdi-extender/src/main/java/org/apache/aries/cdi/container/internal/model/ComponentPropertiesModel.java
+++ b/cdi-extender/src/main/java/org/apache/aries/cdi/container/internal/model/ComponentPropertiesModel.java
@@ -23,12 +23,9 @@
 import java.util.Objects;
 import java.util.Set;
 
-import javax.enterprise.inject.spi.InjectionPoint;
-
 import org.osgi.service.cdi.ConfigurationPolicy;
 import org.osgi.service.cdi.MaximumCardinality;
 import org.osgi.service.cdi.annotations.PID;
-import org.osgi.service.cdi.runtime.dto.template.ConfigurationTemplateDTO;
 
 public class ComponentPropertiesModel {
 
@@ -49,9 +46,9 @@
 			return this;
 		}
 
-		public Builder injectionPoint(InjectionPoint injectionPoint) {
-			_qualifiers = injectionPoint.getQualifiers();
-			_pid = injectionPoint.getAnnotated().getAnnotation(PID.class);
+		public Builder qualifiers(Set<Annotation> qualifiers) {
+			_qualifiers = qualifiers;
+			_pid = _qualifiers.stream().filter(PID.class::isInstance).map(PID.class::cast).findFirst().orElse(null);
 			return this;
 		}
 
@@ -100,7 +97,7 @@
 		return _injectionPointType;
 	}
 
-	public ConfigurationTemplateDTO toDTO() {
+	public ExtendedConfigurationTemplateDTO toDTO() {
 		ExtendedConfigurationTemplateDTO dto = new ExtendedConfigurationTemplateDTO();
 
 		dto.beanClass = _beanClass;
diff --git a/cdi-extender/src/main/java/org/apache/aries/cdi/container/internal/model/ExtendedActivationTemplateDTO.java b/cdi-extender/src/main/java/org/apache/aries/cdi/container/internal/model/ExtendedActivationTemplateDTO.java
index 89cc5d8..887aa12 100644
--- a/cdi-extender/src/main/java/org/apache/aries/cdi/container/internal/model/ExtendedActivationTemplateDTO.java
+++ b/cdi-extender/src/main/java/org/apache/aries/cdi/container/internal/model/ExtendedActivationTemplateDTO.java
@@ -16,6 +16,8 @@
 
 import java.lang.annotation.Annotation;
 
+import javax.enterprise.inject.spi.AnnotatedMember;
+
 import org.osgi.service.cdi.runtime.dto.template.ActivationTemplateDTO;
 
 public class ExtendedActivationTemplateDTO extends ActivationTemplateDTO {
@@ -27,6 +29,6 @@
 
 	public Class<? extends Annotation> cdiScope;
 
-	public Object producer;
+	public AnnotatedMember<?> producer;
 
 }
diff --git a/cdi-extender/src/main/java/org/apache/aries/cdi/container/internal/model/ExtendedComponentTemplateDTO.java b/cdi-extender/src/main/java/org/apache/aries/cdi/container/internal/model/ExtendedComponentTemplateDTO.java
index d150668..506c2e2 100644
--- a/cdi-extender/src/main/java/org/apache/aries/cdi/container/internal/model/ExtendedComponentTemplateDTO.java
+++ b/cdi-extender/src/main/java/org/apache/aries/cdi/container/internal/model/ExtendedComponentTemplateDTO.java
@@ -14,11 +14,15 @@
 
 package org.apache.aries.cdi.container.internal.model;
 
-import javax.enterprise.inject.spi.Bean;
+import java.lang.annotation.Annotation;
+import java.util.Set;
 
 import org.osgi.service.cdi.runtime.dto.template.ComponentTemplateDTO;
 
 public class ExtendedComponentTemplateDTO extends ComponentTemplateDTO {
 
-	public Bean<?> bean;
+	public Class<?> beanClass;
+
+	public Set<Annotation> qualifiers;
+
 }
diff --git a/cdi-extender/src/main/java/org/apache/aries/cdi/container/internal/model/FactoryActivator.java b/cdi-extender/src/main/java/org/apache/aries/cdi/container/internal/model/FactoryActivator.java
index 5853603..d358161 100644
--- a/cdi-extender/src/main/java/org/apache/aries/cdi/container/internal/model/FactoryActivator.java
+++ b/cdi-extender/src/main/java/org/apache/aries/cdi/container/internal/model/FactoryActivator.java
@@ -130,7 +130,7 @@
 			ExtendedComponentTemplateDTO extended = (ExtendedComponentTemplateDTO)_instance.template;
 
 			Set<Bean<?>> beans = beanManager.getBeans(
-				extended.bean.getBeanClass(), extended.bean.getQualifiers().toArray(new Annotation[0]));
+				extended.beanClass, extended.qualifiers.toArray(new Annotation[0]));
 			Bean<? extends Object> bean = beanManager.resolve(beans);
 
 			if (activationTemplate.serviceClasses.isEmpty() /* immediate */) {
diff --git a/cdi-extender/src/main/java/org/apache/aries/cdi/container/internal/model/OSGiBean.java b/cdi-extender/src/main/java/org/apache/aries/cdi/container/internal/model/OSGiBean.java
index cfdd2ff..09c22c5 100644
--- a/cdi-extender/src/main/java/org/apache/aries/cdi/container/internal/model/OSGiBean.java
+++ b/cdi-extender/src/main/java/org/apache/aries/cdi/container/internal/model/OSGiBean.java
@@ -14,8 +14,9 @@
 
 package org.apache.aries.cdi.container.internal.model;
 
+import static java.util.Objects.*;
+
 import java.util.List;
-import java.util.Objects;
 import java.util.concurrent.CopyOnWriteArrayList;
 import java.util.concurrent.atomic.AtomicBoolean;
 
@@ -33,9 +34,8 @@
 	public static class Builder {
 
 		public Builder(Logs logs, Class<?> beanClass) {
-			Objects.requireNonNull(beanClass);
 			_logs = logs;
-			_beanClass = beanClass;
+			_beanClass = requireNonNull(beanClass);
 		}
 
 		public OSGiBean build() {
diff --git a/cdi-extender/src/main/java/org/apache/aries/cdi/container/internal/model/ReferenceModel.java b/cdi-extender/src/main/java/org/apache/aries/cdi/container/internal/model/ReferenceModel.java
index b8f8ca8..df21438 100644
--- a/cdi-extender/src/main/java/org/apache/aries/cdi/container/internal/model/ReferenceModel.java
+++ b/cdi-extender/src/main/java/org/apache/aries/cdi/container/internal/model/ReferenceModel.java
@@ -36,7 +36,6 @@
 import javax.enterprise.inject.spi.AnnotatedField;
 import javax.enterprise.inject.spi.AnnotatedMethod;
 import javax.enterprise.inject.spi.AnnotatedParameter;
-import javax.enterprise.inject.spi.InjectionPoint;
 import javax.inject.Named;
 import javax.inject.Provider;
 import javax.inject.Qualifier;
@@ -62,21 +61,21 @@
 
 	public static class Builder {
 
-		public Builder() {}
-
-		public Builder(AnnotatedField<?> annotated) {
+		public Builder(Annotated annotated) {
 			_annotated = annotated;
-			_declaringClass = annotated.getDeclaringType().getJavaClass();
-		}
 
-		public Builder(AnnotatedMethod<?> annotated) {
-			_annotated = annotated;
-			_declaringClass = annotated.getDeclaringType().getJavaClass();
-		}
+			if (_annotated instanceof AnnotatedParameter) {
+				AnnotatedParameter<?> parameter = (AnnotatedParameter<?>)_annotated;
 
-		public Builder(AnnotatedParameter<?> annotated) {
-			_annotated = annotated;
-			_declaringClass = annotated.getDeclaringCallable().getDeclaringType().getJavaClass();
+				_declaringClass = parameter.getDeclaringCallable().getDeclaringType().getJavaClass();
+			}
+			else if ((_annotated instanceof AnnotatedField) ||
+					(_annotated instanceof AnnotatedMethod)) {
+
+				AnnotatedField<?> field = (AnnotatedField<?>)_annotated;
+
+				_declaringClass = field.getDeclaringType().getJavaClass();
+			}
 		}
 
 		public ReferenceModel build() {
@@ -86,24 +85,6 @@
 			return new ReferenceModel(_type, _declaringClass, _annotated);
 		}
 
-		public Builder injectionPoint(InjectionPoint injectionPoint) {
-			_annotated = injectionPoint.getAnnotated();
-			_type = injectionPoint.getType();
-
-			if (_annotated instanceof AnnotatedParameter) {
-				AnnotatedParameter<?> parameter = (AnnotatedParameter<?>)_annotated;
-
-				_declaringClass = parameter.getDeclaringCallable().getDeclaringType().getJavaClass();
-			}
-			else if (_annotated instanceof AnnotatedField) {
-				AnnotatedField<?> field = (AnnotatedField<?>)_annotated;
-
-				_declaringClass = field.getDeclaringType().getJavaClass();
-			}
-
-			return this;
-		}
-
 		public Builder type(Type type) {
 			_type = type;
 			return this;
diff --git a/cdi-extender/src/main/java/org/apache/aries/cdi/container/internal/model/SingleActivator.java b/cdi-extender/src/main/java/org/apache/aries/cdi/container/internal/model/SingleActivator.java
index 0acd76b..a59d5a3 100644
--- a/cdi-extender/src/main/java/org/apache/aries/cdi/container/internal/model/SingleActivator.java
+++ b/cdi-extender/src/main/java/org/apache/aries/cdi/container/internal/model/SingleActivator.java
@@ -131,7 +131,7 @@
 			ExtendedComponentTemplateDTO extended = (ExtendedComponentTemplateDTO)_instance.template;
 
 			Set<Bean<?>> beans = beanManager.getBeans(
-				extended.bean.getBeanClass(), extended.bean.getQualifiers().toArray(new Annotation[0]));
+				extended.beanClass, extended.qualifiers.toArray(new Annotation[0]));
 			Bean<? extends Object> bean = beanManager.resolve(beans);
 
 			if (activationTemplate.serviceClasses.isEmpty() /* immediate */) {
diff --git a/cdi-extender/src/main/java/org/apache/aries/cdi/container/internal/provider/CDIProvider.java b/cdi-extender/src/main/java/org/apache/aries/cdi/container/internal/provider/CDIProvider.java
index c350c0c..dc3b430 100644
--- a/cdi-extender/src/main/java/org/apache/aries/cdi/container/internal/provider/CDIProvider.java
+++ b/cdi-extender/src/main/java/org/apache/aries/cdi/container/internal/provider/CDIProvider.java
@@ -14,19 +14,21 @@
 
 package org.apache.aries.cdi.container.internal.provider;
 
+import static java.util.Optional.ofNullable;
+
 import java.lang.annotation.Annotation;
+import java.util.Arrays;
 import java.util.Collections;
 import java.util.Iterator;
-import java.util.Optional;
 
 import javax.enterprise.inject.Instance;
 import javax.enterprise.inject.spi.BeanManager;
 import javax.enterprise.inject.spi.CDI;
 import javax.enterprise.util.TypeLiteral;
 
-import org.apache.aries.cdi.container.internal.Activator;
 import org.osgi.framework.Bundle;
 import org.osgi.framework.BundleReference;
+import org.osgi.framework.Constants;
 
 public class CDIProvider implements javax.enterprise.inject.spi.CDIProvider {
 
@@ -44,22 +46,24 @@
 
 		@Override
 		public BeanManager getBeanManager() {
-			ClassLoader contextClassLoader = Thread.currentThread().getContextClassLoader();
+			Bundle bundle = ofNullable(
+				Thread.currentThread().getContextClassLoader()
+			).map(BundleReference.class::cast).map(BundleReference::getBundle).orElseThrow(
+				() -> new IllegalStateException(
+					"No Bundle found for Thread.ContextClassLoader " + Thread.currentThread())
+			);
 
-			if (contextClassLoader instanceof BundleReference) {
-				BundleReference br = (BundleReference)contextClassLoader;
-
-				Bundle bundle = br.getBundle();
-
-				return Optional.ofNullable(
-					Activator.ccr.getContainerState(bundle)
-				).map(
-					cs -> cs.beanManager()
-				).orElse(null);
-			}
-
-			throw new IllegalStateException(
-				"This method can only be used when the Thread context class loader has been set to a Bundle's classloader.");
+			return Arrays.stream(bundle.getRegisteredServices()).filter(
+				sr -> ofNullable(
+					sr.getProperty(Constants.OBJECTCLASS)
+				).map(String[].class::cast).map(Arrays::asList).filter(
+					list -> list.contains(BeanManager.class.getName())
+				).isPresent()
+			).findFirst().map(
+				bundle.getBundleContext()::getService
+			).map(BeanManager.class::cast).orElseThrow(
+				() -> new IllegalStateException("No BeanManager service for bundle " + bundle)
+			);
 		}
 
 		@Override
diff --git a/cdi-extender/src/main/java/org/apache/aries/cdi/container/internal/spi/ContainerListener.java b/cdi-extender/src/main/java/org/apache/aries/cdi/container/internal/spi/ContainerListener.java
new file mode 100644
index 0000000..c77f82e
--- /dev/null
+++ b/cdi-extender/src/main/java/org/apache/aries/cdi/container/internal/spi/ContainerListener.java
@@ -0,0 +1,21 @@
+/**
+ * Licensed 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.aries.cdi.container.internal.spi;
+
+public interface ContainerListener {
+    void onStartSuccess();
+    void onStartError(Throwable error);
+    void onStopSuccess();
+    void onStopError(Throwable error);
+}
diff --git a/cdi-extender/src/main/java/org/apache/aries/cdi/container/internal/util/Annotates.java b/cdi-extender/src/main/java/org/apache/aries/cdi/container/internal/util/Annotates.java
index cf78a5c..93da73a 100644
--- a/cdi-extender/src/main/java/org/apache/aries/cdi/container/internal/util/Annotates.java
+++ b/cdi-extender/src/main/java/org/apache/aries/cdi/container/internal/util/Annotates.java
@@ -14,16 +14,24 @@
 
 package org.apache.aries.cdi.container.internal.util;
 
+import static org.apache.aries.cdi.container.internal.util.Reflection.getRawType;
+
+import java.lang.annotation.Annotation;
 import java.lang.reflect.Executable;
 import java.lang.reflect.Parameter;
 import java.lang.reflect.Type;
 import java.util.ArrayList;
 import java.util.Arrays;
+import java.util.Collection;
 import java.util.List;
 import java.util.Map;
 import java.util.Optional;
+import java.util.Set;
+import java.util.function.Predicate;
 import java.util.stream.Collectors;
 
+import javax.enterprise.context.Dependent;
+import javax.enterprise.context.NormalScope;
 import javax.enterprise.inject.spi.Annotated;
 import javax.enterprise.inject.spi.AnnotatedField;
 import javax.enterprise.inject.spi.AnnotatedMember;
@@ -36,8 +44,10 @@
 import javax.enterprise.inject.spi.ProcessProducerMethod;
 import javax.enterprise.inject.spi.ProcessSessionBean;
 import javax.enterprise.inject.spi.ProcessSyntheticBean;
+import javax.inject.Named;
+import javax.inject.Qualifier;
+import javax.inject.Scope;
 
-import org.jboss.weld.util.Types;
 import org.osgi.service.cdi.ServiceScope;
 import org.osgi.service.cdi.annotations.Service;
 import org.osgi.service.cdi.annotations.ServiceInstance;
@@ -48,6 +58,14 @@
 		// no instances
 	}
 
+	private static final Predicate<Annotation> isQualifier = annotation ->
+		!annotation.annotationType().equals(Qualifier.class) &&
+		annotation.annotationType().isAnnotationPresent(Qualifier.class);
+
+	private static final Predicate<Annotation> isScope = annotation ->
+		annotation.annotationType().isAnnotationPresent(Scope.class) ||
+		annotation.annotationType().isAnnotationPresent(NormalScope.class);
+
 	public static Map<String, Object> componentProperties(Annotated annotated) {
 		return Maps.merge(annotated.getAnnotations());
 	}
@@ -77,8 +95,7 @@
 		}
 		else if (instance instanceof Annotated) {
 			Annotated annotated = (Annotated)instance;
-
-			declaringClass = Types.getRawTypes(new Type[] {annotated.getBaseType()})[0];
+			declaringClass = getRawType(annotated.getBaseType());
 		}
 		else if (instance instanceof ProcessManagedBean) {
 			ProcessManagedBean<?> bean = (ProcessManagedBean<?>)instance;
@@ -114,6 +131,31 @@
 		return (Class<X>)declaringClass;
 	}
 
+	public static Set<Annotation> qualifiers(Annotated annotated) {
+		return collect(annotated.getAnnotations()).stream().filter(isQualifier).collect(Collectors.toSet());
+	}
+
+	private static List<Annotation> collect(Collection<Annotation> annotations) {
+		List<Annotation> list = new ArrayList<>();
+		for (Annotation a1 : annotations) {
+			if (a1.annotationType().getName().startsWith("java.lang.annotation.")) continue;
+			list.add(a1);
+		}
+		list.addAll(inherit(list));
+		return list;
+	}
+
+	private static List<Annotation> inherit(Collection<Annotation> annotations) {
+		List<Annotation> list = new ArrayList<>();
+		for (Annotation a1 : annotations) {
+			for (Annotation a2 : collect(Arrays.asList(a1.annotationType().getAnnotations()))) {
+				if (list.contains(a2)) continue;
+				list.add(a2);
+			}
+		}
+		return list;
+	}
+
 	public static List<Class<?>> serviceClasses(Annotated annotated) {
 		List<Class<?>> serviceTypes = new ArrayList<>();
 
@@ -214,9 +256,7 @@
 	}
 
 	public static List<String> serviceClassNames(Annotated annotated) {
-		return serviceClasses(annotated).stream().map(
-			st -> st.getName()
-		).sorted().collect(Collectors.toList());
+		return serviceClasses(annotated).stream().map(Class::getName).sorted().collect(Collectors.toList());
 	}
 
 	public static ServiceScope serviceScope(Annotated annotated) {
@@ -229,4 +269,43 @@
 		return ServiceScope.SINGLETON;
 	}
 
+	public static String beanName(Annotated annotated) {
+		return collect(annotated.getAnnotations()).stream().filter(Named.class::isInstance).map(Named.class::cast).findFirst().map(
+			named -> {
+				if (named.value().isEmpty()) {
+					if (annotated instanceof AnnotatedMethod) {
+						AnnotatedMethod<?> annotatedMethod = (AnnotatedMethod<?>)annotated;
+						String name = annotatedMethod.getJavaMember().getName();
+						if (name.startsWith("get")) {
+							name = name.substring(3);
+						}
+						else if (name.startsWith("is")) {
+							name = name.substring(2);
+						}
+						char c[] = name.toCharArray();
+						c[0] = Character.toLowerCase(c[0]);
+						return new String(c);
+					}
+					else if (annotated instanceof AnnotatedField) {
+						AnnotatedField<?> annotatedField = (AnnotatedField<?>)annotated;
+						return annotatedField.getJavaMember().getName();
+					}
+					else {
+						char c[] = Reflection.getRawType(annotated.getBaseType()).getSimpleName().toCharArray();
+						c[0] = Character.toLowerCase(c[0]);
+						return new String(c);
+					}
+				}
+
+				return named.value();
+			}
+		).orElse(null);
+	}
+
+	public static Class<? extends Annotation> beanScope(Annotated annotated) {
+		Class<? extends Annotation> scope = collect(annotated.getAnnotations()).stream().filter(isScope).map(Annotation::annotationType).findFirst().orElse(null);
+
+		return (scope == null) ? Dependent.class : scope;
+	}
+
 }
\ No newline at end of file
diff --git a/cdi-extender/src/main/java/org/apache/aries/cdi/container/internal/util/Maps.java b/cdi-extender/src/main/java/org/apache/aries/cdi/container/internal/util/Maps.java
index ca61323..5b457a0 100644
--- a/cdi-extender/src/main/java/org/apache/aries/cdi/container/internal/util/Maps.java
+++ b/cdi-extender/src/main/java/org/apache/aries/cdi/container/internal/util/Maps.java
@@ -14,19 +14,23 @@
 
 package org.apache.aries.cdi.container.internal.util;
 
+import static java.util.Collections.list;
+import static java.util.Objects.requireNonNull;
+
 import java.lang.annotation.Annotation;
+import java.util.AbstractMap;
 import java.util.ArrayList;
+import java.util.Arrays;
 import java.util.Collection;
 import java.util.Collections;
 import java.util.Dictionary;
-import java.util.Enumeration;
 import java.util.HashMap;
 import java.util.Hashtable;
 import java.util.List;
 import java.util.Map;
-import java.util.Map.Entry;
 import java.util.Objects;
 import java.util.stream.Collectors;
+import java.util.stream.Stream;
 
 import org.osgi.service.cdi.annotations.BeanPropertyType;
 import org.osgi.util.converter.TypeReference;
@@ -51,13 +55,14 @@
 		}
 	}
 
+	public static <T> Stream<Map.Entry<String, T>> streamOf(Dictionary<String, T> dictionary) {
+		return list(dictionary.keys()).stream().map(key -> new AbstractMap.SimpleEntry<>(key, dictionary.get(key)));
+	}
+
 	public static Map<String, Object> of(Dictionary<String, ?> dict) {
 		Map<String, Object> map = new HashMap<>();
 
-		for (Enumeration<String> enu = dict.keys(); enu.hasMoreElements();) {
-			String key = enu.nextElement();
-			map.put(key, dict.get(key));
-		}
+		streamOf(dict).forEach(e -> map.put(e.getKey(), e.getValue()));
 
 		return map;
 	}
@@ -65,11 +70,7 @@
 	public static Dictionary<String, ?> dict(Map<String, Object> map) {
 		Dictionary<String, Object> dict = new Hashtable<>();
 
-		if (map != null) {
-			for (Entry<String, Object> entry : map.entrySet()) {
-				dict.put(entry.getKey(), entry.getValue());
-			}
-		}
+		requireNonNull(map).forEach(dict::put);
 
 		return dict;
 	}
@@ -100,15 +101,28 @@
 	}
 
 	public static Map<String, Object> merge(Collection<Annotation> annotations) {
-		return annotations.stream().filter(
+		return merge(annotations.stream().filter(
 			ann -> Objects.nonNull(ann.annotationType().getAnnotation(BeanPropertyType.class))
 		).map(
 			ann -> Conversions.convert(ann).sourceAs(ann.annotationType()).to(new TypeReference<Map<String, Object>>() {})
-		).map(Map::entrySet).flatMap(Collection::stream).collect(
+		).map(Map::entrySet).flatMap(Collection::stream));
+	}
+
+	public static Map<String, Object> merge(List<Dictionary<String, Object>> dictionaries) {
+		return merge(dictionaries.stream().flatMap(Maps::streamOf));
+	}
+
+	@SafeVarargs
+	public static Map<String, Object> merge(Map<String, Object>... maps) {
+		return merge(Arrays.stream(maps).map(Map::entrySet).flatMap(Collection::stream));
+	}
+
+	public static Map<String, Object> merge(Stream<Map.Entry<String, Object>> mapEntries) {
+		return mapEntries.collect(
 			Collectors.toMap(
 				Map.Entry::getKey,
 				Map.Entry::getValue,
-				Maps::merge
+				Maps::mergeValues
 			)
 		);
 	}
@@ -122,10 +136,11 @@
 		);
 	}
 
-	@SuppressWarnings({ "rawtypes", "unchecked" })
-	public static List<?> merge(Object a, Object b) {
+	@SuppressWarnings("unchecked")
+	public static List<?> mergeValues(Object a, Object b) {
 		List<?> aList = Conversions.convert(a).to(new TypeReference<List<?>>() {});
 		List<?> bList = Conversions.convert(b).to(new TypeReference<List<?>>() {});
+		@SuppressWarnings({ "rawtypes" })
 		List checkedList = Collections.checkedList(new ArrayList(), aList.get(0).getClass());
 		checkedList.addAll(aList);
 		checkedList.addAll(bList);
diff --git a/cdi-extender/src/main/java/org/apache/aries/cdi/container/internal/util/Reflection.java b/cdi-extender/src/main/java/org/apache/aries/cdi/container/internal/util/Reflection.java
index ac2789e..ae03c79 100644
--- a/cdi-extender/src/main/java/org/apache/aries/cdi/container/internal/util/Reflection.java
+++ b/cdi-extender/src/main/java/org/apache/aries/cdi/container/internal/util/Reflection.java
@@ -14,15 +14,102 @@
 
 package org.apache.aries.cdi.container.internal.util;
 
+import java.lang.reflect.Array;
+import java.lang.reflect.Constructor;
+import java.lang.reflect.Field;
+import java.lang.reflect.GenericArrayType;
+import java.lang.reflect.Method;
+import java.lang.reflect.ParameterizedType;
+import java.lang.reflect.Type;
+import java.lang.reflect.TypeVariable;
+import java.lang.reflect.WildcardType;
+import java.util.Arrays;
+import java.util.HashSet;
+import java.util.Set;
+import java.util.stream.Stream;
+
 public class Reflection {
 
 	private Reflection() {
 		// no instances
 	}
 
+	public static Stream<Constructor<?>> allConstructors(Class<?> declaringClass) {
+		Set<Constructor<?>> allconstructors = new HashSet<>();
+		allconstructors.addAll(Arrays.asList(declaringClass.getConstructors()));
+		allconstructors.addAll(Arrays.asList(declaringClass.getDeclaredConstructors()));
+		return allconstructors.stream().distinct();
+	}
+
+	public static Stream<Field> allFields(Class<?> declaringClass) {
+		Set<Field> allfields = new HashSet<>();
+		allfields.addAll(Arrays.asList(declaringClass.getFields()));
+		allfields.addAll(Arrays.asList(declaringClass.getDeclaredFields()));
+		return allfields.stream().distinct();
+	}
+
+	public static Stream<Method> allMethods(Class<?> declaringClass) {
+		Set<Method> allmethods = new HashSet<>();
+		allmethods.addAll(Arrays.asList(declaringClass.getMethods()));
+		allmethods.addAll(Arrays.asList(declaringClass.getDeclaredMethods()));
+		return allmethods.stream().distinct();
+	}
+
 	@SuppressWarnings("unchecked")
 	public static <T> T cast(Object obj) {
 		return (T) obj;
 	}
 
+	public static Set<Type> getTypes(Type type) {
+		Set<Type> types = new HashSet<>();
+		types.add(type);
+		Class<?> rawType = getRawType(type);
+		if (rawType != null) {
+			for (Type iface : rawType.getGenericInterfaces()) {
+				types.addAll(getTypes(iface));
+			}
+			types.addAll(getTypes(rawType.getGenericSuperclass()));
+		}
+		types.remove(java.io.Serializable.class);
+		return types;
+	}
+
+	@SuppressWarnings("unchecked")
+	public static <T> Class<T> getRawType(Type type) {
+		if (type instanceof Class<?>) {
+			return (Class<T>) type;
+		}
+		if (type instanceof ParameterizedType) {
+			if (((ParameterizedType) type).getRawType() instanceof Class<?>) {
+				return (Class<T>) ((ParameterizedType) type).getRawType();
+			}
+		}
+		if (type instanceof TypeVariable<?>) {
+			TypeVariable<?> variable = (TypeVariable<?>) type;
+			Type[] bounds = variable.getBounds();
+			return getBound(bounds);
+		}
+		if (type instanceof WildcardType) {
+			WildcardType wildcard = (WildcardType) type;
+			return getBound(wildcard.getUpperBounds());
+		}
+		if (type instanceof GenericArrayType) {
+			GenericArrayType genericArrayType = (GenericArrayType) type;
+			Class<?> rawType = getRawType(genericArrayType.getGenericComponentType());
+			if (rawType != null) {
+				return (Class<T>) Array.newInstance(rawType, 0).getClass();
+			}
+		}
+		return null;
+	}
+
+	@SuppressWarnings("unchecked")
+	static <T> Class<T> getBound(Type[] bounds) {
+		if (bounds.length == 0) {
+			return (Class<T>) Object.class;
+		} else {
+			return getRawType(bounds[0]);
+		}
+	}
+
 }
diff --git a/cdi-extender/src/main/java/org/apache/aries/cdi/container/package-info.java b/cdi-extender/src/main/java/org/apache/aries/cdi/container/package-info.java
index fbc8be2..55ede24 100644
--- a/cdi-extender/src/main/java/org/apache/aries/cdi/container/package-info.java
+++ b/cdi-extender/src/main/java/org/apache/aries/cdi/container/package-info.java
@@ -60,7 +60,7 @@
 	}
 )
 @Capability(
-	attribute = "register:=javax.enterprise.inject.se.SeContainerInitializer",
+	attribute = "register:=org.apache.aries.cdi.container.internal.provider.SeContainerInitializer",
 	namespace = "osgi.serviceloader",
 	name = "javax.enterprise.inject.se.SeContainerInitializer",
 	uses = {
@@ -69,7 +69,7 @@
 	}
 )
 @Capability(
-	attribute = "register:=javax.enterprise.inject.spi.CDIProvider",
+	attribute = "register:=org.apache.aries.cdi.container.internal.provider.CDIProvider",
 	namespace = "osgi.serviceloader",
 	name = "javax.enterprise.inject.spi.CDIProvider",
 	uses = {
@@ -82,6 +82,11 @@
 	namespace = ExtenderNamespace.EXTENDER_NAMESPACE,
 	name = "osgi.serviceloader.registrar"
 )
+@Requirement(
+	namespace = ServiceNamespace.SERVICE_NAMESPACE,
+	filter = "(objectClass=org.apache.aries.cdi.spi.CDIContainerInitializer)",
+	effective = "active"
+)
 package org.apache.aries.cdi.container;
 
 import org.osgi.annotation.bundle.Capability;
diff --git a/cdi-extender/src/test/java/org/apache/aries/cdi/container/internal/model/ReferenceModel_BeanServiceObjectsTest.java b/cdi-extender/src/test/java/org/apache/aries/cdi/container/internal/model/ReferenceModel_BeanServiceObjectsTest.java
index d3236f8..2ee2ad3 100644
--- a/cdi-extender/src/test/java/org/apache/aries/cdi/container/internal/model/ReferenceModel_BeanServiceObjectsTest.java
+++ b/cdi-extender/src/test/java/org/apache/aries/cdi/container/internal/model/ReferenceModel_BeanServiceObjectsTest.java
@@ -45,7 +45,7 @@
 
 		InjectionPoint injectionPoint = new MockInjectionPoint(C.class.getField("m"));
 
-		new ReferenceModel.Builder().injectionPoint(injectionPoint).build();
+		new ReferenceModel.Builder(injectionPoint.getAnnotated()).type(injectionPoint.getType()).build();
 	}
 
 	@Test(expected = IllegalArgumentException.class)
@@ -58,7 +58,7 @@
 
 		InjectionPoint injectionPoint = new MockInjectionPoint(C.class.getField("m"));
 
-		new ReferenceModel.Builder().injectionPoint(injectionPoint).build();
+		new ReferenceModel.Builder(injectionPoint.getAnnotated()).type(injectionPoint.getType()).build();
 	}
 
 	@Test
@@ -75,7 +75,7 @@
 
 		InjectionPoint injectionPoint = new MockInjectionPoint(C.class.getField("m"));
 
-		ReferenceModel referenceModel = new ReferenceModel.Builder().injectionPoint(injectionPoint).build();
+		ReferenceModel referenceModel = new ReferenceModel.Builder(injectionPoint.getAnnotated()).type(injectionPoint.getType()).build();
 
 		assertEquals(BeanServiceObjects.class, referenceModel.getBeanClass());
 		assertEquals(Integer.class, referenceModel.getServiceType());
@@ -102,7 +102,7 @@
 
 		InjectionPoint injectionPoint = new MockInjectionPoint(C.class.getField("m"));
 
-		ReferenceModel referenceModel = new ReferenceModel.Builder().injectionPoint(injectionPoint).build();
+		ReferenceModel referenceModel = new ReferenceModel.Builder(injectionPoint.getAnnotated()).type(injectionPoint.getType()).build();
 
 		assertEquals(BeanServiceObjects.class, referenceModel.getBeanClass());
 		assertEquals(Integer.class, referenceModel.getServiceType());
@@ -127,7 +127,7 @@
 
 		InjectionPoint injectionPoint = new MockInjectionPoint(C.class.getField("m"));
 
-		ReferenceModel referenceModel = new ReferenceModel.Builder().injectionPoint(injectionPoint).build();
+		ReferenceModel referenceModel = new ReferenceModel.Builder(injectionPoint.getAnnotated()).type(injectionPoint.getType()).build();
 
 		assertEquals(BeanServiceObjects.class, referenceModel.getBeanClass());
 		assertEquals(Integer.class, referenceModel.getServiceType());
@@ -152,7 +152,7 @@
 
 		InjectionPoint injectionPoint = new MockInjectionPoint(C.class.getField("m"));
 
-		ReferenceModel referenceModel = new ReferenceModel.Builder().injectionPoint(injectionPoint).build();
+		ReferenceModel referenceModel = new ReferenceModel.Builder(injectionPoint.getAnnotated()).type(injectionPoint.getType()).build();
 
 		assertEquals(BeanServiceObjects.class, referenceModel.getBeanClass());
 		assertEquals(Integer.class, referenceModel.getServiceType());
@@ -173,7 +173,7 @@
 
 		InjectionPoint injectionPoint = new MockInjectionPoint(C.class.getField("m"));
 
-		new ReferenceModel.Builder().injectionPoint(injectionPoint).build();
+		new ReferenceModel.Builder(injectionPoint.getAnnotated()).type(injectionPoint.getType()).build();
 	}
 
 	@Test(expected = IllegalArgumentException.class)
@@ -187,7 +187,7 @@
 
 		InjectionPoint injectionPoint = new MockInjectionPoint(C.class.getField("m"));
 
-		new ReferenceModel.Builder().injectionPoint(injectionPoint).build();
+		new ReferenceModel.Builder(injectionPoint.getAnnotated()).type(injectionPoint.getType()).build();
 	}
 
 	@Test(expected = IllegalArgumentException.class)
@@ -200,7 +200,7 @@
 
 		InjectionPoint injectionPoint = new MockInjectionPoint(C.class.getField("m"));
 
-		new ReferenceModel.Builder().injectionPoint(injectionPoint).build();
+		new ReferenceModel.Builder(injectionPoint.getAnnotated()).type(injectionPoint.getType()).build();
 	}
 
 	@Test
@@ -217,7 +217,7 @@
 
 		InjectionPoint injectionPoint = new MockInjectionPoint(C.class.getField("m"));
 
-		ReferenceModel referenceModel = new ReferenceModel.Builder().injectionPoint(injectionPoint).build();
+		ReferenceModel referenceModel = new ReferenceModel.Builder(injectionPoint.getAnnotated()).type(injectionPoint.getType()).build();
 
 		assertEquals(Collection.class, referenceModel.getBeanClass());
 		assertEquals(Integer.class, referenceModel.getServiceType());
@@ -244,7 +244,7 @@
 
 		InjectionPoint injectionPoint = new MockInjectionPoint(C.class.getField("m"));
 
-		ReferenceModel referenceModel = new ReferenceModel.Builder().injectionPoint(injectionPoint).build();
+		ReferenceModel referenceModel = new ReferenceModel.Builder(injectionPoint.getAnnotated()).type(injectionPoint.getType()).build();
 
 		assertEquals(Collection.class, referenceModel.getBeanClass());
 		assertEquals(Integer.class, referenceModel.getServiceType());
@@ -268,7 +268,7 @@
 
 		InjectionPoint injectionPoint = new MockInjectionPoint(C.class.getField("m"));
 
-		ReferenceModel referenceModel = new ReferenceModel.Builder().injectionPoint(injectionPoint).build();
+		ReferenceModel referenceModel = new ReferenceModel.Builder(injectionPoint.getAnnotated()).type(injectionPoint.getType()).build();
 
 		assertEquals(Collection.class, referenceModel.getBeanClass());
 		assertEquals(Integer.class, referenceModel.getServiceType());
@@ -294,7 +294,7 @@
 
 		InjectionPoint injectionPoint = new MockInjectionPoint(C.class.getField("m"));
 
-		ReferenceModel referenceModel = new ReferenceModel.Builder().injectionPoint(injectionPoint).build();
+		ReferenceModel referenceModel = new ReferenceModel.Builder(injectionPoint.getAnnotated()).type(injectionPoint.getType()).build();
 
 		assertEquals(Collection.class, referenceModel.getBeanClass());
 		assertEquals(Integer.class, referenceModel.getServiceType());
@@ -315,7 +315,7 @@
 
 		InjectionPoint injectionPoint = new MockInjectionPoint(C.class.getField("m"));
 
-		new ReferenceModel.Builder().injectionPoint(injectionPoint).build();
+		new ReferenceModel.Builder(injectionPoint.getAnnotated()).type(injectionPoint.getType()).build();
 	}
 
 	@Test(expected = IllegalArgumentException.class)
@@ -329,7 +329,7 @@
 
 		InjectionPoint injectionPoint = new MockInjectionPoint(C.class.getField("m"));
 
-		new ReferenceModel.Builder().injectionPoint(injectionPoint).build();
+		new ReferenceModel.Builder(injectionPoint.getAnnotated()).type(injectionPoint.getType()).build();
 	}
 
 	@Test(expected = IllegalArgumentException.class)
@@ -342,7 +342,7 @@
 
 		InjectionPoint injectionPoint = new MockInjectionPoint(C.class.getField("m"));
 
-		new ReferenceModel.Builder().injectionPoint(injectionPoint).build();
+		new ReferenceModel.Builder(injectionPoint.getAnnotated()).type(injectionPoint.getType()).build();
 	}
 
 	@Test
@@ -359,7 +359,7 @@
 
 		InjectionPoint injectionPoint = new MockInjectionPoint(C.class.getField("m"));
 
-		ReferenceModel referenceModel = new ReferenceModel.Builder().injectionPoint(injectionPoint).build();
+		ReferenceModel referenceModel = new ReferenceModel.Builder(injectionPoint.getAnnotated()).type(injectionPoint.getType()).build();
 
 		assertEquals(List.class, referenceModel.getBeanClass());
 		assertEquals(Integer.class, referenceModel.getServiceType());
@@ -386,7 +386,7 @@
 
 		InjectionPoint injectionPoint = new MockInjectionPoint(C.class.getField("m"));
 
-		ReferenceModel referenceModel = new ReferenceModel.Builder().injectionPoint(injectionPoint).build();
+		ReferenceModel referenceModel = new ReferenceModel.Builder(injectionPoint.getAnnotated()).type(injectionPoint.getType()).build();
 
 		assertEquals(List.class, referenceModel.getBeanClass());
 		assertEquals(Integer.class, referenceModel.getServiceType());
@@ -411,7 +411,7 @@
 
 		InjectionPoint injectionPoint = new MockInjectionPoint(C.class.getField("m"));
 
-		ReferenceModel referenceModel = new ReferenceModel.Builder().injectionPoint(injectionPoint).build();
+		ReferenceModel referenceModel = new ReferenceModel.Builder(injectionPoint.getAnnotated()).type(injectionPoint.getType()).build();
 
 		assertEquals(List.class, referenceModel.getBeanClass());
 		assertEquals(Integer.class, referenceModel.getServiceType());
@@ -436,7 +436,7 @@
 
 		InjectionPoint injectionPoint = new MockInjectionPoint(C.class.getField("m"));
 
-		ReferenceModel referenceModel = new ReferenceModel.Builder().injectionPoint(injectionPoint).build();
+		ReferenceModel referenceModel = new ReferenceModel.Builder(injectionPoint.getAnnotated()).type(injectionPoint.getType()).build();
 
 		assertEquals(List.class, referenceModel.getBeanClass());
 		assertEquals(Integer.class, referenceModel.getServiceType());
@@ -457,7 +457,7 @@
 
 		InjectionPoint injectionPoint = new MockInjectionPoint(C.class.getField("m"));
 
-		new ReferenceModel.Builder().injectionPoint(injectionPoint).build();
+		new ReferenceModel.Builder(injectionPoint.getAnnotated()).type(injectionPoint.getType()).build();
 	}
 
 	@Test(expected = IllegalArgumentException.class)
@@ -471,7 +471,7 @@
 
 		InjectionPoint injectionPoint = new MockInjectionPoint(C.class.getField("m"));
 
-		new ReferenceModel.Builder().injectionPoint(injectionPoint).build();
+		new ReferenceModel.Builder(injectionPoint.getAnnotated()).type(injectionPoint.getType()).build();
 	}
 
 	@Test(expected = IllegalArgumentException.class)
@@ -485,7 +485,7 @@
 
 		InjectionPoint injectionPoint = new MockInjectionPoint(C.class.getField("m"));
 
-		new ReferenceModel.Builder().injectionPoint(injectionPoint).build();
+		new ReferenceModel.Builder(injectionPoint.getAnnotated()).type(injectionPoint.getType()).build();
 	}
 
 	///////////////////////////////////////////////////////////////////////////////
@@ -504,7 +504,7 @@
 
 		InjectionPoint injectionPoint = new MockInjectionPoint(C.class.getMethod("set", BeanServiceObjects.class).getParameters()[0]);
 
-		new ReferenceModel.Builder().injectionPoint(injectionPoint).build();
+		new ReferenceModel.Builder(injectionPoint.getAnnotated()).type(injectionPoint.getType()).build();
 	}
 
 	@Test(expected = IllegalArgumentException.class)
@@ -516,7 +516,7 @@
 
 		InjectionPoint injectionPoint = new MockInjectionPoint(C.class.getMethod("set", BeanServiceObjects.class).getParameters()[0]);
 
-		new ReferenceModel.Builder().injectionPoint(injectionPoint).build();
+		new ReferenceModel.Builder(injectionPoint.getAnnotated()).type(injectionPoint.getType()).build();
 	}
 
 	@Test
@@ -532,7 +532,7 @@
 
 		InjectionPoint injectionPoint = new MockInjectionPoint(C.class.getMethod("set", BeanServiceObjects.class).getParameters()[0]);
 
-		ReferenceModel referenceModel = new ReferenceModel.Builder().injectionPoint(injectionPoint).build();
+		ReferenceModel referenceModel = new ReferenceModel.Builder(injectionPoint.getAnnotated()).type(injectionPoint.getType()).build();
 
 		assertEquals(BeanServiceObjects.class, referenceModel.getBeanClass());
 		assertEquals(Integer.class, referenceModel.getServiceType());
@@ -557,7 +557,7 @@
 
 		InjectionPoint injectionPoint = new MockInjectionPoint(C.class.getMethod("set", BeanServiceObjects.class).getParameters()[0]);
 
-		ReferenceModel referenceModel = new ReferenceModel.Builder().injectionPoint(injectionPoint).build();
+		ReferenceModel referenceModel = new ReferenceModel.Builder(injectionPoint.getAnnotated()).type(injectionPoint.getType()).build();
 
 		assertEquals(BeanServiceObjects.class, referenceModel.getBeanClass());
 		assertEquals(Integer.class, referenceModel.getServiceType());
@@ -581,7 +581,7 @@
 
 		InjectionPoint injectionPoint = new MockInjectionPoint(C.class.getMethod("set", BeanServiceObjects.class).getParameters()[0]);
 
-		ReferenceModel referenceModel = new ReferenceModel.Builder().injectionPoint(injectionPoint).build();
+		ReferenceModel referenceModel = new ReferenceModel.Builder(injectionPoint.getAnnotated()).type(injectionPoint.getType()).build();
 
 		assertEquals(BeanServiceObjects.class, referenceModel.getBeanClass());
 		assertEquals(Integer.class, referenceModel.getServiceType());
@@ -605,7 +605,7 @@
 
 		InjectionPoint injectionPoint = new MockInjectionPoint(C.class.getMethod("set", BeanServiceObjects.class).getParameters()[0]);
 
-		ReferenceModel referenceModel = new ReferenceModel.Builder().injectionPoint(injectionPoint).build();
+		ReferenceModel referenceModel = new ReferenceModel.Builder(injectionPoint.getAnnotated()).type(injectionPoint.getType()).build();
 
 		assertEquals(BeanServiceObjects.class, referenceModel.getBeanClass());
 		assertEquals(Integer.class, referenceModel.getServiceType());
@@ -625,7 +625,7 @@
 
 		InjectionPoint injectionPoint = new MockInjectionPoint(C.class.getMethod("set", BeanServiceObjects.class).getParameters()[0]);
 
-		new ReferenceModel.Builder().injectionPoint(injectionPoint).build();
+		new ReferenceModel.Builder(injectionPoint.getAnnotated()).type(injectionPoint.getType()).build();
 	}
 
 	@Test(expected = IllegalArgumentException.class)
@@ -638,7 +638,7 @@
 
 		InjectionPoint injectionPoint = new MockInjectionPoint(C.class.getMethod("set", Collection.class).getParameters()[0]);
 
-		new ReferenceModel.Builder().injectionPoint(injectionPoint).build();
+		new ReferenceModel.Builder(injectionPoint.getAnnotated()).type(injectionPoint.getType()).build();
 	}
 
 	@Test(expected = IllegalArgumentException.class)
@@ -650,7 +650,7 @@
 
 		InjectionPoint injectionPoint = new MockInjectionPoint(C.class.getMethod("set", Collection.class).getParameters()[0]);
 
-		new ReferenceModel.Builder().injectionPoint(injectionPoint).build();
+		new ReferenceModel.Builder(injectionPoint.getAnnotated()).type(injectionPoint.getType()).build();
 	}
 
 	@Test
@@ -666,7 +666,7 @@
 
 		InjectionPoint injectionPoint = new MockInjectionPoint(C.class.getMethod("set", Collection.class).getParameters()[0]);
 
-		ReferenceModel referenceModel = new ReferenceModel.Builder().injectionPoint(injectionPoint).build();
+		ReferenceModel referenceModel = new ReferenceModel.Builder(injectionPoint.getAnnotated()).type(injectionPoint.getType()).build();
 
 		assertEquals(Collection.class, referenceModel.getBeanClass());
 		assertEquals(Integer.class, referenceModel.getServiceType());
@@ -691,7 +691,7 @@
 
 		InjectionPoint injectionPoint = new MockInjectionPoint(C.class.getMethod("set", Collection.class).getParameters()[0]);
 
-		ReferenceModel referenceModel = new ReferenceModel.Builder().injectionPoint(injectionPoint).build();
+		ReferenceModel referenceModel = new ReferenceModel.Builder(injectionPoint.getAnnotated()).type(injectionPoint.getType()).build();
 
 		assertEquals(Collection.class, referenceModel.getBeanClass());
 		assertEquals(Integer.class, referenceModel.getServiceType());
@@ -715,7 +715,7 @@
 
 		InjectionPoint injectionPoint = new MockInjectionPoint(C.class.getMethod("set", Collection.class).getParameters()[0]);
 
-		ReferenceModel referenceModel = new ReferenceModel.Builder().injectionPoint(injectionPoint).build();
+		ReferenceModel referenceModel = new ReferenceModel.Builder(injectionPoint.getAnnotated()).type(injectionPoint.getType()).build();
 
 		assertEquals(Collection.class, referenceModel.getBeanClass());
 		assertEquals(Integer.class, referenceModel.getServiceType());
@@ -739,7 +739,7 @@
 
 		InjectionPoint injectionPoint = new MockInjectionPoint(C.class.getMethod("set", Collection.class).getParameters()[0]);
 
-		ReferenceModel referenceModel = new ReferenceModel.Builder().injectionPoint(injectionPoint).build();
+		ReferenceModel referenceModel = new ReferenceModel.Builder(injectionPoint.getAnnotated()).type(injectionPoint.getType()).build();
 
 		assertEquals(Collection.class, referenceModel.getBeanClass());
 		assertEquals(Integer.class, referenceModel.getServiceType());
@@ -759,7 +759,7 @@
 
 		InjectionPoint injectionPoint = new MockInjectionPoint(C.class.getMethod("set", Collection.class).getParameters()[0]);
 
-		new ReferenceModel.Builder().injectionPoint(injectionPoint).build();
+		new ReferenceModel.Builder(injectionPoint.getAnnotated()).type(injectionPoint.getType()).build();
 	}
 
 	@Test(expected = IllegalArgumentException.class)
@@ -772,7 +772,7 @@
 
 		InjectionPoint injectionPoint = new MockInjectionPoint(C.class.getMethod("set", List.class).getParameters()[0]);
 
-		new ReferenceModel.Builder().injectionPoint(injectionPoint).build();
+		new ReferenceModel.Builder(injectionPoint.getAnnotated()).type(injectionPoint.getType()).build();
 	}
 
 	@Test(expected = IllegalArgumentException.class)
@@ -784,7 +784,7 @@
 
 		InjectionPoint injectionPoint = new MockInjectionPoint(C.class.getMethod("set", List.class).getParameters()[0]);
 
-		new ReferenceModel.Builder().injectionPoint(injectionPoint).build();
+		new ReferenceModel.Builder(injectionPoint.getAnnotated()).type(injectionPoint.getType()).build();
 	}
 
 	@Test
@@ -800,7 +800,7 @@
 
 		InjectionPoint injectionPoint = new MockInjectionPoint(C.class.getMethod("set", List.class).getParameters()[0]);
 
-		ReferenceModel referenceModel = new ReferenceModel.Builder().injectionPoint(injectionPoint).build();
+		ReferenceModel referenceModel = new ReferenceModel.Builder(injectionPoint.getAnnotated()).type(injectionPoint.getType()).build();
 
 		assertEquals(List.class, referenceModel.getBeanClass());
 		assertEquals(Foo.class, referenceModel.getServiceType());
@@ -826,7 +826,7 @@
 
 		InjectionPoint injectionPoint = new MockInjectionPoint(C.class.getMethod("set", List.class).getParameters()[0]);
 
-		ReferenceModel referenceModel = new ReferenceModel.Builder().injectionPoint(injectionPoint).build();
+		ReferenceModel referenceModel = new ReferenceModel.Builder(injectionPoint.getAnnotated()).type(injectionPoint.getType()).build();
 
 		assertEquals(List.class, referenceModel.getBeanClass());
 		assertEquals(Integer.class, referenceModel.getServiceType());
@@ -850,7 +850,7 @@
 
 		InjectionPoint injectionPoint = new MockInjectionPoint(C.class.getMethod("set", List.class).getParameters()[0]);
 
-		ReferenceModel referenceModel = new ReferenceModel.Builder().injectionPoint(injectionPoint).build();
+		ReferenceModel referenceModel = new ReferenceModel.Builder(injectionPoint.getAnnotated()).type(injectionPoint.getType()).build();
 
 		assertEquals(List.class, referenceModel.getBeanClass());
 		assertEquals(Integer.class, referenceModel.getServiceType());
@@ -874,7 +874,7 @@
 
 		InjectionPoint injectionPoint = new MockInjectionPoint(C.class.getMethod("set", List.class).getParameters()[0]);
 
-		ReferenceModel referenceModel = new ReferenceModel.Builder().injectionPoint(injectionPoint).build();
+		ReferenceModel referenceModel = new ReferenceModel.Builder(injectionPoint.getAnnotated()).type(injectionPoint.getType()).build();
 
 		assertEquals(List.class, referenceModel.getBeanClass());
 		assertEquals(Integer.class, referenceModel.getServiceType());
@@ -894,7 +894,7 @@
 
 		InjectionPoint injectionPoint = new MockInjectionPoint(C.class.getMethod("set", List.class).getParameters()[0]);
 
-		new ReferenceModel.Builder().injectionPoint(injectionPoint).build();
+		new ReferenceModel.Builder(injectionPoint.getAnnotated()).type(injectionPoint.getType()).build();
 	}
 
 	@Test(expected = IllegalArgumentException.class)
@@ -907,7 +907,7 @@
 
 		InjectionPoint injectionPoint = new MockInjectionPoint(C.class.getMethod("set", Instance.class).getParameters()[0]);
 
-		new ReferenceModel.Builder().injectionPoint(injectionPoint).build();
+		new ReferenceModel.Builder(injectionPoint.getAnnotated()).type(injectionPoint.getType()).build();
 	}
 
 	@Test(expected = IllegalArgumentException.class)
@@ -920,7 +920,7 @@
 
 		InjectionPoint injectionPoint = new MockInjectionPoint(C.class.getMethod("set", Instance.class).getParameters()[0]);
 
-		new ReferenceModel.Builder().injectionPoint(injectionPoint).build();
+		new ReferenceModel.Builder(injectionPoint.getAnnotated()).type(injectionPoint.getType()).build();
 	}
 
 }
diff --git a/cdi-extender/src/test/java/org/apache/aries/cdi/container/internal/model/ReferenceModel_PropertiesTest.java b/cdi-extender/src/test/java/org/apache/aries/cdi/container/internal/model/ReferenceModel_PropertiesTest.java
index f48ae90..7f00739 100644
--- a/cdi-extender/src/test/java/org/apache/aries/cdi/container/internal/model/ReferenceModel_PropertiesTest.java
+++ b/cdi-extender/src/test/java/org/apache/aries/cdi/container/internal/model/ReferenceModel_PropertiesTest.java
@@ -43,7 +43,7 @@
 
 		InjectionPoint injectionPoint = new MockInjectionPoint(C.class.getField("m"));
 
-		new ReferenceModel.Builder().injectionPoint(injectionPoint).build();
+		new ReferenceModel.Builder(injectionPoint.getAnnotated()).type(injectionPoint.getType()).build();
 	}
 
 	@Test
@@ -60,7 +60,7 @@
 
 		InjectionPoint injectionPoint = new MockInjectionPoint(C.class.getField("m"));
 
-		ReferenceModel referenceModel = new ReferenceModel.Builder().injectionPoint(injectionPoint).build();
+		ReferenceModel referenceModel = new ReferenceModel.Builder(injectionPoint.getAnnotated()).type(injectionPoint.getType()).build();
 
 		assertEquals(Map.class, referenceModel.getBeanClass());
 		assertEquals(Integer.class, referenceModel.getServiceType());
@@ -85,7 +85,7 @@
 
 		InjectionPoint injectionPoint = new MockInjectionPoint(C.class.getField("m"));
 
-		ReferenceModel referenceModel = new ReferenceModel.Builder().injectionPoint(injectionPoint).build();
+		ReferenceModel referenceModel = new ReferenceModel.Builder(injectionPoint.getAnnotated()).type(injectionPoint.getType()).build();
 
 		assertEquals(Map.class, referenceModel.getBeanClass());
 		assertEquals(Integer.class, referenceModel.getServiceType());
@@ -110,7 +110,7 @@
 
 		InjectionPoint injectionPoint = new MockInjectionPoint(C.class.getField("m"));
 
-		ReferenceModel referenceModel = new ReferenceModel.Builder().injectionPoint(injectionPoint).build();
+		ReferenceModel referenceModel = new ReferenceModel.Builder(injectionPoint.getAnnotated()).type(injectionPoint.getType()).build();
 
 		assertEquals(Optional.class, referenceModel.getBeanClass());
 		assertEquals(Integer.class, referenceModel.getServiceType());
@@ -131,7 +131,7 @@
 
 		InjectionPoint injectionPoint = new MockInjectionPoint(C.class.getField("m"));
 
-		new ReferenceModel.Builder().injectionPoint(injectionPoint).build();
+		new ReferenceModel.Builder(injectionPoint.getAnnotated()).type(injectionPoint.getType()).build();
 	}
 
 	@Test(expected = IllegalArgumentException.class)
@@ -144,7 +144,7 @@
 
 		InjectionPoint injectionPoint = new MockInjectionPoint(C.class.getField("m"));
 
-		new ReferenceModel.Builder().injectionPoint(injectionPoint).build();
+		new ReferenceModel.Builder(injectionPoint.getAnnotated()).type(injectionPoint.getType()).build();
 	}
 
 	@Test
@@ -161,7 +161,7 @@
 
 		InjectionPoint injectionPoint = new MockInjectionPoint(C.class.getField("m"));
 
-		ReferenceModel referenceModel = new ReferenceModel.Builder().injectionPoint(injectionPoint).build();
+		ReferenceModel referenceModel = new ReferenceModel.Builder(injectionPoint.getAnnotated()).type(injectionPoint.getType()).build();
 
 		assertEquals(Collection.class, referenceModel.getBeanClass());
 		assertEquals(Integer.class, referenceModel.getServiceType());
@@ -186,7 +186,7 @@
 
 		InjectionPoint injectionPoint = new MockInjectionPoint(C.class.getField("m"));
 
-		ReferenceModel referenceModel = new ReferenceModel.Builder().injectionPoint(injectionPoint).build();
+		ReferenceModel referenceModel = new ReferenceModel.Builder(injectionPoint.getAnnotated()).type(injectionPoint.getType()).build();
 
 		assertEquals(Collection.class, referenceModel.getBeanClass());
 		assertEquals(Integer.class, referenceModel.getServiceType());
@@ -207,7 +207,7 @@
 
 		InjectionPoint injectionPoint = new MockInjectionPoint(C.class.getField("m"));
 
-		new ReferenceModel.Builder().injectionPoint(injectionPoint).build();
+		new ReferenceModel.Builder(injectionPoint.getAnnotated()).type(injectionPoint.getType()).build();
 	}
 
 	@Test(expected = IllegalArgumentException.class)
@@ -220,7 +220,7 @@
 
 		InjectionPoint injectionPoint = new MockInjectionPoint(C.class.getField("m"));
 
-		new ReferenceModel.Builder().injectionPoint(injectionPoint).build();
+		new ReferenceModel.Builder(injectionPoint.getAnnotated()).type(injectionPoint.getType()).build();
 	}
 
 	@Test
@@ -237,7 +237,7 @@
 
 		InjectionPoint injectionPoint = new MockInjectionPoint(C.class.getField("m"));
 
-		ReferenceModel referenceModel = new ReferenceModel.Builder().injectionPoint(injectionPoint).build();
+		ReferenceModel referenceModel = new ReferenceModel.Builder(injectionPoint.getAnnotated()).type(injectionPoint.getType()).build();
 
 		assertEquals(List.class, referenceModel.getBeanClass());
 		assertEquals(Integer.class, referenceModel.getServiceType());
@@ -262,7 +262,7 @@
 
 		InjectionPoint injectionPoint = new MockInjectionPoint(C.class.getField("m"));
 
-		ReferenceModel referenceModel = new ReferenceModel.Builder().injectionPoint(injectionPoint).build();
+		ReferenceModel referenceModel = new ReferenceModel.Builder(injectionPoint.getAnnotated()).type(injectionPoint.getType()).build();
 
 		assertEquals(List.class, referenceModel.getBeanClass());
 		assertEquals(Integer.class, referenceModel.getServiceType());
@@ -284,7 +284,7 @@
 
 		InjectionPoint injectionPoint = new MockInjectionPoint(C.class.getMethod("set", Map.class).getParameters()[0]);
 
-		new ReferenceModel.Builder().injectionPoint(injectionPoint).build();
+		new ReferenceModel.Builder(injectionPoint.getAnnotated()).type(injectionPoint.getType()).build();
 	}
 
 	@Test
@@ -300,7 +300,7 @@
 
 		InjectionPoint injectionPoint = new MockInjectionPoint(C.class.getMethod("set", Map.class).getParameters()[0]);
 
-		ReferenceModel referenceModel = new ReferenceModel.Builder().injectionPoint(injectionPoint).build();
+		ReferenceModel referenceModel = new ReferenceModel.Builder(injectionPoint.getAnnotated()).type(injectionPoint.getType()).build();
 
 		assertEquals(Map.class, referenceModel.getBeanClass());
 		assertEquals(Integer.class, referenceModel.getServiceType());
@@ -324,7 +324,7 @@
 
 		InjectionPoint injectionPoint = new MockInjectionPoint(C.class.getMethod("set", Optional.class).getParameters()[0]);
 
-		ReferenceModel referenceModel = new ReferenceModel.Builder().injectionPoint(injectionPoint).build();
+		ReferenceModel referenceModel = new ReferenceModel.Builder(injectionPoint.getAnnotated()).type(injectionPoint.getType()).build();
 
 		assertEquals(Optional.class, referenceModel.getBeanClass());
 		assertEquals(Integer.class, referenceModel.getServiceType());
@@ -348,7 +348,7 @@
 
 		InjectionPoint injectionPoint = new MockInjectionPoint(C.class.getMethod("set", Map.class).getParameters()[0]);
 
-		ReferenceModel referenceModel = new ReferenceModel.Builder().injectionPoint(injectionPoint).build();
+		ReferenceModel referenceModel = new ReferenceModel.Builder(injectionPoint.getAnnotated()).type(injectionPoint.getType()).build();
 
 		assertEquals(Map.class, referenceModel.getBeanClass());
 		assertEquals(Integer.class, referenceModel.getServiceType());
@@ -368,7 +368,7 @@
 
 		InjectionPoint injectionPoint = new MockInjectionPoint(C.class.getMethod("set", Collection.class).getParameters()[0]);
 
-		new ReferenceModel.Builder().injectionPoint(injectionPoint).build();
+		new ReferenceModel.Builder(injectionPoint.getAnnotated()).type(injectionPoint.getType()).build();
 	}
 
 	@Test(expected = IllegalArgumentException.class)
@@ -380,7 +380,7 @@
 
 		InjectionPoint injectionPoint = new MockInjectionPoint(C.class.getMethod("set", Collection.class).getParameters()[0]);
 
-		new ReferenceModel.Builder().injectionPoint(injectionPoint).build();
+		new ReferenceModel.Builder(injectionPoint.getAnnotated()).type(injectionPoint.getType()).build();
 	}
 
 	@Test
@@ -396,7 +396,7 @@
 
 		InjectionPoint injectionPoint = new MockInjectionPoint(C.class.getMethod("set", Collection.class).getParameters()[0]);
 
-		ReferenceModel referenceModel = new ReferenceModel.Builder().injectionPoint(injectionPoint).build();
+		ReferenceModel referenceModel = new ReferenceModel.Builder(injectionPoint.getAnnotated()).type(injectionPoint.getType()).build();
 
 		assertEquals(Collection.class, referenceModel.getBeanClass());
 		assertEquals(Integer.class, referenceModel.getServiceType());
@@ -420,7 +420,7 @@
 
 		InjectionPoint injectionPoint = new MockInjectionPoint(C.class.getMethod("set", Collection.class).getParameters()[0]);
 
-		ReferenceModel referenceModel = new ReferenceModel.Builder().injectionPoint(injectionPoint).build();
+		ReferenceModel referenceModel = new ReferenceModel.Builder(injectionPoint.getAnnotated()).type(injectionPoint.getType()).build();
 
 		assertEquals(Collection.class, referenceModel.getBeanClass());
 		assertEquals(Integer.class, referenceModel.getServiceType());
@@ -440,7 +440,7 @@
 
 		InjectionPoint injectionPoint = new MockInjectionPoint(C.class.getMethod("set", List.class).getParameters()[0]);
 
-		new ReferenceModel.Builder().injectionPoint(injectionPoint).build();
+		new ReferenceModel.Builder(injectionPoint.getAnnotated()).type(injectionPoint.getType()).build();
 	}
 
 	@Test(expected = IllegalArgumentException.class)
@@ -452,7 +452,7 @@
 
 		InjectionPoint injectionPoint = new MockInjectionPoint(C.class.getMethod("set", List.class).getParameters()[0]);
 
-		new ReferenceModel.Builder().injectionPoint(injectionPoint).build();
+		new ReferenceModel.Builder(injectionPoint.getAnnotated()).type(injectionPoint.getType()).build();
 	}
 
 	@Test
@@ -468,7 +468,7 @@
 
 		InjectionPoint injectionPoint = new MockInjectionPoint(C.class.getMethod("set", List.class).getParameters()[0]);
 
-		ReferenceModel referenceModel = new ReferenceModel.Builder().injectionPoint(injectionPoint).build();
+		ReferenceModel referenceModel = new ReferenceModel.Builder(injectionPoint.getAnnotated()).type(injectionPoint.getType()).build();
 
 		assertEquals(List.class, referenceModel.getBeanClass());
 		assertEquals(Integer.class, referenceModel.getServiceType());
@@ -492,7 +492,7 @@
 
 		InjectionPoint injectionPoint = new MockInjectionPoint(C.class.getMethod("set", List.class).getParameters()[0]);
 
-		ReferenceModel referenceModel = new ReferenceModel.Builder().injectionPoint(injectionPoint).build();
+		ReferenceModel referenceModel = new ReferenceModel.Builder(injectionPoint.getAnnotated()).type(injectionPoint.getType()).build();
 
 		assertEquals(List.class, referenceModel.getBeanClass());
 		assertEquals(Integer.class, referenceModel.getServiceType());
diff --git a/cdi-extender/src/test/java/org/apache/aries/cdi/container/internal/model/ReferenceModel_ServiceReferenceTest.java b/cdi-extender/src/test/java/org/apache/aries/cdi/container/internal/model/ReferenceModel_ServiceReferenceTest.java
index a274c8e..4f641d0 100644
--- a/cdi-extender/src/test/java/org/apache/aries/cdi/container/internal/model/ReferenceModel_ServiceReferenceTest.java
+++ b/cdi-extender/src/test/java/org/apache/aries/cdi/container/internal/model/ReferenceModel_ServiceReferenceTest.java
@@ -44,7 +44,7 @@
 
 		InjectionPoint injectionPoint = new MockInjectionPoint(C.class.getField("m"));
 
-		new ReferenceModel.Builder().injectionPoint(injectionPoint).build();
+		new ReferenceModel.Builder(injectionPoint.getAnnotated()).type(injectionPoint.getType()).build();
 	}
 
 	@Test(expected = IllegalArgumentException.class)
@@ -57,7 +57,7 @@
 
 		InjectionPoint injectionPoint = new MockInjectionPoint(C.class.getField("m"));
 
-		new ReferenceModel.Builder().injectionPoint(injectionPoint).build();
+		new ReferenceModel.Builder(injectionPoint.getAnnotated()).type(injectionPoint.getType()).build();
 	}
 
 	@Test
@@ -74,7 +74,7 @@
 
 		InjectionPoint injectionPoint = new MockInjectionPoint(C.class.getField("m"));
 
-		ReferenceModel referenceModel = new ReferenceModel.Builder().injectionPoint(injectionPoint).build();
+		ReferenceModel referenceModel = new ReferenceModel.Builder(injectionPoint.getAnnotated()).type(injectionPoint.getType()).build();
 
 		assertEquals(ServiceReference.class, referenceModel.getBeanClass());
 		assertEquals(Integer.class, referenceModel.getServiceType());
@@ -101,7 +101,7 @@
 
 		InjectionPoint injectionPoint = new MockInjectionPoint(C.class.getField("m"));
 
-		ReferenceModel referenceModel = new ReferenceModel.Builder().injectionPoint(injectionPoint).build();
+		ReferenceModel referenceModel = new ReferenceModel.Builder(injectionPoint.getAnnotated()).type(injectionPoint.getType()).build();
 
 		assertEquals(ServiceReference.class, referenceModel.getBeanClass());
 		assertEquals(Integer.class, referenceModel.getServiceType());
@@ -125,7 +125,7 @@
 
 		InjectionPoint injectionPoint = new MockInjectionPoint(C.class.getField("m"));
 
-		ReferenceModel referenceModel = new ReferenceModel.Builder().injectionPoint(injectionPoint).build();
+		ReferenceModel referenceModel = new ReferenceModel.Builder(injectionPoint.getAnnotated()).type(injectionPoint.getType()).build();
 
 		assertEquals(ServiceReference.class, referenceModel.getBeanClass());
 		assertEquals(Integer.class, referenceModel.getServiceType());
@@ -149,7 +149,7 @@
 
 		InjectionPoint injectionPoint = new MockInjectionPoint(C.class.getField("m"));
 
-		ReferenceModel referenceModel = new ReferenceModel.Builder().injectionPoint(injectionPoint).build();
+		ReferenceModel referenceModel = new ReferenceModel.Builder(injectionPoint.getAnnotated()).type(injectionPoint.getType()).build();
 
 		assertEquals(ServiceReference.class, referenceModel.getBeanClass());
 		assertEquals(Integer.class, referenceModel.getServiceType());
@@ -170,7 +170,7 @@
 
 		InjectionPoint injectionPoint = new MockInjectionPoint(C.class.getField("m"));
 
-		new ReferenceModel.Builder().injectionPoint(injectionPoint).build();
+		new ReferenceModel.Builder(injectionPoint.getAnnotated()).type(injectionPoint.getType()).build();
 	}
 
 	@Test(expected = IllegalArgumentException.class)
@@ -184,7 +184,7 @@
 
 		InjectionPoint injectionPoint = new MockInjectionPoint(C.class.getField("m"));
 
-		new ReferenceModel.Builder().injectionPoint(injectionPoint).build();
+		new ReferenceModel.Builder(injectionPoint.getAnnotated()).type(injectionPoint.getType()).build();
 	}
 
 	@Test(expected = IllegalArgumentException.class)
@@ -197,7 +197,7 @@
 
 		InjectionPoint injectionPoint = new MockInjectionPoint(C.class.getField("m"));
 
-		new ReferenceModel.Builder().injectionPoint(injectionPoint).build();
+		new ReferenceModel.Builder(injectionPoint.getAnnotated()).type(injectionPoint.getType()).build();
 	}
 
 	@Test
@@ -214,7 +214,7 @@
 
 		InjectionPoint injectionPoint = new MockInjectionPoint(C.class.getField("m"));
 
-		ReferenceModel referenceModel = new ReferenceModel.Builder().injectionPoint(injectionPoint).build();
+		ReferenceModel referenceModel = new ReferenceModel.Builder(injectionPoint.getAnnotated()).type(injectionPoint.getType()).build();
 
 		assertEquals(Collection.class, referenceModel.getBeanClass());
 		assertEquals(Integer.class, referenceModel.getServiceType());
@@ -241,7 +241,7 @@
 
 		InjectionPoint injectionPoint = new MockInjectionPoint(C.class.getField("m"));
 
-		ReferenceModel referenceModel = new ReferenceModel.Builder().injectionPoint(injectionPoint).build();
+		ReferenceModel referenceModel = new ReferenceModel.Builder(injectionPoint.getAnnotated()).type(injectionPoint.getType()).build();
 
 		assertEquals(Collection.class, referenceModel.getBeanClass());
 		assertEquals(Integer.class, referenceModel.getServiceType());
@@ -266,7 +266,7 @@
 
 		InjectionPoint injectionPoint = new MockInjectionPoint(C.class.getField("m"));
 
-		ReferenceModel referenceModel = new ReferenceModel.Builder().injectionPoint(injectionPoint).build();
+		ReferenceModel referenceModel = new ReferenceModel.Builder(injectionPoint.getAnnotated()).type(injectionPoint.getType()).build();
 
 		assertEquals(Collection.class, referenceModel.getBeanClass());
 		assertEquals(Integer.class, referenceModel.getServiceType());
@@ -291,7 +291,7 @@
 
 		InjectionPoint injectionPoint = new MockInjectionPoint(C.class.getField("m"));
 
-		ReferenceModel referenceModel = new ReferenceModel.Builder().injectionPoint(injectionPoint).build();
+		ReferenceModel referenceModel = new ReferenceModel.Builder(injectionPoint.getAnnotated()).type(injectionPoint.getType()).build();
 
 		assertEquals(Collection.class, referenceModel.getBeanClass());
 		assertEquals(Integer.class, referenceModel.getServiceType());
@@ -312,7 +312,7 @@
 
 		InjectionPoint injectionPoint = new MockInjectionPoint(C.class.getField("m"));
 
-		new ReferenceModel.Builder().injectionPoint(injectionPoint).build();
+		new ReferenceModel.Builder(injectionPoint.getAnnotated()).type(injectionPoint.getType()).build();
 	}
 
 	@Test(expected = IllegalArgumentException.class)
@@ -326,7 +326,7 @@
 
 		InjectionPoint injectionPoint = new MockInjectionPoint(C.class.getField("m"));
 
-		new ReferenceModel.Builder().injectionPoint(injectionPoint).build();
+		new ReferenceModel.Builder(injectionPoint.getAnnotated()).type(injectionPoint.getType()).build();
 	}
 
 	@Test(expected = IllegalArgumentException.class)
@@ -339,7 +339,7 @@
 
 		InjectionPoint injectionPoint = new MockInjectionPoint(C.class.getField("m"));
 
-		new ReferenceModel.Builder().injectionPoint(injectionPoint).build();
+		new ReferenceModel.Builder(injectionPoint.getAnnotated()).type(injectionPoint.getType()).build();
 	}
 
 	@Test
@@ -356,7 +356,7 @@
 
 		InjectionPoint injectionPoint = new MockInjectionPoint(C.class.getField("m"));
 
-		ReferenceModel referenceModel = new ReferenceModel.Builder().injectionPoint(injectionPoint).build();
+		ReferenceModel referenceModel = new ReferenceModel.Builder(injectionPoint.getAnnotated()).type(injectionPoint.getType()).build();
 
 		assertEquals(List.class, referenceModel.getBeanClass());
 		assertEquals(Integer.class, referenceModel.getServiceType());
@@ -383,7 +383,7 @@
 
 		InjectionPoint injectionPoint = new MockInjectionPoint(C.class.getField("m"));
 
-		ReferenceModel referenceModel = new ReferenceModel.Builder().injectionPoint(injectionPoint).build();
+		ReferenceModel referenceModel = new ReferenceModel.Builder(injectionPoint.getAnnotated()).type(injectionPoint.getType()).build();
 
 		assertEquals(List.class, referenceModel.getBeanClass());
 		assertEquals(Integer.class, referenceModel.getServiceType());
@@ -408,7 +408,7 @@
 
 		InjectionPoint injectionPoint = new MockInjectionPoint(C.class.getField("m"));
 
-		ReferenceModel referenceModel = new ReferenceModel.Builder().injectionPoint(injectionPoint).build();
+		ReferenceModel referenceModel = new ReferenceModel.Builder(injectionPoint.getAnnotated()).type(injectionPoint.getType()).build();
 
 		assertEquals(List.class, referenceModel.getBeanClass());
 		assertEquals(Integer.class, referenceModel.getServiceType());
@@ -433,7 +433,7 @@
 
 		InjectionPoint injectionPoint = new MockInjectionPoint(C.class.getField("m"));
 
-		ReferenceModel referenceModel = new ReferenceModel.Builder().injectionPoint(injectionPoint).build();
+		ReferenceModel referenceModel = new ReferenceModel.Builder(injectionPoint.getAnnotated()).type(injectionPoint.getType()).build();
 
 		assertEquals(List.class, referenceModel.getBeanClass());
 		assertEquals(Integer.class, referenceModel.getServiceType());
@@ -454,7 +454,7 @@
 
 		InjectionPoint injectionPoint = new MockInjectionPoint(C.class.getField("m"));
 
-		new ReferenceModel.Builder().injectionPoint(injectionPoint).build();
+		new ReferenceModel.Builder(injectionPoint.getAnnotated()).type(injectionPoint.getType()).build();
 	}
 
 	// parameters
@@ -469,7 +469,7 @@
 
 		InjectionPoint injectionPoint = new MockInjectionPoint(C.class.getMethod("set", ServiceReference.class).getParameters()[0]);
 
-		new ReferenceModel.Builder().injectionPoint(injectionPoint).build();
+		new ReferenceModel.Builder(injectionPoint.getAnnotated()).type(injectionPoint.getType()).build();
 	}
 
 	@Test(expected = IllegalArgumentException.class)
@@ -481,7 +481,7 @@
 
 		InjectionPoint injectionPoint = new MockInjectionPoint(C.class.getMethod("set", ServiceReference.class).getParameters()[0]);
 
-		new ReferenceModel.Builder().injectionPoint(injectionPoint).build();
+		new ReferenceModel.Builder(injectionPoint.getAnnotated()).type(injectionPoint.getType()).build();
 	}
 
 	@Test
@@ -497,7 +497,7 @@
 
 		InjectionPoint injectionPoint = new MockInjectionPoint(C.class.getMethod("set", ServiceReference.class).getParameters()[0]);
 
-		ReferenceModel referenceModel = new ReferenceModel.Builder().injectionPoint(injectionPoint).build();
+		ReferenceModel referenceModel = new ReferenceModel.Builder(injectionPoint.getAnnotated()).type(injectionPoint.getType()).build();
 
 		assertEquals(ServiceReference.class, referenceModel.getBeanClass());
 		assertEquals(Integer.class, referenceModel.getServiceType());
@@ -523,7 +523,7 @@
 
 		InjectionPoint injectionPoint = new MockInjectionPoint(C.class.getMethod("set", ServiceReference.class).getParameters()[0]);
 
-		ReferenceModel referenceModel = new ReferenceModel.Builder().injectionPoint(injectionPoint).build();
+		ReferenceModel referenceModel = new ReferenceModel.Builder(injectionPoint.getAnnotated()).type(injectionPoint.getType()).build();
 
 		assertEquals(ServiceReference.class, referenceModel.getBeanClass());
 		assertEquals(Integer.class, referenceModel.getServiceType());
@@ -546,7 +546,7 @@
 
 		InjectionPoint injectionPoint = new MockInjectionPoint(C.class.getMethod("set", ServiceReference.class).getParameters()[0]);
 
-		ReferenceModel referenceModel = new ReferenceModel.Builder().injectionPoint(injectionPoint).build();
+		ReferenceModel referenceModel = new ReferenceModel.Builder(injectionPoint.getAnnotated()).type(injectionPoint.getType()).build();
 
 		assertEquals(ServiceReference.class, referenceModel.getBeanClass());
 		assertEquals(Integer.class, referenceModel.getServiceType());
@@ -569,7 +569,7 @@
 
 		InjectionPoint injectionPoint = new MockInjectionPoint(C.class.getMethod("set", ServiceReference.class).getParameters()[0]);
 
-		ReferenceModel referenceModel = new ReferenceModel.Builder().injectionPoint(injectionPoint).build();
+		ReferenceModel referenceModel = new ReferenceModel.Builder(injectionPoint.getAnnotated()).type(injectionPoint.getType()).build();
 
 		assertEquals(ServiceReference.class, referenceModel.getBeanClass());
 		assertEquals(Integer.class, referenceModel.getServiceType());
@@ -589,7 +589,7 @@
 
 		InjectionPoint injectionPoint = new MockInjectionPoint(C.class.getMethod("set", ServiceReference.class).getParameters()[0]);
 
-		new ReferenceModel.Builder().injectionPoint(injectionPoint).build();
+		new ReferenceModel.Builder(injectionPoint.getAnnotated()).type(injectionPoint.getType()).build();
 	}
 
 	@Test(expected = IllegalArgumentException.class)
@@ -602,7 +602,7 @@
 
 		InjectionPoint injectionPoint = new MockInjectionPoint(C.class.getMethod("set", Collection.class).getParameters()[0]);
 
-		new ReferenceModel.Builder().injectionPoint(injectionPoint).build();
+		new ReferenceModel.Builder(injectionPoint.getAnnotated()).type(injectionPoint.getType()).build();
 	}
 
 	@Test(expected = IllegalArgumentException.class)
@@ -614,7 +614,7 @@
 
 		InjectionPoint injectionPoint = new MockInjectionPoint(C.class.getMethod("set", Collection.class).getParameters()[0]);
 
-		new ReferenceModel.Builder().injectionPoint(injectionPoint).build();
+		new ReferenceModel.Builder(injectionPoint.getAnnotated()).type(injectionPoint.getType()).build();
 	}
 
 	@Test
@@ -630,7 +630,7 @@
 
 		InjectionPoint injectionPoint = new MockInjectionPoint(C.class.getMethod("set", Collection.class).getParameters()[0]);
 
-		ReferenceModel referenceModel = new ReferenceModel.Builder().injectionPoint(injectionPoint).build();
+		ReferenceModel referenceModel = new ReferenceModel.Builder(injectionPoint.getAnnotated()).type(injectionPoint.getType()).build();
 
 		assertEquals(Collection.class, referenceModel.getBeanClass());
 		assertEquals(Integer.class, referenceModel.getServiceType());
@@ -656,7 +656,7 @@
 
 		InjectionPoint injectionPoint = new MockInjectionPoint(C.class.getMethod("set", Collection.class).getParameters()[0]);
 
-		ReferenceModel referenceModel = new ReferenceModel.Builder().injectionPoint(injectionPoint).build();
+		ReferenceModel referenceModel = new ReferenceModel.Builder(injectionPoint.getAnnotated()).type(injectionPoint.getType()).build();
 
 		assertEquals(Collection.class, referenceModel.getBeanClass());
 		assertEquals(Integer.class, referenceModel.getServiceType());
@@ -680,7 +680,7 @@
 
 		InjectionPoint injectionPoint = new MockInjectionPoint(C.class.getMethod("set", Collection.class).getParameters()[0]);
 
-		ReferenceModel referenceModel = new ReferenceModel.Builder().injectionPoint(injectionPoint).build();
+		ReferenceModel referenceModel = new ReferenceModel.Builder(injectionPoint.getAnnotated()).type(injectionPoint.getType()).build();
 
 		assertEquals(Collection.class, referenceModel.getBeanClass());
 		assertEquals(Integer.class, referenceModel.getServiceType());
@@ -704,7 +704,7 @@
 
 		InjectionPoint injectionPoint = new MockInjectionPoint(C.class.getMethod("set", Collection.class).getParameters()[0]);
 
-		ReferenceModel referenceModel = new ReferenceModel.Builder().injectionPoint(injectionPoint).build();
+		ReferenceModel referenceModel = new ReferenceModel.Builder(injectionPoint.getAnnotated()).type(injectionPoint.getType()).build();
 
 		assertEquals(Collection.class, referenceModel.getBeanClass());
 		assertEquals(Integer.class, referenceModel.getServiceType());
@@ -724,7 +724,7 @@
 
 		InjectionPoint injectionPoint = new MockInjectionPoint(C.class.getMethod("set", Collection.class).getParameters()[0]);
 
-		new ReferenceModel.Builder().injectionPoint(injectionPoint).build();
+		new ReferenceModel.Builder(injectionPoint.getAnnotated()).type(injectionPoint.getType()).build();
 	}
 
 	@Test(expected = IllegalArgumentException.class)
@@ -737,7 +737,7 @@
 
 		InjectionPoint injectionPoint = new MockInjectionPoint(C.class.getMethod("set", List.class).getParameters()[0]);
 
-		new ReferenceModel.Builder().injectionPoint(injectionPoint).build();
+		new ReferenceModel.Builder(injectionPoint.getAnnotated()).type(injectionPoint.getType()).build();
 	}
 
 	@Test(expected = IllegalArgumentException.class)
@@ -749,7 +749,7 @@
 
 		InjectionPoint injectionPoint = new MockInjectionPoint(C.class.getMethod("set", List.class).getParameters()[0]);
 
-		new ReferenceModel.Builder().injectionPoint(injectionPoint).build();
+		new ReferenceModel.Builder(injectionPoint.getAnnotated()).type(injectionPoint.getType()).build();
 	}
 
 	@Test
@@ -765,7 +765,7 @@
 
 		InjectionPoint injectionPoint = new MockInjectionPoint(C.class.getMethod("set", List.class).getParameters()[0]);
 
-		ReferenceModel referenceModel = new ReferenceModel.Builder().injectionPoint(injectionPoint).build();
+		ReferenceModel referenceModel = new ReferenceModel.Builder(injectionPoint.getAnnotated()).type(injectionPoint.getType()).build();
 
 		assertEquals(List.class, referenceModel.getBeanClass());
 		assertEquals(Integer.class, referenceModel.getServiceType());
@@ -791,7 +791,7 @@
 
 		InjectionPoint injectionPoint = new MockInjectionPoint(C.class.getMethod("set", List.class).getParameters()[0]);
 
-		ReferenceModel referenceModel = new ReferenceModel.Builder().injectionPoint(injectionPoint).build();
+		ReferenceModel referenceModel = new ReferenceModel.Builder(injectionPoint.getAnnotated()).type(injectionPoint.getType()).build();
 
 		assertEquals(List.class, referenceModel.getBeanClass());
 		assertEquals(Integer.class, referenceModel.getServiceType());
@@ -815,7 +815,7 @@
 
 		InjectionPoint injectionPoint = new MockInjectionPoint(C.class.getMethod("set", List.class).getParameters()[0]);
 
-		ReferenceModel referenceModel = new ReferenceModel.Builder().injectionPoint(injectionPoint).build();
+		ReferenceModel referenceModel = new ReferenceModel.Builder(injectionPoint.getAnnotated()).type(injectionPoint.getType()).build();
 
 		assertEquals(List.class, referenceModel.getBeanClass());
 		assertEquals(Integer.class, referenceModel.getServiceType());
@@ -839,7 +839,7 @@
 
 		InjectionPoint injectionPoint = new MockInjectionPoint(C.class.getMethod("set", List.class).getParameters()[0]);
 
-		ReferenceModel referenceModel = new ReferenceModel.Builder().injectionPoint(injectionPoint).build();
+		ReferenceModel referenceModel = new ReferenceModel.Builder(injectionPoint.getAnnotated()).type(injectionPoint.getType()).build();
 
 		assertEquals(List.class, referenceModel.getBeanClass());
 		assertEquals(Integer.class, referenceModel.getServiceType());
@@ -859,7 +859,7 @@
 
 		InjectionPoint injectionPoint = new MockInjectionPoint(C.class.getMethod("set", List.class).getParameters()[0]);
 
-		new ReferenceModel.Builder().injectionPoint(injectionPoint).build();
+		new ReferenceModel.Builder(injectionPoint.getAnnotated()).type(injectionPoint.getType()).build();
 	}
 
 }
\ No newline at end of file
diff --git a/cdi-extender/src/test/java/org/apache/aries/cdi/container/internal/model/ReferenceModel_ServiceTest.java b/cdi-extender/src/test/java/org/apache/aries/cdi/container/internal/model/ReferenceModel_ServiceTest.java
index 1252c85..3a8a436 100644
--- a/cdi-extender/src/test/java/org/apache/aries/cdi/container/internal/model/ReferenceModel_ServiceTest.java
+++ b/cdi-extender/src/test/java/org/apache/aries/cdi/container/internal/model/ReferenceModel_ServiceTest.java
@@ -48,7 +48,7 @@
 
 		InjectionPoint injectionPoint = new MockInjectionPoint(C.class.getField("m"));
 
-		ReferenceModel referenceModel = new ReferenceModel.Builder().injectionPoint(injectionPoint).build();
+		ReferenceModel referenceModel = new ReferenceModel.Builder(injectionPoint.getAnnotated()).type(injectionPoint.getType()).build();
 
 		assertEquals(Integer.class, referenceModel.getBeanClass());
 		assertEquals(Integer.class, referenceModel.getServiceType());
@@ -69,7 +69,7 @@
 
 		InjectionPoint injectionPoint = new MockInjectionPoint(C.class.getField("m"));
 
-		new ReferenceModel.Builder().injectionPoint(injectionPoint).build();
+		new ReferenceModel.Builder(injectionPoint.getAnnotated()).type(injectionPoint.getType()).build();
 	}
 
 	@Test
@@ -86,7 +86,7 @@
 
 		InjectionPoint injectionPoint = new MockInjectionPoint(C.class.getField("m"));
 
-		ReferenceModel referenceModel = new ReferenceModel.Builder().injectionPoint(injectionPoint).build();
+		ReferenceModel referenceModel = new ReferenceModel.Builder(injectionPoint.getAnnotated()).type(injectionPoint.getType()).build();
 
 		assertEquals(Optional.class, referenceModel.getBeanClass());
 		assertEquals(Integer.class, referenceModel.getServiceType());
@@ -111,7 +111,7 @@
 
 		InjectionPoint injectionPoint = new MockInjectionPoint(C.class.getField("m"));
 
-		ReferenceModel referenceModel = new ReferenceModel.Builder().injectionPoint(injectionPoint).build();
+		ReferenceModel referenceModel = new ReferenceModel.Builder(injectionPoint.getAnnotated()).type(injectionPoint.getType()).build();
 
 		assertEquals(Integer.class, referenceModel.getBeanClass());
 		assertEquals(Integer.class, referenceModel.getServiceType());
@@ -132,7 +132,7 @@
 
 		InjectionPoint injectionPoint = new MockInjectionPoint(C.class.getField("m"));
 
-		new ReferenceModel.Builder().injectionPoint(injectionPoint).build();
+		new ReferenceModel.Builder(injectionPoint.getAnnotated()).type(injectionPoint.getType()).build();
 	}
 
 	@Test
@@ -149,7 +149,7 @@
 
 		InjectionPoint injectionPoint = new MockInjectionPoint(C.class.getField("m"));
 
-		ReferenceModel referenceModel = new ReferenceModel.Builder().injectionPoint(injectionPoint).build();
+		ReferenceModel referenceModel = new ReferenceModel.Builder(injectionPoint.getAnnotated()).type(injectionPoint.getType()).build();
 
 		assertEquals(Optional.class, referenceModel.getBeanClass());
 		assertEquals(Integer.class, referenceModel.getServiceType());
@@ -170,7 +170,7 @@
 
 		InjectionPoint injectionPoint = new MockInjectionPoint(C.class.getField("m"));
 
-		new ReferenceModel.Builder().injectionPoint(injectionPoint).build();
+		new ReferenceModel.Builder(injectionPoint.getAnnotated()).type(injectionPoint.getType()).build();
 	}
 
 	@Test(expected = IllegalArgumentException.class)
@@ -183,7 +183,7 @@
 
 		InjectionPoint injectionPoint = new MockInjectionPoint(C.class.getField("m"));
 
-		new ReferenceModel.Builder().injectionPoint(injectionPoint).build();
+		new ReferenceModel.Builder(injectionPoint.getAnnotated()).type(injectionPoint.getType()).build();
 	}
 
 	@Test(expected = IllegalArgumentException.class)
@@ -197,7 +197,7 @@
 
 		InjectionPoint injectionPoint = new MockInjectionPoint(C.class.getField("m"));
 
-		new ReferenceModel.Builder().injectionPoint(injectionPoint).build();
+		new ReferenceModel.Builder(injectionPoint.getAnnotated()).type(injectionPoint.getType()).build();
 	}
 
 	@Test(expected = IllegalArgumentException.class)
@@ -210,7 +210,7 @@
 
 		InjectionPoint injectionPoint = new MockInjectionPoint(C.class.getField("m"));
 
-		new ReferenceModel.Builder().injectionPoint(injectionPoint).build();
+		new ReferenceModel.Builder(injectionPoint.getAnnotated()).type(injectionPoint.getType()).build();
 	}
 
 	@Test
@@ -227,7 +227,7 @@
 
 		InjectionPoint injectionPoint = new MockInjectionPoint(C.class.getField("m"));
 
-		ReferenceModel referenceModel = new ReferenceModel.Builder().injectionPoint(injectionPoint).build();
+		ReferenceModel referenceModel = new ReferenceModel.Builder(injectionPoint.getAnnotated()).type(injectionPoint.getType()).build();
 
 		assertEquals(Collection.class, referenceModel.getBeanClass());
 		assertEquals(Integer.class, referenceModel.getServiceType());
@@ -254,7 +254,7 @@
 
 		InjectionPoint injectionPoint = new MockInjectionPoint(C.class.getField("m"));
 
-		ReferenceModel referenceModel = new ReferenceModel.Builder().injectionPoint(injectionPoint).build();
+		ReferenceModel referenceModel = new ReferenceModel.Builder(injectionPoint.getAnnotated()).type(injectionPoint.getType()).build();
 
 		assertEquals(Collection.class, referenceModel.getBeanClass());
 		assertEquals(Integer.class, referenceModel.getServiceType());
@@ -279,7 +279,7 @@
 
 		InjectionPoint injectionPoint = new MockInjectionPoint(C.class.getField("m"));
 
-		ReferenceModel referenceModel = new ReferenceModel.Builder().injectionPoint(injectionPoint).build();
+		ReferenceModel referenceModel = new ReferenceModel.Builder(injectionPoint.getAnnotated()).type(injectionPoint.getType()).build();
 
 		assertEquals(Collection.class, referenceModel.getBeanClass());
 		assertEquals(Integer.class, referenceModel.getServiceType());
@@ -304,7 +304,7 @@
 
 		InjectionPoint injectionPoint = new MockInjectionPoint(C.class.getField("m"));
 
-		ReferenceModel referenceModel = new ReferenceModel.Builder().injectionPoint(injectionPoint).build();
+		ReferenceModel referenceModel = new ReferenceModel.Builder(injectionPoint.getAnnotated()).type(injectionPoint.getType()).build();
 
 		assertEquals(Collection.class, referenceModel.getBeanClass());
 		assertEquals(Integer.class, referenceModel.getServiceType());
@@ -325,7 +325,7 @@
 
 		InjectionPoint injectionPoint = new MockInjectionPoint(C.class.getField("m"));
 
-		new ReferenceModel.Builder().injectionPoint(injectionPoint).build();
+		new ReferenceModel.Builder(injectionPoint.getAnnotated()).type(injectionPoint.getType()).build();
 	}
 
 	@Test(expected = IllegalArgumentException.class)
@@ -339,7 +339,7 @@
 
 		InjectionPoint injectionPoint = new MockInjectionPoint(C.class.getField("m"));
 
-		new ReferenceModel.Builder().injectionPoint(injectionPoint).build();
+		new ReferenceModel.Builder(injectionPoint.getAnnotated()).type(injectionPoint.getType()).build();
 	}
 
 	@Test(expected = IllegalArgumentException.class)
@@ -352,7 +352,7 @@
 
 		InjectionPoint injectionPoint = new MockInjectionPoint(C.class.getField("m"));
 
-		new ReferenceModel.Builder().injectionPoint(injectionPoint).build();
+		new ReferenceModel.Builder(injectionPoint.getAnnotated()).type(injectionPoint.getType()).build();
 	}
 
 	@Test
@@ -369,7 +369,7 @@
 
 		InjectionPoint injectionPoint = new MockInjectionPoint(C.class.getField("m"));
 
-		ReferenceModel referenceModel = new ReferenceModel.Builder().injectionPoint(injectionPoint).build();
+		ReferenceModel referenceModel = new ReferenceModel.Builder(injectionPoint.getAnnotated()).type(injectionPoint.getType()).build();
 
 		assertEquals(List.class, referenceModel.getBeanClass());
 		assertEquals(Integer.class, referenceModel.getServiceType());
@@ -396,7 +396,7 @@
 
 		InjectionPoint injectionPoint = new MockInjectionPoint(C.class.getField("m"));
 
-		ReferenceModel referenceModel = new ReferenceModel.Builder().injectionPoint(injectionPoint).build();
+		ReferenceModel referenceModel = new ReferenceModel.Builder(injectionPoint.getAnnotated()).type(injectionPoint.getType()).build();
 
 		assertEquals(List.class, referenceModel.getBeanClass());
 		assertEquals(Integer.class, referenceModel.getServiceType());
@@ -421,7 +421,7 @@
 
 		InjectionPoint injectionPoint = new MockInjectionPoint(C.class.getField("m"));
 
-		ReferenceModel referenceModel = new ReferenceModel.Builder().injectionPoint(injectionPoint).build();
+		ReferenceModel referenceModel = new ReferenceModel.Builder(injectionPoint.getAnnotated()).type(injectionPoint.getType()).build();
 
 		assertEquals(List.class, referenceModel.getBeanClass());
 		assertEquals(Integer.class, referenceModel.getServiceType());
@@ -446,7 +446,7 @@
 
 		InjectionPoint injectionPoint = new MockInjectionPoint(C.class.getField("m"));
 
-		ReferenceModel referenceModel = new ReferenceModel.Builder().injectionPoint(injectionPoint).build();
+		ReferenceModel referenceModel = new ReferenceModel.Builder(injectionPoint.getAnnotated()).type(injectionPoint.getType()).build();
 
 		assertEquals(List.class, referenceModel.getBeanClass());
 		assertEquals(Integer.class, referenceModel.getServiceType());
@@ -467,7 +467,7 @@
 
 		InjectionPoint injectionPoint = new MockInjectionPoint(C.class.getField("m"));
 
-		new ReferenceModel.Builder().injectionPoint(injectionPoint).build();
+		new ReferenceModel.Builder(injectionPoint.getAnnotated()).type(injectionPoint.getType()).build();
 	}
 
 	// params
@@ -485,7 +485,7 @@
 
 		InjectionPoint injectionPoint = new MockInjectionPoint(C.class.getMethod("set", Integer.class).getParameters()[0]);
 
-		ReferenceModel referenceModel = new ReferenceModel.Builder().injectionPoint(injectionPoint).build();
+		ReferenceModel referenceModel = new ReferenceModel.Builder(injectionPoint.getAnnotated()).type(injectionPoint.getType()).build();
 
 		assertEquals(Integer.class, referenceModel.getBeanClass());
 		assertEquals(Integer.class, referenceModel.getServiceType());
@@ -505,7 +505,7 @@
 
 		InjectionPoint injectionPoint = new MockInjectionPoint(C.class.getMethod("set", Callable.class).getParameters()[0]);
 
-		new ReferenceModel.Builder().injectionPoint(injectionPoint).build();
+		new ReferenceModel.Builder(injectionPoint.getAnnotated()).type(injectionPoint.getType()).build();
 	}
 
 	@Test
@@ -521,7 +521,7 @@
 
 		InjectionPoint injectionPoint = new MockInjectionPoint(C.class.getMethod("set", Optional.class).getParameters()[0]);
 
-		ReferenceModel referenceModel = new ReferenceModel.Builder().injectionPoint(injectionPoint).build();
+		ReferenceModel referenceModel = new ReferenceModel.Builder(injectionPoint.getAnnotated()).type(injectionPoint.getType()).build();
 
 		assertEquals(Optional.class, referenceModel.getBeanClass());
 		assertEquals(Integer.class, referenceModel.getServiceType());
@@ -545,7 +545,7 @@
 
 		InjectionPoint injectionPoint = new MockInjectionPoint(C.class.getMethod("set", Integer.class).getParameters()[0]);
 
-		ReferenceModel referenceModel = new ReferenceModel.Builder().injectionPoint(injectionPoint).build();
+		ReferenceModel referenceModel = new ReferenceModel.Builder(injectionPoint.getAnnotated()).type(injectionPoint.getType()).build();
 
 		assertEquals(Integer.class, referenceModel.getBeanClass());
 		assertEquals(Integer.class, referenceModel.getServiceType());
@@ -565,7 +565,7 @@
 
 		InjectionPoint injectionPoint = new MockInjectionPoint(C.class.getMethod("set", Callable.class).getParameters()[0]);
 
-		new ReferenceModel.Builder().injectionPoint(injectionPoint).build();
+		new ReferenceModel.Builder(injectionPoint.getAnnotated()).type(injectionPoint.getType()).build();
 	}
 
 	@Test
@@ -581,7 +581,7 @@
 
 		InjectionPoint injectionPoint = new MockInjectionPoint(C.class.getMethod("set", Optional.class).getParameters()[0]);
 
-		ReferenceModel referenceModel = new ReferenceModel.Builder().injectionPoint(injectionPoint).build();
+		ReferenceModel referenceModel = new ReferenceModel.Builder(injectionPoint.getAnnotated()).type(injectionPoint.getType()).build();
 
 		assertEquals(Optional.class, referenceModel.getBeanClass());
 		assertEquals(Integer.class, referenceModel.getServiceType());
@@ -601,7 +601,7 @@
 
 		InjectionPoint injectionPoint = new MockInjectionPoint(C.class.getMethod("set", Integer.class).getParameters()[0]);
 
-		new ReferenceModel.Builder().injectionPoint(injectionPoint).build();
+		new ReferenceModel.Builder(injectionPoint.getAnnotated()).type(injectionPoint.getType()).build();
 	}
 
 	@Test(expected = IllegalArgumentException.class)
@@ -613,7 +613,7 @@
 
 		InjectionPoint injectionPoint = new MockInjectionPoint(C.class.getMethod("set", Optional.class).getParameters()[0]);
 
-		new ReferenceModel.Builder().injectionPoint(injectionPoint).build();
+		new ReferenceModel.Builder(injectionPoint.getAnnotated()).type(injectionPoint.getType()).build();
 	}
 
 	@Test(expected = IllegalArgumentException.class)
@@ -626,7 +626,7 @@
 
 		InjectionPoint injectionPoint = new MockInjectionPoint(C.class.getMethod("set", Collection.class).getParameters()[0]);
 
-		new ReferenceModel.Builder().injectionPoint(injectionPoint).build();
+		new ReferenceModel.Builder(injectionPoint.getAnnotated()).type(injectionPoint.getType()).build();
 	}
 
 	@Test(expected = IllegalArgumentException.class)
@@ -638,7 +638,7 @@
 
 		InjectionPoint injectionPoint = new MockInjectionPoint(C.class.getMethod("set", Collection.class).getParameters()[0]);
 
-		new ReferenceModel.Builder().injectionPoint(injectionPoint).build();
+		new ReferenceModel.Builder(injectionPoint.getAnnotated()).type(injectionPoint.getType()).build();
 	}
 
 	@Test
@@ -654,7 +654,7 @@
 
 		InjectionPoint injectionPoint = new MockInjectionPoint(C.class.getMethod("set", Collection.class).getParameters()[0]);
 
-		ReferenceModel referenceModel = new ReferenceModel.Builder().injectionPoint(injectionPoint).build();
+		ReferenceModel referenceModel = new ReferenceModel.Builder(injectionPoint.getAnnotated()).type(injectionPoint.getType()).build();
 
 		assertEquals(Collection.class, referenceModel.getBeanClass());
 		assertEquals(Integer.class, referenceModel.getServiceType());
@@ -680,7 +680,7 @@
 
 		InjectionPoint injectionPoint = new MockInjectionPoint(C.class.getMethod("set", Collection.class).getParameters()[0]);
 
-		ReferenceModel referenceModel = new ReferenceModel.Builder().injectionPoint(injectionPoint).build();
+		ReferenceModel referenceModel = new ReferenceModel.Builder(injectionPoint.getAnnotated()).type(injectionPoint.getType()).build();
 
 		assertEquals(Collection.class, referenceModel.getBeanClass());
 		assertEquals(Integer.class, referenceModel.getServiceType());
@@ -704,7 +704,7 @@
 
 		InjectionPoint injectionPoint = new MockInjectionPoint(C.class.getMethod("set", Collection.class).getParameters()[0]);
 
-		ReferenceModel referenceModel = new ReferenceModel.Builder().injectionPoint(injectionPoint).build();
+		ReferenceModel referenceModel = new ReferenceModel.Builder(injectionPoint.getAnnotated()).type(injectionPoint.getType()).build();
 
 		assertEquals(Collection.class, referenceModel.getBeanClass());
 		assertEquals(Integer.class, referenceModel.getServiceType());
@@ -728,7 +728,7 @@
 
 		InjectionPoint injectionPoint = new MockInjectionPoint(C.class.getMethod("set", Collection.class).getParameters()[0]);
 
-		ReferenceModel referenceModel = new ReferenceModel.Builder().injectionPoint(injectionPoint).build();
+		ReferenceModel referenceModel = new ReferenceModel.Builder(injectionPoint.getAnnotated()).type(injectionPoint.getType()).build();
 
 		assertEquals(Collection.class, referenceModel.getBeanClass());
 		assertEquals(Integer.class, referenceModel.getServiceType());
@@ -748,7 +748,7 @@
 
 		InjectionPoint injectionPoint = new MockInjectionPoint(C.class.getMethod("set", Collection.class).getParameters()[0]);
 
-		new ReferenceModel.Builder().injectionPoint(injectionPoint).build();
+		new ReferenceModel.Builder(injectionPoint.getAnnotated()).type(injectionPoint.getType()).build();
 	}
 
 	@Test(expected = IllegalArgumentException.class)
@@ -761,7 +761,7 @@
 
 		InjectionPoint injectionPoint = new MockInjectionPoint(C.class.getMethod("set", List.class).getParameters()[0]);
 
-		new ReferenceModel.Builder().injectionPoint(injectionPoint).build();
+		new ReferenceModel.Builder(injectionPoint.getAnnotated()).type(injectionPoint.getType()).build();
 	}
 
 	@Test(expected = IllegalArgumentException.class)
@@ -773,7 +773,7 @@
 
 		InjectionPoint injectionPoint = new MockInjectionPoint(C.class.getMethod("set", List.class).getParameters()[0]);
 
-		new ReferenceModel.Builder().injectionPoint(injectionPoint).build();
+		new ReferenceModel.Builder(injectionPoint.getAnnotated()).type(injectionPoint.getType()).build();
 	}
 
 	@Test
@@ -789,7 +789,7 @@
 
 		InjectionPoint injectionPoint = new MockInjectionPoint(C.class.getMethod("set", List.class).getParameters()[0]);
 
-		ReferenceModel referenceModel = new ReferenceModel.Builder().injectionPoint(injectionPoint).build();
+		ReferenceModel referenceModel = new ReferenceModel.Builder(injectionPoint.getAnnotated()).type(injectionPoint.getType()).build();
 
 		assertEquals(List.class, referenceModel.getBeanClass());
 		assertEquals(Integer.class, referenceModel.getServiceType());
@@ -815,7 +815,7 @@
 
 		InjectionPoint injectionPoint = new MockInjectionPoint(C.class.getMethod("set", List.class).getParameters()[0]);
 
-		ReferenceModel referenceModel = new ReferenceModel.Builder().injectionPoint(injectionPoint).build();
+		ReferenceModel referenceModel = new ReferenceModel.Builder(injectionPoint.getAnnotated()).type(injectionPoint.getType()).build();
 
 		assertEquals(List.class, referenceModel.getBeanClass());
 		assertEquals(Integer.class, referenceModel.getServiceType());
@@ -839,7 +839,7 @@
 
 		InjectionPoint injectionPoint = new MockInjectionPoint(C.class.getMethod("set", List.class).getParameters()[0]);
 
-		ReferenceModel referenceModel = new ReferenceModel.Builder().injectionPoint(injectionPoint).build();
+		ReferenceModel referenceModel = new ReferenceModel.Builder(injectionPoint.getAnnotated()).type(injectionPoint.getType()).build();
 
 		assertEquals(List.class, referenceModel.getBeanClass());
 		assertEquals(Integer.class, referenceModel.getServiceType());
@@ -863,7 +863,7 @@
 
 		InjectionPoint injectionPoint = new MockInjectionPoint(C.class.getMethod("set", List.class).getParameters()[0]);
 
-		ReferenceModel referenceModel = new ReferenceModel.Builder().injectionPoint(injectionPoint).build();
+		ReferenceModel referenceModel = new ReferenceModel.Builder(injectionPoint.getAnnotated()).type(injectionPoint.getType()).build();
 
 		assertEquals(List.class, referenceModel.getBeanClass());
 		assertEquals(Integer.class, referenceModel.getServiceType());
@@ -883,6 +883,6 @@
 
 		InjectionPoint injectionPoint = new MockInjectionPoint(C.class.getMethod("set", List.class).getParameters()[0]);
 
-		new ReferenceModel.Builder().injectionPoint(injectionPoint).build();
+		new ReferenceModel.Builder(injectionPoint.getAnnotated()).type(injectionPoint.getType()).build();
 	}
 }
\ No newline at end of file
diff --git a/cdi-extender/src/test/java/org/apache/aries/cdi/container/internal/model/ReferenceModel_TupleTest.java b/cdi-extender/src/test/java/org/apache/aries/cdi/container/internal/model/ReferenceModel_TupleTest.java
index 605724c..97bcbef 100644
--- a/cdi-extender/src/test/java/org/apache/aries/cdi/container/internal/model/ReferenceModel_TupleTest.java
+++ b/cdi-extender/src/test/java/org/apache/aries/cdi/container/internal/model/ReferenceModel_TupleTest.java
@@ -45,7 +45,7 @@
 
 		InjectionPoint injectionPoint = new MockInjectionPoint(C.class.getField("m"));
 
-		new ReferenceModel.Builder().injectionPoint(injectionPoint).build();
+		new ReferenceModel.Builder(injectionPoint.getAnnotated()).type(injectionPoint.getType()).build();
 	}
 
 	@Test(expected = IllegalArgumentException.class)
@@ -58,7 +58,7 @@
 
 		InjectionPoint injectionPoint = new MockInjectionPoint(C.class.getField("m"));
 
-		new ReferenceModel.Builder().injectionPoint(injectionPoint).build();
+		new ReferenceModel.Builder(injectionPoint.getAnnotated()).type(injectionPoint.getType()).build();
 	}
 
 	@Test(expected = IllegalArgumentException.class)
@@ -71,7 +71,7 @@
 
 		InjectionPoint injectionPoint = new MockInjectionPoint(C.class.getField("m"));
 
-		new ReferenceModel.Builder().injectionPoint(injectionPoint).build();
+		new ReferenceModel.Builder(injectionPoint.getAnnotated()).type(injectionPoint.getType()).build();
 	}
 
 	@Test
@@ -88,7 +88,7 @@
 
 		InjectionPoint injectionPoint = new MockInjectionPoint(C.class.getField("m"));
 
-		ReferenceModel referenceModel = new ReferenceModel.Builder().injectionPoint(injectionPoint).build();
+		ReferenceModel referenceModel = new ReferenceModel.Builder(injectionPoint.getAnnotated()).type(injectionPoint.getType()).build();
 
 		assertEquals(Map.Entry.class, referenceModel.getBeanClass());
 		assertEquals(Integer.class, referenceModel.getServiceType());
@@ -113,7 +113,7 @@
 
 		InjectionPoint injectionPoint = new MockInjectionPoint(C.class.getField("m"));
 
-		ReferenceModel referenceModel = new ReferenceModel.Builder().injectionPoint(injectionPoint).build();
+		ReferenceModel referenceModel = new ReferenceModel.Builder(injectionPoint.getAnnotated()).type(injectionPoint.getType()).build();
 
 		assertEquals(Map.Entry.class, referenceModel.getBeanClass());
 		assertEquals(Integer.class, referenceModel.getServiceType());
@@ -134,7 +134,7 @@
 
 		InjectionPoint injectionPoint = new MockInjectionPoint(C.class.getField("m"));
 
-		new ReferenceModel.Builder().injectionPoint(injectionPoint).build();
+		new ReferenceModel.Builder(injectionPoint.getAnnotated()).type(injectionPoint.getType()).build();
 	}
 
 	@Test(expected = IllegalArgumentException.class)
@@ -147,7 +147,7 @@
 
 		InjectionPoint injectionPoint = new MockInjectionPoint(C.class.getField("m"));
 
-		new ReferenceModel.Builder().injectionPoint(injectionPoint).build();
+		new ReferenceModel.Builder(injectionPoint.getAnnotated()).type(injectionPoint.getType()).build();
 	}
 
 	@Test(expected = IllegalArgumentException.class)
@@ -161,7 +161,7 @@
 
 		InjectionPoint injectionPoint = new MockInjectionPoint(C.class.getField("m"));
 
-		new ReferenceModel.Builder().injectionPoint(injectionPoint).build();
+		new ReferenceModel.Builder(injectionPoint.getAnnotated()).type(injectionPoint.getType()).build();
 	}
 
 	@Test(expected = IllegalArgumentException.class)
@@ -174,7 +174,7 @@
 
 		InjectionPoint injectionPoint = new MockInjectionPoint(C.class.getField("m"));
 
-		new ReferenceModel.Builder().injectionPoint(injectionPoint).build();
+		new ReferenceModel.Builder(injectionPoint.getAnnotated()).type(injectionPoint.getType()).build();
 	}
 
 	@Test(expected = IllegalArgumentException.class)
@@ -187,7 +187,7 @@
 
 		InjectionPoint injectionPoint = new MockInjectionPoint(C.class.getField("m"));
 
-		new ReferenceModel.Builder().injectionPoint(injectionPoint).build();
+		new ReferenceModel.Builder(injectionPoint.getAnnotated()).type(injectionPoint.getType()).build();
 	}
 
 	@Test(expected = IllegalArgumentException.class)
@@ -200,7 +200,7 @@
 
 		InjectionPoint injectionPoint = new MockInjectionPoint(C.class.getField("m"));
 
-		new ReferenceModel.Builder().injectionPoint(injectionPoint).build();
+		new ReferenceModel.Builder(injectionPoint.getAnnotated()).type(injectionPoint.getType()).build();
 	}
 
 	@Test(expected = IllegalArgumentException.class)
@@ -214,7 +214,7 @@
 
 		InjectionPoint injectionPoint = new MockInjectionPoint(C.class.getField("m"));
 
-		new ReferenceModel.Builder().injectionPoint(injectionPoint).build();
+		new ReferenceModel.Builder(injectionPoint.getAnnotated()).type(injectionPoint.getType()).build();
 	}
 
 	@Test
@@ -231,7 +231,7 @@
 
 		InjectionPoint injectionPoint = new MockInjectionPoint(C.class.getField("m"));
 
-		ReferenceModel referenceModel = new ReferenceModel.Builder().injectionPoint(injectionPoint).build();
+		ReferenceModel referenceModel = new ReferenceModel.Builder(injectionPoint.getAnnotated()).type(injectionPoint.getType()).build();
 
 		assertEquals(Map.Entry.class, referenceModel.getBeanClass());
 		assertEquals(Integer.class, referenceModel.getServiceType());
@@ -256,7 +256,7 @@
 
 		InjectionPoint injectionPoint = new MockInjectionPoint(C.class.getField("m"));
 
-		ReferenceModel referenceModel = new ReferenceModel.Builder().injectionPoint(injectionPoint).build();
+		ReferenceModel referenceModel = new ReferenceModel.Builder(injectionPoint.getAnnotated()).type(injectionPoint.getType()).build();
 
 		assertEquals(Map.Entry.class, referenceModel.getBeanClass());
 		assertEquals(Integer.class, referenceModel.getServiceType());
@@ -281,7 +281,7 @@
 
 		InjectionPoint injectionPoint = new MockInjectionPoint(C.class.getField("m"));
 
-		ReferenceModel referenceModel = new ReferenceModel.Builder().injectionPoint(injectionPoint).build();
+		ReferenceModel referenceModel = new ReferenceModel.Builder(injectionPoint.getAnnotated()).type(injectionPoint.getType()).build();
 
 		assertEquals(Map.Entry.class, referenceModel.getBeanClass());
 		assertEquals(Integer.class, referenceModel.getServiceType());
@@ -306,7 +306,7 @@
 
 		InjectionPoint injectionPoint = new MockInjectionPoint(C.class.getField("m"));
 
-		ReferenceModel referenceModel = new ReferenceModel.Builder().injectionPoint(injectionPoint).build();
+		ReferenceModel referenceModel = new ReferenceModel.Builder(injectionPoint.getAnnotated()).type(injectionPoint.getType()).build();
 
 		assertEquals(Map.Entry.class, referenceModel.getBeanClass());
 		assertEquals(Integer.class, referenceModel.getServiceType());
@@ -327,7 +327,7 @@
 
 		InjectionPoint injectionPoint = new MockInjectionPoint(C.class.getField("m"));
 
-		new ReferenceModel.Builder().injectionPoint(injectionPoint).build();
+		new ReferenceModel.Builder(injectionPoint.getAnnotated()).type(injectionPoint.getType()).build();
 	}
 
 	@Test(expected = IllegalArgumentException.class)
@@ -340,7 +340,7 @@
 
 		InjectionPoint injectionPoint = new MockInjectionPoint(C.class.getField("m"));
 
-		new ReferenceModel.Builder().injectionPoint(injectionPoint).build();
+		new ReferenceModel.Builder(injectionPoint.getAnnotated()).type(injectionPoint.getType()).build();
 	}
 
 	@Test(expected = IllegalArgumentException.class)
@@ -354,7 +354,7 @@
 
 		InjectionPoint injectionPoint = new MockInjectionPoint(C.class.getField("m"));
 
-		new ReferenceModel.Builder().injectionPoint(injectionPoint).build();
+		new ReferenceModel.Builder(injectionPoint.getAnnotated()).type(injectionPoint.getType()).build();
 	}
 
 	@Test(expected = IllegalArgumentException.class)
@@ -367,7 +367,7 @@
 
 		InjectionPoint injectionPoint = new MockInjectionPoint(C.class.getField("m"));
 
-		new ReferenceModel.Builder().injectionPoint(injectionPoint).build();
+		new ReferenceModel.Builder(injectionPoint.getAnnotated()).type(injectionPoint.getType()).build();
 	}
 
 	@Test(expected = IllegalArgumentException.class)
@@ -380,7 +380,7 @@
 
 		InjectionPoint injectionPoint = new MockInjectionPoint(C.class.getField("m"));
 
-		new ReferenceModel.Builder().injectionPoint(injectionPoint).build();
+		new ReferenceModel.Builder(injectionPoint.getAnnotated()).type(injectionPoint.getType()).build();
 	}
 
 	@Test(expected = IllegalArgumentException.class)
@@ -393,7 +393,7 @@
 
 		InjectionPoint injectionPoint = new MockInjectionPoint(C.class.getField("m"));
 
-		new ReferenceModel.Builder().injectionPoint(injectionPoint).build();
+		new ReferenceModel.Builder(injectionPoint.getAnnotated()).type(injectionPoint.getType()).build();
 	}
 
 	@Test(expected = IllegalArgumentException.class)
@@ -406,7 +406,7 @@
 
 		InjectionPoint injectionPoint = new MockInjectionPoint(C.class.getField("m"));
 
-		new ReferenceModel.Builder().injectionPoint(injectionPoint).build();
+		new ReferenceModel.Builder(injectionPoint.getAnnotated()).type(injectionPoint.getType()).build();
 	}
 
 	@Test
@@ -423,7 +423,7 @@
 
 		InjectionPoint injectionPoint = new MockInjectionPoint(C.class.getField("m"));
 
-		ReferenceModel referenceModel = new ReferenceModel.Builder().injectionPoint(injectionPoint).build();
+		ReferenceModel referenceModel = new ReferenceModel.Builder(injectionPoint.getAnnotated()).type(injectionPoint.getType()).build();
 
 		assertEquals(Map.Entry.class, referenceModel.getBeanClass());
 		assertEquals(Integer.class, referenceModel.getServiceType());
@@ -445,7 +445,7 @@
 
 		InjectionPoint injectionPoint = new MockInjectionPoint(C.class.getField("m"));
 
-		new ReferenceModel.Builder().injectionPoint(injectionPoint).build();
+		new ReferenceModel.Builder(injectionPoint.getAnnotated()).type(injectionPoint.getType()).build();
 	}
 
 	@Test
@@ -462,7 +462,7 @@
 
 		InjectionPoint injectionPoint = new MockInjectionPoint(C.class.getField("m"));
 
-		ReferenceModel referenceModel = new ReferenceModel.Builder().injectionPoint(injectionPoint).build();
+		ReferenceModel referenceModel = new ReferenceModel.Builder(injectionPoint.getAnnotated()).type(injectionPoint.getType()).build();
 
 		assertEquals(Collection.class, referenceModel.getBeanClass());
 		assertEquals(Foo.class, referenceModel.getServiceType());
@@ -487,7 +487,7 @@
 
 		InjectionPoint injectionPoint = new MockInjectionPoint(C.class.getField("m"));
 
-		ReferenceModel referenceModel = new ReferenceModel.Builder().injectionPoint(injectionPoint).build();
+		ReferenceModel referenceModel = new ReferenceModel.Builder(injectionPoint.getAnnotated()).type(injectionPoint.getType()).build();
 
 		assertEquals(Collection.class, referenceModel.getBeanClass());
 		assertEquals(Integer.class, referenceModel.getServiceType());
@@ -508,7 +508,7 @@
 
 		InjectionPoint injectionPoint = new MockInjectionPoint(C.class.getField("m"));
 
-		new ReferenceModel.Builder().injectionPoint(injectionPoint).build();
+		new ReferenceModel.Builder(injectionPoint.getAnnotated()).type(injectionPoint.getType()).build();
 	}
 
 	@Test(expected = IllegalArgumentException.class)
@@ -522,7 +522,7 @@
 
 		InjectionPoint injectionPoint = new MockInjectionPoint(C.class.getField("m"));
 
-		new ReferenceModel.Builder().injectionPoint(injectionPoint).build();
+		new ReferenceModel.Builder(injectionPoint.getAnnotated()).type(injectionPoint.getType()).build();
 	}
 
 	@Test
@@ -539,7 +539,7 @@
 
 		InjectionPoint injectionPoint = new MockInjectionPoint(C.class.getField("m"));
 
-		ReferenceModel referenceModel = new ReferenceModel.Builder().injectionPoint(injectionPoint).build();
+		ReferenceModel referenceModel = new ReferenceModel.Builder(injectionPoint.getAnnotated()).type(injectionPoint.getType()).build();
 
 		assertEquals(List.class, referenceModel.getBeanClass());
 		assertEquals(Foo.class, referenceModel.getServiceType());
@@ -564,7 +564,7 @@
 
 		InjectionPoint injectionPoint = new MockInjectionPoint(C.class.getField("m"));
 
-		ReferenceModel referenceModel = new ReferenceModel.Builder().injectionPoint(injectionPoint).build();
+		ReferenceModel referenceModel = new ReferenceModel.Builder(injectionPoint.getAnnotated()).type(injectionPoint.getType()).build();
 
 		assertEquals(List.class, referenceModel.getBeanClass());
 		assertEquals(Integer.class, referenceModel.getServiceType());
@@ -585,7 +585,7 @@
 
 		InjectionPoint injectionPoint = new MockInjectionPoint(C.class.getField("m"));
 
-		new ReferenceModel.Builder().injectionPoint(injectionPoint).build();
+		new ReferenceModel.Builder(injectionPoint.getAnnotated()).type(injectionPoint.getType()).build();
 	}
 
 	@Test(expected = IllegalArgumentException.class)
@@ -598,7 +598,7 @@
 
 		InjectionPoint injectionPoint = new MockInjectionPoint(C.class.getField("m"));
 
-		new ReferenceModel.Builder().injectionPoint(injectionPoint).build();
+		new ReferenceModel.Builder(injectionPoint.getAnnotated()).type(injectionPoint.getType()).build();
 	}
 
 	@Test(expected = IllegalArgumentException.class)
@@ -611,7 +611,7 @@
 
 		InjectionPoint injectionPoint = new MockInjectionPoint(C.class.getField("m"));
 
-		new ReferenceModel.Builder().injectionPoint(injectionPoint).build();
+		new ReferenceModel.Builder(injectionPoint.getAnnotated()).type(injectionPoint.getType()).build();
 	}
 
 }
\ No newline at end of file
diff --git a/cdi-extender/src/test/java/org/apache/aries/cdi/container/internal/phase/ContainerBootstrapTest.java b/cdi-extender/src/test/java/org/apache/aries/cdi/container/internal/phase/ContainerBootstrapTest.java
index 74b70db..be14d4a 100644
--- a/cdi-extender/src/test/java/org/apache/aries/cdi/container/internal/phase/ContainerBootstrapTest.java
+++ b/cdi-extender/src/test/java/org/apache/aries/cdi/container/internal/phase/ContainerBootstrapTest.java
@@ -14,8 +14,11 @@
 
 package org.apache.aries.cdi.container.internal.phase;
 
-import static org.junit.Assert.*;
-import static org.mockito.Mockito.*;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertTrue;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.when;
 
 import java.util.Arrays;
 import java.util.HashMap;
@@ -35,7 +38,10 @@
 import org.apache.aries.cdi.container.test.BaseCDIBundleTest;
 import org.apache.aries.cdi.container.test.TestUtil;
 import org.apache.aries.cdi.container.test.beans.FooService;
+import org.apache.aries.cdi.spi.CDIContainerInitializer;
+import org.junit.Ignore;
 import org.junit.Test;
+import org.osgi.framework.ServiceObjects;
 import org.osgi.framework.wiring.BundleWiring;
 import org.osgi.namespace.extender.ExtenderNamespace;
 import org.osgi.service.cdi.CDIConstants;
@@ -47,6 +53,7 @@
 
 public class ContainerBootstrapTest extends BaseCDIBundleTest {
 
+	@Ignore
 	@Test
 	public void test_publishServices() throws Exception {
 		Map<String, Object> attributes = new HashMap<>();
@@ -73,11 +80,15 @@
 		componentDTO.instances = new CopyOnWriteArrayList<>();
 		componentDTO.template = containerState.containerDTO().template.components.get(0);
 
+		@SuppressWarnings("unchecked")
+		ServiceTracker<CDIContainerInitializer, ServiceObjects<CDIContainerInitializer>> serviceTracker = mock(ServiceTracker.class);
+
 		ContainerBootstrap containerBootstrap = new ContainerBootstrap(
-			containerState,
+			containerState, serviceTracker,
 			new ConfigurationListener.Builder(containerState),
 			new SingleComponent.Builder(containerState, null),
-			new FactoryComponent.Builder(containerState, null));
+			new FactoryComponent.Builder(containerState, null),
+			mock(ServiceTracker.class));
 
 		ExtendedComponentInstanceDTO componentInstanceDTO = new ExtendedComponentInstanceDTO(containerState, new ContainerActivator.Builder(containerState, containerBootstrap));
 		componentInstanceDTO.activations = new CopyOnWriteArrayList<>();
@@ -93,7 +104,7 @@
 
 		Promise<Boolean> p0 = containerState.addCallback(
 			(CheckedCallback<Boolean, Boolean>) op -> {
-				return op.mode == Op.Mode.OPEN && op.type == Op.Type.CONTAINER_PUBLISH_SERVICES;
+				return op.mode == Op.Mode.OPEN && op.type == Op.Type.CONTAINER_INIT_COMPONENTS;
 			}
 		);
 
diff --git a/cdi-extender/src/test/java/org/apache/aries/cdi/container/internal/phase/TemplatesTests.java b/cdi-extender/src/test/java/org/apache/aries/cdi/container/internal/phase/TemplatesTests.java
index d854f66..4e4b7fd 100644
--- a/cdi-extender/src/test/java/org/apache/aries/cdi/container/internal/phase/TemplatesTests.java
+++ b/cdi-extender/src/test/java/org/apache/aries/cdi/container/internal/phase/TemplatesTests.java
@@ -14,10 +14,12 @@
 
 package org.apache.aries.cdi.container.internal.phase;
 
+import static java.util.Collections.singletonList;
 import static org.junit.Assert.*;
 import static org.mockito.Mockito.*;
 
 import java.util.Arrays;
+import java.util.Comparator;
 import java.util.HashMap;
 import java.util.List;
 import java.util.Map;
@@ -60,7 +62,7 @@
 
 		assertNotNull(containerDTO.template);
 		List<ComponentTemplateDTO> components = TestUtil.sort(
-			containerDTO.template.components, (a, b) -> a.name.compareTo(b.name));
+			containerDTO.template.components, Comparator.comparing(a -> a.name));
 		assertEquals(2, components.size());
 
 		{
@@ -134,7 +136,7 @@
 
 		assertNotNull(containerDTO.template);
 		List<ComponentTemplateDTO> components = TestUtil.sort(
-			containerDTO.template.components, (a, b) -> a.name.compareTo(b.name));
+			containerDTO.template.components, Comparator.comparing(a -> a.name));
 		assertEquals(3, components.size());
 
 		{
@@ -148,7 +150,7 @@
 				assertEquals(Arrays.asList("org.apache.aries.cdi.container.test.beans.Bar"), at.serviceClasses);
 			}
 
-			assertEquals(1, ct.beans.size());
+			assertEquals(2, ct.beans.size());
 			assertEquals(1, ct.configurations.size());
 			assertEquals("barService", ct.name);
 			assertEquals(Maps.of(), ct.properties);
@@ -175,7 +177,7 @@
 				ActivationTemplateDTO at = ct.activations.get(0);
 				assertEquals(Maps.of(), at.properties);
 				assertEquals(ServiceScope.SINGLETON, at.scope);
-				assertEquals(Arrays.asList("org.apache.aries.cdi.container.test.beans.Foo"), at.serviceClasses);
+				assertEquals(singletonList("org.apache.aries.cdi.container.test.beans.Foo"), at.serviceClasses);
 			}
 
 			assertEquals(2, ct.beans.size());
@@ -219,7 +221,7 @@
 		assertNotNull(containerDTO.template);
 
 		List<ComponentTemplateDTO> components = TestUtil.sort(
-			containerDTO.template.components, (a, b) -> a.name.compareTo(b.name));
+			containerDTO.template.components, Comparator.comparing(a -> a.name));
 		assertEquals(3, components.size());
 
 		{ // component "barService"
@@ -233,7 +235,7 @@
 				assertEquals(Arrays.asList("org.apache.aries.cdi.container.test.beans.Bar"), at.serviceClasses);
 			}
 
-			assertEquals(1, ct.beans.size());
+			assertEquals(2, ct.beans.size());
 			assertEquals("org.apache.aries.cdi.container.test.beans.BarService", ct.beans.get(0));
 			assertEquals(1, ct.configurations.size());
 			assertEquals("barService", ct.name);
diff --git a/cdi-extender/src/test/java/org/apache/aries/cdi/container/test/ContainerListenerTest.java b/cdi-extender/src/test/java/org/apache/aries/cdi/container/test/ContainerListenerTest.java
new file mode 100644
index 0000000..20ba3af
--- /dev/null
+++ b/cdi-extender/src/test/java/org/apache/aries/cdi/container/test/ContainerListenerTest.java
@@ -0,0 +1,217 @@
+/**
+ * Licensed 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
+ * <p>
+ * http://www.apache.org/licenses/LICENSE-2.0
+ * <p>
+ * 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.aries.cdi.container.test;
+
+import static java.util.Arrays.asList;
+import static java.util.Collections.singletonList;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertTrue;
+import static org.junit.Assert.fail;
+
+import java.lang.reflect.Proxy;
+import java.net.URL;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Map;
+import java.util.function.BiConsumer;
+import java.util.stream.Stream;
+
+import javax.enterprise.inject.spi.Extension;
+
+import org.apache.aries.cdi.container.internal.container.ConfigurationListener;
+import org.apache.aries.cdi.container.internal.container.ContainerBootstrap;
+import org.apache.aries.cdi.container.internal.container.ContainerState;
+import org.apache.aries.cdi.container.internal.model.FactoryComponent;
+import org.apache.aries.cdi.container.internal.model.SingleComponent;
+import org.apache.aries.cdi.container.internal.spi.ContainerListener;
+import org.apache.aries.cdi.container.internal.util.Logs;
+import org.apache.aries.cdi.spi.CDIContainerInitializer;
+import org.apache.aries.cdi.spi.loader.SpiLoader;
+import org.junit.Test;
+import org.osgi.framework.BundleContext;
+import org.osgi.framework.ServiceObjects;
+import org.osgi.framework.ServiceReference;
+import org.osgi.service.cdi.runtime.dto.ComponentDTO;
+import org.osgi.util.tracker.ServiceTracker;
+
+public class ContainerListenerTest extends BaseCDIBundleTest {
+    private enum State {
+        BEFORE_START, STARTED, STOPPED
+    }
+
+    @Test
+    public void ensureListenerIsCalledForSuccesses() throws Exception {
+        final EmptyCdiContainer cdiContainer = new EmptyCdiContainer();
+        doRun(cdiContainer, (containerBootstrap, listenerCalls) -> {
+            assertTrue(listenerCalls.isEmpty());
+            assertEquals(State.BEFORE_START, cdiContainer.state);
+            containerBootstrap.open();
+            assertEquals(singletonList("onStartSuccess"), listenerCalls);
+            assertEquals(State.STARTED, cdiContainer.state);
+            assertTrue(containerBootstrap.close());
+            assertEquals(asList("onStartSuccess", "onStopSuccess"), listenerCalls);
+            assertEquals(State.STOPPED, cdiContainer.state);
+        });
+    }
+
+    @Test
+    public void ensureListenerIsCalledForFailedStop() throws Exception {
+        final EmptyCdiContainer cdiContainer = new EmptyCdiContainer();
+        cdiContainer.failAtState = State.STOPPED;
+        doRun(cdiContainer, (containerBootstrap, listenerCalls) -> {
+            assertTrue(listenerCalls.isEmpty());
+            assertEquals(State.BEFORE_START, cdiContainer.state);
+            containerBootstrap.open();
+            assertEquals(singletonList("onStartSuccess"), listenerCalls);
+            assertEquals(State.STARTED, cdiContainer.state);
+            assertFalse(containerBootstrap.close());
+            assertEquals(asList("onStartSuccess", "onStopError"), listenerCalls);
+        });
+    }
+
+    @Test
+    public void ensureListenerIsCalledForFailedStartup() throws Exception {
+        final EmptyCdiContainer cdiContainer = new EmptyCdiContainer();
+        cdiContainer.failAtState = State.STARTED;
+        doRun(cdiContainer, (containerBootstrap, listenerCalls) -> {
+            assertTrue(listenerCalls.isEmpty());
+            assertEquals(State.BEFORE_START, cdiContainer.state);
+            try {
+                containerBootstrap.open();
+                fail();
+            } catch (final RuntimeException re) {
+                // expected
+            }
+            assertEquals(singletonList("onStartError"), listenerCalls);
+        });
+    }
+
+    private void doRun(EmptyCdiContainer cdiContainer, final BiConsumer<ContainerBootstrap, List<String>> test) throws Exception {
+        ContainerState containerState = new ContainerState(
+                bundle, ccrBundle, ccrChangeCount, promiseFactory, TestUtil.mockCaSt(bundle),
+                new Logs.Builder(bundle.getBundleContext()).build());
+
+        // ensure it starts, this is not really used in this test but required due to current open() impl
+        ComponentDTO componentDTO = new ComponentDTO();
+        componentDTO.enabled = false;
+        containerState.containerDTO().components.add(componentDTO);
+
+        List<String> listenerCalls = new ArrayList<>();
+        ContainerListener listenerSpy = ContainerListener.class.cast(Proxy.newProxyInstance(
+                Thread.currentThread().getContextClassLoader(),
+                new Class<?>[]{ContainerListener.class},
+                (proxy, method, args) -> {
+                    listenerCalls.add(method.getName());
+                    return null; // all methods return void
+                }));
+
+        final MockServiceRegistration<ContainerListener> initializer = new MockServiceRegistration<>(
+                new MockServiceReference<>(bundle, listenerSpy, new String[]{CDIContainerInitializer.class.getName()}),
+                TestUtil.serviceRegistrations,
+                TestUtil.serviceListeners);
+        final MockServiceRegistration<ContainerListener> listener = new MockServiceRegistration<>(
+                new MockServiceReference<>(bundle, listenerSpy, new String[]{ContainerListener.class.getName()}),
+                TestUtil.serviceRegistrations,
+                TestUtil.serviceListeners);
+        ContainerBootstrap containerBootstrap = new ContainerBootstrap(
+                containerState,
+                new ServiceTracker<CDIContainerInitializer, ServiceObjects<CDIContainerInitializer>>(
+                        bundle.getBundleContext(), CDIContainerInitializer.class, null) {
+                    @Override
+                    public ServiceObjects<CDIContainerInitializer> getService() {
+                        return cdiContainer;
+                    }
+                },
+                new ConfigurationListener.Builder(containerState),
+                new SingleComponent.Builder(containerState, null),
+                new FactoryComponent.Builder(containerState, null),
+                new ServiceTracker<ContainerListener, ContainerListener>(bundle.getBundleContext(), ContainerListener.class, null) {
+                    @Override
+                    public ServiceReference<ContainerListener>[] getServiceReferences() {
+                        return new ServiceReference[] { listener.getReference() };
+                    }
+                });
+
+        try {
+            test.accept(containerBootstrap, listenerCalls);
+        } finally {
+            Stream.of(initializer, listener).forEach(TestUtil.serviceRegistrations::remove);
+        }
+    }
+
+    private static class EmptyCdiContainer implements ServiceObjects<CDIContainerInitializer> {
+        private State state = State.BEFORE_START;
+        private State failAtState;
+
+        @Override
+        public CDIContainerInitializer getService() {
+            return new CDIContainerInitializer() {
+                @Override
+                public CDIContainerInitializer addBeanClasses(Class<?>... classes) {
+                    return this;
+                }
+
+                @Override
+                public CDIContainerInitializer addBeanXmls(URL... beanXmls) {
+                    return this;
+                }
+
+                @Override
+                public CDIContainerInitializer addExtension(Extension extension, Map<String, Object> properties) {
+                    return this;
+                }
+
+                @Override
+                public CDIContainerInitializer addProperty(String key, Object value) {
+                    return this;
+                }
+
+                @Override
+                public CDIContainerInitializer setClassLoader(SpiLoader spiLoader) {
+                    return this;
+                }
+
+                @Override
+                public CDIContainerInitializer setBundleContext(BundleContext bundleContext) {
+                    return this;
+                }
+
+                @Override
+                public AutoCloseable initialize() {
+                    state = State.STARTED;
+                    if (failAtState != null && failAtState == State.STARTED) {
+                        throw new RuntimeException("failed for test");
+                    }
+                    return () -> {
+                        if (failAtState != null && failAtState == State.STOPPED) {
+                            throw new RuntimeException("failed for test");
+                        }
+                        state = State.STOPPED;
+                    };
+                }
+            };
+        }
+
+        @Override
+        public void ungetService(final CDIContainerInitializer service) {
+            // no-op
+        }
+
+        @Override
+        public ServiceReference<CDIContainerInitializer> getServiceReference() {
+            return null;
+        }
+    }
+}
diff --git a/cdi-extender/src/test/java/org/apache/aries/cdi/container/test/MockBeanDeploymentArchive.java b/cdi-extender/src/test/java/org/apache/aries/cdi/container/test/MockBeanDeploymentArchive.java
deleted file mode 100644
index 0558319..0000000
--- a/cdi-extender/src/test/java/org/apache/aries/cdi/container/test/MockBeanDeploymentArchive.java
+++ /dev/null
@@ -1,69 +0,0 @@
-/**
- * Licensed 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.aries.cdi.container.test;
-
-import java.util.Arrays;
-import java.util.Collection;
-import java.util.Collections;
-import java.util.List;
-
-import org.jboss.weld.bootstrap.api.ServiceRegistry;
-import org.jboss.weld.bootstrap.api.helpers.SimpleServiceRegistry;
-import org.jboss.weld.bootstrap.spi.BeanDeploymentArchive;
-import org.jboss.weld.bootstrap.spi.BeansXml;
-import org.jboss.weld.ejb.spi.EjbDescriptor;
-
-public class MockBeanDeploymentArchive implements BeanDeploymentArchive {
-
-	public MockBeanDeploymentArchive(String id, String... beanClasses) {
-		_id = id;
-		_beanClasses = Arrays.asList(beanClasses);
-	}
-
-	@Override
-	public Collection<BeanDeploymentArchive> getBeanDeploymentArchives() {
-		return Collections.emptyList();
-	}
-
-	@Override
-	public Collection<String> getBeanClasses() {
-		return _beanClasses;
-	}
-
-	@Override
-	public BeansXml getBeansXml() {
-		return BeansXml.EMPTY_BEANS_XML;
-	}
-
-	@Override
-	public Collection<EjbDescriptor<?>> getEjbs() {
-		return Collections.emptyList();
-	}
-
-	@Override
-	public ServiceRegistry getServices() {
-		return _services;
-	}
-
-	@Override
-	public String getId() {
-		return _id;
-	}
-
-	private final List<String> _beanClasses;
-	private final String _id;
-	private final ServiceRegistry _services = new SimpleServiceRegistry();
-
-}
\ No newline at end of file
diff --git a/cdi-extender/src/test/java/org/apache/aries/cdi/container/test/MockCdiContainer.java b/cdi-extender/src/test/java/org/apache/aries/cdi/container/test/MockCdiContainer.java
deleted file mode 100644
index 331b726..0000000
--- a/cdi-extender/src/test/java/org/apache/aries/cdi/container/test/MockCdiContainer.java
+++ /dev/null
@@ -1,89 +0,0 @@
-/**
- * Licensed 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.aries.cdi.container.test;
-
-import java.util.Collections;
-import java.util.List;
-import java.util.Set;
-
-import javax.enterprise.inject.Any;
-import javax.enterprise.inject.spi.Bean;
-import javax.enterprise.inject.spi.BeanManager;
-import javax.enterprise.inject.spi.Extension;
-
-import org.apache.aries.cdi.container.internal.container.ContainerDeployment;
-import org.apache.aries.cdi.container.internal.container.ContainerEnvironment;
-import org.jboss.weld.bootstrap.WeldBootstrap;
-import org.jboss.weld.bootstrap.spi.BeanDeploymentArchive;
-import org.jboss.weld.bootstrap.spi.Deployment;
-import org.jboss.weld.bootstrap.spi.Metadata;
-import org.junit.Assert;
-
-public class MockCdiContainer implements AutoCloseable {
-
-	public MockCdiContainer(String name, String... beanClasses) {
-		this(name, Collections.emptyList(), beanClasses);
-	}
-
-	public MockCdiContainer(String name, List<Metadata<Extension>> extensions, String... beanClasses) {
-		_bda = new MockBeanDeploymentArchive(name, beanClasses);
-
-		Deployment deployment = new ContainerDeployment(extensions, _bda);
-
-		WeldBootstrap bootstrap = new WeldBootstrap();
-
-		bootstrap.startExtensions(extensions);
-		bootstrap.startContainer(new ContainerEnvironment(), deployment);
-		bootstrap.startInitialization();
-		bootstrap.deployBeans();
-		bootstrap.validateBeans();
-		bootstrap.endInitialization();
-
-		_bootstrap = bootstrap;
-	}
-
-	@Override
-	public void close() {
-		_bootstrap.shutdown();
-	}
-
-	public Bean<?> getBean(Class<?> clazz) {
-		final BeanManager managerImpl = getBeanManager();
-
-		Set<javax.enterprise.inject.spi.Bean<?>> beans =
-			managerImpl.getBeans(clazz, Any.Literal.INSTANCE);
-
-		Assert.assertFalse(beans.isEmpty());
-
-		return managerImpl.resolve(beans);
-	}
-
-	public BeanManager getBeanManager() {
-		if (_beanManager != null) {
-			return _beanManager;
-		}
-
-		return _beanManager = _bootstrap.getManager(_bda);
-	}
-
-	public WeldBootstrap getBootstrap() {
-		return _bootstrap;
-	}
-
-	private final BeanDeploymentArchive _bda;
-	private BeanManager _beanManager;
-	private final WeldBootstrap _bootstrap;
-
-}
\ No newline at end of file
diff --git a/cdi-extender/src/test/java/org/apache/aries/cdi/container/test/MockInjectionPoint.java b/cdi-extender/src/test/java/org/apache/aries/cdi/container/test/MockInjectionPoint.java
index 413062b..edf0c55 100644
--- a/cdi-extender/src/test/java/org/apache/aries/cdi/container/test/MockInjectionPoint.java
+++ b/cdi-extender/src/test/java/org/apache/aries/cdi/container/test/MockInjectionPoint.java
@@ -28,8 +28,6 @@
 import javax.enterprise.inject.spi.InjectionPoint;
 import javax.inject.Qualifier;
 
-import org.jboss.weld.exceptions.IllegalArgumentException;
-
 public class MockInjectionPoint implements InjectionPoint {
 
 	public MockInjectionPoint(AnnotatedElement annotatedElement) {
diff --git a/cdi-extender/src/test/java/org/apache/aries/cdi/container/test/TestUtil.java b/cdi-extender/src/test/java/org/apache/aries/cdi/container/test/TestUtil.java
index 293a4e9..5da1cd3 100644
--- a/cdi-extender/src/test/java/org/apache/aries/cdi/container/test/TestUtil.java
+++ b/cdi-extender/src/test/java/org/apache/aries/cdi/container/test/TestUtil.java
@@ -41,8 +41,6 @@
 import org.apache.aries.cdi.container.internal.util.Filters;
 import org.apache.aries.cdi.container.internal.util.Logs;
 import org.apache.aries.cdi.container.internal.util.Sfl4jLogger;
-import org.jboss.weld.resources.spi.ResourceLoader;
-import org.jboss.weld.serialization.spi.ProxyServices;
 import org.mockito.stubbing.Answer;
 import org.osgi.framework.Bundle;
 import org.osgi.framework.BundleContext;
@@ -71,7 +69,7 @@
 public class TestUtil {
 
 	public static <T extends Comparable<T>> List<T> sort(Collection<T> set) {
-		return sort(set, (c1, c2) -> c1.getClass().getName().compareTo(c2.getClass().getName()));
+		return sort(set, Comparator.comparing(c -> c.getClass().getName()));
 	}
 
 	public static <T> List<T> sort(Collection<T> set, Comparator<T> comparator) {
@@ -126,12 +124,6 @@
 			public BeansModel beansModel() {
 				return beansModel;
 			}
-
-			@Override
-			public <T extends ResourceLoader & ProxyServices> T loader() {
-				return null;
-			}
-
 		};
 	}
 
diff --git a/cdi-extension-el-jsp/pom.xml b/cdi-extension-el-jsp/pom.xml
index 16acbd3..5b5c252 100644
--- a/cdi-extension-el-jsp/pom.xml
+++ b/cdi-extension-el-jsp/pom.xml
@@ -91,6 +91,7 @@
 		<dependency>
 			<groupId>org.jboss.weld</groupId>
 			<artifactId>weld-osgi-bundle</artifactId>
+			<version>${weld.version}</version>
 		</dependency>
 		<dependency>
 			<groupId>org.osgi</groupId>
diff --git a/cdi-extension-http/pom.xml b/cdi-extension-http/pom.xml
index b1a6a1c..51d3da0 100644
--- a/cdi-extension-http/pom.xml
+++ b/cdi-extension-http/pom.xml
@@ -81,6 +81,7 @@
 		<dependency>
 			<groupId>org.jboss.weld</groupId>
 			<artifactId>weld-osgi-bundle</artifactId>
+			<version>${weld.version}</version>
 		</dependency>
 		<dependency>
 			<groupId>org.osgi</groupId>
diff --git a/cdi-extension-http/src/main/java/org/apache/aries/cdi/extension/http/HttpExtension.java b/cdi-extension-http/src/main/java/org/apache/aries/cdi/extension/http/HttpExtension.java
index 7aed15f..5b0c55d 100644
--- a/cdi-extension-http/src/main/java/org/apache/aries/cdi/extension/http/HttpExtension.java
+++ b/cdi-extension-http/src/main/java/org/apache/aries/cdi/extension/http/HttpExtension.java
@@ -24,7 +24,6 @@
 import static org.osgi.service.http.whiteboard.HttpWhiteboardConstants.HTTP_WHITEBOARD_LISTENER;
 
 import java.lang.annotation.Annotation;
-import java.lang.reflect.Type;
 import java.util.ArrayList;
 import java.util.Collections;
 import java.util.Dictionary;
@@ -39,9 +38,6 @@
 import javax.enterprise.event.Observes;
 import javax.enterprise.event.ObservesAsync;
 import javax.enterprise.inject.spi.AfterDeploymentValidation;
-import javax.enterprise.inject.spi.AnnotatedConstructor;
-import javax.enterprise.inject.spi.AnnotatedField;
-import javax.enterprise.inject.spi.AnnotatedMethod;
 import javax.enterprise.inject.spi.AnnotatedType;
 import javax.enterprise.inject.spi.Bean;
 import javax.enterprise.inject.spi.BeanManager;
@@ -96,42 +92,44 @@
 
 		WebFilter webFilter = annotatedType.getAnnotation(WebFilter.class);
 
-		final Set<Annotation> annotations = new HashSet<>(annotatedType.getAnnotations());
+		final Set<Annotation> annotationsToAdd = new HashSet<>();
 
 		if (!annotatedType.isAnnotationPresent(Service.class)) {
-			annotations.add(Service.Literal.of(new Class[] {Filter.class}));
+			annotationsToAdd.add(Service.Literal.of(new Class[] {Filter.class}));
 		}
 
 		if(!annotatedType.isAnnotationPresent(HttpWhiteboardContextSelect.class)) {
-			annotations.add(HttpWhiteboardContextSelect.Literal.of(getSelectedContext()));
+			annotationsToAdd.add(HttpWhiteboardContextSelect.Literal.of(getSelectedContext()));
 		}
 
 		if (!webFilter.description().isEmpty()) {
-			annotations.add(ServiceDescription.Literal.of(webFilter.description()));
+			annotationsToAdd.add(ServiceDescription.Literal.of(webFilter.description()));
 		}
 
 		if (!webFilter.filterName().isEmpty()) {
-			annotations.add(HttpWhiteboardFilterName.Literal.of(webFilter.filterName()));
+			annotationsToAdd.add(HttpWhiteboardFilterName.Literal.of(webFilter.filterName()));
 		}
 
 		if (webFilter.servletNames().length > 0) {
-			annotations.add(HttpWhiteboardFilterServlet.Literal.of(webFilter.servletNames()));
+			annotationsToAdd.add(HttpWhiteboardFilterServlet.Literal.of(webFilter.servletNames()));
 		}
 
 		if (webFilter.value().length > 0) {
-			annotations.add(HttpWhiteboardFilterPattern.Literal.of(webFilter.value()));
+			annotationsToAdd.add(HttpWhiteboardFilterPattern.Literal.of(webFilter.value()));
 		}
 		else if (webFilter.urlPatterns().length > 0) {
-			annotations.add(HttpWhiteboardFilterPattern.Literal.of(webFilter.urlPatterns()));
+			annotationsToAdd.add(HttpWhiteboardFilterPattern.Literal.of(webFilter.urlPatterns()));
 		}
 
 		if (webFilter.dispatcherTypes().length > 0) {
-			annotations.add(HttpWhiteboardFilterDispatcher.Literal.of(webFilter.dispatcherTypes()));
+			annotationsToAdd.add(HttpWhiteboardFilterDispatcher.Literal.of(webFilter.dispatcherTypes()));
 		}
 
-		annotations.add(HttpWhiteboardFilterAsyncSupported.Literal.of(webFilter.asyncSupported()));
+		annotationsToAdd.add(HttpWhiteboardFilterAsyncSupported.Literal.of(webFilter.asyncSupported()));
 
-		pat.setAnnotatedType(new WebAnnotated<>(annotatedType, annotations));
+		if (!annotationsToAdd.isEmpty()) {
+			annotationsToAdd.forEach(pat.configureAnnotatedType()::add);
+		}
 	}
 
 	<X> void processWebListener(@Observes @WithAnnotations(WebListener.class) ProcessAnnotatedType<X> pat) {
@@ -139,7 +137,7 @@
 
 		WebListener webListener = annotatedType.getAnnotation(WebListener.class);
 
-		final Set<Annotation> annotations = new HashSet<>(annotatedType.getAnnotations());
+		final Set<Annotation> annotationsToAdd = new HashSet<>();
 
 		if (!annotatedType.isAnnotationPresent(Service.class)) {
 			List<Class<?>> listenerTypes = new ArrayList<>();
@@ -168,20 +166,22 @@
 				listenerTypes.add(javax.servlet.http.HttpSessionIdListener.class);
 			}
 
-			annotations.add(Service.Literal.of(listenerTypes.toArray(new Class<?>[0])));
+			annotationsToAdd.add(Service.Literal.of(listenerTypes.toArray(new Class<?>[0])));
 		}
 
 		if(!annotatedType.isAnnotationPresent(HttpWhiteboardContextSelect.class)) {
-			annotations.add(HttpWhiteboardContextSelect.Literal.of(getSelectedContext()));
+			annotationsToAdd.add(HttpWhiteboardContextSelect.Literal.of(getSelectedContext()));
 		}
 
-		annotations.add(HttpWhiteboardListener.Literal.INSTANCE);
+		annotationsToAdd.add(HttpWhiteboardListener.Literal.INSTANCE);
 
 		if (!webListener.value().isEmpty()) {
-			annotations.add(ServiceDescription.Literal.of(webListener.value()));
+			annotationsToAdd.add(ServiceDescription.Literal.of(webListener.value()));
 		}
 
-		pat.setAnnotatedType(new WebAnnotated<>(annotatedType, annotations));
+		if (!annotationsToAdd.isEmpty()) {
+			annotationsToAdd.forEach(pat.configureAnnotatedType()::add);
+		}
 	}
 
 	<X> void processWebServlet(@Observes @WithAnnotations(WebServlet.class) ProcessAnnotatedType<X> pat) {
@@ -189,46 +189,48 @@
 
 		WebServlet webServlet = annotatedType.getAnnotation(WebServlet.class);
 
-		final Set<Annotation> annotations = new HashSet<>(annotatedType.getAnnotations());
+		final Set<Annotation> annotationsToAdd = new HashSet<>();
 
 		if (!annotatedType.isAnnotationPresent(Service.class)) {
-			annotations.add(Service.Literal.of(new Class[] {Servlet.class}));
+			annotationsToAdd.add(Service.Literal.of(new Class[] {Servlet.class}));
 		}
 
 		if(!annotatedType.isAnnotationPresent(HttpWhiteboardContextSelect.class)) {
-			annotations.add(HttpWhiteboardContextSelect.Literal.of(getSelectedContext()));
+			annotationsToAdd.add(HttpWhiteboardContextSelect.Literal.of(getSelectedContext()));
 		}
 
 		if (!webServlet.name().isEmpty()) {
-			annotations.add(HttpWhiteboardServletName.Literal.of(webServlet.name()));
+			annotationsToAdd.add(HttpWhiteboardServletName.Literal.of(webServlet.name()));
 		}
 
 		if (webServlet.value().length > 0) {
-			annotations.add(HttpWhiteboardServletPattern.Literal.of(webServlet.value()));
+			annotationsToAdd.add(HttpWhiteboardServletPattern.Literal.of(webServlet.value()));
 		}
 		else if (webServlet.urlPatterns().length > 0) {
-			annotations.add(HttpWhiteboardServletPattern.Literal.of(webServlet.urlPatterns()));
+			annotationsToAdd.add(HttpWhiteboardServletPattern.Literal.of(webServlet.urlPatterns()));
 		}
 
-		annotations.add(ServiceRanking.Literal.of(webServlet.loadOnStartup()));
+		annotationsToAdd.add(ServiceRanking.Literal.of(webServlet.loadOnStartup()));
 
 		// TODO Howto: INIT PARAMS ???
 
-		annotations.add(HttpWhiteboardServletAsyncSupported.Literal.of(webServlet.asyncSupported()));
+		annotationsToAdd.add(HttpWhiteboardServletAsyncSupported.Literal.of(webServlet.asyncSupported()));
 
 		if (!webServlet.description().isEmpty()) {
-			annotations.add(ServiceDescription.Literal.of(webServlet.description()));
+			annotationsToAdd.add(ServiceDescription.Literal.of(webServlet.description()));
 		}
 
 		MultipartConfig multipartConfig = annotatedType.getAnnotation(MultipartConfig.class);
 
 		if (multipartConfig != null) {
-			annotations.add(HttpWhiteboardServletMultipart.Literal.of(true, multipartConfig.fileSizeThreshold(), multipartConfig.location(), multipartConfig.maxFileSize(), multipartConfig.maxRequestSize()));
+			annotationsToAdd.add(HttpWhiteboardServletMultipart.Literal.of(true, multipartConfig.fileSizeThreshold(), multipartConfig.location(), multipartConfig.maxFileSize(), multipartConfig.maxRequestSize()));
 		}
 
 		// TODO HowTo: ServletSecurity ???
 
-		pat.setAnnotatedType(new WebAnnotated<>(annotatedType, annotations));
+		if (!annotationsToAdd.isEmpty()) {
+			annotationsToAdd.forEach(pat.configureAnnotatedType()::add);
+		}
 	}
 
 	void afterDeploymentValidation(
@@ -241,7 +243,7 @@
 	void ready(@ObservesAsync Ready ready, BeanManager beanManager) {
 		Dictionary<String, Object> properties = new Hashtable<>();
 
-		properties.put(SERVICE_DESCRIPTION, "Aries CDI - HTTP Portable Extension");
+		properties.put(SERVICE_DESCRIPTION, "Aries CDI - HTTP Portable Extension for Weld");
 		properties.put(SERVICE_VENDOR, "Apache Software Foundation");
 		properties.put(HTTP_WHITEBOARD_CONTEXT_SELECT, getSelectedContext());
 		properties.put(HTTP_WHITEBOARD_LISTENER, Boolean.TRUE.toString());
@@ -259,7 +261,12 @@
 
 	void beforeShutdown(@Observes BeforeShutdown bs) {
 		if (_listenerRegistration != null && !destroyed.get()) {
-			_listenerRegistration.unregister();
+			try {
+				_listenerRegistration.unregister();
+			}
+			catch (IllegalStateException ise) {
+				// the service was already unregistered.
+			}
 		}
 	}
 
@@ -371,66 +378,4 @@
 
 	}
 
-	private class WebAnnotated<X> implements AnnotatedType<X> {
-
-		private final AnnotatedType<X> annotatedType;
-		private final Set<Annotation> annotations;
-
-		public WebAnnotated(AnnotatedType<X> annotatedType, Set<Annotation> annotations) {
-			this.annotatedType = annotatedType;
-			this.annotations = annotations;
-		}
-
-		@Override
-		public Type getBaseType() {
-			return annotatedType.getBaseType();
-		}
-
-		@Override
-		public Set<Type> getTypeClosure() {
-			return annotatedType.getTypeClosure();
-		}
-
-		@Override
-		public <T extends Annotation> T getAnnotation(Class<T> annotationType) {
-			return annotations.stream().filter(
-				ann -> annotationType.isAssignableFrom(ann.annotationType())
-			).map(
-				ann -> annotationType.cast(ann)
-			).findFirst().orElse(null);
-		}
-
-		@Override
-		public Set<Annotation> getAnnotations() {
-			return annotations;
-		}
-
-		@Override
-		public boolean isAnnotationPresent(Class<? extends Annotation> annotationType) {
-			return annotations.stream().anyMatch(
-				ann -> annotationType.isAssignableFrom(ann.annotationType())
-			);
-		}
-
-		@Override
-		public Class<X> getJavaClass() {
-			return annotatedType.getJavaClass();
-		}
-
-		@Override
-		public Set<AnnotatedConstructor<X>> getConstructors() {
-			return annotatedType.getConstructors();
-		}
-
-		@Override
-		public Set<AnnotatedMethod<? super X>> getMethods() {
-			return annotatedType.getMethods();
-		}
-
-		@Override
-		public Set<AnnotatedField<? super X>> getFields() {
-			return annotatedType.getFields();
-		}
-	}
-
 }
diff --git a/cdi-extension-jndi/src/main/java/org/apache/aries/cdi/extension/jndi/JndiContext.java b/cdi-extension-jndi/src/main/java/org/apache/aries/cdi/extension/jndi/JndiContext.java
index 4651e95..fcc3aee 100644
--- a/cdi-extension-jndi/src/main/java/org/apache/aries/cdi/extension/jndi/JndiContext.java
+++ b/cdi-extension-jndi/src/main/java/org/apache/aries/cdi/extension/jndi/JndiContext.java
@@ -32,9 +32,13 @@
 
 public class JndiContext implements Context {
 
-	public JndiContext(Logger log, Promise<BeanManager> beanManager) {
+	public JndiContext(Logger log) {
 		_log = log;
+	}
+
+	public JndiContext setBeanManager(Promise<BeanManager> beanManager) {
 		_beanManager = beanManager;
+		return this;
 	}
 
 	@Override
@@ -45,7 +49,7 @@
 	@Override
 	public Object lookup(String name) throws NamingException {
 		if (name.length() == 0) {
-			return new JndiContext(_log, _beanManager);
+			return new JndiContext(_log).setBeanManager(_beanManager);
 		}
 		if (name.equals("java:comp/BeanManager")) {
 			try {
@@ -194,6 +198,6 @@
 	}
 
 	private final Logger _log;
-	private final Promise<BeanManager> _beanManager;
+	private volatile Promise<BeanManager> _beanManager;
 
 }
\ No newline at end of file
diff --git a/cdi-extension-jndi/src/main/java/org/apache/aries/cdi/extension/jndi/JndiExtension.java b/cdi-extension-jndi/src/main/java/org/apache/aries/cdi/extension/jndi/JndiExtension.java
index 94591eb..cd126c5 100644
--- a/cdi-extension-jndi/src/main/java/org/apache/aries/cdi/extension/jndi/JndiExtension.java
+++ b/cdi-extension-jndi/src/main/java/org/apache/aries/cdi/extension/jndi/JndiExtension.java
@@ -33,7 +33,7 @@
 
 	public JndiExtension(Logger log) {
 		_beanManager = new Deferred<>();
-		_jndiContext = new JndiContext(log, _beanManager.getPromise());
+		_jndiContext = new JndiContext(log).setBeanManager(_beanManager.getPromise());
 	}
 
 	@Override
@@ -53,9 +53,11 @@
 		AfterDeploymentValidation adv, BeanManager beanManager) {
 
 		_beanManager.resolve(beanManager);
+		_jndiContext.setBeanManager(_beanManager.getPromise());
+		_beanManager = new Deferred<>();
 	}
 
-	private final Deferred<BeanManager> _beanManager;
+	private volatile Deferred<BeanManager> _beanManager;
 	private final JndiContext _jndiContext;
 
 }
diff --git a/cdi-extension-mp-config/pom.xml b/cdi-extension-mp-config/pom.xml
new file mode 100644
index 0000000..3aa538a
--- /dev/null
+++ b/cdi-extension-mp-config/pom.xml
@@ -0,0 +1,156 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+/**
+ * Licensed 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.aries.cdi</groupId>
+		<artifactId>org.apache.aries.cdi</artifactId>
+		<version>1.1.0-SNAPSHOT</version>
+		<relativePath>..</relativePath>
+	</parent>
+
+	<properties>
+		<mp.config.version>1.3</mp.config.version>
+		<byte.buddy.version>1.10.3</byte.buddy.version>
+	</properties>
+
+	<artifactId>org.apache.aries.cdi.extension.mp-config</artifactId>
+	<name>Apache Aries CDI - MicroProfile Config ${mp.config.version} Using Apache Geronimo</name>
+	<description>Apache Aries CDI - MicroProfile Config ${mp.config.version} Using Apache Geronimo</description>
+
+	<licenses>
+		<license>
+			<name>ASL 2.0</name>
+			<url>https://www.apache.org/licenses/LICENSE-2.0</url>
+		</license>
+	</licenses>
+
+	<scm>
+		<connection>scm:git:git@github.com:apache/aries-cdi.git</connection>
+		<developerConnection>scm:git:git@github.com:apache/aries-cdi.git</developerConnection>
+		<tag>HEAD</tag>
+		<url>https://github.com/apache/aries-cdi</url>
+	</scm>
+
+	<build>
+		<plugins>
+			<plugin>
+				<groupId>biz.aQute.bnd</groupId>
+				<artifactId>bnd-maven-plugin</artifactId>
+				<configuration>
+					<bnd><![CDATA[
+						Export-Package: org.eclipse.microprofile.config.*
+						Import-Package: \
+							!net.bytebuddy.*,\
+							!org.osgi.annotation.bundle.*,\
+							*
+						-includepackage: org.apache.geronimo.config.*
+						-cdiannotations:
+						-noclassforname: true
+						-fixupmessages: "Split package...";is:=ignore
+					]]></bnd>
+				</configuration>
+			</plugin>
+			<plugin>
+				<groupId>net.bytebuddy</groupId>
+				<artifactId>byte-buddy-maven-plugin</artifactId>
+				<version>${byte.buddy.version}</version>
+				<executions>
+					<execution>
+						<goals>
+							<goal>transform</goal>
+						</goals>
+					</execution>
+				</executions>
+				<configuration>
+					<transformations>
+						<transformation>
+							<plugin>org.apache.aries.cdi.extension.mp.config.BB</plugin>
+							<arguments>
+								<argument>
+									<index>1</index>
+									<value>${mp.config.version}</value>
+								</argument>
+							</arguments>
+						</transformation>
+					</transformations>
+				</configuration>
+				<dependencies>
+					<dependency>
+						<groupId>org.osgi</groupId>
+						<artifactId>osgi.annotation</artifactId>
+						<version>7.0.0</version>
+					</dependency>
+				</dependencies>
+			</plugin>
+		</plugins>
+	</build>
+
+	<dependencies>
+		<dependency>
+			<groupId>biz.aQute.bnd</groupId>
+			<artifactId>biz.aQute.bnd.annotation</artifactId>
+			<version>${bnd.version}</version>
+			<scope>provided</scope>
+		</dependency>
+		<dependency>
+			<groupId>org.apache.geronimo.specs</groupId>
+			<artifactId>geronimo-annotation_1.3_spec</artifactId>
+		</dependency>
+		<dependency>
+			<groupId>org.apache.geronimo.specs</groupId>
+			<artifactId>geronimo-atinject_1.0_spec</artifactId>
+		</dependency>
+		<dependency>
+			<groupId>org.apache.geronimo.specs</groupId>
+			<artifactId>geronimo-jcdi_2.0_spec</artifactId>
+		</dependency>
+		<dependency>
+			<groupId>org.apache.geronimo.config</groupId>
+			<artifactId>geronimo-config-impl</artifactId>
+			<version>1.2.2</version>
+			<scope>provided</scope>
+		</dependency>
+		<dependency>
+			<groupId>org.osgi</groupId>
+			<artifactId>org.osgi.namespace.service</artifactId>
+		</dependency>
+		<dependency>
+			<groupId>org.osgi</groupId>
+			<artifactId>org.osgi.service.cdi</artifactId>
+		</dependency>
+		<dependency>
+			<groupId>org.osgi</groupId>
+			<artifactId>osgi.annotation</artifactId>
+		</dependency>
+		<dependency>
+			<groupId>org.osgi</groupId>
+			<artifactId>osgi.core</artifactId>
+		</dependency>
+
+		<dependency>
+			<groupId>net.bytebuddy</groupId>
+			<artifactId>byte-buddy</artifactId>
+			<version>${byte.buddy.version}</version>
+			<scope>provided</scope>
+		</dependency>
+	</dependencies>
+
+</project>
\ No newline at end of file
diff --git a/cdi-extension-mp-config/src/main/java/org/apache/aries/cdi/extension/mp/config/BB.java b/cdi-extension-mp-config/src/main/java/org/apache/aries/cdi/extension/mp/config/BB.java
new file mode 100644
index 0000000..1de5285
--- /dev/null
+++ b/cdi-extension-mp-config/src/main/java/org/apache/aries/cdi/extension/mp/config/BB.java
@@ -0,0 +1,60 @@
+/**
+ * Licensed 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.aries.cdi.extension.mp.config;
+
+import java.io.IOException;
+
+import org.osgi.annotation.bundle.Requirement;
+import org.osgi.service.cdi.CDIConstants;
+
+import net.bytebuddy.build.BuildLogger;
+import net.bytebuddy.build.Plugin;
+import net.bytebuddy.description.annotation.AnnotationDescription;
+import net.bytebuddy.description.type.TypeDescription;
+import net.bytebuddy.dynamic.ClassFileLocator;
+import net.bytebuddy.dynamic.DynamicType.Builder;
+
+public class BB implements Plugin {
+
+	private final BuildLogger buildLogger;
+	private final String mpVersion;
+
+	public BB(BuildLogger buildLogger, String mpVersion) {
+		this.buildLogger = buildLogger;
+		this.mpVersion = mpVersion;
+	}
+
+	@Override
+	public boolean matches(TypeDescription target) {
+		return target.getName().equals("org.eclipse.microprofile.config.inject.ConfigProperty");
+	}
+
+	@Override
+	public Builder<?> apply(Builder<?> builder, TypeDescription typeDescription, ClassFileLocator cfl) {
+		buildLogger.info("Processing class: " + typeDescription.getActualName());
+
+		return builder.annotateType(
+			AnnotationDescription.Builder.ofType(Requirement.class)
+				.define("namespace", CDIConstants.CDI_EXTENSION_PROPERTY)
+				.define("name", "eclipse.microprofile.config")
+				.define("version", mpVersion)
+				.build());
+	}
+
+	@Override
+	public void close() throws IOException {
+	}
+
+}
diff --git a/cdi-extension-mp-config/src/main/java/org/apache/aries/cdi/extension/mp/config/StubConfigProviderResolver.java b/cdi-extension-mp-config/src/main/java/org/apache/aries/cdi/extension/mp/config/StubConfigProviderResolver.java
new file mode 100644
index 0000000..63245e5
--- /dev/null
+++ b/cdi-extension-mp-config/src/main/java/org/apache/aries/cdi/extension/mp/config/StubConfigProviderResolver.java
@@ -0,0 +1,24 @@
+/**
+ * Licensed 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.aries.cdi.extension.mp.config;
+
+import org.apache.geronimo.config.DefaultConfigProvider;
+import org.eclipse.microprofile.config.spi.ConfigProviderResolver;
+
+import aQute.bnd.annotation.spi.ServiceProvider;
+
+@ServiceProvider(ConfigProviderResolver.class)
+public class StubConfigProviderResolver extends DefaultConfigProvider {
+}
diff --git a/cdi-extension-mp-config/src/main/java/org/apache/aries/cdi/extension/mp/config/StubExtension.java b/cdi-extension-mp-config/src/main/java/org/apache/aries/cdi/extension/mp/config/StubExtension.java
new file mode 100644
index 0000000..84040cd
--- /dev/null
+++ b/cdi-extension-mp-config/src/main/java/org/apache/aries/cdi/extension/mp/config/StubExtension.java
@@ -0,0 +1,52 @@
+/**
+ * Licensed 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.aries.cdi.extension.mp.config;
+
+import static org.apache.aries.cdi.extension.mp.config.StubExtension.EXTENSION_NAME;
+import static org.osgi.service.cdi.CDIConstants.CDI_EXTENSION_PROPERTY;
+
+import javax.enterprise.event.Observes;
+import javax.enterprise.inject.spi.AfterBeanDiscovery;
+import javax.enterprise.inject.spi.BeanManager;
+import javax.enterprise.inject.spi.Extension;
+
+import org.apache.geronimo.config.cdi.ConfigExtension;
+import org.apache.geronimo.config.cdi.ConfigInjectionProducer;
+
+import aQute.bnd.annotation.spi.ServiceProvider;
+
+@ServiceProvider(
+	attribute = {
+		CDI_EXTENSION_PROPERTY + "=" + EXTENSION_NAME,
+		"service.scope=prototype",
+		"service.vendor=Apache Software Foundation",
+		"version:Version=1.3.0"
+	},
+	effective = "active",
+	uses = Extension.class,
+	value = Extension.class
+)
+public class StubExtension extends ConfigExtension {
+
+	public final static String EXTENSION_NAME = "eclipse.microprofile.config";
+
+	@Override
+	public void registerConfigProducer(@Observes AfterBeanDiscovery abd, BeanManager bm) {
+		abd.addBean().beanClass(ConfigInjectionProducer.class).createWith(c -> new ConfigInjectionProducer());
+
+		super.registerConfigProducer(abd, bm);
+	}
+
+}
diff --git a/cdi-extension-mp-config/src/main/java/org/apache/aries/cdi/extension/mp/config/package-info.java b/cdi-extension-mp-config/src/main/java/org/apache/aries/cdi/extension/mp/config/package-info.java
new file mode 100644
index 0000000..1980043
--- /dev/null
+++ b/cdi-extension-mp-config/src/main/java/org/apache/aries/cdi/extension/mp/config/package-info.java
@@ -0,0 +1,39 @@
+/**
+ * Licensed 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.
+ */
+
+@Capability(
+	attribute = "objectClass:List<String>=javax.enterprise.inject.spi.Extension",
+	namespace = SERVICE_NAMESPACE
+)
+@Capability(
+	namespace = CDI_EXTENSION_PROPERTY,
+	name = EXTENSION_NAME,
+	uses= {
+		javax.annotation.Priority.class,
+		javax.enterprise.event.Observes.class,
+		Extension.class
+	},
+	version = "1.3" // TODO ?maybe read this from pom property?
+)
+@RequireCDIExtender
+package org.apache.aries.cdi.extension.mp.config;
+
+import static org.apache.aries.cdi.extension.mp.config.StubExtension.EXTENSION_NAME;
+import static org.osgi.namespace.service.ServiceNamespace.SERVICE_NAMESPACE;
+import static org.osgi.service.cdi.CDIConstants.CDI_EXTENSION_PROPERTY;
+
+import javax.enterprise.inject.spi.Extension;
+
+import org.osgi.annotation.bundle.Capability;
+import org.osgi.service.cdi.annotations.RequireCDIExtender;
diff --git a/cdi-itests/base-itest.bndrun b/cdi-itests/base-itest.bndrun
new file mode 100644
index 0000000..cbf4ddb
--- /dev/null
+++ b/cdi-itests/base-itest.bndrun
@@ -0,0 +1,38 @@
+#    Licensed 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.
+
+#-runjdb: 8000
+
+-standalone: true
+-runee: JavaSE-1.8
+-runfw: org.eclipse.osgi
+-runproperties: \
+	eclipse.log.enabled=false,\
+	logback.configurationFile=file:${.}/logback.xml,\
+	org.osgi.service.http.port=0,\
+	osgi.console=,\
+	tck.config.test.javaconfig.converter.stringvalues=foo
+
+-resolve.effective: resolve, active
+
+-runpath: \
+	ch.qos.logback.classic,\
+	ch.qos.logback.core,\
+	org.apache.felix.logback,\
+	slf4j.api
+
+-runsystempackages: \
+	org.slf4j;version=1.7.25,\
+	org.slf4j.event;version=1.7.25,\
+	org.slf4j.helpers;version=1.7.25,\
+	org.slf4j.spi;version=1.7.25,\
+	sun.misc
diff --git a/cdi-itests/bnd.bnd b/cdi-itests/bnd.bnd
index 1fd7594..d574c45 100644
--- a/cdi-itests/bnd.bnd
+++ b/cdi-itests/bnd.bnd
@@ -57,7 +57,8 @@
 	tb152_3_1_1l.jar,\
 	tb12.jar,\
 	tb13.jar,\
-	tb14.jar
+	tb14.jar,\
+	tb16.jar
 
 # Don't forget that we had to coax the `maven-jar-plugin` NOT to include the `sub-bundle` packages in
 # the root bundle:
diff --git a/cdi-itests/bnd/tb16.bnd b/cdi-itests/bnd/tb16.bnd
new file mode 100644
index 0000000..c6d1f50
--- /dev/null
+++ b/cdi-itests/bnd/tb16.bnd
@@ -0,0 +1,13 @@
+#    Licensed 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.
+
+Export-Package: ${p}.tb16.*;-split-package:=first
diff --git a/cdi-itests/itest.bndrun b/cdi-itests/owb-itest.bndrun
similarity index 64%
copy from cdi-itests/itest.bndrun
copy to cdi-itests/owb-itest.bndrun
index 959cdb8..5cafc6e 100644
--- a/cdi-itests/itest.bndrun
+++ b/cdi-itests/owb-itest.bndrun
@@ -10,49 +10,32 @@
 #    See the License for the specific language governing permissions and
 #    limitations under the License.
 
+-include: base-itest.bndrun
 #-runjdb: 8000
 
--standalone: true
--runee: JavaSE-1.8
--runfw: org.eclipse.osgi
--runproperties: \
-	eclipse.log.enabled=false,\
-	logback.configurationFile=file:${.}/logback.xml,\
-	org.osgi.service.http.port=0,\
-	osgi.console=
-
--resolve.effective: resolve, active
-
 -runrequires: \
-	osgi.identity;filter:='(osgi.identity=javax.ejb-api)',\
-	osgi.identity;filter:='(osgi.identity=javax.transaction-api)',\
-	osgi.identity;filter:='(osgi.identity=org.apache.aries.cdi.extra)',\
+	osgi.identity;filter:='(osgi.identity=org.apache.aries.cdi.owb)',\
 	osgi.identity;filter:='(osgi.identity=org.apache.aries.cdi.itests)',\
 	osgi.identity;filter:='(osgi.identity=org.apache.aries.jndi.core)',\
 	osgi.identity;filter:='(osgi.identity=org.apache.felix.gogo.command)'
 
--runpath: \
-	ch.qos.logback.classic,\
-	ch.qos.logback.core,\
-	org.apache.felix.logback,\
-	slf4j.api
-
--runsystempackages: \
-	org.slf4j;version=1.7.25,\
-	org.slf4j.helpers;version=1.7.25,\
-	org.slf4j.spi;version=1.7.25,\
-	sun.misc
+-runblacklist: \
+	osgi.identity;filter:='(osgi.identity=org.apache.aries.cdi.weld)',\
+	osgi.identity;filter:='(osgi.identity=org.jboss.spec.*)'
 
 -runbundles: \
 	biz.aQute.junit;version='[4.3.1,4.3.2)',\
-	javax.ejb-api;version='[3.2.0,3.2.1)',\
-	javax.transaction-api;version='[1.2.0,1.2.1)',\
-	jboss-classfilewriter;version='[1.2.3,1.2.4)',\
-	org.apache.aries.cdi.extender;version='[1.0.3,1.0.4)',\
-	org.apache.aries.cdi.extension.http;version='[1.0.3,1.0.4)',\
-	org.apache.aries.cdi.extension.jndi;version='[1.0.3,1.0.4)',\
-	org.apache.aries.cdi.extra;version='[1.0.3,1.0.4)',\
-	org.apache.aries.cdi.itests;version='[1.0.3,1.0.4)',\
+	javax.servlet.jsp-api;version='[2.3.3,2.3.4)',\
+	openwebbeans-impl;version='[2.0.13,2.0.14)',\
+	openwebbeans-spi;version='[2.0.13,2.0.14)',\
+	openwebbeans-web;version='[2.0.13,2.0.14)',\
+	org.apache.aries.cdi.extender;version='[1.1.0,1.1.1)',\
+	org.apache.aries.cdi.extension.jndi;version='[1.1.0,1.1.1)',\
+	org.apache.aries.cdi.extension.mp-config;version='[1.1.0,1.1.1)',\
+	org.apache.aries.cdi.extra;version='[1.1.0,1.1.1)',\
+	org.apache.aries.cdi.itests;version='[1.1.0,1.1.1)',\
+	org.apache.aries.cdi.owb;version='[1.1.0,1.1.1)',\
+	org.apache.aries.cdi.spi;version='[1.1.0,1.1.1)',\
 	org.apache.aries.jndi.api;version='[1.1.0,1.1.1)',\
 	org.apache.aries.jndi.core;version='[1.0.2,1.0.3)',\
 	org.apache.aries.spifly.dynamic.framework.extension;version='[1.2.0,1.2.1)',\
@@ -71,8 +54,9 @@
 	org.apache.geronimo.specs.geronimo-jcdi_2.0_spec;version='[1.1.0,1.1.1)',\
 	org.apache.httpcomponents.httpclient;version='[4.5.3,4.5.4)',\
 	org.apache.httpcomponents.httpcore;version='[4.4.6,4.4.7)',\
-	org.jboss.logging.jboss-logging;version='[3.3.2,3.3.3)',\
-	org.jboss.weld.osgi-bundle;version='[3.0.5,3.0.6)',\
+	org.apache.xbean.asm7-shaded;version='[4.13.0,4.13.1)',\
+	org.apache.xbean.bundleutils;version='[4.15.0,4.15.1)',\
+	org.apache.xbean.finder-shaded;version='[4.13.0,4.13.1)',\
 	org.osgi.service.cdi;version='[1.0.0,1.0.1)',\
 	org.osgi.util.function;version='[1.1.0,1.1.1)',\
 	org.osgi.util.promise;version='[1.1.0,1.1.1)'
diff --git a/cdi-itests/pom.xml b/cdi-itests/pom.xml
index 3bca27e..9697bb8 100644
--- a/cdi-itests/pom.xml
+++ b/cdi-itests/pom.xml
@@ -64,6 +64,10 @@
 			<artifactId>org.apache.aries.cdi.extra</artifactId>
 		</dependency>
 		<dependency>
+			<groupId>org.apache.aries.cdi</groupId>
+			<artifactId>org.apache.aries.cdi.extension.mp-config</artifactId>
+		</dependency>
+		<dependency>
 			<groupId>org.apache.felix</groupId>
 			<artifactId>org.apache.felix.http.servlet-api</artifactId>
 		</dependency>
@@ -119,6 +123,22 @@
 
 		<!-- RUNTIME dependencies not found in BOMs -->
 		<dependency>
+			<groupId>org.apache.aries.cdi</groupId>
+			<artifactId>org.apache.aries.cdi.owb</artifactId>
+			<scope>runtime</scope>
+		</dependency>
+		<dependency>
+			<groupId>org.apache.openwebbeans</groupId>
+			<artifactId>openwebbeans-web</artifactId>
+			<version>${owb.version}</version>
+			<scope>runtime</scope>
+		</dependency>
+		<dependency>
+			<groupId>org.apache.aries.cdi</groupId>
+			<artifactId>org.apache.aries.cdi.weld</artifactId>
+			<scope>runtime</scope>
+		</dependency>
+		<dependency>
 			<groupId>org.apache.aries.jndi</groupId>
 			<artifactId>org.apache.aries.jndi.core</artifactId>
 			<version>1.0.2</version>
@@ -181,21 +201,65 @@
 				<groupId>biz.aQute.bnd</groupId>
 				<artifactId>bnd-resolver-maven-plugin</artifactId>
 				<configuration>
-					<bndruns>
-						<bndrun>itest.bndrun</bndrun>
-					</bndruns>
 					<includeDependencyManagement>true</includeDependencyManagement>
 				</configuration>
+				<executions>
+					<execution>
+						<id>owb-resolve</id>
+						<phase>package</phase>
+						<goals>
+							<goal>resolve</goal>
+						</goals>
+						<configuration>
+							<bndruns>
+								<bndrun>owb-itest.bndrun</bndrun>
+							</bndruns>
+						</configuration>
+					</execution>
+					<execution>
+						<id>weld-resolve</id>
+						<phase>package</phase>
+						<goals>
+							<goal>resolve</goal>
+						</goals>
+						<configuration>
+							<bndruns>
+								<bndrun>weld-itest.bndrun</bndrun>
+							</bndruns>
+						</configuration>
+					</execution>
+				</executions>
 			</plugin>
 			<plugin>
 				<groupId>biz.aQute.bnd</groupId>
 				<artifactId>bnd-testing-maven-plugin</artifactId>
 				<configuration>
-					<bndruns>
-						<bndrun>itest.bndrun</bndrun>
-					</bndruns>
 					<includeDependencyManagement>true</includeDependencyManagement>
 				</configuration>
+				<executions>
+					<execution>
+						<id>owb-test</id>
+						<goals>
+							<goal>testing</goal>
+						</goals>
+						<configuration>
+							<bndruns>
+								<bndrun>owb-itest.bndrun</bndrun>
+							</bndruns>
+						</configuration>
+					</execution>
+					<execution>
+						<id>weld-test</id>
+						<goals>
+							<goal>testing</goal>
+						</goals>
+						<configuration>
+							<bndruns>
+								<bndrun>weld-itest.bndrun</bndrun>
+							</bndruns>
+						</configuration>
+					</execution>
+				</executions>
 			</plugin>
 		</plugins>
 	</build>
diff --git a/cdi-itests/src/main/java/org/apache/aries/cdi/test/beans/BundleContextBean.java b/cdi-itests/src/main/java/org/apache/aries/cdi/test/beans/BundleContextBean.java
index cb70344..1b64791 100644
--- a/cdi-itests/src/main/java/org/apache/aries/cdi/test/beans/BundleContextBean.java
+++ b/cdi-itests/src/main/java/org/apache/aries/cdi/test/beans/BundleContextBean.java
@@ -25,6 +25,10 @@
 @BundleContextBeanQualifier
 public class BundleContextBean implements BeanService<BundleContext> {
 
+	protected BundleContextBean() {
+		// no-op: a normal scoped bean MUST have a default constructor to let container create a proxy
+	}
+
 	@Override
 	public String doSomething() {
 		return toString();
diff --git a/cdi-itests/src/main/java/org/apache/aries/cdi/test/beans/CdiEventObserver.java b/cdi-itests/src/main/java/org/apache/aries/cdi/test/beans/CdiEventObserver.java
index 504a44b..a29e3ca 100644
--- a/cdi-itests/src/main/java/org/apache/aries/cdi/test/beans/CdiEventObserver.java
+++ b/cdi-itests/src/main/java/org/apache/aries/cdi/test/beans/CdiEventObserver.java
@@ -28,6 +28,10 @@
 @ApplicationScoped
 public class CdiEventObserver implements BeanService<List<Object>> {
 
+	protected CdiEventObserver() {
+		// no-op: a normal scoped bean MUST have a default constructor to let container create a proxy
+	}
+
 	@Override
 	public String doSomething() {
 		return this.toString();
diff --git a/cdi-itests/src/main/java/org/apache/aries/cdi/test/beans/IntegerServiceProvider.java b/cdi-itests/src/main/java/org/apache/aries/cdi/test/beans/IntegerServiceProvider.java
index 3508fc6..ffbd609 100644
--- a/cdi-itests/src/main/java/org/apache/aries/cdi/test/beans/IntegerServiceProvider.java
+++ b/cdi-itests/src/main/java/org/apache/aries/cdi/test/beans/IntegerServiceProvider.java
@@ -23,6 +23,10 @@
 @ApplicationScoped
 public class IntegerServiceProvider {
 
+	protected IntegerServiceProvider() {
+		// no-op: a normal scoped bean MUST have a default constructor to let container create a proxy
+	}
+
 	@Produces
 	@Service(Integer.class)
 	@ServiceRanking(5000)
diff --git a/cdi-itests/src/main/java/org/apache/aries/cdi/test/beans/PojoImpl.java b/cdi-itests/src/main/java/org/apache/aries/cdi/test/beans/PojoImpl.java
index 5c9c7e9..102ff21 100644
--- a/cdi-itests/src/main/java/org/apache/aries/cdi/test/beans/PojoImpl.java
+++ b/cdi-itests/src/main/java/org/apache/aries/cdi/test/beans/PojoImpl.java
@@ -23,6 +23,10 @@
 @ApplicationScoped
 public class PojoImpl implements Pojo {
 
+	protected PojoImpl() {
+		// no-op: a normal scoped bean MUST have a default constructor to let container create a proxy
+	}
+
 	@Override
 	public String foo(String fooInput) {
 		_counter.incrementAndGet();
diff --git a/cdi-itests/src/main/java/org/apache/aries/cdi/test/cases/AbstractTestCase.java b/cdi-itests/src/main/java/org/apache/aries/cdi/test/cases/AbstractTestCase.java
index 7ba6581..25414dd 100644
--- a/cdi-itests/src/main/java/org/apache/aries/cdi/test/cases/AbstractTestCase.java
+++ b/cdi-itests/src/main/java/org/apache/aries/cdi/test/cases/AbstractTestCase.java
@@ -17,6 +17,7 @@
 import static org.junit.Assert.assertFalse;
 import static org.junit.Assert.assertNotNull;
 import static org.junit.Assert.assertTrue;
+import static org.osgi.service.cdi.CDIConstants.CDI_EXTENSION_PROPERTY;
 
 import java.io.InputStream;
 import java.util.Dictionary;
@@ -64,13 +65,17 @@
 	namespace = ServiceNamespace.SERVICE_NAMESPACE
 )
 @Requirement(
-	namespace = CDIConstants.CDI_EXTENSION_PROPERTY,
+	namespace = CDI_EXTENSION_PROPERTY,
 	name = "aries.cdi.http"
 )
 @Requirement(
-	namespace = CDIConstants.CDI_EXTENSION_PROPERTY,
+	namespace = CDI_EXTENSION_PROPERTY,
 	name = "aries.cdi.jndi"
 )
+@Requirement(
+	namespace = CDI_EXTENSION_PROPERTY,
+	name = "eclipse.microprofile.config"
+)
 public abstract class AbstractTestCase {
 
 	@Rule
@@ -91,7 +96,7 @@
 		runtimeTracker = new ServiceTracker<>(
 				bundleContext, CDIComponentRuntime.class, null);
 		runtimeTracker.open();
-		servicesBundle = installBundle("services-one.jar");
+		servicesBundle = installBundle("services-one.jar", false);
 		servicesBundle.start();
 	}
 
@@ -104,7 +109,7 @@
 	@Before
 	public void setUp() throws Exception {
 		cdiRuntime = runtimeTracker.waitForService(timeout);
-		cdiBundle = installBundle("basic-beans.jar");
+		cdiBundle = installBundle("basic-beans.jar", false);
 		cdiBundle.start();
 	}
 
diff --git a/cdi-itests/src/main/java/org/apache/aries/cdi/test/cases/CdiBeanTests.java b/cdi-itests/src/main/java/org/apache/aries/cdi/test/cases/CdiBeanTests.java
index debd60a..29e613a 100644
--- a/cdi-itests/src/main/java/org/apache/aries/cdi/test/cases/CdiBeanTests.java
+++ b/cdi-itests/src/main/java/org/apache/aries/cdi/test/cases/CdiBeanTests.java
@@ -14,7 +14,10 @@
 
 package org.apache.aries.cdi.test.cases;
 
-import static org.junit.Assert.*;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertNull;
+import static org.junit.Assert.assertTrue;
 
 import java.util.Map;
 import java.util.Set;
@@ -43,7 +46,7 @@
 		try (CloseableTracker<BeanService, BeanService> tracker = track(
 			"(&(objectClass=%s)(objectClass=*.%s))",
 			BeanService.class.getName(),
-			"ConstructorInjectedService");) {
+			"ConstructorInjectedService")) {
 
 			BeanService beanService = tracker.waitForService(timeout);
 
@@ -57,7 +60,7 @@
 		try (CloseableTracker<FieldInjectedReference, FieldInjectedReference> tracker = track(
 			"(&(objectClass=%s)(objectClass=*.%s))",
 			FieldInjectedReference.class.getName(),
-			"FieldInjectedBundleScopedImpl");) {
+			"FieldInjectedBundleScopedImpl")) {
 
 			FieldInjectedReference fieldInjectedReference = tracker.waitForService(timeout);
 
@@ -77,7 +80,7 @@
 		try (CloseableTracker<FieldInjectedReference, FieldInjectedReference> tracker = track(
 			"(&(objectClass=%s)(objectClass=*.%s))",
 			FieldInjectedReference.class.getName(),
-			"FieldInjectedPrototypeScopedImpl");) {
+			"FieldInjectedPrototypeScopedImpl")) {
 
 			FieldInjectedReference fieldInjectedReference = tracker.waitForService(timeout);
 
@@ -97,7 +100,7 @@
 		try (CloseableTracker<BeanService, BeanService> tracker = track(
 			"(&(objectClass=%s)(objectClass=*.%s))",
 			BeanService.class.getName(),
-			"FieldInjectedService");) {
+			"FieldInjectedService")) {
 
 			BeanService beanService = tracker.waitForService(timeout);
 
@@ -111,7 +114,7 @@
 		try (CloseableTracker<BeanService, BeanService> tracker = track(
 			"(&(objectClass=%s)(objectClass=*.%s))",
 			BeanService.class.getName(),
-			"MethodInjectedService");) {
+			"MethodInjectedService")) {
 
 			BeanService beanService = tracker.waitForService(timeout);
 
@@ -140,7 +143,7 @@
 		try (CloseableTracker<BeanService, BeanService> tracker = track(
 			"(&(objectClass=%s)(objectClass=*.%s))",
 			BeanService.class.getName(),
-			"ServiceWithProperties");) {
+			"ServiceWithProperties")) {
 
 			BeanService beanService = tracker.waitForService(timeout);
 
@@ -217,7 +220,7 @@
 		try (CloseableTracker<BeanService, BeanService> tracker = track(
 			"(&(objectClass=%s)(objectClass=*.%s))",
 			BeanService.class.getName(),
-			"Instance_ServiceProperties");) {
+			"Instance_ServiceProperties")) {
 
 			BeanService beanService = tracker.waitForService(timeout);
 
@@ -235,7 +238,7 @@
 		try (CloseableTracker<BeanService, BeanService> tracker = track(
 			"(&(objectClass=%s)(objectClass=*.%s))",
 			BeanService.class.getName(),
-			"Instance_ServiceReference");) {
+			"Instance_ServiceReference")) {
 
 			BeanService beanService = tracker.waitForService(timeout);
 
@@ -252,7 +255,7 @@
 		try (CloseableTracker<BeanService, BeanService> tracker = track(
 			"(&(objectClass=%s)(objectClass=*.%s))",
 			BeanService.class.getName(),
-			"Instance_Optional");) {
+			"Instance_Optional")) {
 
 			BeanService beanService = tracker.waitForService(timeout);
 
diff --git a/cdi-itests/src/main/java/org/apache/aries/cdi/test/cases/ConfigurationTests.java b/cdi-itests/src/main/java/org/apache/aries/cdi/test/cases/ConfigurationTests.java
index d9c1375..c72a161 100644
--- a/cdi-itests/src/main/java/org/apache/aries/cdi/test/cases/ConfigurationTests.java
+++ b/cdi-itests/src/main/java/org/apache/aries/cdi/test/cases/ConfigurationTests.java
@@ -14,6 +14,7 @@
 
 package org.apache.aries.cdi.test.cases;
 
+import static java.lang.Thread.sleep;
 import static org.junit.Assert.*;
 
 import java.util.Dictionary;
@@ -112,27 +113,40 @@
 			p2.put("ports", new int[] {80});
 			configurationB.update(p2);
 
-			stA = new ServiceTracker<BeanService, BeanService>(
-				bundleContext, bundleContext.createFilter(
+			stA = new ServiceTracker<>(
+					bundleContext, bundleContext.createFilter(
 					"(&(objectClass=org.apache.aries.cdi.test.interfaces.BeanService)(bean=A))"), null);
 			stA.open(true);
 
 			BeanService<Callable<int[]>> beanService = stA.waitForService(timeout);
 
 			assertNotNull(beanService);
-			assertEquals("blue", beanService.doSomething());
-			assertArrayEquals(new int[] {12, 4567}, beanService.get().call());
 
-			stB = new ServiceTracker<BeanService, BeanService>(
-				bundleContext, bundleContext.createFilter(
+			assertWithRetries(() -> {
+				assertEquals("blue", beanService.doSomething());
+				try {
+					assertArrayEquals(new int[]{12, 4567}, beanService.get().call());
+				} catch (final Exception e) {
+					fail(e.getMessage());
+				}
+			});
+
+			stB = new ServiceTracker<>(
+					bundleContext, bundleContext.createFilter(
 					"(&(objectClass=org.apache.aries.cdi.test.interfaces.BeanService)(bean=B))"), null);
 			stB.open(true);
 
-			beanService = stB.waitForService(timeout);
+			final BeanService<Callable<int[]>> beanServiceB = stB.waitForService(timeout);
+			assertNotNull(beanServiceB);
 
-			assertNotNull(beanService);
-			assertEquals("green", beanService.doSomething());
-			assertArrayEquals(new int[] {80}, beanService.get().call());
+			assertWithRetries(() -> {
+				assertEquals("green", beanServiceB.doSomething());
+				try {
+					assertArrayEquals(new int[]{80}, beanServiceB.get().call());
+				} catch (final Exception e) {
+					fail(e.getMessage());
+				}
+			});
 		}
 		finally {
 			if (configurationA != null) {
@@ -161,6 +175,22 @@
 		}
 	}
 
+	private void assertWithRetries(final Runnable runnable) throws Exception {
+		int retries = 50;
+		for (int i = 0; i < retries; i++) { // can take some time to let configuration listener get the event and update the bean
+			try {
+				runnable.run();
+				break;
+			} catch (final AssertionError ae) {
+				retries--;
+				if (retries == 0) {
+					throw ae;
+				}
+				sleep(200);
+			}
+		}
+	}
+
 	@Test
 	@SuppressWarnings({ "rawtypes", "unchecked" })
 	public void testOptionalConfiguration() throws Exception {
@@ -190,29 +220,41 @@
 			configurationC.update(properties);
 
 			stC.close();
-			stC = new ServiceTracker<BeanService, BeanService>(
-				bundleContext, bundleContext.createFilter(
+			stC = new ServiceTracker<>(
+					bundleContext, bundleContext.createFilter(
 					"(&(objectClass=org.apache.aries.cdi.test.interfaces.BeanService)(bean=C)(ports=12))"), null);
 			stC.open(true);
 
-			beanService = stC.waitForService(timeout);
+			final BeanService<Callable<int[]>> beanServiceC = stC.waitForService(timeout);
 
-			assertNotNull(beanService);
-			assertEquals("blue", beanService.doSomething());
-			assertArrayEquals(new int[] {12, 4567}, beanService.get().call());
+			assertNotNull(beanServiceC);
+			assertWithRetries(() -> {
+				assertEquals("blue", beanServiceC.doSomething());
+				try {
+					assertArrayEquals(new int[]{12, 4567}, beanServiceC.get().call());
+				} catch (final Exception e) {
+					fail(e.getMessage());
+				}
+			});
 
 			configurationC.delete();
 
 			stC.close();
-			stC = new ServiceTracker<BeanService, BeanService>(
-				bundleContext, bundleContext.createFilter(
+			stC = new ServiceTracker<>(
+					bundleContext, bundleContext.createFilter(
 					"(&(objectClass=org.apache.aries.cdi.test.interfaces.BeanService)(bean=C)(!(ports=*)))"), null);
 			stC.open(true);
-			beanService = stC.waitForService(timeout);
+			final BeanService<Callable<int[]>> beanServiceC2 = stC.waitForService(timeout);
 
 			assertNotNull(beanService);
-			assertEquals("blue", beanService.doSomething());
-			assertArrayEquals(new int[] {35777}, beanService.get().call());
+			assertWithRetries(() -> {
+				assertEquals("blue", beanServiceC2.doSomething());
+				try {
+					assertArrayEquals(new int[] {35777}, beanServiceC2.get().call());
+				} catch (final Exception e) {
+					fail(e.getMessage());
+				}
+			});
 		}
 		finally {
 			if (configurationC != null) {
diff --git a/cdi-itests/src/main/java/org/apache/aries/cdi/test/cases/MpConfigTests.java b/cdi-itests/src/main/java/org/apache/aries/cdi/test/cases/MpConfigTests.java
new file mode 100644
index 0000000..7b083e5
--- /dev/null
+++ b/cdi-itests/src/main/java/org/apache/aries/cdi/test/cases/MpConfigTests.java
@@ -0,0 +1,48 @@
+/**
+ * Licensed 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.aries.cdi.test.cases;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
+
+import org.apache.aries.cdi.test.interfaces.Pojo;
+import org.junit.Test;
+import org.osgi.framework.Bundle;
+import org.osgi.util.tracker.ServiceTracker;
+
+public class MpConfigTests extends SlimTestCase {
+
+	@Test
+	public void testConfigIsSet() throws Exception {
+		Bundle tb2Bundle = installBundle("tb16.jar", false);
+
+		tb2Bundle.start();
+
+		ServiceTracker<Pojo, Pojo> st = new ServiceTracker<Pojo, Pojo>(
+			bundleContext, Pojo.class, null);
+		st.open(true);
+
+		try {
+			Pojo pojo = st.waitForService(timeout);
+			assertNotNull(pojo);
+			assertEquals("[foo]", pojo.foo(null));
+		}
+		finally {
+			st.close();
+			tb2Bundle.uninstall();
+		}
+	}
+
+}
diff --git a/cdi-itests/src/main/java/org/apache/aries/cdi/test/cases/OSGiBeanDescriptorTests.java b/cdi-itests/src/main/java/org/apache/aries/cdi/test/cases/OSGiBeanDescriptorTests.java
index 9446b0e..c8d8233 100644
--- a/cdi-itests/src/main/java/org/apache/aries/cdi/test/cases/OSGiBeanDescriptorTests.java
+++ b/cdi-itests/src/main/java/org/apache/aries/cdi/test/cases/OSGiBeanDescriptorTests.java
@@ -14,7 +14,8 @@
 
 package org.apache.aries.cdi.test.cases;
 
-import static org.junit.Assert.*;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
 
 import java.util.Set;
 
diff --git a/cdi-itests/src/main/java/org/apache/aries/cdi/test/tb11/OptionalReference_AS.java b/cdi-itests/src/main/java/org/apache/aries/cdi/test/tb11/OptionalReference_AS.java
index 4048bae..f185b70 100644
--- a/cdi-itests/src/main/java/org/apache/aries/cdi/test/tb11/OptionalReference_AS.java
+++ b/cdi-itests/src/main/java/org/apache/aries/cdi/test/tb11/OptionalReference_AS.java
@@ -30,6 +30,10 @@
 @Service
 public class OptionalReference_AS implements Pojo {
 
+	protected OptionalReference_AS() {
+		// no-op: a normal scoped bean MUST have a default constructor to let container create a proxy
+	}
+
 	@Inject
 	@Reluctant
 	@Reference
diff --git a/cdi-itests/src/main/java/org/apache/aries/cdi/test/tb12/IntegerServiceProvider.java b/cdi-itests/src/main/java/org/apache/aries/cdi/test/tb12/IntegerServiceProvider.java
index dc3c672..3f792a3 100644
--- a/cdi-itests/src/main/java/org/apache/aries/cdi/test/tb12/IntegerServiceProvider.java
+++ b/cdi-itests/src/main/java/org/apache/aries/cdi/test/tb12/IntegerServiceProvider.java
@@ -23,6 +23,10 @@
 @ApplicationScoped
 public class IntegerServiceProvider {
 
+	protected IntegerServiceProvider() {
+		// no-op: a normal scoped bean MUST have a default constructor to let container create a proxy
+	}
+
 	@Produces
 	@Service(Integer.class)
 	@ServiceRanking(5000)
diff --git a/cdi-itests/src/main/java/org/apache/aries/cdi/test/tb13/CustomContext.java b/cdi-itests/src/main/java/org/apache/aries/cdi/test/tb13/CustomContext.java
index 024714e..6da953a 100644
--- a/cdi-itests/src/main/java/org/apache/aries/cdi/test/tb13/CustomContext.java
+++ b/cdi-itests/src/main/java/org/apache/aries/cdi/test/tb13/CustomContext.java
@@ -30,6 +30,9 @@
 @HttpWhiteboardListener
 @Service({ServletContextHelper.class, ServletContextListener.class})
 public class CustomContext extends ServletContextHelper implements ServletContextListener {
+	protected CustomContext() {
+		// no-op: a normal scoped bean MUST have a default constructor to let container create a proxy
+	}
 
 	@Inject
 	public CustomContext(BundleContext bundleContext) {
diff --git a/cdi-itests/src/main/java/org/apache/aries/cdi/test/tb152_3/One.java b/cdi-itests/src/main/java/org/apache/aries/cdi/test/tb152_3/One.java
index b965c1b..3f82cf4 100644
--- a/cdi-itests/src/main/java/org/apache/aries/cdi/test/tb152_3/One.java
+++ b/cdi-itests/src/main/java/org/apache/aries/cdi/test/tb152_3/One.java
@@ -32,6 +32,10 @@
 @ServiceDescription("one")
 public class One implements BeanService<Context> {
 
+	protected One() {
+		// no-op: a normal scoped bean MUST have a default constructor to let container create a proxy
+	}
+
 	private Context _context;
 
 	void onComponent(@Observes @Initialized(ComponentScoped.class) Object obj, BeanManager bm) {
diff --git a/cdi-itests/src/main/java/org/apache/aries/cdi/test/tb152_3_1/One.java b/cdi-itests/src/main/java/org/apache/aries/cdi/test/tb152_3_1/One.java
index 2ebf274..8aa1353 100644
--- a/cdi-itests/src/main/java/org/apache/aries/cdi/test/tb152_3_1/One.java
+++ b/cdi-itests/src/main/java/org/apache/aries/cdi/test/tb152_3_1/One.java
@@ -35,6 +35,10 @@
 @SuppressWarnings({"rawtypes", "unchecked"})
 public class One {
 
+	protected One() {
+		// no-op: a normal scoped bean MUST have a default constructor to let container create a proxy
+	}
+
 	@Inject
 	@Reference
 	@ServiceDescription("onInitialized")
diff --git a/cdi-itests/src/main/java/org/apache/aries/cdi/test/tb152_3_1_1a/ContextObserver.java b/cdi-itests/src/main/java/org/apache/aries/cdi/test/tb152_3_1_1a/ContextObserver.java
index ff2ec01..4cebf18 100644
--- a/cdi-itests/src/main/java/org/apache/aries/cdi/test/tb152_3_1_1a/ContextObserver.java
+++ b/cdi-itests/src/main/java/org/apache/aries/cdi/test/tb152_3_1_1a/ContextObserver.java
@@ -33,6 +33,10 @@
 @ApplicationScoped
 @SuppressWarnings({"rawtypes", "unchecked"})
 public class ContextObserver {
+	protected ContextObserver() {
+		this(null, null, null);
+		// no-op: a normal scoped bean MUST have a default constructor to let container create a proxy
+	}
 
 	@Inject
 	public ContextObserver(
diff --git a/cdi-itests/src/main/java/org/apache/aries/cdi/test/tb152_3_1_1b/ContextObserver.java b/cdi-itests/src/main/java/org/apache/aries/cdi/test/tb152_3_1_1b/ContextObserver.java
index 67888cc..d267abe 100644
--- a/cdi-itests/src/main/java/org/apache/aries/cdi/test/tb152_3_1_1b/ContextObserver.java
+++ b/cdi-itests/src/main/java/org/apache/aries/cdi/test/tb152_3_1_1b/ContextObserver.java
@@ -33,6 +33,10 @@
 @ApplicationScoped
 @SuppressWarnings({"rawtypes", "unchecked"})
 public class ContextObserver {
+	protected ContextObserver() {
+		this(null, null, null);
+		// no-op: a normal scoped bean MUST have a default constructor to let container create a proxy
+	}
 
 	@Inject
 	public ContextObserver(
diff --git a/cdi-itests/src/main/java/org/apache/aries/cdi/test/tb152_3_1_1c/ContextObserver.java b/cdi-itests/src/main/java/org/apache/aries/cdi/test/tb152_3_1_1c/ContextObserver.java
index 77215f1..1662c38 100644
--- a/cdi-itests/src/main/java/org/apache/aries/cdi/test/tb152_3_1_1c/ContextObserver.java
+++ b/cdi-itests/src/main/java/org/apache/aries/cdi/test/tb152_3_1_1c/ContextObserver.java
@@ -33,6 +33,10 @@
 @ApplicationScoped
 @SuppressWarnings({"rawtypes", "unchecked"})
 public class ContextObserver {
+	protected ContextObserver() {
+		this(null, null, null);
+		// no-op: a normal scoped bean MUST have a default constructor to let container create a proxy
+	}
 
 	@Inject
 	public ContextObserver(
diff --git a/cdi-itests/src/main/java/org/apache/aries/cdi/test/tb152_3_1_1d/ContextObserver.java b/cdi-itests/src/main/java/org/apache/aries/cdi/test/tb152_3_1_1d/ContextObserver.java
index 17a5347..ca6b3b3 100644
--- a/cdi-itests/src/main/java/org/apache/aries/cdi/test/tb152_3_1_1d/ContextObserver.java
+++ b/cdi-itests/src/main/java/org/apache/aries/cdi/test/tb152_3_1_1d/ContextObserver.java
@@ -33,6 +33,10 @@
 @ApplicationScoped
 @SuppressWarnings({"rawtypes", "unchecked"})
 public class ContextObserver {
+	protected ContextObserver() {
+		this(null, null, null);
+		// no-op: a normal scoped bean MUST have a default constructor to let container create a proxy
+	}
 
 	@Inject
 	public ContextObserver(
diff --git a/cdi-itests/src/main/java/org/apache/aries/cdi/test/tb152_3_1_1e/ContextObserver.java b/cdi-itests/src/main/java/org/apache/aries/cdi/test/tb152_3_1_1e/ContextObserver.java
index b5f2167..de43ec3 100644
--- a/cdi-itests/src/main/java/org/apache/aries/cdi/test/tb152_3_1_1e/ContextObserver.java
+++ b/cdi-itests/src/main/java/org/apache/aries/cdi/test/tb152_3_1_1e/ContextObserver.java
@@ -33,6 +33,10 @@
 @ApplicationScoped
 @SuppressWarnings({"rawtypes", "unchecked"})
 public class ContextObserver {
+	protected ContextObserver() {
+		this(null, null, null);
+		// no-op: a normal scoped bean MUST have a default constructor to let container create a proxy
+	}
 
 	@Inject
 	public ContextObserver(
diff --git a/cdi-itests/src/main/java/org/apache/aries/cdi/test/tb152_3_1_1f/ContextObserver.java b/cdi-itests/src/main/java/org/apache/aries/cdi/test/tb152_3_1_1f/ContextObserver.java
index da4882e..cfc2cf0 100644
--- a/cdi-itests/src/main/java/org/apache/aries/cdi/test/tb152_3_1_1f/ContextObserver.java
+++ b/cdi-itests/src/main/java/org/apache/aries/cdi/test/tb152_3_1_1f/ContextObserver.java
@@ -33,6 +33,10 @@
 @ApplicationScoped
 @SuppressWarnings({"rawtypes", "unchecked"})
 public class ContextObserver {
+	protected ContextObserver() {
+		this(null, null, null);
+		// no-op: a normal scoped bean MUST have a default constructor to let container create a proxy
+	}
 
 	@Inject
 	public ContextObserver(
diff --git a/cdi-itests/src/main/java/org/apache/aries/cdi/test/tb152_3_1_1g/ContextObserver.java b/cdi-itests/src/main/java/org/apache/aries/cdi/test/tb152_3_1_1g/ContextObserver.java
index 9fbb33b..ff6fab2 100644
--- a/cdi-itests/src/main/java/org/apache/aries/cdi/test/tb152_3_1_1g/ContextObserver.java
+++ b/cdi-itests/src/main/java/org/apache/aries/cdi/test/tb152_3_1_1g/ContextObserver.java
@@ -33,6 +33,10 @@
 @ApplicationScoped
 @SuppressWarnings({"rawtypes", "unchecked"})
 public class ContextObserver {
+	protected ContextObserver() {
+		this(null, null, null);
+		// no-op: a normal scoped bean MUST have a default constructor to let container create a proxy
+	}
 
 	@Inject
 	public ContextObserver(
diff --git a/cdi-itests/src/main/java/org/apache/aries/cdi/test/tb152_3_1_1h/ContextObserver.java b/cdi-itests/src/main/java/org/apache/aries/cdi/test/tb152_3_1_1h/ContextObserver.java
index b746faf..570195c 100644
--- a/cdi-itests/src/main/java/org/apache/aries/cdi/test/tb152_3_1_1h/ContextObserver.java
+++ b/cdi-itests/src/main/java/org/apache/aries/cdi/test/tb152_3_1_1h/ContextObserver.java
@@ -33,6 +33,10 @@
 @ApplicationScoped
 @SuppressWarnings({"rawtypes", "unchecked"})
 public class ContextObserver {
+	protected ContextObserver() {
+		this(null, null, null);
+		// no-op: a normal scoped bean MUST have a default constructor to let container create a proxy
+	}
 
 	@Inject
 	public ContextObserver(
diff --git a/cdi-itests/src/main/java/org/apache/aries/cdi/test/tb152_3_1_1i/ContextObserver.java b/cdi-itests/src/main/java/org/apache/aries/cdi/test/tb152_3_1_1i/ContextObserver.java
index d98f7be..0aa40fa 100644
--- a/cdi-itests/src/main/java/org/apache/aries/cdi/test/tb152_3_1_1i/ContextObserver.java
+++ b/cdi-itests/src/main/java/org/apache/aries/cdi/test/tb152_3_1_1i/ContextObserver.java
@@ -33,6 +33,10 @@
 @ApplicationScoped
 @SuppressWarnings({"rawtypes", "unchecked"})
 public class ContextObserver {
+	protected ContextObserver() {
+		this(null, null, null);
+		// no-op: a normal scoped bean MUST have a default constructor to let container create a proxy
+	}
 
 	@Inject
 	public ContextObserver(
diff --git a/cdi-itests/src/main/java/org/apache/aries/cdi/test/tb152_3_1_1j/ContextObserver.java b/cdi-itests/src/main/java/org/apache/aries/cdi/test/tb152_3_1_1j/ContextObserver.java
index 9563ae1..3a5ffe8 100644
--- a/cdi-itests/src/main/java/org/apache/aries/cdi/test/tb152_3_1_1j/ContextObserver.java
+++ b/cdi-itests/src/main/java/org/apache/aries/cdi/test/tb152_3_1_1j/ContextObserver.java
@@ -33,6 +33,10 @@
 @ApplicationScoped
 @SuppressWarnings({"rawtypes", "unchecked"})
 public class ContextObserver {
+	protected ContextObserver() {
+		this(null, null, null);
+		// no-op: a normal scoped bean MUST have a default constructor to let container create a proxy
+	}
 
 	@Inject
 	public ContextObserver(
diff --git a/cdi-itests/src/main/java/org/apache/aries/cdi/test/tb152_3_1_1k/ContextObserver.java b/cdi-itests/src/main/java/org/apache/aries/cdi/test/tb152_3_1_1k/ContextObserver.java
index 5dad7b7..afdc1c8 100644
--- a/cdi-itests/src/main/java/org/apache/aries/cdi/test/tb152_3_1_1k/ContextObserver.java
+++ b/cdi-itests/src/main/java/org/apache/aries/cdi/test/tb152_3_1_1k/ContextObserver.java
@@ -33,6 +33,10 @@
 @ApplicationScoped
 @SuppressWarnings({"rawtypes", "unchecked"})
 public class ContextObserver {
+	protected ContextObserver() {
+		this(null, null, null);
+		// no-op: a normal scoped bean MUST have a default constructor to let container create a proxy
+	}
 
 	@Inject
 	public ContextObserver(
diff --git a/cdi-itests/src/main/java/org/apache/aries/cdi/test/tb152_3_1_1l/ContextObserver.java b/cdi-itests/src/main/java/org/apache/aries/cdi/test/tb152_3_1_1l/ContextObserver.java
index 29b0608..a17685c 100644
--- a/cdi-itests/src/main/java/org/apache/aries/cdi/test/tb152_3_1_1l/ContextObserver.java
+++ b/cdi-itests/src/main/java/org/apache/aries/cdi/test/tb152_3_1_1l/ContextObserver.java
@@ -33,6 +33,10 @@
 @ApplicationScoped
 @SuppressWarnings({"rawtypes", "unchecked"})
 public class ContextObserver {
+	protected ContextObserver() {
+		this(null, null, null);
+		// no-op: a normal scoped bean MUST have a default constructor to let container create a proxy
+	}
 
 	@Inject
 	public ContextObserver(
diff --git a/cdi-itests/src/main/java/org/apache/aries/cdi/test/tb16/ConfiguredBean.java b/cdi-itests/src/main/java/org/apache/aries/cdi/test/tb16/ConfiguredBean.java
new file mode 100644
index 0000000..478caa9
--- /dev/null
+++ b/cdi-itests/src/main/java/org/apache/aries/cdi/test/tb16/ConfiguredBean.java
@@ -0,0 +1,42 @@
+/**
+ * Licensed 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.aries.cdi.test.tb16;
+
+import java.util.List;
+
+import javax.inject.Inject;
+
+import org.apache.aries.cdi.test.interfaces.Pojo;
+import org.eclipse.microprofile.config.inject.ConfigProperty;
+import org.osgi.service.cdi.annotations.Service;
+
+@Service
+public class ConfiguredBean implements Pojo {
+
+	@Inject
+	@ConfigProperty(name = "tck.config.test.javaconfig.converter.stringvalues")
+	private List<String> myStringList;
+
+	@Override
+	public String foo(String ignored) {
+		return myStringList.toString();
+	}
+
+	@Override
+	public int getCount() {
+		return 0;
+	}
+
+}
diff --git a/cdi-itests/src/main/java/org/apache/aries/cdi/test/tb16/package-info.java b/cdi-itests/src/main/java/org/apache/aries/cdi/test/tb16/package-info.java
new file mode 100644
index 0000000..315634c
--- /dev/null
+++ b/cdi-itests/src/main/java/org/apache/aries/cdi/test/tb16/package-info.java
@@ -0,0 +1,16 @@
+/**
+ * Licensed 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.
+ */
+
+@org.osgi.service.cdi.annotations.Beans
+package org.apache.aries.cdi.test.tb16;
diff --git a/cdi-itests/src/main/java/org/apache/aries/cdi/test/tb3/Config.java b/cdi-itests/src/main/java/org/apache/aries/cdi/test/tb3/Config.java
index 733ac15..fab0878 100644
--- a/cdi-itests/src/main/java/org/apache/aries/cdi/test/tb3/Config.java
+++ b/cdi-itests/src/main/java/org/apache/aries/cdi/test/tb3/Config.java
@@ -14,7 +14,7 @@
 
 package org.apache.aries.cdi.test.tb3;
 
-@interface Config {
+public @interface Config {
 
 	String color() default "blue";
 
diff --git a/cdi-itests/src/main/java/org/apache/aries/cdi/test/tb5/Config.java b/cdi-itests/src/main/java/org/apache/aries/cdi/test/tb5/Config.java
index 230aea7..5c30f4b 100644
--- a/cdi-itests/src/main/java/org/apache/aries/cdi/test/tb5/Config.java
+++ b/cdi-itests/src/main/java/org/apache/aries/cdi/test/tb5/Config.java
@@ -14,7 +14,7 @@
 
 package org.apache.aries.cdi.test.tb5;
 
-@interface Config {
+public @interface Config {
 
 	String color() default "blue";
 
diff --git a/cdi-itests/src/main/java/org/apache/aries/cdi/test/tb7/Config.java b/cdi-itests/src/main/java/org/apache/aries/cdi/test/tb7/Config.java
index fe0342e..5e0e380 100644
--- a/cdi-itests/src/main/java/org/apache/aries/cdi/test/tb7/Config.java
+++ b/cdi-itests/src/main/java/org/apache/aries/cdi/test/tb7/Config.java
@@ -14,7 +14,7 @@
 
 package org.apache.aries.cdi.test.tb7;
 
-@interface Config {
+public @interface Config {
 
 	String color() default "blue";
 
diff --git a/cdi-itests/src/main/java/org/apache/aries/cdi/test/tb8/ContainerBean.java b/cdi-itests/src/main/java/org/apache/aries/cdi/test/tb8/ContainerBean.java
index b9f7541..265b492 100644
--- a/cdi-itests/src/main/java/org/apache/aries/cdi/test/tb8/ContainerBean.java
+++ b/cdi-itests/src/main/java/org/apache/aries/cdi/test/tb8/ContainerBean.java
@@ -25,6 +25,10 @@
 @Service({Pojo.class, ContainerBean.class})
 public class ContainerBean implements Pojo {
 
+	protected ContainerBean() {
+		// no-op: a normal scoped bean MUST have a default constructor to let container create a proxy
+	}
+
 	@Override
 	public String foo(String fooInput) {
 		return getCount() + fooInput + getCount();
diff --git a/cdi-itests/src/main/java/org/apache/aries/cdi/test/tb9/ContainerReferenceEventHandler.java b/cdi-itests/src/main/java/org/apache/aries/cdi/test/tb9/ContainerReferenceEventHandler.java
index e67ee3e..2bf87e6 100644
--- a/cdi-itests/src/main/java/org/apache/aries/cdi/test/tb9/ContainerReferenceEventHandler.java
+++ b/cdi-itests/src/main/java/org/apache/aries/cdi/test/tb9/ContainerReferenceEventHandler.java
@@ -31,6 +31,10 @@
 @Service
 public class ContainerReferenceEventHandler implements Pojo {
 
+	protected ContainerReferenceEventHandler() {
+		// no-op: a normal scoped bean MUST have a default constructor to let container create a proxy
+	}
+
 	@Inject
 	void integers(BindServiceReference<Integer> binder, Logger logger) {
 		binder.adding(
diff --git a/cdi-itests/itest.bndrun b/cdi-itests/weld-itest.bndrun
similarity index 78%
rename from cdi-itests/itest.bndrun
rename to cdi-itests/weld-itest.bndrun
index 959cdb8..a88a2b5 100644
--- a/cdi-itests/itest.bndrun
+++ b/cdi-itests/weld-itest.bndrun
@@ -10,35 +10,24 @@
 #    See the License for the specific language governing permissions and
 #    limitations under the License.
 
+-include: base-itest.bndrun
 #-runjdb: 8000
 
--standalone: true
--runee: JavaSE-1.8
--runfw: org.eclipse.osgi
--runproperties: \
-	eclipse.log.enabled=false,\
-	logback.configurationFile=file:${.}/logback.xml,\
-	org.osgi.service.http.port=0,\
-	osgi.console=
-
--resolve.effective: resolve, active
-
 -runrequires: \
 	osgi.identity;filter:='(osgi.identity=javax.ejb-api)',\
 	osgi.identity;filter:='(osgi.identity=javax.transaction-api)',\
-	osgi.identity;filter:='(osgi.identity=org.apache.aries.cdi.extra)',\
+	osgi.identity;filter:='(osgi.identity=org.apache.aries.cdi.weld)',\
 	osgi.identity;filter:='(osgi.identity=org.apache.aries.cdi.itests)',\
 	osgi.identity;filter:='(osgi.identity=org.apache.aries.jndi.core)',\
 	osgi.identity;filter:='(osgi.identity=org.apache.felix.gogo.command)'
 
--runpath: \
-	ch.qos.logback.classic,\
-	ch.qos.logback.core,\
-	org.apache.felix.logback,\
-	slf4j.api
+-runblacklist: \
+	osgi.identity;filter:='(osgi.identity=org.apache.aries.cdi.owb)',\
+	osgi.identity;filter:='(osgi.identity=org.jboss.spec.*)'
 
 -runsystempackages: \
 	org.slf4j;version=1.7.25,\
+	org.slf4j.event;version=1.7.25,\
 	org.slf4j.helpers;version=1.7.25,\
 	org.slf4j.spi;version=1.7.25,\
 	sun.misc
@@ -48,11 +37,14 @@
 	javax.ejb-api;version='[3.2.0,3.2.1)',\
 	javax.transaction-api;version='[1.2.0,1.2.1)',\
 	jboss-classfilewriter;version='[1.2.3,1.2.4)',\
-	org.apache.aries.cdi.extender;version='[1.0.3,1.0.4)',\
-	org.apache.aries.cdi.extension.http;version='[1.0.3,1.0.4)',\
-	org.apache.aries.cdi.extension.jndi;version='[1.0.3,1.0.4)',\
-	org.apache.aries.cdi.extra;version='[1.0.3,1.0.4)',\
-	org.apache.aries.cdi.itests;version='[1.0.3,1.0.4)',\
+	org.apache.aries.cdi.extender;version='[1.1.0,1.1.1)',\
+	org.apache.aries.cdi.extension.http;version='[1.1.0,1.1.1)',\
+	org.apache.aries.cdi.extension.jndi;version='[1.1.0,1.1.1)',\
+	org.apache.aries.cdi.extension.mp-config;version='[1.1.0,1.1.1)',\
+	org.apache.aries.cdi.extra;version='[1.1.0,1.1.1)',\
+	org.apache.aries.cdi.itests;version='[1.1.0,1.1.1)',\
+	org.apache.aries.cdi.spi;version='[1.1.0,1.1.1)',\
+	org.apache.aries.cdi.weld;version='[1.1.0,1.1.1)',\
 	org.apache.aries.jndi.api;version='[1.1.0,1.1.1)',\
 	org.apache.aries.jndi.core;version='[1.0.2,1.0.3)',\
 	org.apache.aries.spifly.dynamic.framework.extension;version='[1.2.0,1.2.1)',\
diff --git a/cdi-owb/pom.xml b/cdi-owb/pom.xml
new file mode 100644
index 0000000..66c47c4
--- /dev/null
+++ b/cdi-owb/pom.xml
@@ -0,0 +1,149 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+/**
+ * Licensed 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.aries.cdi</groupId>
+		<artifactId>org.apache.aries.cdi</artifactId>
+		<version>1.1.0-SNAPSHOT</version>
+		<relativePath>..</relativePath>
+	</parent>
+
+	<artifactId>org.apache.aries.cdi.owb</artifactId>
+	<name>Apache Aries CDI - Container using Apache OpenWebBeans</name>
+	<description>Apache Aries CDI - Container using Apache OpenWebBeans</description>
+
+	<licenses>
+		<license>
+			<name>ASL 2.0</name>
+			<url>https://www.apache.org/licenses/LICENSE-2.0</url>
+		</license>
+	</licenses>
+
+	<scm>
+		<connection>scm:git:git@github.com:apache/aries-cdi.git</connection>
+		<developerConnection>scm:git:git@github.com:apache/aries-cdi.git</developerConnection>
+		<tag>HEAD</tag>
+		<url>https://github.com/apache/aries-cdi</url>
+	</scm>
+
+	<build>
+		<plugins>
+			<plugin>
+				<groupId>biz.aQute.bnd</groupId>
+				<artifactId>bnd-maven-plugin</artifactId>
+				<configuration>
+					<bnd><![CDATA[
+						-cdiannotations:
+						-noclassforname: true
+						#Import-Package: \
+						#	org.apache.webbeans.servlet;resolution:=optional,\
+						#	org.apache.webbeans.web.*;resolution:=optional,\
+						#	javax.servlet.*;resolution:=optional,\
+						#	*
+					]]></bnd>
+				</configuration>
+			</plugin>
+		</plugins>
+	</build>
+
+	<dependencies>
+		<dependency>
+			<groupId>org.apache.aries.cdi</groupId>
+			<artifactId>org.apache.aries.cdi.extra</artifactId>
+			<version>${project.version}</version>
+		</dependency>
+		<dependency>
+			<groupId>org.apache.aries.cdi</groupId>
+			<artifactId>org.apache.aries.cdi.spi</artifactId>
+			<version>${project.version}</version>
+		</dependency>
+		<dependency>
+			<groupId>org.apache.geronimo.specs</groupId>
+			<artifactId>geronimo-annotation_1.3_spec</artifactId>
+		</dependency>
+		<dependency>
+			<groupId>org.apache.geronimo.specs</groupId>
+			<artifactId>geronimo-atinject_1.0_spec</artifactId>
+		</dependency>
+		<dependency>
+			<groupId>org.apache.geronimo.specs</groupId>
+			<artifactId>geronimo-interceptor_1.2_spec</artifactId>
+		</dependency>
+		<dependency>
+			<groupId>org.apache.geronimo.specs</groupId>
+			<artifactId>geronimo-jcdi_2.0_spec</artifactId>
+		</dependency>
+		<dependency>
+			<groupId>org.apache.openwebbeans</groupId>
+			<artifactId>openwebbeans-impl</artifactId>
+			<version>${owb.version}</version>
+		</dependency>
+		<dependency>
+			<groupId>org.apache.openwebbeans</groupId>
+			<artifactId>openwebbeans-web</artifactId>
+			<version>${owb.version}</version>
+		</dependency>
+		<dependency>
+			<groupId>org.apache.xbean</groupId>
+			<artifactId>xbean-bundleutils</artifactId>
+			<version>4.15</version>
+			<exclusions>
+				<exclusion>
+					<groupId>org.slf4j</groupId>
+					<artifactId>slf4j-api</artifactId>
+				</exclusion>
+			</exclusions>
+		</dependency>
+		<dependency>
+			<groupId>org.apache.felix</groupId>
+			<artifactId>org.apache.felix.http.servlet-api</artifactId>
+		</dependency>
+		<dependency>
+			<groupId>org.osgi</groupId>
+			<artifactId>org.osgi.namespace.extender</artifactId>
+		</dependency>
+		<dependency>
+			<groupId>org.osgi</groupId>
+			<artifactId>org.osgi.namespace.implementation</artifactId>
+		</dependency>
+		<dependency>
+			<groupId>org.osgi</groupId>
+			<artifactId>org.osgi.namespace.service</artifactId>
+		</dependency>
+		<dependency>
+			<groupId>org.osgi</groupId>
+			<artifactId>org.osgi.service.cdi</artifactId>
+		</dependency>
+		<dependency>
+			<groupId>org.osgi</groupId>
+			<artifactId>org.osgi.service.http.whiteboard</artifactId>
+		</dependency>
+		<dependency>
+			<groupId>org.osgi</groupId>
+			<artifactId>osgi.annotation</artifactId>
+		</dependency>
+		<dependency>
+			<groupId>org.osgi</groupId>
+			<artifactId>osgi.core</artifactId>
+		</dependency>
+	</dependencies>
+
+</project>
\ No newline at end of file
diff --git a/cdi-owb/src/main/java/org/apache/aries/cdi/owb/Activator.java b/cdi-owb/src/main/java/org/apache/aries/cdi/owb/Activator.java
new file mode 100644
index 0000000..7474276
--- /dev/null
+++ b/cdi-owb/src/main/java/org/apache/aries/cdi/owb/Activator.java
@@ -0,0 +1,73 @@
+/**
+ * Licensed 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.aries.cdi.owb;
+
+import static org.osgi.framework.Constants.BUNDLE_ACTIVATOR;
+import static org.osgi.framework.Constants.SERVICE_DESCRIPTION;
+import static org.osgi.framework.Constants.SERVICE_VENDOR;
+import static org.osgi.service.cdi.CDIConstants.CDI_EXTENSION_PROPERTY;
+
+import java.util.Dictionary;
+import java.util.Hashtable;
+
+import javax.enterprise.inject.spi.Extension;
+
+import org.apache.aries.cdi.spi.CDIContainerInitializer;
+import org.osgi.annotation.bundle.Header;
+import org.osgi.framework.BundleActivator;
+import org.osgi.framework.BundleContext;
+import org.osgi.framework.ServiceRegistration;
+
+@Header(
+	name = BUNDLE_ACTIVATOR,
+	value = "${@class}"
+)
+public class Activator implements BundleActivator {
+
+	public static final boolean webEnabled = true;
+
+	@Override
+	public void start(BundleContext bundleContext) throws Exception {
+		System.setProperty("openwebbeans.web.sci.active", "false"); // we handle it ourself, disable this jetty feature
+		Dictionary<String, Object> properties = new Hashtable<>();
+		properties.put(SERVICE_DESCRIPTION, "Aries CDI - OpenWebBeans CDIContainerInitializer Factory");
+		properties.put(SERVICE_VENDOR, "Apache Software Foundation");
+
+		_containerInitializer = bundleContext.registerService(
+			CDIContainerInitializer.class, new OWBCDIContainerInitializerFactory(bundleContext), properties);
+
+		if (webEnabled) {
+			properties = new Hashtable<>();
+			properties.put(CDI_EXTENSION_PROPERTY, "aries.cdi.http");
+			properties.put(SERVICE_DESCRIPTION, "Aries CDI - OpenWebBeans Web Extension Factory");
+			properties.put(SERVICE_VENDOR, "Apache Software Foundation");
+
+			_webExtension = bundleContext.registerService(
+				Extension.class, new org.apache.aries.cdi.owb.web.WebExtensionFactory(), properties);
+		}
+	}
+
+	@Override
+	public void stop(BundleContext context) throws Exception {
+		_containerInitializer.unregister();
+		if (_webExtension != null) {
+			_webExtension.unregister();
+		}
+	}
+
+	private ServiceRegistration<CDIContainerInitializer> _containerInitializer;
+	private ServiceRegistration<Extension> _webExtension;
+
+}
diff --git a/cdi-owb/src/main/java/org/apache/aries/cdi/owb/CdiScannerService.java b/cdi-owb/src/main/java/org/apache/aries/cdi/owb/CdiScannerService.java
new file mode 100644
index 0000000..b0dcb30
--- /dev/null
+++ b/cdi-owb/src/main/java/org/apache/aries/cdi/owb/CdiScannerService.java
@@ -0,0 +1,62 @@
+package org.apache.aries.cdi.owb;
+
+import static java.util.Collections.*;
+
+import java.net.URL;
+import java.util.Collection;
+import java.util.HashSet;
+import java.util.Set;
+
+import org.apache.webbeans.corespi.se.DefaultBDABeansXmlScanner;
+import org.apache.webbeans.spi.BDABeansXmlScanner;
+import org.apache.webbeans.spi.ScannerService;
+
+// todo: bda support
+@SuppressWarnings("deprecation")
+public class CdiScannerService implements ScannerService {
+	private final Set<Class<?>> classes;
+	private final Set<URL> beansXml;
+	private BDABeansXmlScanner bdaBeansXmlScanner = new DefaultBDABeansXmlScanner();
+
+	public CdiScannerService(final Set<Class<?>> beanClassNames,
+							final Collection<URL> beansXml) {
+		this.classes = beanClassNames;
+		this.beansXml = beansXml == null ? emptySet() : new HashSet<>(beansXml);
+	}
+
+	@Override
+	public void init(final Object object) {
+		// no-op
+	}
+
+	@Override
+	public void scan() {
+		// we already scanned
+	}
+
+	@Override
+	public void release() {
+		// no-op
+	}
+
+	@Override
+	public Set<URL> getBeanXmls() {
+		return beansXml;
+	}
+
+	@Override
+	public Set<Class<?>> getBeanClasses() {
+		return classes;
+	}
+
+	@Override
+	public boolean isBDABeansXmlScanningEnabled() {
+		return false;
+	}
+
+	@Override
+	public BDABeansXmlScanner getBDABeansXmlScanner() {
+		return bdaBeansXmlScanner;
+	}
+
+}
\ No newline at end of file
diff --git a/cdi-owb/src/main/java/org/apache/aries/cdi/owb/OSGiDefiningClassService.java b/cdi-owb/src/main/java/org/apache/aries/cdi/owb/OSGiDefiningClassService.java
new file mode 100644
index 0000000..8186eb7
--- /dev/null
+++ b/cdi-owb/src/main/java/org/apache/aries/cdi/owb/OSGiDefiningClassService.java
@@ -0,0 +1,73 @@
+/**
+ * Licensed 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
+ * <p>
+ * http://www.apache.org/licenses/LICENSE-2.0
+ * <p>
+ * 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.aries.cdi.owb;
+
+import java.lang.reflect.Modifier;
+
+import org.apache.aries.cdi.spi.loader.SpiLoader;
+import org.apache.webbeans.config.WebBeansContext;
+import org.apache.webbeans.proxy.Unsafe;
+import org.apache.webbeans.spi.DefiningClassService;
+
+public class OSGiDefiningClassService implements DefiningClassService {
+	private final Unsafe unsafe;
+	private final ClassLoaders classloaders;
+
+	public OSGiDefiningClassService(final WebBeansContext context) {
+		this.unsafe = new Unsafe();
+		this.classloaders = context.getService(ClassLoaders.class);
+	}
+
+	@Override
+	public ClassLoader getProxyClassLoader(final Class<?> aClass) {
+		return classloaders.loader;
+	}
+
+	/**
+	 * We prefer to register the proxy in the dedicated cdi classloader but due to classloader rules it is not always possible.
+	 * In such cases we try to use unsafe.
+	 *
+	 * @param name proxy name.
+	 * @param bytes proxy bytecode.
+	 * @param proxied proxied class.
+	 * @param <T> proxied type.
+	 * @return the proxy class instance.
+	 */
+	@Override
+	@SuppressWarnings("unchecked")
+	public <T> Class<T> defineAndLoad(final String name, final byte[] bytes, final Class<T> proxied) {
+		if (requiresUnsafe(proxied)) { // todo: today we don't really support that
+			final ClassLoader classLoader = proxied.getClassLoader();
+			if (classLoader != classloaders.bundleLoader) {
+				// todo: log a warning?
+			}
+			return unsafe.defineAndLoadClass(classLoader, name, bytes);
+		}
+		return (Class<T>) classloaders.loader.getOrRegister(name, bytes, proxied.getPackage(), proxied.getProtectionDomain());
+	}
+
+	private boolean requiresUnsafe(final Class<?> aClass) {
+		return !Modifier.isPublic(aClass.getModifiers());
+	}
+
+	public static class ClassLoaders {
+		private final ClassLoader bundleLoader;
+		private final SpiLoader loader;
+
+		public ClassLoaders(final ClassLoader bundleLoader, final SpiLoader loader) {
+			this.bundleLoader = bundleLoader;
+			this.loader = loader;
+		}
+	}
+}
diff --git a/cdi-owb/src/main/java/org/apache/aries/cdi/owb/OWBCDIContainerInitializer.java b/cdi-owb/src/main/java/org/apache/aries/cdi/owb/OWBCDIContainerInitializer.java
new file mode 100644
index 0000000..a39756d
--- /dev/null
+++ b/cdi-owb/src/main/java/org/apache/aries/cdi/owb/OWBCDIContainerInitializer.java
@@ -0,0 +1,288 @@
+package org.apache.aries.cdi.owb;
+
+import static java.util.Objects.requireNonNull;
+
+import java.io.IOException;
+import java.lang.annotation.Annotation;
+import java.net.URL;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Enumeration;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.IdentityHashMap;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+import java.util.Properties;
+import java.util.Set;
+
+import javax.enterprise.inject.Instance;
+import javax.enterprise.inject.se.SeContainer;
+import javax.enterprise.inject.spi.BeanManager;
+import javax.enterprise.inject.spi.Extension;
+import javax.enterprise.util.TypeLiteral;
+
+import org.apache.aries.cdi.spi.CDIContainerInitializer;
+import org.apache.aries.cdi.spi.loader.SpiLoader;
+import org.apache.webbeans.config.WebBeansContext;
+import org.apache.webbeans.config.WebBeansFinder;
+import org.apache.webbeans.corespi.DefaultSingletonService;
+import org.apache.webbeans.portable.events.ExtensionLoader;
+import org.apache.webbeans.spi.ApplicationBoundaryService;
+import org.apache.webbeans.spi.ContainerLifecycle;
+import org.apache.webbeans.spi.ContextsService;
+import org.apache.webbeans.spi.ConversationService;
+import org.apache.webbeans.spi.DefiningClassService;
+import org.apache.webbeans.spi.ScannerService;
+import org.osgi.framework.Bundle;
+import org.osgi.framework.BundleContext;
+import org.osgi.framework.namespace.PackageNamespace;
+import org.osgi.framework.wiring.BundleCapability;
+import org.osgi.framework.wiring.BundleWire;
+import org.osgi.framework.wiring.BundleWiring;
+
+public class OWBCDIContainerInitializer extends CDIContainerInitializer {
+
+	public OWBCDIContainerInitializer(BundleContext bundleContext) {
+		owbBundleContext = bundleContext;
+	}
+
+	@Override
+	public CDIContainerInitializer addBeanClasses(Class<?>... classes) {
+		beanClasses.addAll(Arrays.asList(classes));
+		return this;
+	}
+
+	@Override
+	public CDIContainerInitializer addBeanXmls(URL... beanXmls) {
+		beanDescriptorURLs.addAll(Arrays.asList(beanXmls));
+		return this;
+	}
+
+	@Override
+	public CDIContainerInitializer addExtension(Extension extension, Map<String, Object> properties) {
+		this.extensions.put(extension, properties);
+		return this;
+	}
+
+	@Override
+	public CDIContainerInitializer addProperty(String key, Object value) {
+		properties.putIfAbsent(key, value);
+		return this;
+	}
+
+	@Override
+	public CDIContainerInitializer setBundleContext(BundleContext bundleContext) {
+		clientBundleContext = bundleContext;
+		return this;
+	}
+
+	@Override
+	public CDIContainerInitializer setClassLoader(SpiLoader spiLoader) {
+		this.spiLoader = spiLoader;
+		return this;
+	}
+
+	@Override
+	public SeContainer initialize() {
+		requireNonNull(spiLoader).handleResources(
+			s -> (s != null) && s.startsWith("META-INF/openwebbeans/"),
+			this::getResources
+		).findClass(
+			s -> (s != null) && (s.startsWith("org.apache.webbeans.") || s.startsWith("sun.misc.")),
+			this::loadClass);
+
+		spiLoader.getBundles().add(owbBundleContext.getBundle());
+
+		BundleWiring bundleWiring = owbBundleContext.getBundle().adapt(BundleWiring.class);
+		List<BundleWire> requiredWires = bundleWiring.getRequiredWires(PackageNamespace.PACKAGE_NAMESPACE);
+
+		for (BundleWire bundleWire : requiredWires) {
+			BundleCapability capability = bundleWire.getCapability();
+			Map<String, Object> attributes = capability.getAttributes();
+			String packageName = (String)attributes.get(PackageNamespace.PACKAGE_NAMESPACE);
+			if (!packageName.startsWith("org.apache.webbeans.")) {
+				continue;
+			}
+
+			Bundle wireBundle = bundleWire.getProvider().getBundle();
+			if (!spiLoader.getBundles().contains(wireBundle)) {
+				spiLoader.getBundles().add(wireBundle);
+			}
+		}
+
+		Thread currentThread = Thread.currentThread();
+		ClassLoader current = currentThread.getContextClassLoader();
+
+		try {
+			currentThread.setContextClassLoader(spiLoader);
+			startObject = requireNonNull(clientBundleContext);
+
+			final Map<Class<?>, Object> services = new HashMap<>();
+			properties.setProperty(
+				DefiningClassService.class.getName(),
+				OSGiDefiningClassService.class.getName());
+
+			services.put(
+				OSGiDefiningClassService.ClassLoaders.class,
+				new OSGiDefiningClassService.ClassLoaders(current, spiLoader));
+			services.put(
+				ApplicationBoundaryService.class,
+				new OsgiApplicationBoundaryService(current, spiLoader));
+			services.put(
+				ScannerService.class,
+				new CdiScannerService(beanClasses, beanDescriptorURLs));
+			services.put(BundleContext.class, clientBundleContext);
+
+			if (Activator.webEnabled) {
+				// Web mode - minimal set, see META-INF/openwebbeans/openwebbeans.properties in openwebbeans-web for details
+				// todo: enable to not use web?
+				properties.setProperty(
+					ContainerLifecycle.class.getName(),
+					org.apache.webbeans.web.lifecycle.WebContainerLifecycle.class.getName());
+				properties.setProperty(
+					ContextsService.class.getName(),
+					org.apache.webbeans.web.context.WebContextsService.class.getName());
+				properties.setProperty(
+					ConversationService.class.getName(),
+					org.apache.webbeans.web.context.WebConversationService.class.getName());
+
+				startObject = new org.apache.aries.cdi.owb.web.UpdatableServletContext(bootstrap, clientBundleContext);
+				services.put(org.apache.aries.cdi.owb.web.UpdatableServletContext.class, startObject);
+			}
+
+			bootstrap = new WebBeansContext(services, properties) {
+				private final ExtensionLoader overridenExtensionLoader = new ExtensionLoader(this) {
+					@Override
+					public void loadExtensionServices() {
+						extensions.forEach((k, v) -> addExtension(k));
+					}
+				};
+
+				@Override
+				public ExtensionLoader getExtensionLoader() {
+					return overridenExtensionLoader;
+				}
+			};
+
+			final DefaultSingletonService singletonService = getSingletonService();
+			singletonService.register(spiLoader, bootstrap);
+			final ContainerLifecycle lifecycle = bootstrap.getService(ContainerLifecycle.class);
+			lifecycle.startApplication(startObject);
+
+			return new OWBSeContainer();
+		}
+		finally {
+			currentThread.setContextClassLoader(current);
+		}
+	}
+
+	protected Enumeration<URL> getResources(String name) {
+		try {
+			return WebBeansContext.class.getClassLoader().getResources(name);
+		} catch (IOException e) {
+			throwsUnchecked(e);
+			return null; // unreachable
+		}
+	}
+
+	protected Class<?> loadClass(String name) {
+		try {
+			return WebBeansContext.class.getClassLoader().loadClass(name);
+		} catch (ClassNotFoundException e) {
+			throwsUnchecked(e);
+			return null; // unreachable
+		}
+	}
+
+	protected DefaultSingletonService getSingletonService() {
+		return DefaultSingletonService.class.cast(WebBeansFinder.getSingletonService());
+	}
+
+	@SuppressWarnings("unchecked")
+	private static <E extends Throwable> void throwsUnchecked(Throwable throwable) throws E {
+		throw (E) throwable;
+	}
+
+	private volatile WebBeansContext bootstrap;
+	private final List<URL> beanDescriptorURLs = new ArrayList<>();
+	private volatile BundleContext clientBundleContext;
+	private volatile SpiLoader spiLoader;
+	private final Set<Class<?>> beanClasses = new HashSet<>();
+	private final Map<Extension, Map<String, Object>> extensions = new IdentityHashMap<>();
+	private final BundleContext owbBundleContext;
+	private final Properties properties = new Properties();
+	private Object startObject;
+
+	private class OWBSeContainer implements SeContainer {
+
+		private volatile boolean running = true;
+
+		@Override
+		public void close() {
+			running = false;
+			Thread currentThread = Thread.currentThread();
+			ClassLoader current = currentThread.getContextClassLoader();
+			try {
+				currentThread.setContextClassLoader(requireNonNull(spiLoader));
+				bootstrap.getService(ContainerLifecycle.class).stopApplication(startObject);
+			}
+			finally {
+				currentThread.setContextClassLoader(current);
+			}
+		}
+
+		@Override
+		public Instance<Object> select(Annotation... qualifiers) {
+			return bootstrap.getBeanManagerImpl().createInstance().select(qualifiers);
+		}
+
+		@Override
+		public <U> Instance<U> select(Class<U> subtype, Annotation... qualifiers) {
+			return bootstrap.getBeanManagerImpl().createInstance().select(subtype, qualifiers);
+		}
+
+		@Override
+		public <U> Instance<U> select(TypeLiteral<U> subtype, Annotation... qualifiers) {
+			return bootstrap.getBeanManagerImpl().createInstance().select(subtype, qualifiers);
+		}
+
+		@Override
+		public boolean isUnsatisfied() {
+			return bootstrap.getBeanManagerImpl().createInstance().isUnsatisfied();
+		}
+
+		@Override
+		public boolean isAmbiguous() {
+			return bootstrap.getBeanManagerImpl().createInstance().isAmbiguous();
+		}
+
+		@Override
+		public void destroy(Object instance) {
+			bootstrap.getBeanManagerImpl().createInstance().destroy(instance);
+		}
+
+		@Override
+		public Iterator<Object> iterator() {
+			return bootstrap.getBeanManagerImpl().createInstance().iterator();
+		}
+
+		@Override
+		public boolean isRunning() {
+			return running;
+		}
+
+		@Override
+		public BeanManager getBeanManager() {
+			return bootstrap.getBeanManagerImpl();
+		}
+
+		@Override
+		public Object get() {
+			return bootstrap.getBeanManagerImpl().createInstance().get();
+		}
+
+	}
+
+}
diff --git a/cdi-owb/src/main/java/org/apache/aries/cdi/owb/OWBCDIContainerInitializerFactory.java b/cdi-owb/src/main/java/org/apache/aries/cdi/owb/OWBCDIContainerInitializerFactory.java
new file mode 100644
index 0000000..db10ecd
--- /dev/null
+++ b/cdi-owb/src/main/java/org/apache/aries/cdi/owb/OWBCDIContainerInitializerFactory.java
@@ -0,0 +1,46 @@
+/**
+ * Licensed 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.aries.cdi.owb;
+
+import org.apache.aries.cdi.spi.CDIContainerInitializer;
+import org.osgi.framework.Bundle;
+import org.osgi.framework.BundleContext;
+import org.osgi.framework.PrototypeServiceFactory;
+import org.osgi.framework.ServiceRegistration;
+
+public class OWBCDIContainerInitializerFactory implements PrototypeServiceFactory<CDIContainerInitializer> {
+
+	public OWBCDIContainerInitializerFactory(BundleContext bundleContext) {
+		this.bundleContext = bundleContext;
+	}
+
+	@Override
+	public CDIContainerInitializer getService(
+		Bundle bundle,
+		ServiceRegistration<CDIContainerInitializer> registration) {
+
+		return new OWBCDIContainerInitializer(bundleContext);
+	}
+
+	@Override
+	public void ungetService(
+		Bundle bundle,
+		ServiceRegistration<CDIContainerInitializer> registration,
+		CDIContainerInitializer service) {
+	}
+
+	private final BundleContext bundleContext;
+
+}
diff --git a/cdi-owb/src/main/java/org/apache/aries/cdi/owb/OsgiApplicationBoundaryService.java b/cdi-owb/src/main/java/org/apache/aries/cdi/owb/OsgiApplicationBoundaryService.java
new file mode 100644
index 0000000..b3985f9
--- /dev/null
+++ b/cdi-owb/src/main/java/org/apache/aries/cdi/owb/OsgiApplicationBoundaryService.java
@@ -0,0 +1,44 @@
+/**
+ * Licensed 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.aries.cdi.owb;
+
+import org.apache.webbeans.spi.ApplicationBoundaryService;
+
+public class OsgiApplicationBoundaryService implements ApplicationBoundaryService {
+	private final ClassLoader bundleLoader;
+	private final ClassLoader loader;
+
+	public OsgiApplicationBoundaryService(final ClassLoader bundleLoader, final ClassLoader loader) {
+		this.bundleLoader = bundleLoader;
+		this.loader = loader;
+	}
+
+	@Override
+	public ClassLoader getApplicationClassLoader() {
+		return bundleLoader;
+	}
+
+	@Override
+	public ClassLoader getBoundaryClassLoader(@SuppressWarnings("rawtypes") final Class aClass) {
+		final ClassLoader classToProxyCl = aClass.getClassLoader();
+		if (classToProxyCl == null || classToProxyCl == loader) {
+			return loader;
+		}
+		if (classToProxyCl == bundleLoader) {
+			return classToProxyCl;
+		}
+		// todo: refine if needed
+		return classToProxyCl;
+	}
+}
diff --git a/cdi-owb/src/main/java/org/apache/aries/cdi/owb/package-info.java b/cdi-owb/src/main/java/org/apache/aries/cdi/owb/package-info.java
new file mode 100644
index 0000000..5e523d8
--- /dev/null
+++ b/cdi-owb/src/main/java/org/apache/aries/cdi/owb/package-info.java
@@ -0,0 +1,20 @@
+/**
+ * Licensed 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.
+ */
+
+@org.osgi.annotation.bundle.Capability(
+	attribute = "objectClass:List<String>=org.apache.aries.cdi.spi.CDIContainerInitializer",
+	namespace = org.osgi.namespace.service.ServiceNamespace.SERVICE_NAMESPACE
+)
+@org.osgi.service.cdi.annotations.RequireCDIImplementation
+package org.apache.aries.cdi.owb;
diff --git a/cdi-owb/src/main/java/org/apache/aries/cdi/owb/web/UpdatableServletContext.java b/cdi-owb/src/main/java/org/apache/aries/cdi/owb/web/UpdatableServletContext.java
new file mode 100644
index 0000000..a732a3e
--- /dev/null
+++ b/cdi-owb/src/main/java/org/apache/aries/cdi/owb/web/UpdatableServletContext.java
@@ -0,0 +1,67 @@
+/**
+ * Licensed 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.aries.cdi.owb.web;
+
+import static java.util.Optional.ofNullable;
+
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Proxy;
+
+import javax.servlet.ServletContext;
+import javax.servlet.ServletContextEvent;
+
+import org.apache.webbeans.config.WebBeansContext;
+import org.apache.webbeans.web.lifecycle.test.MockServletContext;
+import org.osgi.framework.BundleContext;
+
+@SuppressWarnings("serial")
+public class UpdatableServletContext extends ServletContextEvent {
+	private final WebBeansContext bootstrap;
+	private final BundleContext bundleContext;
+	private final ServletContext context;
+	private ServletContext delegate;
+
+	public UpdatableServletContext(WebBeansContext bootstrap, BundleContext bundleContext) {
+		super(new MockServletContext());
+		this.bootstrap = bootstrap;
+		this.bundleContext = bundleContext;
+
+		// ensure we can switch the impl and keep ServletContextBean working with an updated context
+		this.context = ServletContext.class.cast(Proxy.newProxyInstance(ServletContext.class.getClassLoader(),
+				new Class<?>[]{ServletContext.class},
+				(proxy, method, args) -> {
+					try {
+						return method.invoke(ofNullable(delegate).orElseGet(UpdatableServletContext.super::getServletContext), args);
+					}
+					catch (final InvocationTargetException ite) {
+						throw ite.getTargetException();
+					}
+				}));
+	}
+
+	public void setDelegate(final ServletContext delegate) {
+		this.delegate = delegate;
+		this.delegate.setAttribute(BundleContext.class.getName(), bundleContext);
+		this.delegate.setAttribute(WebBeansContext.class.getName(), bootstrap);
+	}
+
+	public ServletContext getOriginal() {
+		return super.getServletContext();
+	}
+
+	@Override
+	public ServletContext getServletContext() {
+		return context;
+	}
+}
diff --git a/cdi-owb/src/main/java/org/apache/aries/cdi/owb/web/WebExtension.java b/cdi-owb/src/main/java/org/apache/aries/cdi/owb/web/WebExtension.java
new file mode 100644
index 0000000..d07a618
--- /dev/null
+++ b/cdi-owb/src/main/java/org/apache/aries/cdi/owb/web/WebExtension.java
@@ -0,0 +1,367 @@
+/**
+ * Licensed 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.aries.cdi.owb.web;
+
+import static java.util.Collections.list;
+import static javax.interceptor.Interceptor.Priority.LIBRARY_AFTER;
+import static org.osgi.framework.Constants.SERVICE_DESCRIPTION;
+import static org.osgi.framework.Constants.SERVICE_RANKING;
+import static org.osgi.framework.Constants.SERVICE_VENDOR;
+import static org.osgi.namespace.extender.ExtenderNamespace.EXTENDER_NAMESPACE;
+import static org.osgi.service.cdi.CDIConstants.CDI_CAPABILITY_NAME;
+import static org.osgi.service.http.whiteboard.HttpWhiteboardConstants.HTTP_WHITEBOARD_CONTEXT_SELECT;
+import static org.osgi.service.http.whiteboard.HttpWhiteboardConstants.HTTP_WHITEBOARD_LISTENER;
+
+import java.lang.annotation.Annotation;
+import java.lang.reflect.InvocationTargetException;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.Dictionary;
+import java.util.HashSet;
+import java.util.Hashtable;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+import java.util.concurrent.atomic.AtomicBoolean;
+
+import javax.annotation.Priority;
+import javax.enterprise.event.Observes;
+import javax.enterprise.inject.spi.AfterDeploymentValidation;
+import javax.enterprise.inject.spi.AnnotatedType;
+import javax.enterprise.inject.spi.BeanManager;
+import javax.enterprise.inject.spi.BeforeShutdown;
+import javax.enterprise.inject.spi.Extension;
+import javax.enterprise.inject.spi.ProcessAnnotatedType;
+import javax.enterprise.inject.spi.WithAnnotations;
+import javax.servlet.Filter;
+import javax.servlet.Servlet;
+import javax.servlet.ServletContext;
+import javax.servlet.ServletContextEvent;
+import javax.servlet.ServletContextListener;
+import javax.servlet.ServletRequestListener;
+import javax.servlet.annotation.MultipartConfig;
+import javax.servlet.annotation.WebFilter;
+import javax.servlet.annotation.WebListener;
+import javax.servlet.annotation.WebServlet;
+import javax.servlet.http.HttpSessionListener;
+
+import org.apache.aries.cdi.extra.propertytypes.HttpWhiteboardContextSelect;
+import org.apache.aries.cdi.extra.propertytypes.HttpWhiteboardFilterAsyncSupported;
+import org.apache.aries.cdi.extra.propertytypes.HttpWhiteboardFilterDispatcher;
+import org.apache.aries.cdi.extra.propertytypes.HttpWhiteboardFilterName;
+import org.apache.aries.cdi.extra.propertytypes.HttpWhiteboardFilterPattern;
+import org.apache.aries.cdi.extra.propertytypes.HttpWhiteboardFilterServlet;
+import org.apache.aries.cdi.extra.propertytypes.HttpWhiteboardListener;
+import org.apache.aries.cdi.extra.propertytypes.HttpWhiteboardServletAsyncSupported;
+import org.apache.aries.cdi.extra.propertytypes.HttpWhiteboardServletMultipart;
+import org.apache.aries.cdi.extra.propertytypes.HttpWhiteboardServletName;
+import org.apache.aries.cdi.extra.propertytypes.HttpWhiteboardServletPattern;
+import org.apache.aries.cdi.extra.propertytypes.ServiceDescription;
+import org.apache.aries.cdi.extra.propertytypes.ServiceRanking;
+import org.apache.webbeans.config.WebBeansContext;
+import org.apache.webbeans.spi.ContainerLifecycle;
+import org.osgi.framework.Bundle;
+import org.osgi.framework.ServiceRegistration;
+import org.osgi.framework.wiring.BundleCapability;
+import org.osgi.framework.wiring.BundleRequirement;
+import org.osgi.framework.wiring.BundleWire;
+import org.osgi.framework.wiring.BundleWiring;
+import org.osgi.service.cdi.annotations.Service;
+
+public class WebExtension implements Extension {
+
+	public WebExtension(Bundle bundle) {
+		_bundle = bundle;
+	}
+
+	<X> void processWebFilter(@Observes @WithAnnotations(WebFilter.class) ProcessAnnotatedType<X> pat) {
+		final AnnotatedType<X> annotatedType = pat.getAnnotatedType();
+
+		WebFilter webFilter = annotatedType.getAnnotation(WebFilter.class);
+
+		final Set<Annotation> annotationsToAdd = new HashSet<>();
+
+		if (!annotatedType.isAnnotationPresent(Service.class)) {
+			annotationsToAdd.add(Service.Literal.of(new Class[] {Filter.class}));
+		}
+
+		if(!annotatedType.isAnnotationPresent(HttpWhiteboardContextSelect.class)) {
+			annotationsToAdd.add(HttpWhiteboardContextSelect.Literal.of(getSelectedContext()));
+		}
+
+		if (!webFilter.description().isEmpty()) {
+			annotationsToAdd.add(ServiceDescription.Literal.of(webFilter.description()));
+		}
+
+		if (!webFilter.filterName().isEmpty()) {
+			annotationsToAdd.add(HttpWhiteboardFilterName.Literal.of(webFilter.filterName()));
+		}
+
+		if (webFilter.servletNames().length > 0) {
+			annotationsToAdd.add(HttpWhiteboardFilterServlet.Literal.of(webFilter.servletNames()));
+		}
+
+		if (webFilter.value().length > 0) {
+			annotationsToAdd.add(HttpWhiteboardFilterPattern.Literal.of(webFilter.value()));
+		}
+		else if (webFilter.urlPatterns().length > 0) {
+			annotationsToAdd.add(HttpWhiteboardFilterPattern.Literal.of(webFilter.urlPatterns()));
+		}
+
+		if (webFilter.dispatcherTypes().length > 0) {
+			annotationsToAdd.add(HttpWhiteboardFilterDispatcher.Literal.of(webFilter.dispatcherTypes()));
+		}
+
+		annotationsToAdd.add(HttpWhiteboardFilterAsyncSupported.Literal.of(webFilter.asyncSupported()));
+
+		if (!annotationsToAdd.isEmpty()) {
+			annotationsToAdd.forEach(pat.configureAnnotatedType()::add);
+		}
+	}
+
+	<X> void processWebListener(@Observes @WithAnnotations(WebListener.class) ProcessAnnotatedType<X> pat) {
+		final AnnotatedType<X> annotatedType = pat.getAnnotatedType();
+
+		WebListener webListener = annotatedType.getAnnotation(WebListener.class);
+
+		final Set<Annotation> annotationsToAdd = new HashSet<>();
+
+		if (!annotatedType.isAnnotationPresent(Service.class)) {
+			List<Class<?>> listenerTypes = new ArrayList<>();
+
+			Class<X> javaClass = annotatedType.getJavaClass();
+
+			if (javax.servlet.ServletContextListener.class.isAssignableFrom(javaClass)) {
+				listenerTypes.add(javax.servlet.ServletContextListener.class);
+			}
+			if (javax.servlet.ServletContextAttributeListener.class.isAssignableFrom(javaClass)) {
+				listenerTypes.add(javax.servlet.ServletContextAttributeListener.class);
+			}
+			if (javax.servlet.ServletRequestListener.class.isAssignableFrom(javaClass)) {
+				listenerTypes.add(javax.servlet.ServletRequestListener.class);
+			}
+			if (javax.servlet.ServletRequestAttributeListener.class.isAssignableFrom(javaClass)) {
+				listenerTypes.add(javax.servlet.ServletRequestAttributeListener.class);
+			}
+			if (javax.servlet.http.HttpSessionListener.class.isAssignableFrom(javaClass)) {
+				listenerTypes.add(javax.servlet.http.HttpSessionListener.class);
+			}
+			if (javax.servlet.http.HttpSessionAttributeListener.class.isAssignableFrom(javaClass)) {
+				listenerTypes.add(javax.servlet.http.HttpSessionAttributeListener.class);
+			}
+			if (javax.servlet.http.HttpSessionIdListener.class.isAssignableFrom(javaClass)) {
+				listenerTypes.add(javax.servlet.http.HttpSessionIdListener.class);
+			}
+
+			annotationsToAdd.add(Service.Literal.of(listenerTypes.toArray(new Class<?>[0])));
+		}
+
+		if(!annotatedType.isAnnotationPresent(HttpWhiteboardContextSelect.class)) {
+			annotationsToAdd.add(HttpWhiteboardContextSelect.Literal.of(getSelectedContext()));
+		}
+
+		annotationsToAdd.add(HttpWhiteboardListener.Literal.INSTANCE);
+
+		if (!webListener.value().isEmpty()) {
+			annotationsToAdd.add(ServiceDescription.Literal.of(webListener.value()));
+		}
+
+		if (!annotationsToAdd.isEmpty()) {
+			annotationsToAdd.forEach(pat.configureAnnotatedType()::add);
+		}
+	}
+
+	<X> void processWebServlet(@Observes @WithAnnotations(WebServlet.class) ProcessAnnotatedType<X> pat) {
+		final AnnotatedType<X> annotatedType = pat.getAnnotatedType();
+
+		WebServlet webServlet = annotatedType.getAnnotation(WebServlet.class);
+
+		final Set<Annotation> annotationsToAdd = new HashSet<>();
+
+		if (!annotatedType.isAnnotationPresent(Service.class)) {
+			annotationsToAdd.add(Service.Literal.of(new Class[] {Servlet.class}));
+		}
+
+		if(!annotatedType.isAnnotationPresent(HttpWhiteboardContextSelect.class)) {
+			annotationsToAdd.add(HttpWhiteboardContextSelect.Literal.of(getSelectedContext()));
+		}
+
+		if (!webServlet.name().isEmpty()) {
+			annotationsToAdd.add(HttpWhiteboardServletName.Literal.of(webServlet.name()));
+		}
+
+		if (webServlet.value().length > 0) {
+			annotationsToAdd.add(HttpWhiteboardServletPattern.Literal.of(webServlet.value()));
+		}
+		else if (webServlet.urlPatterns().length > 0) {
+			annotationsToAdd.add(HttpWhiteboardServletPattern.Literal.of(webServlet.urlPatterns()));
+		}
+
+		annotationsToAdd.add(ServiceRanking.Literal.of(webServlet.loadOnStartup()));
+
+		// TODO Howto: INIT PARAMS ???
+
+		annotationsToAdd.add(HttpWhiteboardServletAsyncSupported.Literal.of(webServlet.asyncSupported()));
+
+		if (!webServlet.description().isEmpty()) {
+			annotationsToAdd.add(ServiceDescription.Literal.of(webServlet.description()));
+		}
+
+		MultipartConfig multipartConfig = annotatedType.getAnnotation(MultipartConfig.class);
+
+		if (multipartConfig != null) {
+			annotationsToAdd.add(HttpWhiteboardServletMultipart.Literal.of(true, multipartConfig.fileSizeThreshold(), multipartConfig.location(), multipartConfig.maxFileSize(), multipartConfig.maxRequestSize()));
+		}
+
+		// TODO HowTo: ServletSecurity ???
+
+		if (!annotationsToAdd.isEmpty()) {
+			annotationsToAdd.forEach(pat.configureAnnotatedType()::add);
+		}
+	}
+
+	void afterDeploymentValidation(
+		@Observes @Priority(LIBRARY_AFTER + 800)
+		AfterDeploymentValidation adv, BeanManager beanManager) {
+
+		Dictionary<String, Object> properties = new Hashtable<>();
+		properties.put(SERVICE_DESCRIPTION, "Aries CDI - HTTP Portable Extension");
+		properties.put(SERVICE_VENDOR, "Apache Software Foundation");
+		properties.put(HTTP_WHITEBOARD_CONTEXT_SELECT, getSelectedContext());
+		properties.put(HTTP_WHITEBOARD_LISTENER, Boolean.TRUE.toString());
+		properties.put(SERVICE_RANKING, Integer.MAX_VALUE - 100);
+
+		_listenerRegistration = _bundle.getBundleContext().registerService(
+			LISTENER_CLASSES, new CdiListener(WebBeansContext.currentInstance()), properties);
+	}
+
+	void beforeShutdown(@Observes BeforeShutdown bs) {
+		if (_listenerRegistration != null && !destroyed.get()) {
+			try {
+				_listenerRegistration.unregister();
+			}
+			catch (IllegalStateException ise) {
+				// the service was already unregistered.
+			}
+		}
+	}
+
+	private Map<String, Object> getAttributes() {
+		BundleWiring bundleWiring = _bundle.adapt(BundleWiring.class);
+
+		List<BundleWire> wires = bundleWiring.getRequiredWires(EXTENDER_NAMESPACE);
+
+		Map<String, Object> cdiAttributes = Collections.emptyMap();
+
+		for (BundleWire wire : wires) {
+			BundleCapability capability = wire.getCapability();
+			Map<String, Object> attributes = capability.getAttributes();
+			String extender = (String)attributes.get(EXTENDER_NAMESPACE);
+
+			if (extender.equals(CDI_CAPABILITY_NAME)) {
+				BundleRequirement requirement = wire.getRequirement();
+				cdiAttributes = requirement.getAttributes();
+				break;
+			}
+		}
+
+		return cdiAttributes;
+	}
+
+	private String getSelectedContext() {
+		if (_contextSelect != null) {
+			return _contextSelect;
+		}
+
+		return _contextSelect = getSelectedContext0();
+	}
+
+	private String getSelectedContext0() {
+		Map<String, Object> attributes = getAttributes();
+
+		if (attributes.containsKey(HTTP_WHITEBOARD_CONTEXT_SELECT)) {
+			return (String)attributes.get(HTTP_WHITEBOARD_CONTEXT_SELECT);
+		}
+
+		Dictionary<String,String> headers = _bundle.getHeaders();
+
+		if (headers.get(WEB_CONTEXT_PATH) != null) {
+			return CONTEXT_PATH_PREFIX + headers.get(WEB_CONTEXT_PATH) + ')';
+		}
+
+		return DEFAULT_CONTEXT_FILTER;
+	}
+
+	private static final String CONTEXT_PATH_PREFIX = "(osgi.http.whiteboard.context.path=";
+	private static final String DEFAULT_CONTEXT_FILTER = "(osgi.http.whiteboard.context.name=default)";
+	private static final String[] LISTENER_CLASSES = new String[] {
+		ServletContextListener.class.getName(),
+		ServletRequestListener.class.getName(),
+		HttpSessionListener.class.getName()
+	};
+	private static final String WEB_CONTEXT_PATH = "Web-ContextPath";
+
+	private final Bundle _bundle;
+	private String _contextSelect;
+	private volatile ServiceRegistration<?> _listenerRegistration;
+	private final AtomicBoolean destroyed = new AtomicBoolean(false);
+
+	private class CdiListener extends org.apache.webbeans.servlet.WebBeansConfigurationListener {
+		private final WebBeansContext webBeansContext;
+
+		private CdiListener(final WebBeansContext webBeansContext) {
+			this.webBeansContext = webBeansContext;
+		}
+
+		@Override
+		public void contextInitialized(ServletContextEvent event) {
+			// update the sce to have the real one in CDI
+			try {
+				final Class<?> usc = event.getServletContext().getClassLoader()
+						.loadClass("org.apache.aries.cdi.container.internal.servlet.UpdatableServletContext");
+				final Object uscInstance = webBeansContext.getService(usc);
+				usc.getMethod("setDelegate", ServletContext.class)
+						.invoke(uscInstance, event.getServletContext());
+
+				// propagate attributes from the temporary sc
+				final ServletContext original = ServletContext.class.cast(usc.getMethod("getOriginal").invoke(uscInstance));
+				list(original.getAttributeNames())
+					.forEach(attr -> event.getServletContext().setAttribute(attr, original.getAttribute(attr)));
+			}
+			catch (final ClassNotFoundException | NoSuchMethodException | IllegalAccessException cnfe) {
+				// no-op, weirdly using another extender impl
+			}
+			catch (final InvocationTargetException ite) {
+				throw new IllegalStateException(ite.getTargetException());
+			}
+
+			// already started in the activator so let's skip it, just ensure it is skipped if re-called
+			event.getServletContext().setAttribute(getClass().getName(), true);
+			if (lifeCycle == null) {
+				lifeCycle = webBeansContext.getService(ContainerLifecycle.class);
+			}
+		}
+
+		@Override
+		public void contextDestroyed(ServletContextEvent sce) {
+			try {
+				super.contextDestroyed(sce);
+			}
+			finally {
+				destroyed.set(true);
+			}
+		}
+	}
+}
diff --git a/cdi-owb/src/main/java/org/apache/aries/cdi/owb/web/WebExtensionFactory.java b/cdi-owb/src/main/java/org/apache/aries/cdi/owb/web/WebExtensionFactory.java
new file mode 100644
index 0000000..8d1d045
--- /dev/null
+++ b/cdi-owb/src/main/java/org/apache/aries/cdi/owb/web/WebExtensionFactory.java
@@ -0,0 +1,37 @@
+/**
+ * Licensed 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.aries.cdi.owb.web;
+
+import javax.enterprise.inject.spi.Extension;
+
+import org.osgi.framework.Bundle;
+import org.osgi.framework.PrototypeServiceFactory;
+import org.osgi.framework.ServiceRegistration;
+
+public class WebExtensionFactory implements PrototypeServiceFactory<Extension> {
+
+	@Override
+	public Extension getService(
+		Bundle bundle, ServiceRegistration<Extension> registration) {
+
+		return new WebExtension(bundle);
+	}
+
+	@Override
+	public void ungetService(
+		Bundle bundle, ServiceRegistration<Extension> registration, Extension service) {
+	}
+
+}
diff --git a/cdi-owb/src/main/java/org/apache/aries/cdi/owb/web/package-info.java b/cdi-owb/src/main/java/org/apache/aries/cdi/owb/web/package-info.java
new file mode 100644
index 0000000..2312388
--- /dev/null
+++ b/cdi-owb/src/main/java/org/apache/aries/cdi/owb/web/package-info.java
@@ -0,0 +1,45 @@
+/**
+ * Licensed 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.
+ */
+
+@org.osgi.annotation.bundle.Capability(
+	attribute = "objectClass:List<String>=javax.enterprise.inject.spi.Extension",
+	namespace = SERVICE_NAMESPACE
+)
+@org.osgi.annotation.bundle.Capability(
+	name = "aries.cdi.http",
+	namespace = CDI_EXTENSION_PROPERTY,
+	uses= {
+		javax.annotation.Priority.class,
+		javax.enterprise.context.spi.Context.class,
+		javax.enterprise.event.Observes.class,
+		javax.enterprise.inject.spi.Extension.class,
+		javax.servlet.ServletContextListener.class,
+		javax.servlet.http.HttpSessionListener.class
+	},
+	version = "1.0.0"
+)
+//Deliberately depend on Http Whiteboard version 1.0.0 (the spec annotation starts at 1.1.0)
+@org.osgi.annotation.bundle.Requirement(
+	name = "osgi.http",
+	namespace = IMPLEMENTATION_NAMESPACE,
+	version = "1.0.0",
+	resolution = OPTIONAL
+)
+@org.osgi.service.cdi.annotations.RequireCDIImplementation
+package org.apache.aries.cdi.owb.web;
+
+import static org.osgi.annotation.bundle.Requirement.Resolution.OPTIONAL;
+import static org.osgi.namespace.implementation.ImplementationNamespace.IMPLEMENTATION_NAMESPACE;
+import static org.osgi.namespace.service.ServiceNamespace.SERVICE_NAMESPACE;
+import static org.osgi.service.cdi.CDIConstants.CDI_EXTENSION_PROPERTY;
diff --git a/cdi-spi/pom.xml b/cdi-spi/pom.xml
new file mode 100644
index 0000000..d816a49
--- /dev/null
+++ b/cdi-spi/pom.xml
@@ -0,0 +1,77 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+/**
+ * Licensed 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/xsd/maven-4.0.0.xsd">
+
+	<modelVersion>4.0.0</modelVersion>
+
+	<parent>
+		<groupId>org.apache.aries.cdi</groupId>
+		<artifactId>org.apache.aries.cdi</artifactId>
+		<version>1.1.0-SNAPSHOT</version>
+		<relativePath>..</relativePath>
+	</parent>
+
+	<artifactId>org.apache.aries.cdi.spi</artifactId>
+	<name>Apache Aries CDI - SPI</name>
+	<description>Apache Aries CDI - SPI</description>
+
+	<licenses>
+		<license>
+			<name>ASL 2.0</name>
+			<url>https://www.apache.org/licenses/LICENSE-2.0</url>
+		</license>
+	</licenses>
+
+	<scm>
+		<connection>scm:git:git@github.com:apache/aries-cdi.git</connection>
+		<developerConnection>scm:git:git@github.com:apache/aries-cdi.git</developerConnection>
+		<tag>HEAD</tag>
+		<url>https://github.com/apache/aries-cdi</url>
+	</scm>
+
+	<build>
+		<plugins>
+			<plugin>
+				<groupId>biz.aQute.bnd</groupId>
+				<artifactId>bnd-maven-plugin</artifactId>
+				<configuration>
+					<bnd><![CDATA[
+						-cdiannotations:
+					]]></bnd>
+				</configuration>
+			</plugin>
+		</plugins>
+	</build>
+
+	<dependencies>
+		<dependency>
+			<groupId>org.apache.geronimo.specs</groupId>
+			<artifactId>geronimo-jcdi_2.0_spec</artifactId>
+			<scope>provided</scope>
+		</dependency>
+		<dependency>
+			<groupId>org.osgi</groupId>
+			<artifactId>osgi.annotation</artifactId>
+		</dependency>
+		<dependency>
+			<groupId>org.osgi</groupId>
+			<artifactId>osgi.core</artifactId>
+		</dependency>
+	</dependencies>
+
+</project>
\ No newline at end of file
diff --git a/cdi-spi/src/main/java/org/apache/aries/cdi/spi/CDIContainerInitializer.java b/cdi-spi/src/main/java/org/apache/aries/cdi/spi/CDIContainerInitializer.java
new file mode 100644
index 0000000..9e1b883
--- /dev/null
+++ b/cdi-spi/src/main/java/org/apache/aries/cdi/spi/CDIContainerInitializer.java
@@ -0,0 +1,98 @@
+/**
+ * Licensed 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
+ * <p>
+ * http://www.apache.org/licenses/LICENSE-2.0
+ * <p>
+ * 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.aries.cdi.spi;
+
+import java.net.URL;
+import java.util.Map;
+
+import javax.enterprise.inject.spi.Extension;
+
+import org.apache.aries.cdi.spi.loader.SpiLoader;
+import org.osgi.annotation.versioning.ProviderType;
+import org.osgi.framework.BundleContext;
+
+@ProviderType
+public abstract class CDIContainerInitializer {
+
+	/**
+	 * Adds the listed classes to the resulting synthetic bean archive.
+	 * <p>
+	 * Contents will be added to those added during previous calls.
+	 *
+	 * @param classes
+	 * @return this
+	 */
+	public abstract CDIContainerInitializer addBeanClasses(Class<?>... classes);
+
+	/**
+	 * Adds the listed bean.xml files the resulting synthetic bean archive
+	 * <p>
+	 * Contents will be added to those added during previous calls.
+	 *
+	 * @param beanXmls
+	 * @return this
+	 */
+	public abstract CDIContainerInitializer addBeanXmls(URL... beanXmls);
+
+	/**
+	 * Adds the given Extension instance along with any service properties available to the synthetic bean archive
+	 * <p>
+	 * Contents will be added to those added during previous calls.
+	 *
+	 * @param extension
+	 * @param properties
+	 * @return this
+	 */
+	public abstract CDIContainerInitializer addExtension(Extension extension, Map<String, Object> properties);
+
+	/**
+	 * Adds a configuration property to the container
+	 * <p>
+	 * Contents will be added to those added during previous calls.
+	 *
+	 * @param key
+	 * @param value
+	 * @return this
+	 */
+	public abstract CDIContainerInitializer addProperty(String key, Object value);
+
+	/**
+	 * Sets the SpiLoader for this synthetic bean archive
+	 * <p>
+	 * The last such call will win.
+	 *
+	 * @param spiLoader
+	 * @return this
+	 */
+	public abstract CDIContainerInitializer setClassLoader(SpiLoader spiLoader);
+
+	/**
+	 * Sets the {@link BundleContext} for which this synthetic bean archive is created
+	 * <p>
+	 * The last such call will win.
+	 *
+	 * @param beanXmls
+	 * @return this
+	 */
+	public abstract CDIContainerInitializer setBundleContext(BundleContext bundleContext);
+
+	/**
+	 * Bootstraps the container that has been built from this CDIContainerInitializer
+	 *
+	 * @return a new SeContainer representing this synthetic bean archive
+	 */
+	public abstract AutoCloseable initialize();
+
+}
diff --git a/cdi-spi/src/main/java/org/apache/aries/cdi/spi/loader/SpiLoader.java b/cdi-spi/src/main/java/org/apache/aries/cdi/spi/loader/SpiLoader.java
new file mode 100644
index 0000000..69360ad
--- /dev/null
+++ b/cdi-spi/src/main/java/org/apache/aries/cdi/spi/loader/SpiLoader.java
@@ -0,0 +1,42 @@
+/**
+ * Licensed 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.aries.cdi.spi.loader;
+
+import java.net.URL;
+import java.security.ProtectionDomain;
+import java.util.Enumeration;
+import java.util.List;
+import java.util.function.Function;
+import java.util.function.Predicate;
+
+import org.osgi.framework.Bundle;
+
+public abstract class SpiLoader extends ClassLoader {
+
+	public abstract List<Bundle> getBundles();
+
+	public abstract Class<?> getOrRegister(
+		final String proxyClassName, final byte[] proxyBytes,
+		final Package pck, final ProtectionDomain protectionDomain);
+
+	public abstract SpiLoader handleResources(
+		final Predicate<String> predicate,
+		final Function<String, Enumeration<URL>> function);
+
+	public abstract SpiLoader findClass(
+		final Predicate<String> predicate,
+		final Function<String, Class<?>> function);
+
+}
diff --git a/cdi-spi/src/main/java/org/apache/aries/cdi/spi/loader/package-info.java b/cdi-spi/src/main/java/org/apache/aries/cdi/spi/loader/package-info.java
new file mode 100644
index 0000000..0499ce7
--- /dev/null
+++ b/cdi-spi/src/main/java/org/apache/aries/cdi/spi/loader/package-info.java
@@ -0,0 +1,17 @@
+/**
+ * Licensed 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.
+ */
+
+@org.osgi.annotation.bundle.Export
+@org.osgi.annotation.versioning.Version("1.0.0")
+package org.apache.aries.cdi.spi.loader;
diff --git a/cdi-spi/src/main/java/org/apache/aries/cdi/spi/package-info.java b/cdi-spi/src/main/java/org/apache/aries/cdi/spi/package-info.java
new file mode 100644
index 0000000..8f3c546
--- /dev/null
+++ b/cdi-spi/src/main/java/org/apache/aries/cdi/spi/package-info.java
@@ -0,0 +1,17 @@
+/**
+ * Licensed 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.
+ */
+
+@org.osgi.annotation.bundle.Export
+@org.osgi.annotation.versioning.Version("1.0.0")
+package org.apache.aries.cdi.spi;
diff --git a/cdi-weld/pom.xml b/cdi-weld/pom.xml
new file mode 100644
index 0000000..c20a3d4
--- /dev/null
+++ b/cdi-weld/pom.xml
@@ -0,0 +1,162 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+/**
+ * Licensed 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.aries.cdi</groupId>
+		<artifactId>org.apache.aries.cdi</artifactId>
+		<version>1.1.0-SNAPSHOT</version>
+		<relativePath>..</relativePath>
+	</parent>
+
+	<artifactId>org.apache.aries.cdi.weld</artifactId>
+	<name>Apache Aries CDI - Container using JBoss Weld</name>
+	<description>Apache Aries CDI - Container using JBoss Weld</description>
+
+	<licenses>
+		<license>
+			<name>ASL 2.0</name>
+			<url>https://www.apache.org/licenses/LICENSE-2.0</url>
+		</license>
+	</licenses>
+
+	<scm>
+		<connection>scm:git:git@github.com:apache/aries-cdi.git</connection>
+		<developerConnection>scm:git:git@github.com:apache/aries-cdi.git</developerConnection>
+		<tag>HEAD</tag>
+		<url>https://github.com/apache/aries-cdi</url>
+	</scm>
+
+	<build>
+		<plugins>
+			<plugin>
+				<groupId>biz.aQute.bnd</groupId>
+				<artifactId>bnd-maven-plugin</artifactId>
+				<configuration>
+					<bnd><![CDATA[
+						-cdiannotations:
+						-noclassforname: true
+					]]></bnd>
+				</configuration>
+			</plugin>
+		</plugins>
+	</build>
+
+	<dependencies>
+		<dependency>
+			<groupId>org.apache.aries.cdi</groupId>
+			<artifactId>org.apache.aries.cdi.extra</artifactId>
+			<version>${project.version}</version>
+		</dependency>
+		<dependency>
+			<groupId>org.apache.aries.cdi</groupId>
+			<artifactId>org.apache.aries.cdi.spi</artifactId>
+			<version>${project.version}</version>
+		</dependency>
+		<dependency>
+			<groupId>org.apache.geronimo.specs</groupId>
+			<artifactId>geronimo-annotation_1.3_spec</artifactId>
+		</dependency>
+		<dependency>
+			<groupId>org.apache.geronimo.specs</groupId>
+			<artifactId>geronimo-atinject_1.0_spec</artifactId>
+		</dependency>
+		<dependency>
+			<groupId>org.apache.geronimo.specs</groupId>
+			<artifactId>geronimo-interceptor_1.2_spec</artifactId>
+		</dependency>
+		<dependency>
+			<groupId>org.apache.geronimo.specs</groupId>
+			<artifactId>geronimo-jcdi_2.0_spec</artifactId>
+		</dependency>
+		<dependency>
+			<groupId>org.jboss.weld</groupId>
+			<artifactId>weld-osgi-bundle</artifactId>
+			<version>${weld.version}</version>
+			<exclusions>
+				<exclusion>
+					<groupId>javax.annotation</groupId>
+					<artifactId>javax.annotation-api</artifactId>
+				</exclusion>
+				<exclusion>
+					<groupId>javax.enterprise</groupId>
+					<artifactId>cdi-api</artifactId>
+				</exclusion>
+				<exclusion>
+					<groupId>javax.inject</groupId>
+					<artifactId>javax.inject</artifactId>
+				</exclusion>
+				<exclusion>
+					<groupId>org.jboss.spec.javax.annotation</groupId>
+					<artifactId>jboss-annotations-api_1.3_spec</artifactId>
+				</exclusion>
+				<exclusion>
+					<groupId>org.jboss.spec.javax.ejb</groupId>
+					<artifactId>jboss-ejb-api_3.2_spec</artifactId>
+				</exclusion>
+				<exclusion>
+					<groupId>org.jboss.spec.javax.el</groupId>
+					<artifactId>jboss-el-api_3.0_spec</artifactId>
+				</exclusion>
+				<exclusion>
+					<groupId>org.jboss.spec.javax.interceptor</groupId>
+					<artifactId>jboss-interceptors-api_1.2_spec</artifactId>
+				</exclusion>
+				<exclusion>
+					<groupId>org.jboss.spec.javax.transaction</groupId>
+					<artifactId>jboss-transaction-api_1.2_spec</artifactId>
+				</exclusion>
+			</exclusions>
+		</dependency>
+		<dependency>
+			<groupId>org.apache.felix</groupId>
+			<artifactId>org.apache.felix.http.servlet-api</artifactId>
+		</dependency>
+		<dependency>
+			<groupId>org.osgi</groupId>
+			<artifactId>org.osgi.namespace.extender</artifactId>
+		</dependency>
+		<dependency>
+			<groupId>org.osgi</groupId>
+			<artifactId>org.osgi.namespace.implementation</artifactId>
+		</dependency>
+		<dependency>
+			<groupId>org.osgi</groupId>
+			<artifactId>org.osgi.namespace.service</artifactId>
+		</dependency>
+		<dependency>
+			<groupId>org.osgi</groupId>
+			<artifactId>org.osgi.service.cdi</artifactId>
+		</dependency>
+		<dependency>
+			<groupId>org.osgi</groupId>
+			<artifactId>org.osgi.service.http.whiteboard</artifactId>
+		</dependency>
+		<dependency>
+			<groupId>org.osgi</groupId>
+			<artifactId>osgi.annotation</artifactId>
+		</dependency>
+		<dependency>
+			<groupId>org.osgi</groupId>
+			<artifactId>osgi.core</artifactId>
+		</dependency>
+	</dependencies>
+
+</project>
\ No newline at end of file
diff --git a/cdi-weld/src/main/java/org/apache/aries/cdi/weld/Activator.java b/cdi-weld/src/main/java/org/apache/aries/cdi/weld/Activator.java
new file mode 100644
index 0000000..e7da0ec
--- /dev/null
+++ b/cdi-weld/src/main/java/org/apache/aries/cdi/weld/Activator.java
@@ -0,0 +1,53 @@
+/**
+ * Licensed 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.aries.cdi.weld;
+
+import static org.osgi.framework.Constants.BUNDLE_ACTIVATOR;
+import static org.osgi.framework.Constants.SERVICE_DESCRIPTION;
+import static org.osgi.framework.Constants.SERVICE_VENDOR;
+
+import java.util.Dictionary;
+import java.util.Hashtable;
+
+import org.apache.aries.cdi.spi.CDIContainerInitializer;
+import org.osgi.annotation.bundle.Header;
+import org.osgi.framework.BundleActivator;
+import org.osgi.framework.BundleContext;
+import org.osgi.framework.ServiceRegistration;
+
+@Header(
+	name = BUNDLE_ACTIVATOR,
+	value = "${@class}"
+)
+public class Activator implements BundleActivator {
+
+	@Override
+	public void start(BundleContext bundleContext) throws Exception {
+		Dictionary<String, Object> properties = new Hashtable<>();
+		properties.put(SERVICE_DESCRIPTION, "Aries CDI - Weld CDIContainerInitializer Factory");
+		properties.put(SERVICE_VENDOR, "Apache Software Foundation");
+
+		_containerInitializer = bundleContext.registerService(
+			CDIContainerInitializer.class, new WeldCDIContainerInitializerFactory(bundleContext), properties);
+	}
+
+	@Override
+	public void stop(BundleContext context) throws Exception {
+		_containerInitializer.unregister();
+	}
+
+	private ServiceRegistration<CDIContainerInitializer> _containerInitializer;
+
+}
diff --git a/cdi-extender/src/main/java/org/apache/aries/cdi/container/internal/loader/BundleResourcesLoader.java b/cdi-weld/src/main/java/org/apache/aries/cdi/weld/BundleResourcesLoader.java
similarity index 73%
rename from cdi-extender/src/main/java/org/apache/aries/cdi/container/internal/loader/BundleResourcesLoader.java
rename to cdi-weld/src/main/java/org/apache/aries/cdi/weld/BundleResourcesLoader.java
index 621ac34..4485138 100644
--- a/cdi-extender/src/main/java/org/apache/aries/cdi/container/internal/loader/BundleResourcesLoader.java
+++ b/cdi-weld/src/main/java/org/apache/aries/cdi/weld/BundleResourcesLoader.java
@@ -12,7 +12,7 @@
  * limitations under the License.
  */
 
-package org.apache.aries.cdi.container.internal.loader;
+package org.apache.aries.cdi.weld;
 
 import java.io.IOException;
 import java.net.URL;
@@ -22,6 +22,7 @@
 import java.util.List;
 import java.util.Map;
 
+import org.apache.aries.cdi.spi.loader.SpiLoader;
 import org.jboss.weld.resources.spi.ResourceLoader;
 import org.jboss.weld.resources.spi.ResourceLoadingException;
 import org.jboss.weld.serialization.spi.ProxyServices;
@@ -33,36 +34,14 @@
 
 public class BundleResourcesLoader implements ProxyServices, ResourceLoader {
 
-	public static class Builder {
-
-		public Builder(Bundle bundle, Bundle extenderBundle) {
-			this.bundle = bundle;
-			this.extenderBundle = extenderBundle;
-		}
-
-		public Builder add(Bundle bundle) {
-			additionalBundles.add(bundle);
-			return this;
-		}
-
-		public BundleResourcesLoader build() {
-			return new BundleResourcesLoader(bundle, extenderBundle, additionalBundles);
-		}
-
-		private final Bundle bundle;
-		private final Bundle extenderBundle;
-		private final List<Bundle> additionalBundles = new ArrayList<>();
-	}
-
-	BundleResourcesLoader(Bundle bundle, Bundle extenderBundle, List<Bundle> additionalBundles) {
-		BundleWiring extenderWiring = extenderBundle.adapt(BundleWiring.class);
+	BundleResourcesLoader(SpiLoader loader, Bundle spiImplBundle) {
+		BundleWiring spiImplWiring = spiImplBundle.adapt(BundleWiring.class);
 
 		List<Bundle> bundles = new ArrayList<>();
 
-		bundles.add(bundle);
-		bundles.add(extenderBundle);
+		bundles.add(spiImplBundle);
 
-		List<BundleWire> requiredWires = extenderWiring.getRequiredWires(PackageNamespace.PACKAGE_NAMESPACE);
+		List<BundleWire> requiredWires = spiImplWiring.getRequiredWires(PackageNamespace.PACKAGE_NAMESPACE);
 
 		for (BundleWire bundleWire : requiredWires) {
 			BundleCapability capability = bundleWire.getCapability();
@@ -78,9 +57,9 @@
 			}
 		}
 
-		bundles.addAll(additionalBundles);
+		loader.getBundles().addAll(bundles);
 
-		_classLoader = new BundleClassLoader(bundles.toArray(new Bundle[0]));
+		_classLoader = loader;
 	}
 
 
@@ -133,4 +112,4 @@
 
 	private final ClassLoader _classLoader;
 
-}
+}
\ No newline at end of file
diff --git a/cdi-extender/src/main/java/org/apache/aries/cdi/container/internal/container/ContainerDeployment.java b/cdi-weld/src/main/java/org/apache/aries/cdi/weld/ContainerDeployment.java
similarity index 96%
rename from cdi-extender/src/main/java/org/apache/aries/cdi/container/internal/container/ContainerDeployment.java
rename to cdi-weld/src/main/java/org/apache/aries/cdi/weld/ContainerDeployment.java
index 7e838a5..188229b 100644
--- a/cdi-extender/src/main/java/org/apache/aries/cdi/container/internal/container/ContainerDeployment.java
+++ b/cdi-weld/src/main/java/org/apache/aries/cdi/weld/ContainerDeployment.java
@@ -12,7 +12,7 @@
  * limitations under the License.
  */
 
-package org.apache.aries.cdi.container.internal.container;
+package org.apache.aries.cdi.weld;
 
 import java.util.ArrayList;
 import java.util.Collection;
diff --git a/cdi-extender/src/main/java/org/apache/aries/cdi/container/internal/container/ContainerDeploymentArchive.java b/cdi-weld/src/main/java/org/apache/aries/cdi/weld/ContainerDeploymentArchive.java
similarity index 96%
rename from cdi-extender/src/main/java/org/apache/aries/cdi/container/internal/container/ContainerDeploymentArchive.java
rename to cdi-weld/src/main/java/org/apache/aries/cdi/weld/ContainerDeploymentArchive.java
index 4fbca9b..bf5680a 100644
--- a/cdi-extender/src/main/java/org/apache/aries/cdi/container/internal/container/ContainerDeploymentArchive.java
+++ b/cdi-weld/src/main/java/org/apache/aries/cdi/weld/ContainerDeploymentArchive.java
@@ -12,7 +12,7 @@
  * limitations under the License.
  */
 
-package org.apache.aries.cdi.container.internal.container;
+package org.apache.aries.cdi.weld;
 
 import java.util.Collection;
 import java.util.Collections;
@@ -42,7 +42,7 @@
 		if (loader != null) {
 			_services.add(ResourceLoader.class, loader);
 			_services.add(ProxyServices.class, loader);
-			_services.add(EEModuleDescriptor.class, new EEModuleDescriptorImpl(id, ModuleType.WEB));
+			_services.add(EEModuleDescriptor.class, new EEModuleDescriptorImpl(id, ModuleType.APPLICATION_CLIENT));
 		}
 	}
 
diff --git a/cdi-extender/src/main/java/org/apache/aries/cdi/container/internal/container/ContainerEnvironment.java b/cdi-weld/src/main/java/org/apache/aries/cdi/weld/ContainerEnvironment.java
similarity index 95%
rename from cdi-extender/src/main/java/org/apache/aries/cdi/container/internal/container/ContainerEnvironment.java
rename to cdi-weld/src/main/java/org/apache/aries/cdi/weld/ContainerEnvironment.java
index a968c32..458a625 100644
--- a/cdi-extender/src/main/java/org/apache/aries/cdi/container/internal/container/ContainerEnvironment.java
+++ b/cdi-weld/src/main/java/org/apache/aries/cdi/weld/ContainerEnvironment.java
@@ -12,7 +12,7 @@
  * limitations under the License.
  */
 
-package org.apache.aries.cdi.container.internal.container;
+package org.apache.aries.cdi.weld;
 
 import java.util.HashSet;
 import java.util.Set;
diff --git a/cdi-extender/src/main/java/org/apache/aries/cdi/container/internal/container/ExtensionMetadata.java b/cdi-weld/src/main/java/org/apache/aries/cdi/weld/ExtensionMetadata.java
similarity index 94%
rename from cdi-extender/src/main/java/org/apache/aries/cdi/container/internal/container/ExtensionMetadata.java
rename to cdi-weld/src/main/java/org/apache/aries/cdi/weld/ExtensionMetadata.java
index 7ae345c..0d99465 100644
--- a/cdi-extender/src/main/java/org/apache/aries/cdi/container/internal/container/ExtensionMetadata.java
+++ b/cdi-weld/src/main/java/org/apache/aries/cdi/weld/ExtensionMetadata.java
@@ -12,7 +12,7 @@
  * limitations under the License.
  */
 
-package org.apache.aries.cdi.container.internal.container;
+package org.apache.aries.cdi.weld;
 
 import javax.enterprise.inject.spi.Extension;
 
diff --git a/cdi-weld/src/main/java/org/apache/aries/cdi/weld/WeldCDIContainerInitializer.java b/cdi-weld/src/main/java/org/apache/aries/cdi/weld/WeldCDIContainerInitializer.java
new file mode 100644
index 0000000..9057214
--- /dev/null
+++ b/cdi-weld/src/main/java/org/apache/aries/cdi/weld/WeldCDIContainerInitializer.java
@@ -0,0 +1,149 @@
+package org.apache.aries.cdi.weld;
+
+import static java.util.Objects.requireNonNull;
+
+import java.net.URL;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.HashSet;
+import java.util.IdentityHashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.Properties;
+import java.util.Set;
+import java.util.stream.Collectors;
+
+import javax.enterprise.inject.spi.Extension;
+
+import org.apache.aries.cdi.spi.CDIContainerInitializer;
+import org.apache.aries.cdi.spi.loader.SpiLoader;
+import org.jboss.weld.bootstrap.WeldBootstrap;
+import org.jboss.weld.bootstrap.spi.BeanDeploymentArchive;
+import org.jboss.weld.bootstrap.spi.BeansXml;
+import org.jboss.weld.bootstrap.spi.Deployment;
+import org.jboss.weld.bootstrap.spi.Metadata;
+import org.jboss.weld.xml.BeansXmlParser;
+import org.osgi.framework.BundleContext;
+import org.osgi.framework.Constants;
+
+public class WeldCDIContainerInitializer extends CDIContainerInitializer {
+
+	public WeldCDIContainerInitializer(BundleContext bundleContext) {
+		weldBundleContext = bundleContext;
+	}
+
+	@Override
+	public CDIContainerInitializer addBeanClasses(Class<?>... classes) {
+		beanClasses.addAll(Arrays.asList(classes));
+		return this;
+	}
+
+	@Override
+	public CDIContainerInitializer addBeanXmls(URL... beanXmls) {
+		beanDescriptorURLs.addAll(Arrays.asList(beanXmls));
+		return this;
+	}
+
+	@Override
+	public CDIContainerInitializer addExtension(Extension extension, Map<String, Object> properties) {
+		this.extensions.put(extension, properties);
+		return this;
+	}
+
+	@Override
+	public CDIContainerInitializer addProperty(String key, Object value) {
+		properties.putIfAbsent(key, value);
+		return this;
+	}
+
+	@Override
+	public CDIContainerInitializer setBundleContext(BundleContext bundleContext) {
+		clientBundleContext = bundleContext;
+		return this;
+	}
+
+	@Override
+	public CDIContainerInitializer setClassLoader(SpiLoader spiLoader) {
+		this.spiLoader = spiLoader;
+		return this;
+	}
+
+	@Override
+	public AutoCloseable initialize() {
+		Thread currentThread = Thread.currentThread();
+		ClassLoader current = currentThread.getContextClassLoader();
+		BundleResourcesLoader resourceLoader = new BundleResourcesLoader(requireNonNull(spiLoader), weldBundleContext.getBundle());
+
+		try {
+			currentThread.setContextClassLoader(spiLoader);
+
+			// Add external extensions
+			List<Metadata<Extension>> metaExtensions = extensions.entrySet().stream().map(
+				e -> new ExtensionMetadata(e.getKey(), location(e.getValue()))
+			).collect(Collectors.toList());
+
+			BeansXml beansXml = BeansXml.EMPTY_BEANS_XML;
+
+			if (!beanDescriptorURLs.isEmpty()) {
+				BeansXmlParser beansXmlParser = new BeansXmlParser();
+				beansXml = beansXmlParser.parse(beanDescriptorURLs);
+			}
+
+			String id = clientBundleContext.getBundle().toString();
+
+			bootstrap = new WeldBootstrap();
+
+			beanDeploymentArchive = new ContainerDeploymentArchive(
+				resourceLoader,
+				id,
+				beanClasses.stream().map(Class::getName).collect(Collectors.toList()),
+				beansXml);
+
+			Deployment deployment = new ContainerDeployment(metaExtensions, beanDeploymentArchive);
+
+			bootstrap.startExtensions(metaExtensions);
+			bootstrap.startContainer(id, new ContainerEnvironment(), deployment);
+			bootstrap.startInitialization();
+			bootstrap.deployBeans();
+			bootstrap.validateBeans();
+			bootstrap.endInitialization();
+
+			return new WeldSeContainer();
+		}
+		finally {
+			currentThread.setContextClassLoader(current);
+		}
+	}
+
+	private String location(Map<String, Object> extensionProperties) {
+		return String.valueOf(extensionProperties.get(Constants.SERVICE_ID));
+	}
+
+	private volatile BeanDeploymentArchive beanDeploymentArchive;
+	private final List<URL> beanDescriptorURLs = new ArrayList<>();
+	private volatile WeldBootstrap bootstrap;
+	private volatile BundleContext clientBundleContext;
+	private volatile SpiLoader spiLoader;
+	private final Set<Class<?>> beanClasses = new HashSet<>();
+	private final Map<Extension, Map<String, Object>> extensions = new IdentityHashMap<>();
+	private final BundleContext weldBundleContext;
+	private final Properties properties = new Properties();
+
+	private class WeldSeContainer implements AutoCloseable {
+
+		@Override
+		public void close() {
+			Thread currentThread = Thread.currentThread();
+			ClassLoader current = currentThread.getContextClassLoader();
+			try {
+				currentThread.setContextClassLoader(requireNonNull(spiLoader));
+				bootstrap.shutdown();
+			}
+			finally {
+				currentThread.setContextClassLoader(current);
+			}
+		}
+
+	}
+
+}
diff --git a/cdi-weld/src/main/java/org/apache/aries/cdi/weld/WeldCDIContainerInitializerFactory.java b/cdi-weld/src/main/java/org/apache/aries/cdi/weld/WeldCDIContainerInitializerFactory.java
new file mode 100644
index 0000000..1ca91e1
--- /dev/null
+++ b/cdi-weld/src/main/java/org/apache/aries/cdi/weld/WeldCDIContainerInitializerFactory.java
@@ -0,0 +1,47 @@
+/**
+ * Licensed 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.aries.cdi.weld;
+
+import org.apache.aries.cdi.spi.CDIContainerInitializer;
+import org.osgi.framework.Bundle;
+import org.osgi.framework.BundleContext;
+import org.osgi.framework.PrototypeServiceFactory;
+import org.osgi.framework.ServiceRegistration;
+
+public class WeldCDIContainerInitializerFactory
+	implements PrototypeServiceFactory<CDIContainerInitializer> {
+
+	public WeldCDIContainerInitializerFactory(BundleContext bundleContext) {
+		this.bundleContext = bundleContext;
+	}
+
+	@Override
+	public CDIContainerInitializer getService(
+		Bundle bundle,
+		ServiceRegistration<CDIContainerInitializer> registration) {
+
+		return new WeldCDIContainerInitializer(bundleContext);
+	}
+
+	@Override
+	public void ungetService(
+		Bundle bundle,
+		ServiceRegistration<CDIContainerInitializer> registration,
+		CDIContainerInitializer service) {
+	}
+
+	private final BundleContext bundleContext;
+
+}
diff --git a/cdi-weld/src/main/java/org/apache/aries/cdi/weld/package-info.java b/cdi-weld/src/main/java/org/apache/aries/cdi/weld/package-info.java
new file mode 100644
index 0000000..218f42e
--- /dev/null
+++ b/cdi-weld/src/main/java/org/apache/aries/cdi/weld/package-info.java
@@ -0,0 +1,20 @@
+/**
+ * Licensed 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.
+ */
+
+@org.osgi.annotation.bundle.Capability(
+	attribute = "objectClass:List<String>=org.apache.aries.cdi.spi.CDIContainerInitializer",
+	namespace = org.osgi.namespace.service.ServiceNamespace.SERVICE_NAMESPACE
+)
+@org.osgi.service.cdi.annotations.RequireCDIImplementation
+package org.apache.aries.cdi.weld;
diff --git a/pom.xml b/pom.xml
index eefeb15..f567cc4 100644
--- a/pom.xml
+++ b/pom.xml
@@ -37,8 +37,9 @@
 		<jsp.version>2.0</jsp.version>
 		<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
 		<surefire.version>2.12</surefire.version>
-		<slf4j.version>1.7.25</slf4j.version>
+		<slf4j.version>1.7.28</slf4j.version>
 		<weld.version>3.0.5.Final</weld.version>
+		<owb.version>2.0.13</owb.version>
 	</properties>
 
 	<licenses>
@@ -57,10 +58,14 @@
 
 	<modules>
 		<module>cdi-extra</module>
+		<module>cdi-spi</module>
 		<module>cdi-extender</module>
 		<module>cdi-extension-el-jsp</module>
 		<module>cdi-extension-http</module>
 		<module>cdi-extension-jndi</module>
+		<module>cdi-extension-mp-config</module>
+		<module>cdi-owb</module>
+		<module>cdi-weld</module>
 		<module>cdi-bom</module>
 		<module>cdi-itests</module>
 		<module>cdi-executable</module>
@@ -111,45 +116,6 @@
 				<version>1.1</version>
 			</dependency>
 			<dependency>
-				<groupId>org.jboss.weld</groupId>
-				<artifactId>weld-osgi-bundle</artifactId>
-				<version>${weld.version}</version>
-				<exclusions>
-					<exclusion>
-						<groupId>javax.annotation</groupId>
-						<artifactId>javax.annotation-api</artifactId>
-					</exclusion>
-					<exclusion>
-						<groupId>javax.enterprise</groupId>
-						<artifactId>cdi-api</artifactId>
-					</exclusion>
-					<exclusion>
-						<groupId>javax.inject</groupId>
-						<artifactId>javax.inject</artifactId>
-					</exclusion>
-					<exclusion>
-						<groupId>org.jboss.spec.javax.annotation</groupId>
-						<artifactId>jboss-annotations-api_1.3_spec</artifactId>
-					</exclusion>
-					<exclusion>
-						<groupId>org.jboss.spec.javax.ejb</groupId>
-						<artifactId>jboss-ejb-api_3.2_spec</artifactId>
-					</exclusion>
-					<exclusion>
-						<groupId>org.jboss.spec.javax.el</groupId>
-						<artifactId>jboss-el-api_3.0_spec</artifactId>
-					</exclusion>
-					<exclusion>
-						<groupId>org.jboss.spec.javax.interceptor</groupId>
-						<artifactId>jboss-interceptors-api_1.2_spec</artifactId>
-					</exclusion>
-					<exclusion>
-						<groupId>org.jboss.spec.javax.transaction</groupId>
-						<artifactId>jboss-transaction-api_1.2_spec</artifactId>
-					</exclusion>
-				</exclusions>
-			</dependency>
-			<dependency>
 				<groupId>org.osgi</groupId>
 				<artifactId>org.osgi.namespace.extender</artifactId>
 				<version>1.0.1</version>
@@ -319,14 +285,6 @@
 						<failOnChanges>false</failOnChanges>
 						<resolve>false</resolve>
 					</configuration>
-					<executions>
-						<execution>
-							<id>export</id>
-							<goals>
-								<goal>export</goal>
-							</goals>
-						</execution>
-					</executions>
 				</plugin>
 				<plugin>
 					<groupId>biz.aQute.bnd</groupId>
@@ -349,15 +307,6 @@
 						<failOnChanges>false</failOnChanges>
 						<reportOptional>false</reportOptional>
 					</configuration>
-					<executions>
-						<execution>
-							<id>resolve</id>
-							<goals>
-								<goal>resolve</goal>
-							</goals>
-							<phase>package</phase>
-						</execution>
-					</executions>
 				</plugin>
 				<plugin>
 					<groupId>biz.aQute.bnd</groupId>
@@ -367,14 +316,6 @@
 						<failOnChanges>false</failOnChanges>
 						<resolve>false</resolve>
 					</configuration>
-					<executions>
-						<execution>
-							<id>testing</id>
-							<goals>
-								<goal>testing</goal>
-							</goals>
-						</execution>
-					</executions>
 				</plugin>
 				<plugin>
 					<groupId>biz.aQute.bnd</groupId>
@@ -431,6 +372,19 @@
 										</ignore>
 									</action>
 								</pluginExecution>
+								<pluginExecution>
+									<pluginExecutionFilter>
+										<groupId>net.bytebuddy</groupId>
+										<artifactId>byte-buddy-maven-plugin</artifactId>
+										<versionRange>[${byte.buddy.version},)</versionRange>
+										<goals>
+											<goal>transform</goal>
+										</goals>
+									</pluginExecutionFilter>
+									<action>
+										<execute />
+									</action>
+								</pluginExecution>
 							</pluginExecutions>
 						</lifecycleMappingMetadata>
 					</configuration>