You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@aries.apache.org by ro...@apache.org on 2018/04/14 01:10:31 UTC

svn commit: r1829115 [8/12] - in /aries/trunk/cdi: ./ cdi-extender/ cdi-extender/src/main/java/org/apache/aries/cdi/container/internal/ cdi-extender/src/main/java/org/apache/aries/cdi/container/internal/bean/ cdi-extender/src/main/java/org/apache/aries...

Added: aries/trunk/cdi/cdi-extender/src/test/java/org/apache/aries/cdi/container/internal/phase/ContainerReferencesTest.java
URL: http://svn.apache.org/viewvc/aries/trunk/cdi/cdi-extender/src/test/java/org/apache/aries/cdi/container/internal/phase/ContainerReferencesTest.java?rev=1829115&view=auto
==============================================================================
--- aries/trunk/cdi/cdi-extender/src/test/java/org/apache/aries/cdi/container/internal/phase/ContainerReferencesTest.java (added)
+++ aries/trunk/cdi/cdi-extender/src/test/java/org/apache/aries/cdi/container/internal/phase/ContainerReferencesTest.java Sat Apr 14 01:10:27 2018
@@ -0,0 +1,530 @@
+/**
+ * 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.phase;
+
+import static org.junit.Assert.*;
+import static org.mockito.Mockito.*;
+
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.Map.Entry;
+import java.util.Optional;
+import java.util.stream.Collectors;
+
+import javax.inject.Provider;
+
+import org.apache.aries.cdi.container.internal.container.CheckedCallback;
+import org.apache.aries.cdi.container.internal.container.ConfigurationListener;
+import org.apache.aries.cdi.container.internal.container.ContainerState;
+import org.apache.aries.cdi.container.internal.container.Op;
+import org.apache.aries.cdi.container.internal.model.CollectionType;
+import org.apache.aries.cdi.container.internal.model.ContainerActivator;
+import org.apache.aries.cdi.container.internal.model.ContainerComponent;
+import org.apache.aries.cdi.container.internal.model.ExtendedReferenceDTO;
+import org.apache.aries.cdi.container.internal.model.ExtendedReferenceTemplateDTO;
+import org.apache.aries.cdi.container.internal.util.Logs;
+import org.apache.aries.cdi.container.internal.util.Maps;
+import org.apache.aries.cdi.container.internal.util.SRs;
+import org.apache.aries.cdi.container.test.BaseCDIBundleTest;
+import org.apache.aries.cdi.container.test.MockConfiguration;
+import org.apache.aries.cdi.container.test.TestUtil;
+import org.apache.aries.cdi.container.test.beans.Foo;
+import org.junit.Test;
+import org.osgi.framework.Bundle;
+import org.osgi.framework.Constants;
+import org.osgi.framework.ServiceReference;
+import org.osgi.framework.ServiceRegistration;
+import org.osgi.framework.dto.BundleDTO;
+import org.osgi.framework.wiring.BundleWiring;
+import org.osgi.namespace.extender.ExtenderNamespace;
+import org.osgi.service.cdi.CDIConstants;
+import org.osgi.service.cdi.ComponentType;
+import org.osgi.service.cdi.MaximumCardinality;
+import org.osgi.service.cdi.ReferencePolicy;
+import org.osgi.service.cdi.ReferencePolicyOption;
+import org.osgi.service.cdi.runtime.dto.ComponentDTO;
+import org.osgi.service.cdi.runtime.dto.ComponentInstanceDTO;
+import org.osgi.service.cdi.runtime.dto.ContainerDTO;
+import org.osgi.service.cdi.runtime.dto.ReferenceDTO;
+import org.osgi.service.cm.ConfigurationAdmin;
+import org.osgi.util.converter.TypeReference;
+import org.osgi.util.promise.Promise;
+import org.osgi.util.promise.TimeoutException;
+import org.osgi.util.tracker.ServiceTracker;
+
+public class ContainerReferencesTest extends BaseCDIBundleTest {
+
+	@Test
+	public void reference_tracking() throws Exception {
+		ServiceTracker<ConfigurationAdmin, ConfigurationAdmin> caTracker = TestUtil.mockCaSt(bundle);
+
+		MockConfiguration mockConfiguration = new MockConfiguration("foo.config", null);
+		mockConfiguration.update(Maps.dict("fiz", "buz"));
+		TestUtil.configurations.add(mockConfiguration);
+
+		ContainerState containerState = new ContainerState(bundle, ccrBundle, ccrChangeCount, promiseFactory, caTracker, new Logs.Builder(bundle.getBundleContext()).build());
+
+		ConfigurationListener configurationListener = new ConfigurationListener.Builder(containerState
+		).component(
+			new ContainerComponent.Builder(containerState,
+				new ContainerActivator.Builder(containerState, null)
+			).template(
+				containerState.containerDTO().template.components.get(0)
+			).build()
+		).build();
+
+		Promise<Boolean> p0 = containerState.addCallback(
+			(CheckedCallback<Boolean, Boolean>) op -> {
+				return op.mode == Op.Mode.OPEN && op.type == Op.Type.CONTAINER_COMPONENT;
+			}
+		);
+
+		configurationListener.open();
+
+		ContainerDTO containerDTO = containerState.containerDTO();
+		assertNotNull(containerDTO);
+		assertEquals(1, containerDTO.changeCount);
+		assertTrue(containerDTO.errors + "", containerDTO.errors.isEmpty());
+		assertNotNull(containerDTO.template);
+
+		p0.getValue();
+
+		ComponentDTO componentDTO = containerDTO.components.stream().filter(
+			c -> c.template.type == ComponentType.CONTAINER
+		).findFirst().get();
+
+		assertNotNull(componentDTO);
+		assertEquals(1, componentDTO.instances.size());
+
+		ComponentInstanceDTO componentInstanceDTO = componentDTO.instances.get(0);
+
+		assertNotNull(componentInstanceDTO);
+		assertEquals(6, componentInstanceDTO.references.size());
+
+		// are we currently blocked waiting for those references?
+
+		Promise<Boolean> p1 = containerState.addCallback(
+			(CheckedCallback<Boolean, Boolean>) op -> {
+				return op.mode == Op.Mode.OPEN && op.type == Op.Type.CONTAINER_INSTANCE;
+			}
+		);
+
+		p1.timeout(200).getFailure();
+
+		List<ReferenceDTO> references = TestUtil.sort(
+			componentInstanceDTO.references, (a, b) -> a.template.name.compareTo(b.template.name));
+
+		{
+			ExtendedReferenceDTO reference = (ExtendedReferenceDTO)references.get(0);
+			ExtendedReferenceTemplateDTO template = (ExtendedReferenceTemplateDTO)reference.template;
+
+			assertEquals(CollectionType.SERVICE, template.collectionType);
+			assertEquals(new TypeReference<Provider<Collection<Foo>>>() {}.getType(), template.injectionPointType);
+			assertEquals(MaximumCardinality.MANY, template.maximumCardinality);
+			assertEquals(0, template.minimumCardinality);
+			assertEquals("org.apache.aries.cdi.container.test.beans.BarAnnotated.dynamicFoos", template.name);
+			assertEquals(ReferencePolicy.DYNAMIC, template.policy);
+			assertEquals(ReferencePolicyOption.RELUCTANT, template.policyOption);
+			assertEquals(Foo.class.getName(), template.serviceType);
+			assertEquals("", template.targetFilter);
+
+			assertEquals(0, reference.matches.size());
+			assertEquals(0, reference.minimumCardinality);
+			assertEquals("(objectClass=" + Foo.class.getName() + ")", reference.targetFilter);
+		}
+
+		{
+			ExtendedReferenceDTO reference = (ExtendedReferenceDTO)references.get(1);
+			ExtendedReferenceTemplateDTO template = (ExtendedReferenceTemplateDTO)reference.template;
+
+			assertEquals(CollectionType.SERVICE, template.collectionType);
+			assertEquals(new TypeReference<Foo>() {}.getType(), template.injectionPointType);
+			assertEquals(MaximumCardinality.ONE, template.maximumCardinality);
+			assertEquals(1, template.minimumCardinality);
+			assertEquals("org.apache.aries.cdi.container.test.beans.BarAnnotated.foo", template.name);
+			assertEquals(ReferencePolicy.STATIC, template.policy);
+			assertEquals(ReferencePolicyOption.GREEDY, template.policyOption);
+			assertEquals(Foo.class.getName(), template.serviceType);
+			assertEquals("", template.targetFilter);
+
+			assertEquals(0, reference.matches.size());
+			assertEquals(1, reference.minimumCardinality);
+			assertEquals("(objectClass=" + Foo.class.getName() + ")", reference.targetFilter);
+		}
+
+		{
+			ExtendedReferenceDTO reference = (ExtendedReferenceDTO)references.get(2);
+			ExtendedReferenceTemplateDTO template = (ExtendedReferenceTemplateDTO)reference.template;
+
+			assertEquals(CollectionType.SERVICE, template.collectionType);
+			assertEquals(new TypeReference<Optional<Foo>>() {}.getType(), template.injectionPointType);
+			assertEquals(MaximumCardinality.ONE, template.maximumCardinality);
+			assertEquals(0, template.minimumCardinality);
+			assertEquals("org.apache.aries.cdi.container.test.beans.BarAnnotated.fooOptional", template.name);
+			assertEquals(ReferencePolicy.STATIC, template.policy);
+			assertEquals(ReferencePolicyOption.RELUCTANT, template.policyOption);
+			assertEquals(Foo.class.getName(), template.serviceType);
+			assertEquals("", template.targetFilter);
+
+			assertEquals(0, reference.matches.size());
+			assertEquals(0, reference.minimumCardinality);
+			assertEquals("(objectClass=" + Foo.class.getName() + ")", reference.targetFilter);
+		}
+
+		{
+			ExtendedReferenceDTO reference = (ExtendedReferenceDTO)references.get(3);
+			ExtendedReferenceTemplateDTO template = (ExtendedReferenceTemplateDTO)reference.template;
+
+			assertEquals(CollectionType.PROPERTIES, template.collectionType);
+			assertEquals(new TypeReference<Collection<Map<String, Object>>>() {}.getType(), template.injectionPointType);
+			assertEquals(MaximumCardinality.MANY, template.maximumCardinality);
+			assertEquals(0, template.minimumCardinality);
+			assertEquals("org.apache.aries.cdi.container.test.beans.BarAnnotated.propertiesFoos", template.name);
+			assertEquals(ReferencePolicy.STATIC, template.policy);
+			assertEquals(ReferencePolicyOption.RELUCTANT, template.policyOption);
+			assertEquals(Foo.class.getName(), template.serviceType);
+			assertEquals("", template.targetFilter);
+
+			assertEquals(0, reference.matches.size());
+			assertEquals(0, reference.minimumCardinality);
+			assertEquals("(objectClass=" + Foo.class.getName() + ")", reference.targetFilter);
+		}
+
+		{
+			ExtendedReferenceDTO reference = (ExtendedReferenceDTO)references.get(4);
+			ExtendedReferenceTemplateDTO template = (ExtendedReferenceTemplateDTO)reference.template;
+
+			assertEquals(CollectionType.REFERENCE, template.collectionType);
+			assertEquals(new TypeReference<Collection<ServiceReference<Foo>>>() {}.getType(), template.injectionPointType);
+			assertEquals(MaximumCardinality.MANY, template.maximumCardinality);
+			assertEquals(0, template.minimumCardinality);
+			assertEquals("org.apache.aries.cdi.container.test.beans.BarAnnotated.serviceReferencesFoos", template.name);
+			assertEquals(ReferencePolicy.STATIC, template.policy);
+			assertEquals(ReferencePolicyOption.RELUCTANT, template.policyOption);
+			assertEquals(Foo.class.getName(), template.serviceType);
+			assertEquals("(service.scope=prototype)", template.targetFilter);
+
+			assertEquals(0, reference.matches.size());
+			assertEquals(0, reference.minimumCardinality);
+			assertEquals("(&(objectClass=" + Foo.class.getName() + ")(service.scope=prototype))", reference.targetFilter);
+		}
+
+		{
+			ExtendedReferenceDTO reference = (ExtendedReferenceDTO)references.get(5);
+			ExtendedReferenceTemplateDTO template = (ExtendedReferenceTemplateDTO)reference.template;
+
+			assertEquals(CollectionType.TUPLE, template.collectionType);
+			assertEquals(new TypeReference<Collection<Entry<Map<String, Object>, Integer>>>() {}.getType(), template.injectionPointType);
+			assertEquals(MaximumCardinality.MANY, template.maximumCardinality);
+			assertEquals(0, template.minimumCardinality);
+			assertEquals("org.apache.aries.cdi.container.test.beans.BarAnnotated.tupleIntegers", template.name);
+			assertEquals(ReferencePolicy.STATIC, template.policy);
+			assertEquals(ReferencePolicyOption.RELUCTANT, template.policyOption);
+			assertEquals(Integer.class.getName(), template.serviceType);
+			assertEquals("", template.targetFilter);
+
+			assertEquals(0, reference.matches.size());
+			assertEquals(0, reference.minimumCardinality);
+			assertEquals("(objectClass=" + Integer.class.getName() + ")", reference.targetFilter);
+		}
+	}
+
+	@Test
+	public void test_S_R_M_U_Service() throws Exception {
+		Map<String, Object> attributes = new HashMap<>();
+
+		attributes.put(
+			CDIConstants.REQUIREMENT_OSGI_BEANS_ATTRIBUTE,
+			Arrays.asList(
+				"org.apache.aries.cdi.container.test.beans.Reference_S_R_M_U_Service"
+			)
+		);
+
+		when(
+			bundle.adapt(
+				BundleWiring.class).getRequiredWires(
+					ExtenderNamespace.EXTENDER_NAMESPACE).get(
+						0).getRequirement().getAttributes()
+		).thenReturn(attributes);
+
+		ServiceTracker<ConfigurationAdmin, ConfigurationAdmin> caTracker = TestUtil.mockCaSt(bundle);
+
+		MockConfiguration mockConfiguration = new MockConfiguration("foo.config", null);
+		mockConfiguration.update(Maps.dict("fiz", "buz"));
+		TestUtil.configurations.add(mockConfiguration);
+
+		ContainerState containerState = new ContainerState(bundle, ccrBundle, ccrChangeCount, promiseFactory, caTracker, new Logs.Builder(bundle.getBundleContext()).build());
+
+		ContainerComponent containerComponent = new ContainerComponent.Builder(containerState,
+			new ContainerActivator.Builder(containerState, null)
+		).template(
+			containerState.containerDTO().template.components.get(0)
+		).build();
+
+		Promise<Boolean> p0 = containerState.addCallback(
+			(CheckedCallback<Boolean, Boolean>) op -> {
+				return op.mode == Op.Mode.OPEN && op.type == Op.Type.REFERENCES;
+			}
+		);
+
+		containerComponent.open();
+
+		ContainerDTO containerDTO = containerState.containerDTO();
+		assertNotNull(containerDTO);
+		assertEquals(1, containerDTO.changeCount);
+		assertTrue(containerDTO.errors + "", containerDTO.errors.isEmpty());
+		assertNotNull(containerDTO.template);
+
+		assertNotNull(p0.timeout(200).getValue());
+
+		ComponentInstanceDTO containerComponentInstance = containerDTO.components.get(0).instances.get(0);
+
+		List<ExtendedReferenceDTO> unresolvedReferences = containerComponentInstance.references.stream().map(
+			r -> (ExtendedReferenceDTO)r
+		).filter(
+			r -> r.matches.size() < r.minimumCardinality
+		).collect(Collectors.toList());
+
+		assertEquals(1, unresolvedReferences.size());
+
+		ExtendedReferenceDTO extendedReferenceDTO = unresolvedReferences.get(0);
+
+		assertTrue(extendedReferenceDTO.matches.isEmpty());
+		assertEquals(1, extendedReferenceDTO.minimumCardinality);
+		assertNotNull(extendedReferenceDTO.serviceTracker);
+		assertEquals("(objectClass=org.apache.aries.cdi.container.test.beans.Foo)", extendedReferenceDTO.targetFilter);
+		assertNotNull(extendedReferenceDTO.template);
+		assertEquals(MaximumCardinality.ONE, extendedReferenceDTO.template.maximumCardinality);
+		assertEquals(1, extendedReferenceDTO.template.minimumCardinality);
+		assertEquals("org.apache.aries.cdi.container.test.beans.Reference_S_R_M_U_Service.foo", extendedReferenceDTO.template.name);
+		assertEquals(ReferencePolicy.STATIC, extendedReferenceDTO.template.policy);
+		assertEquals(ReferencePolicyOption.RELUCTANT, extendedReferenceDTO.template.policyOption);
+		assertEquals(Foo.class.getName(), extendedReferenceDTO.template.serviceType);
+		assertEquals("", extendedReferenceDTO.template.targetFilter);
+
+		// first test publishing a service targeting one of the optional references
+
+		BundleDTO serviceBundleDTO = new BundleDTO();
+
+		Bundle serviceBundle = TestUtil.mockBundle(serviceBundleDTO, b -> {});
+
+		p0 = containerState.addCallback(
+			(CheckedCallback<Boolean, Boolean>) op -> {
+				return op.mode == Op.Mode.OPEN && op.type == Op.Type.CONTAINER_ACTIVATOR;
+			}
+		);
+
+		ServiceRegistration<Foo> sr1 = serviceBundle.getBundleContext().registerService(
+			Foo.class, new Foo() {}, Maps.dict("sr1", "sr1"));
+
+		assertTrue(p0.timeout(200).getValue());
+
+		assertEquals(1, extendedReferenceDTO.matches.size());
+
+		p0 = containerState.addCallback(
+			(CheckedCallback<Boolean, Boolean>) op -> {
+				return op.mode == Op.Mode.CLOSE && op.type == Op.Type.CONTAINER_INSTANCE;
+			}
+		);
+
+		serviceBundle.getBundleContext().registerService(
+			Foo.class, new Foo() {}, Maps.dict("sr2", "sr2"));
+
+		assertTrue("should be a TimeoutException", TimeoutException.class.equals(p0.timeout(200).getFailure().getClass()));
+
+		assertEquals(2, extendedReferenceDTO.matches.size());
+
+		p0 = containerState.addCallback(
+			(CheckedCallback<Boolean, Boolean>) op -> {
+				return op.mode == Op.Mode.CLOSE && op.type == Op.Type.CONTAINER_INSTANCE;
+			}
+		);
+
+		Foo foo = new Foo() {};
+
+		ServiceRegistration<Foo> sr3 = serviceBundle.getBundleContext().registerService(
+			Foo.class, foo, Maps.dict("sr3", "sr3", Constants.SERVICE_RANKING, 100));
+
+		assertTrue("should be a TimeoutException", TimeoutException.class.equals(p0.timeout(200).getFailure().getClass()));
+
+		assertEquals(3, extendedReferenceDTO.matches.size());
+
+		p0 = containerState.addCallback(
+			(CheckedCallback<Boolean, Boolean>) op -> {
+				return op.mode == Op.Mode.CLOSE && op.type == Op.Type.CONTAINER_ACTIVATOR;
+			}
+		);
+		Promise<Boolean> p1 = containerState.addCallback(
+			(CheckedCallback<Boolean, Boolean>) op -> {
+				return op.mode == Op.Mode.OPEN && op.type == Op.Type.CONTAINER_ACTIVATOR;
+			}
+		);
+
+		sr1.unregister();
+
+		p0.timeout(200).getFailure();
+
+		assertEquals(2, extendedReferenceDTO.matches.size());
+		assertEquals(SRs.id(sr3.getReference()), SRs.id(extendedReferenceDTO.serviceTracker.getServiceReference()));
+		assertEquals(foo, extendedReferenceDTO.serviceTracker.getService());
+
+		assertTrue(p1.timeout(200).getValue());
+	}
+
+	@Test
+	public void test_D_R_M_U_Service() throws Exception {
+		Map<String, Object> attributes = new HashMap<>();
+
+		attributes.put(
+			CDIConstants.REQUIREMENT_OSGI_BEANS_ATTRIBUTE,
+			Arrays.asList(
+				"org.apache.aries.cdi.container.test.beans.Reference_D_R_M_U_Service"
+			)
+		);
+
+		when(
+			bundle.adapt(
+				BundleWiring.class).getRequiredWires(
+					ExtenderNamespace.EXTENDER_NAMESPACE).get(
+						0).getRequirement().getAttributes()
+		).thenReturn(attributes);
+
+		ServiceTracker<ConfigurationAdmin, ConfigurationAdmin> caTracker = TestUtil.mockCaSt(bundle);
+
+		MockConfiguration mockConfiguration = new MockConfiguration("foo.config", null);
+		mockConfiguration.update(Maps.dict("fiz", "buz"));
+		TestUtil.configurations.add(mockConfiguration);
+
+		ContainerState containerState = new ContainerState(bundle, ccrBundle, ccrChangeCount, promiseFactory, caTracker, new Logs.Builder(bundle.getBundleContext()).build());
+
+		ContainerComponent containerComponent = new ContainerComponent.Builder(containerState,
+			new ContainerActivator.Builder(containerState, null)
+		).template(
+			containerState.containerDTO().template.components.get(0)
+		).build();
+
+		Promise<Boolean> p0 = containerState.addCallback(
+			(CheckedCallback<Boolean, Boolean>) op -> {
+				return op.mode == Op.Mode.OPEN && op.type == Op.Type.REFERENCES;
+			}
+		);
+
+		containerComponent.open();
+
+		ContainerDTO containerDTO = containerState.containerDTO();
+		assertNotNull(containerDTO);
+		assertEquals(1, containerDTO.changeCount);
+		assertTrue(containerDTO.errors + "", containerDTO.errors.isEmpty());
+		assertNotNull(containerDTO.template);
+
+		assertNotNull(p0.timeout(200).getValue());
+
+		ComponentInstanceDTO containerComponentInstance = containerDTO.components.get(0).instances.get(0);
+
+		List<ExtendedReferenceDTO> unresolvedReferences = containerComponentInstance.references.stream().map(
+			r -> (ExtendedReferenceDTO)r
+		).filter(
+			r -> r.matches.size() < r.minimumCardinality
+		).collect(Collectors.toList());
+
+		assertEquals(1, unresolvedReferences.size());
+
+		ExtendedReferenceDTO extendedReferenceDTO = unresolvedReferences.get(0);
+
+		assertTrue(extendedReferenceDTO.matches.isEmpty());
+		assertEquals(1, extendedReferenceDTO.minimumCardinality);
+		assertNotNull(extendedReferenceDTO.serviceTracker);
+		assertEquals("(objectClass=org.apache.aries.cdi.container.test.beans.Foo)", extendedReferenceDTO.targetFilter);
+		assertNotNull(extendedReferenceDTO.template);
+		assertEquals(MaximumCardinality.ONE, extendedReferenceDTO.template.maximumCardinality);
+		assertEquals(1, extendedReferenceDTO.template.minimumCardinality);
+		assertEquals("org.apache.aries.cdi.container.test.beans.Reference_D_R_M_U_Service.foo", extendedReferenceDTO.template.name);
+		assertEquals(ReferencePolicy.DYNAMIC, extendedReferenceDTO.template.policy);
+		assertEquals(ReferencePolicyOption.RELUCTANT, extendedReferenceDTO.template.policyOption);
+		assertEquals(Foo.class.getName(), extendedReferenceDTO.template.serviceType);
+		assertEquals("", extendedReferenceDTO.template.targetFilter);
+
+		// first test publishing a service targeting one of the optional references
+
+		BundleDTO serviceBundleDTO = new BundleDTO();
+
+		Bundle serviceBundle = TestUtil.mockBundle(serviceBundleDTO, b -> {});
+
+		p0 = containerState.addCallback(
+			(CheckedCallback<Boolean, Boolean>) op -> {
+				return op.mode == Op.Mode.OPEN && op.type == Op.Type.CONTAINER_ACTIVATOR;
+			}
+		);
+
+		ServiceRegistration<Foo> sr1 = serviceBundle.getBundleContext().registerService(
+			Foo.class, new Foo() {}, Maps.dict("sr1", "sr1"));
+
+		assertTrue(p0.timeout(200).getValue());
+
+		assertEquals(1, extendedReferenceDTO.matches.size());
+
+		p0 = containerState.addCallback(
+			(CheckedCallback<Boolean, Boolean>) op -> {
+				return op.mode == Op.Mode.CLOSE && op.type == Op.Type.CONTAINER_INSTANCE;
+			}
+		);
+
+		serviceBundle.getBundleContext().registerService(
+			Foo.class, new Foo() {}, Maps.dict("sr2", "sr2"));
+
+		p0.timeout(200).getFailure();
+
+		assertEquals(2, extendedReferenceDTO.matches.size());
+
+		p0 = containerState.addCallback(
+			(CheckedCallback<Boolean, Boolean>) op -> {
+				return op.mode == Op.Mode.CLOSE && op.type == Op.Type.CONTAINER_INSTANCE;
+			}
+		);
+
+		Foo foo = new Foo() {};
+
+		ServiceRegistration<Foo> sr3 = serviceBundle.getBundleContext().registerService(
+			Foo.class, foo, Maps.dict("sr3", "sr3", Constants.SERVICE_RANKING, 100));
+
+		p0.timeout(200).getFailure();
+
+		assertEquals(3, extendedReferenceDTO.matches.size());
+
+		p0 = containerState.addCallback(
+			(CheckedCallback<Boolean, Boolean>) op -> {
+				return op.mode == Op.Mode.CLOSE && op.type == Op.Type.CONTAINER_INSTANCE;
+			}
+		);
+		Promise<Boolean> p1 = containerState.addCallback(
+			(CheckedCallback<Boolean, Boolean>) op -> {
+				return op.mode == Op.Mode.OPEN && op.type == Op.Type.CONTAINER_INSTANCE;
+			}
+		);
+
+		sr1.unregister();
+
+		p0.timeout(200).getFailure();
+
+		assertEquals(2, extendedReferenceDTO.matches.size());
+		assertEquals(SRs.id(sr3.getReference()), SRs.id(extendedReferenceDTO.serviceTracker.getServiceReference()));
+		assertEquals(foo, extendedReferenceDTO.serviceTracker.getService());
+
+		p1.timeout(200).getFailure();
+	}
+}

Added: aries/trunk/cdi/cdi-extender/src/test/java/org/apache/aries/cdi/container/internal/phase/ExtensionPhaseTest.java
URL: http://svn.apache.org/viewvc/aries/trunk/cdi/cdi-extender/src/test/java/org/apache/aries/cdi/container/internal/phase/ExtensionPhaseTest.java?rev=1829115&view=auto
==============================================================================
--- aries/trunk/cdi/cdi-extender/src/test/java/org/apache/aries/cdi/container/internal/phase/ExtensionPhaseTest.java (added)
+++ aries/trunk/cdi/cdi-extender/src/test/java/org/apache/aries/cdi/container/internal/phase/ExtensionPhaseTest.java Sat Apr 14 01:10:27 2018
@@ -0,0 +1,137 @@
+/**
+ * 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.phase;
+
+import static org.apache.aries.cdi.container.internal.util.Reflection.*;
+import static org.junit.Assert.*;
+import static org.mockito.Mockito.*;
+
+import java.util.Arrays;
+import java.util.HashMap;
+import java.util.Map;
+
+import javax.enterprise.inject.spi.Extension;
+
+import org.apache.aries.cdi.container.internal.container.CDIBundle;
+import org.apache.aries.cdi.container.internal.container.ContainerState;
+import org.apache.aries.cdi.container.internal.container.ExtensionPhase;
+import org.apache.aries.cdi.container.internal.util.Logs;
+import org.apache.aries.cdi.container.internal.util.Maps;
+import org.apache.aries.cdi.container.test.BaseCDIBundleTest;
+import org.apache.aries.cdi.container.test.MockServiceRegistration;
+import org.apache.aries.cdi.container.test.TestUtil;
+import org.junit.Test;
+import org.osgi.framework.Bundle;
+import org.osgi.framework.Constants;
+import org.osgi.framework.ServiceEvent;
+import org.osgi.framework.ServiceListener;
+import org.osgi.framework.wiring.BundleWiring;
+import org.osgi.namespace.extender.ExtenderNamespace;
+import org.osgi.service.cdi.CDIConstants;
+import org.osgi.service.cdi.runtime.dto.ContainerDTO;
+import org.osgi.service.cdi.runtime.dto.ExtensionDTO;
+import org.osgi.util.promise.Deferred;
+
+public class ExtensionPhaseTest extends BaseCDIBundleTest {
+
+	@Test
+	public void extensions_tracking() throws Exception {
+		Map<String, Object> attributes = new HashMap<>();
+		attributes.put(CDIConstants.REQUIREMENT_EXTENSIONS_ATTRIBUTE, Arrays.asList("(foo=name)"));
+
+		when(
+			bundle.adapt(
+				BundleWiring.class).getRequiredWires(
+					ExtenderNamespace.EXTENDER_NAMESPACE).get(
+						0).getRequirement().getAttributes()
+		).thenReturn(attributes);
+
+		ContainerState containerState = new ContainerState(bundle, ccrBundle, ccrChangeCount, promiseFactory, null, new Logs.Builder(bundle.getBundleContext()).build());
+
+		CDIBundle cdiBundle = new CDIBundle(
+			ccr, containerState,
+				new ExtensionPhase(containerState, null));
+
+		cdiBundle.start();
+
+		ContainerDTO containerDTO = ccr.getContainerDTO(bundle);
+		assertNotNull(containerDTO);
+
+		assertNotNull(containerDTO.bundle);
+		assertEquals(1, containerDTO.bundle.id);
+		assertEquals(24l, containerDTO.bundle.lastModified);
+		assertEquals(Bundle.ACTIVE, containerDTO.bundle.state);
+		assertEquals("foo", containerDTO.bundle.symbolicName);
+		assertEquals("1.0.0", containerDTO.bundle.version);
+
+		assertEquals(1, containerDTO.changeCount);
+
+		assertTrue(containerDTO.errors + "", containerDTO.errors.isEmpty());
+		assertTrue(containerDTO.extensions + "", containerDTO.extensions.isEmpty());
+
+		assertNotNull(containerDTO.template);
+		assertEquals(1, containerDTO.template.extensions.size());
+		assertEquals("(foo=name)", containerDTO.template.extensions.get(0).serviceFilter);
+
+		final MockServiceRegistration<Extension> regA = cast(bundle.getBundleContext().registerService(
+			Extension.class, new Extension(){}, Maps.dict("foo", "name")));
+
+		Deferred<ServiceListener> slD = testPromiseFactory.deferred();
+
+		do {
+			TestUtil.serviceListeners.stream().filter(
+				en -> en.getValue().matches(
+					Maps.of(Constants.OBJECTCLASS, Extension.class.getName(),
+					"foo", "name"))
+			).map(
+				en -> en.getKey()
+			).findFirst().ifPresent(
+				sl -> slD.resolve(sl)
+			);
+
+			Thread.sleep(10);
+		} while(!slD.getPromise().isDone());
+
+		slD.getPromise().thenAccept(
+			sl -> {
+				assertEquals(2, containerState.containerDTO().changeCount);
+				assertEquals(1, containerState.containerDTO().extensions.size());
+				long id = (long)regA.getReference().getProperty(Constants.SERVICE_ID);
+				ExtensionDTO e = containerState.containerDTO().extensions.get(0);
+				assertEquals(id, e.service.id);
+
+				final MockServiceRegistration<Extension> regB = cast(bundle.getBundleContext().registerService(
+					Extension.class, new Extension(){}, Maps.dict("foo", "name", Constants.SERVICE_RANKING, 10)));
+
+				assertEquals(3, containerState.containerDTO().changeCount);
+				assertEquals(1, containerState.containerDTO().extensions.size());
+				assertEquals(regB.getReference().getProperty(Constants.SERVICE_ID), containerState.containerDTO().extensions.get(0).service.id);
+
+				sl.serviceChanged(new ServiceEvent(ServiceEvent.UNREGISTERING, regB.getReference()));
+
+				assertEquals(4, containerState.containerDTO().changeCount);
+				assertEquals(1, containerState.containerDTO().extensions.size());
+				assertEquals(regA.getReference().getProperty(Constants.SERVICE_ID), containerState.containerDTO().extensions.get(0).service.id);
+
+				sl.serviceChanged(new ServiceEvent(ServiceEvent.UNREGISTERING, regA.getReference()));
+
+				assertEquals(0, containerState.containerDTO().extensions.size());
+			}
+		).getValue();
+
+		cdiBundle.destroy();
+	}
+
+}

Added: aries/trunk/cdi/cdi-extender/src/test/java/org/apache/aries/cdi/container/internal/phase/TemplatesTests.java
URL: http://svn.apache.org/viewvc/aries/trunk/cdi/cdi-extender/src/test/java/org/apache/aries/cdi/container/internal/phase/TemplatesTests.java?rev=1829115&view=auto
==============================================================================
--- aries/trunk/cdi/cdi-extender/src/test/java/org/apache/aries/cdi/container/internal/phase/TemplatesTests.java (added)
+++ aries/trunk/cdi/cdi-extender/src/test/java/org/apache/aries/cdi/container/internal/phase/TemplatesTests.java Sat Apr 14 01:10:27 2018
@@ -0,0 +1,460 @@
+/**
+ * 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.phase;
+
+import static org.junit.Assert.*;
+import static org.mockito.Mockito.*;
+
+import java.util.Arrays;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import org.apache.aries.cdi.container.internal.container.ContainerState;
+import org.apache.aries.cdi.container.internal.util.Logs;
+import org.apache.aries.cdi.container.internal.util.Maps;
+import org.apache.aries.cdi.container.test.BaseCDIBundleTest;
+import org.apache.aries.cdi.container.test.TestUtil;
+import org.apache.aries.cdi.container.test.beans.Bar;
+import org.apache.aries.cdi.container.test.beans.Baz;
+import org.junit.Test;
+import org.osgi.framework.Bundle;
+import org.osgi.framework.Constants;
+import org.osgi.framework.wiring.BundleWiring;
+import org.osgi.namespace.extender.ExtenderNamespace;
+import org.osgi.service.cdi.CDIConstants;
+import org.osgi.service.cdi.ComponentType;
+import org.osgi.service.cdi.ConfigurationPolicy;
+import org.osgi.service.cdi.MaximumCardinality;
+import org.osgi.service.cdi.ReferencePolicy;
+import org.osgi.service.cdi.ReferencePolicyOption;
+import org.osgi.service.cdi.ServiceScope;
+import org.osgi.service.cdi.runtime.dto.ContainerDTO;
+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.ReferenceTemplateDTO;
+
+public class TemplatesTests extends BaseCDIBundleTest {
+
+	@Test
+	public void components_simple() throws Exception {
+		ContainerState containerState = new ContainerState(bundle, ccrBundle, ccrChangeCount, promiseFactory, null, new Logs.Builder(bundle.getBundleContext()).build());
+
+		ContainerDTO containerDTO = containerState.containerDTO();
+		assertNotNull(containerDTO);
+
+		assertTrue(containerDTO.errors + "", containerDTO.errors.isEmpty());
+
+		assertNotNull(containerDTO.template);
+		List<ComponentTemplateDTO> components = TestUtil.sort(
+			containerDTO.template.components, (a, b) -> a.name.compareTo(b.name));
+		assertEquals(2, components.size());
+
+		{
+			ComponentTemplateDTO template = components.get(0);
+			assertEquals(1, template.activations.size());
+
+			{
+				ActivationTemplateDTO at = template.activations.get(0);
+				assertEquals(Maps.of("jaxrs.resource", true), at.properties);
+				assertEquals(ServiceScope.SINGLETON, at.scope);
+				assertEquals(Arrays.asList(Baz.class.getName()), at.serviceClasses);
+			}
+
+			assertEquals(1, template.beans.size());
+			assertEquals(2, template.configurations.size());
+			assertEquals("foo", template.name);
+			assertEquals(Maps.of(), template.properties);
+			assertEquals(6, template.references.size());
+			assertEquals(ComponentType.CONTAINER, template.type);
+		}
+
+		{
+			ComponentTemplateDTO template = components.get(1);
+			assertEquals(1, template.activations.size());
+
+			{
+				ActivationTemplateDTO at = template.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(2, template.beans.size());
+			assertEquals(2, template.configurations.size());
+			assertEquals("foo.annotated", template.name);
+			assertEquals(Maps.of("service.ranking", 12), template.properties);
+			assertEquals(3, template.references.size());
+			assertEquals(ComponentType.SINGLE, template.type);
+		}
+	}
+
+	@Test
+	public void components_multiple() throws Exception {
+		Map<String, Object> attributes = new HashMap<>();
+
+		attributes.put(
+			CDIConstants.REQUIREMENT_OSGI_BEANS_ATTRIBUTE,
+			Arrays.asList(
+				"org.apache.aries.cdi.container.test.beans.BarAnnotated",
+				"org.apache.aries.cdi.container.test.beans.BarProducer",
+				"org.apache.aries.cdi.container.test.beans.FooAnnotated",
+				"org.apache.aries.cdi.container.test.beans.FooWithReferenceAndConfig",
+				"org.apache.aries.cdi.container.test.beans.ObserverFoo",
+				"org.apache.aries.cdi.container.test.beans.BarService"
+			)
+		);
+
+		when(
+			bundle.adapt(
+				BundleWiring.class).getRequiredWires(
+					ExtenderNamespace.EXTENDER_NAMESPACE).get(
+						0).getRequirement().getAttributes()
+		).thenReturn(attributes);
+
+		ContainerState containerState = new ContainerState(bundle, ccrBundle, ccrChangeCount, promiseFactory, null, new Logs.Builder(bundle.getBundleContext()).build());
+
+		ContainerDTO containerDTO = containerState.containerDTO();
+		assertNotNull(containerDTO);
+
+		assertTrue(containerDTO.errors + "", containerDTO.errors.isEmpty());
+
+		assertNotNull(containerDTO.template);
+		List<ComponentTemplateDTO> components = TestUtil.sort(
+			containerDTO.template.components, (a, b) -> a.name.compareTo(b.name));
+		assertEquals(3, components.size());
+
+		{
+			ComponentTemplateDTO ct = components.get(0);
+			assertEquals(1, ct.activations.size());
+
+			{
+				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.Bar"), at.serviceClasses);
+			}
+
+			assertEquals(1, ct.beans.size());
+			assertEquals(1, ct.configurations.size());
+			assertEquals("barService", ct.name);
+			assertEquals(Maps.of(), ct.properties);
+			assertEquals(0, ct.references.size());
+			assertEquals(ComponentType.FACTORY, ct.type);
+		}
+
+		{
+			ComponentTemplateDTO ct = components.get(1);
+			assertEquals(3, ct.activations.size());
+			assertEquals(3, ct.beans.size());
+			assertEquals(2, ct.configurations.size());
+			assertEquals("foo", ct.name);
+			assertEquals(Maps.of(), ct.properties);
+			assertEquals(8, ct.references.size());
+			assertEquals(ComponentType.CONTAINER, ct.type);
+		}
+
+		{
+			ComponentTemplateDTO ct = components.get(2);
+			assertEquals(1, ct.activations.size());
+
+			{
+				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(2, ct.beans.size());
+			assertEquals(2, ct.configurations.size());
+			assertEquals("foo.annotated", ct.name);
+			assertEquals(Maps.of("service.ranking", 12), ct.properties);
+			assertEquals(3, ct.references.size());
+			assertEquals(ComponentType.SINGLE, ct.type);
+		}
+	}
+
+	@Test
+	public void components_verifyContainerComponent() throws Exception {
+		Map<String, Object> attributes = new HashMap<>();
+
+		attributes.put(
+			CDIConstants.REQUIREMENT_OSGI_BEANS_ATTRIBUTE,
+			Arrays.asList(
+				"org.apache.aries.cdi.container.test.beans.BarAnnotated",
+				"org.apache.aries.cdi.container.test.beans.BarProducer",
+				"org.apache.aries.cdi.container.test.beans.FooAnnotated",
+				"org.apache.aries.cdi.container.test.beans.FooWithReferenceAndConfig",
+				"org.apache.aries.cdi.container.test.beans.ObserverFoo",
+				"org.apache.aries.cdi.container.test.beans.BarService"
+			)
+		);
+
+		when(
+			bundle.adapt(
+				BundleWiring.class).getRequiredWires(
+					ExtenderNamespace.EXTENDER_NAMESPACE).get(
+						0).getRequirement().getAttributes()
+		).thenReturn(attributes);
+
+		ContainerState containerState = new ContainerState(bundle, ccrBundle, ccrChangeCount, promiseFactory, null, new Logs.Builder(bundle.getBundleContext()).build());
+
+		ContainerDTO containerDTO = containerState.containerDTO();
+		assertNotNull(containerDTO);
+
+		assertTrue(containerDTO.errors + "", containerDTO.errors.isEmpty());
+		assertNotNull(containerDTO.template);
+
+		List<ComponentTemplateDTO> components = TestUtil.sort(
+			containerDTO.template.components, (a, b) -> a.name.compareTo(b.name));
+		assertEquals(3, components.size());
+
+		{ // component "barService"
+			ComponentTemplateDTO ct = components.get(0);
+			assertEquals(1, ct.activations.size());
+
+			{
+				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.Bar"), at.serviceClasses);
+			}
+
+			assertEquals(1, 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);
+			assertEquals(Maps.of(), ct.properties);
+			assertEquals(0, ct.references.size());
+			assertEquals(ComponentType.FACTORY, ct.type);
+
+			{ // configuration "barService"
+				ConfigurationTemplateDTO configurationTemplateDTO = ct.configurations.get(0);
+				assertEquals(true, configurationTemplateDTO.componentConfiguration);
+				assertEquals(MaximumCardinality.MANY, configurationTemplateDTO.maximumCardinality);
+				assertEquals("barService", configurationTemplateDTO.pid);
+				assertEquals(ConfigurationPolicy.REQUIRED, configurationTemplateDTO.policy);
+			}
+		}
+
+		{ // component "foo"
+			ComponentTemplateDTO ct = components.get(1);
+
+			assertEquals(3, ct.activations.size());
+
+			{
+				ActivationTemplateDTO at = ct.activations.get(0);
+				assertEquals(Maps.of("jaxrs.resource", true), at.properties);
+				assertEquals(ServiceScope.SINGLETON, at.scope);
+				assertEquals(Arrays.asList(Baz.class.getName()), at.serviceClasses);
+			}
+
+			{
+				ActivationTemplateDTO at = ct.activations.get(1);
+				assertEquals(Maps.of(Constants.SERVICE_RANKING, 100), at.properties);
+				assertEquals(ServiceScope.BUNDLE, at.scope);
+				assertEquals(Arrays.asList(Integer.class.getName()), at.serviceClasses);
+			}
+
+			{
+				ActivationTemplateDTO at = ct.activations.get(2);
+				assertEquals(Maps.of(), at.properties);
+				assertEquals(ServiceScope.SINGLETON, at.scope);
+				assertEquals(Arrays.asList(Bar.class.getName()), at.serviceClasses);
+			}
+
+			assertEquals(3, ct.beans.size());
+
+			List<String> beans = TestUtil.sort(ct.beans, (a, b) -> a.compareTo(b));
+			assertEquals("org.apache.aries.cdi.container.test.beans.BarAnnotated", beans.get(0));
+			assertEquals("org.apache.aries.cdi.container.test.beans.BarProducer", beans.get(1));
+			assertEquals("org.apache.aries.cdi.container.test.beans.ObserverFoo", beans.get(2));
+
+			assertEquals(2, ct.configurations.size());
+			assertEquals("foo", ct.name);
+			assertEquals(Maps.of(), ct.properties);
+			assertEquals(8, ct.references.size());
+			assertEquals(ComponentType.CONTAINER, ct.type);
+
+			{ // configuration "osgi.cdi.foo"
+				ConfigurationTemplateDTO configurationTemplateDTO = ct.configurations.get(0);
+				assertEquals(true, configurationTemplateDTO.componentConfiguration);
+				assertEquals(MaximumCardinality.ONE, configurationTemplateDTO.maximumCardinality);
+				assertEquals("osgi.cdi.foo", configurationTemplateDTO.pid);
+				assertEquals(ConfigurationPolicy.OPTIONAL, configurationTemplateDTO.policy);
+			}
+
+			{ // "foo.config
+				ConfigurationTemplateDTO configurationTemplateDTO = ct.configurations.get(1);
+				assertEquals(false, configurationTemplateDTO.componentConfiguration);
+				assertEquals(MaximumCardinality.ONE, configurationTemplateDTO.maximumCardinality);
+				assertEquals("foo.config", configurationTemplateDTO.pid);
+				assertEquals(ConfigurationPolicy.REQUIRED, configurationTemplateDTO.policy);
+			}
+
+			List<ReferenceTemplateDTO> references = TestUtil.sort(ct.references, (a, b) -> a.name.compareTo(b.name));
+
+			{
+				ReferenceTemplateDTO ref = references.get(0);
+				assertEquals(MaximumCardinality.MANY, ref.maximumCardinality);
+				assertEquals(0, ref.minimumCardinality);
+				assertEquals("org.apache.aries.cdi.container.test.beans.BarAnnotated.dynamicFoos", ref.name);
+				assertEquals(ReferencePolicy.DYNAMIC, ref.policy);
+				assertEquals(ReferencePolicyOption.RELUCTANT, ref.policyOption);
+				assertEquals("org.apache.aries.cdi.container.test.beans.Foo", ref.serviceType);
+				assertEquals("", ref.targetFilter);
+			}
+
+			{
+				ReferenceTemplateDTO ref = references.get(1);
+				assertEquals(MaximumCardinality.ONE, ref.maximumCardinality);
+				assertEquals(1, ref.minimumCardinality);
+				assertEquals("org.apache.aries.cdi.container.test.beans.BarAnnotated.foo", ref.name);
+				assertEquals(ReferencePolicy.STATIC, ref.policy);
+				assertEquals(ReferencePolicyOption.GREEDY, ref.policyOption);
+				assertEquals("org.apache.aries.cdi.container.test.beans.Foo", ref.serviceType);
+				assertEquals("", ref.targetFilter);
+			}
+
+			{
+				ReferenceTemplateDTO ref = references.get(2);
+				assertEquals(MaximumCardinality.ONE, ref.maximumCardinality);
+				assertEquals(0, ref.minimumCardinality);
+				assertEquals("org.apache.aries.cdi.container.test.beans.BarAnnotated.fooOptional", ref.name);
+				assertEquals(ReferencePolicy.STATIC, ref.policy);
+				assertEquals(ReferencePolicyOption.RELUCTANT, ref.policyOption);
+				assertEquals("org.apache.aries.cdi.container.test.beans.Foo", ref.serviceType);
+				assertEquals("", ref.targetFilter);
+			}
+
+			{
+				ReferenceTemplateDTO ref = references.get(3);
+				assertEquals(MaximumCardinality.MANY, ref.maximumCardinality);
+				assertEquals(0, ref.minimumCardinality);
+				assertEquals("org.apache.aries.cdi.container.test.beans.BarAnnotated.propertiesFoos", ref.name);
+				assertEquals(ReferencePolicy.STATIC, ref.policy);
+				assertEquals(ReferencePolicyOption.RELUCTANT, ref.policyOption);
+				assertEquals("org.apache.aries.cdi.container.test.beans.Foo", ref.serviceType);
+				assertEquals("", ref.targetFilter);
+			}
+
+			{
+				ReferenceTemplateDTO ref = references.get(4);
+				assertEquals(MaximumCardinality.MANY, ref.maximumCardinality);
+				assertEquals(0, ref.minimumCardinality);
+				assertEquals("org.apache.aries.cdi.container.test.beans.BarAnnotated.serviceReferencesFoos", ref.name);
+				assertEquals(ReferencePolicy.STATIC, ref.policy);
+				assertEquals(ReferencePolicyOption.RELUCTANT, ref.policyOption);
+				assertEquals("org.apache.aries.cdi.container.test.beans.Foo", ref.serviceType);
+				assertEquals("(service.scope=prototype)", ref.targetFilter);
+			}
+
+			{
+				ReferenceTemplateDTO ref = references.get(5);
+				assertEquals(MaximumCardinality.MANY, ref.maximumCardinality);
+				assertEquals(0, ref.minimumCardinality);
+				assertEquals("org.apache.aries.cdi.container.test.beans.BarAnnotated.tupleIntegers", ref.name);
+				assertEquals(ReferencePolicy.STATIC, ref.policy);
+				assertEquals(ReferencePolicyOption.RELUCTANT, ref.policyOption);
+				assertEquals("java.lang.Integer", ref.serviceType);
+				assertEquals("", ref.targetFilter);
+			}
+
+			{
+				ReferenceTemplateDTO ref = references.get(6);
+				assertEquals(MaximumCardinality.ONE, ref.maximumCardinality);
+				assertEquals(1, ref.minimumCardinality);
+				assertEquals("org.apache.aries.cdi.container.test.beans.BarProducer.getBar0", ref.name);
+				assertEquals(ReferencePolicy.STATIC, ref.policy);
+				assertEquals(ReferencePolicyOption.RELUCTANT, ref.policyOption);
+				assertEquals("org.apache.aries.cdi.container.test.beans.Bar", ref.serviceType);
+				assertEquals("", ref.targetFilter);
+			}
+
+			{
+				ReferenceTemplateDTO ref = references.get(7);
+				assertEquals(MaximumCardinality.MANY, ref.maximumCardinality);
+				assertEquals(0, ref.minimumCardinality);
+				assertEquals("org.apache.aries.cdi.container.test.beans.ObserverFoo.foos0", ref.name);
+				assertEquals(ReferencePolicy.DYNAMIC, ref.policy);
+				assertEquals(ReferencePolicyOption.GREEDY, ref.policyOption);
+				assertEquals("org.apache.aries.cdi.container.test.beans.Foo", ref.serviceType);
+				assertEquals("", ref.targetFilter);
+			}
+		}
+
+		{ // component "foo.annotated"
+			ComponentTemplateDTO ct = components.get(2);
+			assertEquals(1, ct.activations.size());
+			assertEquals(2, ct.beans.size());
+			assertEquals("org.apache.aries.cdi.container.test.beans.FooAnnotated", ct.beans.get(0));
+			assertEquals(2, ct.configurations.size());
+			assertEquals("foo.annotated", ct.name);
+			assertEquals(Maps.of("service.ranking", 12), ct.properties);
+			assertEquals(3, ct.references.size());
+			assertEquals(ComponentType.SINGLE, ct.type);
+
+			{ // configuration "foo.annotated"
+				ConfigurationTemplateDTO configurationTemplateDTO = ct.configurations.get(0);
+				assertEquals(true, configurationTemplateDTO.componentConfiguration);
+				assertEquals(MaximumCardinality.ONE, configurationTemplateDTO.maximumCardinality);
+				assertEquals("foo.annotated", configurationTemplateDTO.pid);
+				assertEquals(ConfigurationPolicy.OPTIONAL, configurationTemplateDTO.policy);
+			}
+		}
+	}
+
+	@Test
+	public void descriptor_missingbeanclass() throws Exception {
+		Map<String, Object> attributes = new HashMap<>();
+
+		attributes.put(
+			CDIConstants.REQUIREMENT_OSGI_BEANS_ATTRIBUTE,
+			Arrays.asList(
+				"org.apache.aries.cdi.container.test.beans.BarAnnotated",
+				"org.apache.aries.cdi.container.test.beans.FooAnnotated",
+				"org.apache.aries.cdi.container.test.beans.Missing"
+			)
+		);
+
+		when(
+			bundle.adapt(
+				BundleWiring.class).getRequiredWires(
+					ExtenderNamespace.EXTENDER_NAMESPACE).get(
+						0).getRequirement().getAttributes()
+		).thenReturn(attributes);
+
+		ContainerState containerState = new ContainerState(bundle, ccrBundle, ccrChangeCount, promiseFactory, null, new Logs.Builder(bundle.getBundleContext()).build());
+
+		ContainerDTO containerDTO = containerState.containerDTO();
+		assertNotNull(containerDTO);
+
+		assertNotNull(containerDTO.bundle);
+		assertEquals(1, containerDTO.bundle.id);
+		assertEquals(24l, containerDTO.bundle.lastModified);
+		assertEquals(Bundle.ACTIVE, containerDTO.bundle.state);
+		assertEquals("foo", containerDTO.bundle.symbolicName);
+		assertEquals("1.0.0", containerDTO.bundle.version);
+
+		assertEquals(1, containerDTO.changeCount);
+
+		assertTrue(containerDTO.components + "", containerDTO.components.isEmpty());
+		assertFalse(containerDTO.errors.isEmpty());
+		String[] linesOfError = containerDTO.errors.get(0).split("\r\n|\r|\n", 4);
+		assertTrue(linesOfError[0], linesOfError[0].contains("java.lang.ClassNotFoundException: org.apache.aries.cdi.container.test.beans.Missing"));
+	}
+
+}

Added: aries/trunk/cdi/cdi-extender/src/test/java/org/apache/aries/cdi/container/internal/util/Sfl4jLogger.java
URL: http://svn.apache.org/viewvc/aries/trunk/cdi/cdi-extender/src/test/java/org/apache/aries/cdi/container/internal/util/Sfl4jLogger.java?rev=1829115&view=auto
==============================================================================
--- aries/trunk/cdi/cdi-extender/src/test/java/org/apache/aries/cdi/container/internal/util/Sfl4jLogger.java (added)
+++ aries/trunk/cdi/cdi-extender/src/test/java/org/apache/aries/cdi/container/internal/util/Sfl4jLogger.java Sat Apr 14 01:10:27 2018
@@ -0,0 +1,158 @@
+/**
+ * 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.util;
+
+import org.apache.aries.cdi.container.internal.util.Logs.SysoutLogger;
+
+public class Sfl4jLogger extends SysoutLogger {
+
+	private final org.slf4j.Logger _logger;
+
+	public Sfl4jLogger(String name) throws Exception {
+		super(name);
+		_logger = org.slf4j.LoggerFactory.getLogger(name);
+	}
+
+	@Override
+	public void debug(String message) {
+		_logger.debug(message);
+	}
+
+	@Override
+	public void debug(String format, Object arg) {
+		_logger.debug(format, arg);
+	}
+
+	@Override
+	public void debug(String format, Object arg1, Object arg2) {
+		_logger.debug(format, arg1, arg2);
+	}
+
+	@Override
+	public void debug(String format, Object... arguments) {
+		_logger.debug(format, arguments);
+	}
+
+	@Override
+	public void error(String message) {
+		_logger.error(message);
+	}
+
+	@Override
+	public void error(String format, Object arg) {
+		_logger.error(format, arg);
+	}
+
+	@Override
+	public void error(String format, Object arg1, Object arg2) {
+		_logger.error(format, arg1, arg2);
+	}
+
+	@Override
+	public void error(String format, Object... arguments) {
+		_logger.error(format, arguments);
+	}
+
+	@Override
+	public String getName() {
+		return _logger.getName();
+	}
+
+	@Override
+	public void info(String message) {
+		_logger.info(message);
+	}
+
+	@Override
+	public void info(String format, Object arg) {
+		_logger.info(format, arg);
+	}
+
+	@Override
+	public void info(String format, Object arg1, Object arg2) {
+		_logger.info(format, arg1, arg2);
+	}
+
+	@Override
+	public void info(String format, Object... arguments) {
+		_logger.info(format, arguments);
+	}
+
+	@Override
+	public boolean isDebugEnabled() {
+		return _logger.isDebugEnabled();
+	}
+
+	@Override
+	public boolean isErrorEnabled() {
+		return _logger.isErrorEnabled();
+	}
+
+	@Override
+	public boolean isInfoEnabled() {
+		return _logger.isInfoEnabled();
+	}
+
+	@Override
+	public boolean isTraceEnabled() {
+		return _logger.isTraceEnabled();
+	}
+
+	@Override
+	public boolean isWarnEnabled() {
+		return _logger.isWarnEnabled();
+	}
+
+	@Override
+	public void trace(String message) {
+		_logger.trace(message);
+	}
+
+	@Override
+	public void trace(String format, Object arg) {
+		_logger.trace(format, arg);
+	}
+
+	@Override
+	public void trace(String format, Object arg1, Object arg2) {
+		_logger.trace(format, arg1, arg2);
+	}
+
+	@Override
+	public void trace(String format, Object... arguments) {
+		_logger.trace(format, arguments);
+	}
+
+	@Override
+	public void warn(String message) {
+		_logger.warn(message);
+	}
+
+	@Override
+	public void warn(String format, Object arg) {
+		_logger.warn(format, arg);
+	}
+
+	@Override
+	public void warn(String format, Object arg1, Object arg2) {
+		_logger.warn(format, arg1, arg2);
+	}
+
+	@Override
+	public void warn(String format, Object... arguments) {
+		_logger.warn(format, arguments);
+	}
+
+}
\ No newline at end of file

Added: aries/trunk/cdi/cdi-extender/src/test/java/org/apache/aries/cdi/container/test/AnnotatedCache.java
URL: http://svn.apache.org/viewvc/aries/trunk/cdi/cdi-extender/src/test/java/org/apache/aries/cdi/container/test/AnnotatedCache.java?rev=1829115&view=auto
==============================================================================
--- aries/trunk/cdi/cdi-extender/src/test/java/org/apache/aries/cdi/container/test/AnnotatedCache.java (added)
+++ aries/trunk/cdi/cdi-extender/src/test/java/org/apache/aries/cdi/container/test/AnnotatedCache.java Sat Apr 14 01:10:27 2018
@@ -0,0 +1,105 @@
+/**
+ * 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.lang.reflect.Constructor;
+import java.lang.reflect.Executable;
+import java.lang.reflect.Field;
+import java.lang.reflect.Member;
+import java.lang.reflect.Method;
+import java.lang.reflect.Parameter;
+import java.lang.reflect.Type;
+import java.util.HashSet;
+import java.util.Map;
+import java.util.Set;
+import java.util.concurrent.ConcurrentHashMap;
+
+import javax.enterprise.inject.spi.AnnotatedCallable;
+import javax.enterprise.inject.spi.AnnotatedConstructor;
+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.AnnotatedType;
+
+class AnnotatedCache {
+
+	public static Set<Type> collectTypes(Class<?> c) {
+		Set<Type> types = new HashSet<>();
+		collectTypes(types, c);
+		return types;
+	}
+
+	private static void collectTypes(Set<Type> closure, Class<?> c) {
+		if (c == null) return;
+		closure.add(c);
+		collectTypes(closure, c.getSuperclass());
+		for (Class<?> i : c.getInterfaces()) {
+			collectTypes(closure, i);
+		}
+	}
+
+	@SuppressWarnings({ "unchecked", "rawtypes" })
+	public static <X> AnnotatedConstructor<X> getAnnotatedConstructor(Constructor<X> c) {
+		return (AnnotatedConstructor<X>) _ctorCache.computeIfAbsent(c, k -> new MockAnnotatedConstructor(k));
+	}
+
+	@SuppressWarnings("unchecked")
+	public static <X> AnnotatedCallable<X> getAnnotatedCallable(Executable executable) {
+		if (executable instanceof Constructor) {
+			return getAnnotatedConstructor((Constructor<X>)executable);
+		}
+		return getAnnotatedMethod((Method)executable);
+	}
+
+	@SuppressWarnings({ "unchecked", "rawtypes" })
+	public static <X> AnnotatedField<X> getAnnotatedField(Field f) {
+		return (AnnotatedField<X>) _fieldCache.computeIfAbsent(f, k -> new MockAnnotatedField(k));
+	}
+
+	@SuppressWarnings("unchecked")
+	public static <X> AnnotatedMember<X> getAnnotatedMember(Member member) {
+		if (member instanceof Field) {
+			return getAnnotatedField((Field)member);
+		}
+		else if (member instanceof Constructor) {
+			return getAnnotatedConstructor((Constructor<X>)member);
+		}
+
+		return getAnnotatedMethod((Method)member);
+	}
+
+	@SuppressWarnings({ "unchecked", "rawtypes" })
+	public static <X> AnnotatedMethod<X> getAnnotatedMethod(Method m) {
+		return (AnnotatedMethod<X>) _methodCache.computeIfAbsent(m, k -> new MockAnnotatedMethod(k));
+	}
+
+	@SuppressWarnings({ "unchecked", "rawtypes" })
+	public static <X> AnnotatedParameter<X> getAnnotatedParameter(Parameter p) {
+		return (AnnotatedParameter<X>) _paramCache.computeIfAbsent(p, k -> new MockAnnotatedParameter(k));
+	}
+
+	@SuppressWarnings({ "unchecked", "rawtypes" })
+	public static <X> AnnotatedType<X> getAnnotatedType(Class<X> type) {
+		return (AnnotatedType<X>) _typeCache.computeIfAbsent(type, k -> new MockAnnotatedType(k));
+	}
+
+	private static final Map<Constructor<?>, AnnotatedConstructor<?>> _ctorCache = new ConcurrentHashMap<>();
+	private static final Map<Field, AnnotatedField<?>> _fieldCache = new ConcurrentHashMap<>();
+	private static final Map<Method, AnnotatedMethod<?>> _methodCache = new ConcurrentHashMap<>();
+	private static final Map<Parameter, AnnotatedParameter<?>> _paramCache = new ConcurrentHashMap<>();
+	private static final Map<Class<?>, AnnotatedType<?>> _typeCache = new ConcurrentHashMap<>();
+
+}
\ No newline at end of file

Added: aries/trunk/cdi/cdi-extender/src/test/java/org/apache/aries/cdi/container/test/BaseCDIBundleTest.java
URL: http://svn.apache.org/viewvc/aries/trunk/cdi/cdi-extender/src/test/java/org/apache/aries/cdi/container/test/BaseCDIBundleTest.java?rev=1829115&view=auto
==============================================================================
--- aries/trunk/cdi/cdi-extender/src/test/java/org/apache/aries/cdi/container/test/BaseCDIBundleTest.java (added)
+++ aries/trunk/cdi/cdi-extender/src/test/java/org/apache/aries/cdi/container/test/BaseCDIBundleTest.java Sat Apr 14 01:10:27 2018
@@ -0,0 +1,110 @@
+/**
+ * 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 static org.mockito.Mockito.*;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.concurrent.Executors;
+
+import org.apache.aries.cdi.container.internal.CCR;
+import org.apache.aries.cdi.container.internal.ChangeCount;
+import org.apache.aries.cdi.container.internal.util.Logs;
+import org.apache.aries.cdi.container.internal.util.Maps;
+import org.junit.Before;
+import org.osgi.framework.Bundle;
+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;
+import org.osgi.framework.wiring.BundleWiring;
+import org.osgi.namespace.extender.ExtenderNamespace;
+import org.osgi.service.cdi.CDIConstants;
+import org.osgi.util.promise.PromiseFactory;
+
+public class BaseCDIBundleTest {
+
+	protected Bundle bundle;
+	protected CCR ccr;
+	protected Bundle ccrBundle;
+	protected ChangeCount ccrChangeCount;
+	protected PromiseFactory promiseFactory;
+	protected PromiseFactory testPromiseFactory = new PromiseFactory(null);
+
+	@Before
+	public void before() throws Exception {
+		TestUtil.configurations.clear();
+		TestUtil.serviceListeners.clear();
+		TestUtil.serviceRegistrations.clear();
+		promiseFactory = new PromiseFactory(Executors.newFixedThreadPool(1));
+		ccrChangeCount = new ChangeCount();
+
+		BundleDTO ccrBundleDTO = new BundleDTO();
+		ccrBundleDTO.id = 2;
+		ccrBundleDTO.lastModified = 100l;
+		ccrBundleDTO.state = Bundle.ACTIVE;
+		ccrBundleDTO.symbolicName = "extender";
+		ccrBundleDTO.version = "1.0.0";
+
+		ccrBundle = TestUtil.mockBundle(
+			ccrBundleDTO, b -> {
+				when(
+					b.adapt(BundleWiring.class).getRequiredWires(PackageNamespace.PACKAGE_NAMESPACE)
+				).thenReturn(new ArrayList<>());
+			}
+		);
+
+		BundleDTO bundleDTO = new BundleDTO();
+		bundleDTO.id = 1;
+		bundleDTO.lastModified = 24l;
+		bundleDTO.state = Bundle.ACTIVE;
+		bundleDTO.symbolicName = "foo";
+		bundleDTO.version = "1.0.0";
+
+		bundle = TestUtil.mockBundle(
+			bundleDTO, b -> {
+				BundleCapability extenderCapability = mock(BundleCapability.class);
+				BundleRequirement extenderRequirement = mock(BundleRequirement.class);
+				BundleWire extenderWire = mock(BundleWire.class);
+
+				when(
+					b.adapt(BundleWiring.class).getRequiredWires(ExtenderNamespace.EXTENDER_NAMESPACE)
+				).thenReturn(Collections.singletonList(extenderWire));
+				when(
+					b.adapt(BundleWiring.class).listResources("OSGI-INF/cdi", "*.xml", BundleWiring.LISTRESOURCES_LOCAL)
+				).thenReturn(Collections.singletonList("OSGI-INF/cdi/osgi-beans.xml"));
+				when(extenderWire.getCapability()).thenReturn(extenderCapability);
+				when(extenderCapability.getAttributes()).thenReturn(Collections.singletonMap(ExtenderNamespace.EXTENDER_NAMESPACE, CDIConstants.CDI_CAPABILITY_NAME));
+				when(extenderWire.getRequirement()).thenReturn(extenderRequirement);
+				when(extenderRequirement.getAttributes()).thenReturn(
+					Maps.of(
+						"osgi.beans",
+						Arrays.asList(
+							"org.apache.aries.cdi.container.test.beans.BarAnnotated",
+							"org.apache.aries.cdi.container.test.beans.FooAnnotated",
+							"org.apache.aries.cdi.container.test.beans.FooWithReferenceAndConfig"
+						)
+					)
+				);
+			}
+		);
+
+		ccr = new CCR(promiseFactory, new Logs.Builder(bundle.getBundleContext()).build());
+	}
+
+}

Added: aries/trunk/cdi/cdi-extender/src/test/java/org/apache/aries/cdi/container/test/MockAnnotatedConstructor.java
URL: http://svn.apache.org/viewvc/aries/trunk/cdi/cdi-extender/src/test/java/org/apache/aries/cdi/container/test/MockAnnotatedConstructor.java?rev=1829115&view=auto
==============================================================================
--- aries/trunk/cdi/cdi-extender/src/test/java/org/apache/aries/cdi/container/test/MockAnnotatedConstructor.java (added)
+++ aries/trunk/cdi/cdi-extender/src/test/java/org/apache/aries/cdi/container/test/MockAnnotatedConstructor.java Sat Apr 14 01:10:27 2018
@@ -0,0 +1,93 @@
+/**
+ * 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 static org.apache.aries.cdi.container.test.AnnotatedCache.*;
+
+import java.lang.annotation.Annotation;
+import java.lang.reflect.Constructor;
+import java.lang.reflect.Type;
+import java.util.Arrays;
+import java.util.List;
+import java.util.Set;
+import java.util.stream.Collectors;
+
+import javax.enterprise.inject.spi.AnnotatedConstructor;
+import javax.enterprise.inject.spi.AnnotatedParameter;
+import javax.enterprise.inject.spi.AnnotatedType;
+
+class MockAnnotatedConstructor<X> implements AnnotatedConstructor<X> {
+
+	private final Constructor<X> _constructor;
+	private final AnnotatedType<X> _declaringType;
+	private final Set<Type> _types;
+
+	public MockAnnotatedConstructor(Constructor<X> constructor) {
+		_constructor = constructor;
+		_declaringType = getAnnotatedType(constructor.getDeclaringClass());
+		_types = collectTypes(constructor.getDeclaringClass());
+	}
+
+	@Override
+	public <T extends Annotation> T getAnnotation(Class<T> annotationType) {
+		return _constructor.getAnnotation(annotationType);
+	}
+
+	@Override
+	public Set<Annotation> getAnnotations() {
+		return Arrays.stream(_constructor.getAnnotations()).collect(Collectors.toSet());
+	}
+
+	@Override
+	public Type getBaseType() {
+		return _constructor.getDeclaringClass();
+	}
+
+	@Override
+	public AnnotatedType<X> getDeclaringType() {
+		return _declaringType;
+	}
+
+	@Override
+	public Constructor<X> getJavaMember() {
+		return _constructor;
+	}
+
+	@Override
+	@SuppressWarnings("unchecked")
+	public List<AnnotatedParameter<X>> getParameters() {
+		return Arrays.stream(_constructor.getParameters()).map(
+			p -> (AnnotatedParameter<X>)getAnnotatedParameter(p)
+		).collect(Collectors.toList());
+	}
+
+	@Override
+	public Set<Type> getTypeClosure() {
+		return _types;
+	}
+
+	@Override
+	public boolean isAnnotationPresent(Class<? extends Annotation> annotationType) {
+		return Arrays.stream(_constructor.getAnnotations()).filter(
+			ann -> ann.annotationType().equals(annotationType)
+		).findFirst().isPresent();
+	}
+
+	@Override
+	public boolean isStatic() {
+		return false;
+	}
+
+}
\ No newline at end of file

Added: aries/trunk/cdi/cdi-extender/src/test/java/org/apache/aries/cdi/container/test/MockAnnotatedField.java
URL: http://svn.apache.org/viewvc/aries/trunk/cdi/cdi-extender/src/test/java/org/apache/aries/cdi/container/test/MockAnnotatedField.java?rev=1829115&view=auto
==============================================================================
--- aries/trunk/cdi/cdi-extender/src/test/java/org/apache/aries/cdi/container/test/MockAnnotatedField.java (added)
+++ aries/trunk/cdi/cdi-extender/src/test/java/org/apache/aries/cdi/container/test/MockAnnotatedField.java Sat Apr 14 01:10:27 2018
@@ -0,0 +1,94 @@
+/**
+ * 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 static org.apache.aries.cdi.container.test.AnnotatedCache.*;
+
+import java.lang.annotation.Annotation;
+import java.lang.reflect.Field;
+import java.lang.reflect.Type;
+import java.util.Arrays;
+import java.util.Set;
+import java.util.stream.Collectors;
+
+import javax.enterprise.inject.spi.AnnotatedField;
+import javax.enterprise.inject.spi.AnnotatedType;
+
+class MockAnnotatedField<X> implements AnnotatedField<X> {
+
+	private final AnnotatedType<X> _declaringType;
+	private final Field _field;
+	private final Set<Type> _types;
+
+	@SuppressWarnings("unchecked")
+	public MockAnnotatedField(Field field) {
+		_field = field;
+		_declaringType = (AnnotatedType<X>) getAnnotatedType(_field.getDeclaringClass());
+		_types = collectTypes(_field.getType());
+	}
+
+	@Override
+	public <T extends Annotation> T getAnnotation(Class<T> annotationType) {
+		return _field.getAnnotation(annotationType);
+	}
+
+	@Override
+	public Set<Annotation> getAnnotations() {
+		return Arrays.stream(_field.getAnnotations()).collect(Collectors.toSet());
+
+	}
+	@SuppressWarnings("unchecked")
+	@Override
+	public <T extends Annotation> Set<T> getAnnotations(Class<T> annotationType) {
+		return Arrays.stream(_field.getAnnotations()).filter(
+			ann -> ann.annotationType().equals(annotationType)
+		).map(
+			ann -> (T)ann
+		).collect(Collectors.toSet());
+	}
+
+	@Override
+	public Type getBaseType() {
+		return _field.getType();
+	}
+
+	@Override
+	public AnnotatedType<X> getDeclaringType() {
+		return _declaringType;
+	}
+
+	@Override
+	public Field getJavaMember() {
+		return _field;
+	}
+
+	@Override
+	public Set<Type> getTypeClosure() {
+		return _types;
+	}
+
+	@Override
+	public boolean isAnnotationPresent(Class<? extends Annotation> annotationType) {
+		return Arrays.stream(_field.getAnnotations()).filter(
+			ann -> ann.annotationType().equals(annotationType)
+		).findFirst().isPresent();
+	}
+
+	@Override
+	public boolean isStatic() {
+		return false;
+	}
+
+}
\ No newline at end of file

Added: aries/trunk/cdi/cdi-extender/src/test/java/org/apache/aries/cdi/container/test/MockAnnotatedMethod.java
URL: http://svn.apache.org/viewvc/aries/trunk/cdi/cdi-extender/src/test/java/org/apache/aries/cdi/container/test/MockAnnotatedMethod.java?rev=1829115&view=auto
==============================================================================
--- aries/trunk/cdi/cdi-extender/src/test/java/org/apache/aries/cdi/container/test/MockAnnotatedMethod.java (added)
+++ aries/trunk/cdi/cdi-extender/src/test/java/org/apache/aries/cdi/container/test/MockAnnotatedMethod.java Sat Apr 14 01:10:27 2018
@@ -0,0 +1,94 @@
+/**
+ * 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 static org.apache.aries.cdi.container.test.AnnotatedCache.*;
+
+import java.lang.annotation.Annotation;
+import java.lang.reflect.Method;
+import java.lang.reflect.Type;
+import java.util.Arrays;
+import java.util.List;
+import java.util.Set;
+import java.util.stream.Collectors;
+
+import javax.enterprise.inject.spi.AnnotatedMethod;
+import javax.enterprise.inject.spi.AnnotatedParameter;
+import javax.enterprise.inject.spi.AnnotatedType;
+
+public class MockAnnotatedMethod<X> implements AnnotatedMethod<X> {
+
+	private final Method _method;
+	private AnnotatedType<X> _declaringType;
+	private Set<Type> _types;
+
+	@SuppressWarnings("unchecked")
+	public MockAnnotatedMethod(Method method) {
+		_method = method;
+		_declaringType = (AnnotatedType<X>) getAnnotatedType(_method.getDeclaringClass());
+		_types = collectTypes(_method.getDeclaringClass());
+	}
+
+	@Override
+	public <T extends Annotation> T getAnnotation(Class<T> annotationType) {
+		return _method.getAnnotation(annotationType);
+	}
+
+	@Override
+	public Set<Annotation> getAnnotations() {
+		return Arrays.stream(_method.getAnnotations()).collect(Collectors.toSet());
+	}
+
+	@Override
+	public Type getBaseType() {
+		return _method.getDeclaringClass();
+	}
+
+	@Override
+	public AnnotatedType<X> getDeclaringType() {
+		return _declaringType;
+	}
+
+	@Override
+	public Method getJavaMember() {
+		return _method;
+	}
+
+	@Override
+	@SuppressWarnings("unchecked")
+	public List<AnnotatedParameter<X>> getParameters() {
+		return Arrays.stream(_method.getParameters()).map(
+			p -> (AnnotatedParameter<X>)getAnnotatedParameter(p)
+		).collect(Collectors.toList());
+	}
+
+	@Override
+	public Set<Type> getTypeClosure() {
+		return _types;
+	}
+
+	@Override
+	public boolean isAnnotationPresent(Class<? extends Annotation> annotationType) {
+		return Arrays.stream(_method.getAnnotations()).filter(
+			ann -> ann.annotationType().equals(annotationType)
+		).findFirst().isPresent();
+	}
+
+	@Override
+	public boolean isStatic() {
+		return false;
+	}
+
+}

Added: aries/trunk/cdi/cdi-extender/src/test/java/org/apache/aries/cdi/container/test/MockAnnotatedParameter.java
URL: http://svn.apache.org/viewvc/aries/trunk/cdi/cdi-extender/src/test/java/org/apache/aries/cdi/container/test/MockAnnotatedParameter.java?rev=1829115&view=auto
==============================================================================
--- aries/trunk/cdi/cdi-extender/src/test/java/org/apache/aries/cdi/container/test/MockAnnotatedParameter.java (added)
+++ aries/trunk/cdi/cdi-extender/src/test/java/org/apache/aries/cdi/container/test/MockAnnotatedParameter.java Sat Apr 14 01:10:27 2018
@@ -0,0 +1,82 @@
+/**
+ * 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 static org.apache.aries.cdi.container.test.AnnotatedCache.*;
+
+import java.lang.annotation.Annotation;
+import java.lang.reflect.Parameter;
+import java.lang.reflect.Type;
+import java.util.Arrays;
+import java.util.Set;
+import java.util.stream.Collectors;
+
+import javax.enterprise.inject.spi.AnnotatedCallable;
+import javax.enterprise.inject.spi.AnnotatedParameter;
+
+public class MockAnnotatedParameter<X> implements AnnotatedParameter<X> {
+
+	private final Parameter _parameter;
+	private Set<Type> _types;
+
+	public MockAnnotatedParameter(Parameter parameter) {
+		_parameter = parameter;
+		_types = collectTypes(_parameter.getType());
+	}
+
+	@Override
+	public <T extends Annotation> T getAnnotation(Class<T> annotationType) {
+		return _parameter.getAnnotation(annotationType);
+	}
+
+	@Override
+	public Set<Annotation> getAnnotations() {
+		return Arrays.stream(_parameter.getAnnotations()).collect(Collectors.toSet());
+	}
+
+	@Override
+	public Type getBaseType() {
+		return _parameter.getType();
+	}
+
+	@Override
+	public AnnotatedCallable<X> getDeclaringCallable() {
+		return getAnnotatedCallable(_parameter.getDeclaringExecutable());
+	}
+
+	@Override
+	public int getPosition() {
+		Parameter[] parameters = _parameter.getDeclaringExecutable().getParameters();
+		for (int i = 0; i < parameters.length; i++) {
+			if (_parameter.equals(parameters[i])) {
+				return i + 1;
+			}
+		}
+		return -1;
+	}
+
+	@Override
+	public Set<Type> getTypeClosure() {
+		return _types;
+	}
+
+	@Override
+	public boolean isAnnotationPresent(Class<? extends Annotation> annotationType) {
+		return Arrays.stream(_parameter.getAnnotations()).filter(
+			ann -> ann.annotationType().equals(annotationType)
+		).findFirst().isPresent();
+	}
+
+}

Added: aries/trunk/cdi/cdi-extender/src/test/java/org/apache/aries/cdi/container/test/MockAnnotatedType.java
URL: http://svn.apache.org/viewvc/aries/trunk/cdi/cdi-extender/src/test/java/org/apache/aries/cdi/container/test/MockAnnotatedType.java?rev=1829115&view=auto
==============================================================================
--- aries/trunk/cdi/cdi-extender/src/test/java/org/apache/aries/cdi/container/test/MockAnnotatedType.java (added)
+++ aries/trunk/cdi/cdi-extender/src/test/java/org/apache/aries/cdi/container/test/MockAnnotatedType.java Sat Apr 14 01:10:27 2018
@@ -0,0 +1,94 @@
+/**
+ * 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 static org.apache.aries.cdi.container.test.AnnotatedCache.*;
+
+import java.lang.annotation.Annotation;
+import java.lang.reflect.Type;
+import java.util.Arrays;
+import java.util.Set;
+import java.util.stream.Collectors;
+
+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 MockAnnotatedType<X> implements AnnotatedType<X> {
+
+	private final Class<X> _clazz;
+	private final Set<Type> _types;
+
+	public MockAnnotatedType(Class<X> clazz) {
+		_clazz = clazz;
+		_types = collectTypes(_clazz);
+	}
+
+	@Override
+	public <T extends Annotation> T getAnnotation(Class<T> annotationType) {
+		return _clazz.getAnnotation(annotationType);
+	}
+
+	@Override
+	public Set<Annotation> getAnnotations() {
+		return Arrays.stream(_clazz.getAnnotations()).collect(Collectors.toSet());
+	}
+
+	@Override
+	public Type getBaseType() {
+		return _clazz;
+	}
+
+	@Override
+	@SuppressWarnings("unchecked")
+	public Set<AnnotatedConstructor<X>> getConstructors() {
+		return Arrays.stream(_clazz.getConstructors()).map(
+			ctor -> (AnnotatedConstructor<X>)getAnnotatedConstructor(ctor)
+		).collect(Collectors.toSet());
+	}
+
+	@Override
+	@SuppressWarnings("unchecked")
+	public Set<AnnotatedField<? super X>> getFields() {
+		return Arrays.stream(_clazz.getFields()).map(
+			field -> (AnnotatedField<X>)getAnnotatedField(field)
+		).collect(Collectors.toSet());
+	}
+
+	@Override
+	public Class<X> getJavaClass() {
+		return _clazz;
+	}
+
+	@Override
+	@SuppressWarnings("unchecked")
+	public Set<AnnotatedMethod<? super X>> getMethods() {
+		return Arrays.stream(_clazz.getMethods()).map(
+			method -> (AnnotatedMethod<X>)getAnnotatedMethod(method)
+		).collect(Collectors.toSet());
+	}
+
+	@Override
+	public Set<Type> getTypeClosure() {
+		return _types;
+	}
+
+	@Override
+	public boolean isAnnotationPresent(Class<? extends Annotation> annotationType) {
+		return false;
+	}
+
+}
\ No newline at end of file

Modified: aries/trunk/cdi/cdi-extender/src/test/java/org/apache/aries/cdi/container/test/MockCdiContainerAndComponents.java
URL: http://svn.apache.org/viewvc/aries/trunk/cdi/cdi-extender/src/test/java/org/apache/aries/cdi/container/test/MockCdiContainerAndComponents.java?rev=1829115&r1=1829114&r2=1829115&view=diff
==============================================================================
--- aries/trunk/cdi/cdi-extender/src/test/java/org/apache/aries/cdi/container/test/MockCdiContainerAndComponents.java (original)
+++ aries/trunk/cdi/cdi-extender/src/test/java/org/apache/aries/cdi/container/test/MockCdiContainerAndComponents.java Sat Apr 14 01:10:27 2018
@@ -14,18 +14,18 @@
 
 package org.apache.aries.cdi.container.test;
 
-import static org.apache.aries.cdi.container.test.TestUtil.getContainerState;
+import static org.apache.aries.cdi.container.test.TestUtil.*;
 
 import java.util.Collections;
 import java.util.HashMap;
 import java.util.Map;
 
-import org.apache.aries.cdi.container.internal.component.OSGiBean;
-import org.apache.aries.cdi.container.internal.container.ContainerDiscovery;
 import org.apache.aries.cdi.container.internal.container.ContainerState;
+import org.apache.aries.cdi.container.internal.container.ExtensionPhase;
+import org.apache.aries.cdi.container.internal.container.Phase;
 import org.apache.aries.cdi.container.internal.model.BeansModel;
-import org.apache.aries.cdi.container.internal.phase.Phase;
-import org.apache.aries.cdi.container.internal.phase.Phase_Configuration;
+import org.apache.aries.cdi.container.internal.model.OSGiBean;
+import org.apache.aries.cdi.container.internal.util.Logs;
 
 public class MockCdiContainerAndComponents implements AutoCloseable {
 
@@ -35,16 +35,14 @@ public class MockCdiContainerAndComponen
 		for (String className : beanClasses) {
 			Class<?> clazz = Class.forName(className);
 
-			beans.put(className, new OSGiBean.Builder(clazz).build());
+			beans.put(className, new OSGiBean.Builder(new Logs.Builder(null).build(), clazz).build());
 		}
 
-		_beansModel = new BeansModel(beans, Collections.emptyList(), Collections.emptyList(), Collections.emptyList());
+		_beansModel = new BeansModel(beans, Collections.emptyList());
 
 		_containerState = getContainerState(_beansModel);
 
-		ContainerDiscovery.discover(_containerState);
-
-		_nextPhase = new Phase_Configuration(_containerState, Collections.emptyList());
+		_nextPhase = new ExtensionPhase(_containerState, null);
 
 		_nextPhase.open();
 	}

Added: aries/trunk/cdi/cdi-extender/src/test/java/org/apache/aries/cdi/container/test/MockConfiguration.java
URL: http://svn.apache.org/viewvc/aries/trunk/cdi/cdi-extender/src/test/java/org/apache/aries/cdi/container/test/MockConfiguration.java?rev=1829115&view=auto
==============================================================================
--- aries/trunk/cdi/cdi-extender/src/test/java/org/apache/aries/cdi/container/test/MockConfiguration.java (added)
+++ aries/trunk/cdi/cdi-extender/src/test/java/org/apache/aries/cdi/container/test/MockConfiguration.java Sat Apr 14 01:10:27 2018
@@ -0,0 +1,132 @@
+/**
+ * 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.io.IOException;
+import java.util.Dictionary;
+import java.util.Enumeration;
+import java.util.HashSet;
+import java.util.Hashtable;
+import java.util.Set;
+import java.util.concurrent.atomic.AtomicLong;
+
+import org.osgi.framework.Constants;
+import org.osgi.framework.ServiceReference;
+import org.osgi.service.cm.Configuration;
+
+public class MockConfiguration implements Configuration {
+
+	public MockConfiguration(String pid, String factoryPid) {
+		_pid = pid;
+		_factoryPid = factoryPid;
+		_properties = new Hashtable<>();
+	}
+
+	@Override
+	public String getPid() {
+		return _pid;
+	}
+
+	@Override
+	public Dictionary<String, Object> getProperties() {
+		return _properties;
+	}
+
+	@Override
+	public Dictionary<String, Object> getProcessedProperties(ServiceReference<?> reference) {
+		return _properties;
+	}
+
+	@Override
+	public void update(Dictionary<String, ?> properties) throws IOException {
+		Dictionary<String, Object> dict = new Hashtable<>();
+		for (Enumeration<String> enu = properties.keys();enu.hasMoreElements();) {
+			String key = enu.nextElement();
+			dict.put(key, properties.get(key));
+		}
+		dict.put(Constants.SERVICE_PID, _pid);
+		if (_factoryPid != null) {
+			dict.put("factory.pid", _factoryPid);
+		}
+		_properties = dict;
+		_changeCount.incrementAndGet();
+	}
+
+	@Override
+	public void delete() throws IOException {
+		_changeCount.get();
+	}
+
+	@Override
+	public String getFactoryPid() {
+		return _factoryPid;
+	}
+
+	@Override
+	public void update() throws IOException {
+		_changeCount.incrementAndGet();
+	}
+
+	@Override
+	public boolean updateIfDifferent(Dictionary<String, ?> properties) throws IOException {
+		_changeCount.incrementAndGet();
+		return false;
+	}
+
+	@Override
+	public void setBundleLocation(String location) {
+		_location = location;
+		_changeCount.incrementAndGet();
+	}
+
+	@Override
+	public String getBundleLocation() {
+		return _location;
+	}
+
+	@Override
+	public long getChangeCount() {
+		return _changeCount.get();
+	}
+
+	@Override
+	public void addAttributes(ConfigurationAttribute... attrs) throws IOException {
+		for (ConfigurationAttribute attr : attrs) {
+			attributes.add(attr);
+		}
+		_changeCount.incrementAndGet();
+	}
+
+	@Override
+	public Set<ConfigurationAttribute> getAttributes() {
+		return attributes;
+	}
+
+	@Override
+	public void removeAttributes(ConfigurationAttribute... attrs) throws IOException {
+		for (ConfigurationAttribute attr : attrs) {
+			attributes.remove(attr);
+		}
+		_changeCount.incrementAndGet();
+	}
+
+	private final Set<ConfigurationAttribute> attributes = new HashSet<>();
+	private final AtomicLong _changeCount = new AtomicLong();
+	private final String _factoryPid;
+	private volatile String _location;
+	private final String _pid;
+	private volatile Dictionary<String, Object> _properties;
+
+}

Modified: aries/trunk/cdi/cdi-extender/src/test/java/org/apache/aries/cdi/container/test/MockInjectionPoint.java
URL: http://svn.apache.org/viewvc/aries/trunk/cdi/cdi-extender/src/test/java/org/apache/aries/cdi/container/test/MockInjectionPoint.java?rev=1829115&r1=1829114&r2=1829115&view=diff
==============================================================================
--- aries/trunk/cdi/cdi-extender/src/test/java/org/apache/aries/cdi/container/test/MockInjectionPoint.java (original)
+++ aries/trunk/cdi/cdi-extender/src/test/java/org/apache/aries/cdi/container/test/MockInjectionPoint.java Sat Apr 14 01:10:27 2018
@@ -15,30 +15,42 @@
 package org.apache.aries.cdi.container.test;
 
 import java.lang.annotation.Annotation;
+import java.lang.reflect.AnnotatedElement;
+import java.lang.reflect.Field;
 import java.lang.reflect.Member;
+import java.lang.reflect.Parameter;
 import java.lang.reflect.Type;
-import java.util.Collections;
 import java.util.Set;
 import java.util.stream.Collectors;
 
 import javax.enterprise.inject.spi.Annotated;
 import javax.enterprise.inject.spi.Bean;
 import javax.enterprise.inject.spi.InjectionPoint;
+import javax.inject.Qualifier;
 
-import org.apache.aries.cdi.container.internal.util.Sets;
+import org.jboss.weld.exceptions.IllegalArgumentException;
 
 public class MockInjectionPoint implements InjectionPoint {
 
-	public MockInjectionPoint(Type type) {
-		_type = type;
-		_annotated = new MockAnnotated(_type);
-		_qualifiers = Collections.emptySet();
+	public MockInjectionPoint(AnnotatedElement annotatedElement) {
+		_annotatedElement = annotatedElement;
+		if (annotatedElement instanceof Parameter) {
+			_annotated = AnnotatedCache.getAnnotatedParameter((Parameter)annotatedElement);
+			_type = ((Parameter)annotatedElement).getParameterizedType();
+			_member = ((Parameter)annotatedElement).getDeclaringExecutable();
+		}
+		else if (annotatedElement instanceof Field) {
+			_annotated = AnnotatedCache.getAnnotatedField((Field)annotatedElement);
+			_type = ((Field)annotatedElement).getGenericType();
+			_member = (Field)_annotatedElement;
+		}
+		else {
+			throw new IllegalArgumentException("InjectionPoints are parameters or fields");
+		}
 	}
 
-	public MockInjectionPoint(Type type, Set<Annotation> qualifiers) {
-		_type = type;
-		_annotated = new MockAnnotated(_type);
-		_qualifiers = qualifiers;
+	protected String getFoo() {
+		return foo;
 	}
 
 	@Override
@@ -48,7 +60,9 @@ public class MockInjectionPoint implemen
 
 	@Override
 	public Set<Annotation> getQualifiers() {
-		return _qualifiers;
+		return _annotated.getAnnotations().stream().filter(
+			ann -> ann.annotationType().isAnnotationPresent(Qualifier.class)
+		).collect(Collectors.toSet());
 	}
 
 	@Override
@@ -58,7 +72,7 @@ public class MockInjectionPoint implemen
 
 	@Override
 	public Member getMember() {
-		return null;
+		return _member;
 	}
 
 	@Override
@@ -78,59 +92,13 @@ public class MockInjectionPoint implemen
 
 	@Override
 	public String toString() {
-		return getClass().getSimpleName() + "[" + _type + "]";
+		return getClass().getSimpleName() + "[" + _annotated.getBaseType() + "]";
 	}
 
-	private final Type _type;
 	private final Annotated _annotated;
-	private final Set<Annotation> _qualifiers;
-
-	private class MockAnnotated implements Annotated {
-
-		public MockAnnotated(Type service) {
-			_service = service;
-		}
-
-		@SuppressWarnings("unchecked")
-		@Override
-		public <T extends Annotation> T getAnnotation(Class<T> annotationType) {
-			return _qualifiers.stream().filter(
-				ann -> ann.annotationType().equals(annotationType)
-			).map(ann -> (T)ann).findFirst().orElse(null);
-		}
-
-		@Override
-		public Set<Annotation> getAnnotations() {
-			return _qualifiers;
-		}
-
-		@SuppressWarnings("unchecked")
-		@Override
-		public <T extends Annotation> Set<T> getAnnotations(Class<T> annotationType) {
-			return _qualifiers.stream().filter(
-				ann -> ann.annotationType().equals(annotationType)
-			).map(ann -> (T)ann).collect(Collectors.toSet());
-		}
-
-		@Override
-		public Type getBaseType() {
-			return _service;
-		}
-
-		@Override
-		public Set<Type> getTypeClosure() {
-			return Sets.hashSet(_service, Object.class);
-		}
-
-		@Override
-		public boolean isAnnotationPresent(Class<? extends Annotation> annotationType) {
-			return _qualifiers.stream().filter(
-				ann -> ann.annotationType().equals(annotationType)
-			).findFirst().isPresent();
-		}
-
-		private final Type _service;
-
-	}
+	private final AnnotatedElement _annotatedElement;
+	private final String foo = "bar";
+	private final Member _member;
+	private final Type _type;
 
 }