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 2017/09/05 22:01:15 UTC

svn commit: r1807424 [3/8] - 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/...

Modified: aries/trunk/cdi/cdi-extender/src/main/java/org/apache/aries/cdi/container/internal/model/Constants.java
URL: http://svn.apache.org/viewvc/aries/trunk/cdi/cdi-extender/src/main/java/org/apache/aries/cdi/container/internal/model/Constants.java?rev=1807424&r1=1807423&r2=1807424&view=diff
==============================================================================
--- aries/trunk/cdi/cdi-extender/src/main/java/org/apache/aries/cdi/container/internal/model/Constants.java (original)
+++ aries/trunk/cdi/cdi-extender/src/main/java/org/apache/aries/cdi/container/internal/model/Constants.java Tue Sep  5 22:01:11 2017
@@ -28,22 +28,26 @@ public class Constants {
 	public static final Set<String> CDI_URIS = Sets.immutableHashSet(CDI10_URI);
 
 	public static final String ARRAY_ELEMENT = "array";
-	public static final String BEAN_CLASS_ATTRIBUTE = "beanClass";
-	public static final String BEAN_ELEMENT = "bean";
-	public static final String BEANS_ELEMENT = "beans";
+	public static final String CARDINALITY_ATTRIBUTE = "cardinality";
 	public static final String CLASS_ATTRIBUTE = "class";
+	public static final String COMPONENT_ELEMENT = "component";
 	public static final String CONFIGURATION_ELEMENT = "configuration";
+	public static final String CONFIGURATION_PID_ATTRIBUTE = "configuration-pid";
+	public static final String CONFIGURATION_POLICY_ATTRIBUTE = "configuration-policy";
 	public static final String INTERFACE_ATTRIBUTE = "interface";
 	public static final String LIST_ELEMENT = "list";
 	public static final String NAME_ATTRIBUTE = "name";
-	public static final String PID_ATTRIBUTE = "pid";
+	public static final String POLICY_ATTRIBUTE = "policy";
+	public static final String POLICY_OPTION_ATTRIBUTE = "policy-option";
 	public static final String PROPERTY_ELEMENT = "property";
 	public static final String PROVIDE_ELEMENT = "provide";
 	public static final String REFERENCE_ELEMENT = "reference";
-	public static final String REQUIRED_ATTRIBUTE = "required";
-	public static final String SERVICE_ELEMENT = "service";
+	public static final String SCOPE_ATTRIBUTE= "scope";
+	public static final String SERVICE_ATTRIBUTE = "service";
+	public static final String SERVICE_SCOPE_ATTRIBUTE = "service-scope";
 	public static final String SET_ELEMENT = "set";
 	public static final String TARGET_ATTRIBUTE = "target";
+	public static final String TYPE_ATTRIBUTE = "type";
 	public static final String VALUE_ATTRIBUTE = "value";
 	public static final String VALUE_ELEMENT = "value";
 	public static final String VALUE_TYPE_ATTRIBUTE = "value-type";

Copied: aries/trunk/cdi/cdi-extender/src/main/java/org/apache/aries/cdi/container/internal/model/Context.java (from r1806482, aries/trunk/cdi/cdi-extender/src/main/java/org/apache/aries/cdi/container/internal/container/Phase.java)
URL: http://svn.apache.org/viewvc/aries/trunk/cdi/cdi-extender/src/main/java/org/apache/aries/cdi/container/internal/model/Context.java?p2=aries/trunk/cdi/cdi-extender/src/main/java/org/apache/aries/cdi/container/internal/model/Context.java&p1=aries/trunk/cdi/cdi-extender/src/main/java/org/apache/aries/cdi/container/internal/container/Phase.java&r1=1806482&r2=1807424&rev=1807424&view=diff
==============================================================================
--- aries/trunk/cdi/cdi-extender/src/main/java/org/apache/aries/cdi/container/internal/container/Phase.java (original)
+++ aries/trunk/cdi/cdi-extender/src/main/java/org/apache/aries/cdi/container/internal/model/Context.java Tue Sep  5 22:01:11 2017
@@ -12,12 +12,17 @@
  * limitations under the License.
  */
 
-package org.apache.aries.cdi.container.internal.container;
+package org.apache.aries.cdi.container.internal.model;
 
-public interface Phase {
+import org.osgi.framework.ServiceObjects;
+import org.osgi.framework.ServiceReference;
 
-	public void close();
+public abstract class Context {
 
-	public void open();
+	public abstract <T> T getService(ServiceReference<T> reference);
+
+	public abstract <T> ServiceObjects<T> getServiceObjects(ServiceReference<T> reference);
+
+	public abstract <T> boolean ungetService(ServiceReference<T> reference);
 
 }

Copied: aries/trunk/cdi/cdi-extender/src/main/java/org/apache/aries/cdi/container/internal/model/Model.java (from r1806482, aries/trunk/cdi/cdi-extender/src/main/java/org/apache/aries/cdi/container/internal/model/AbstractModel.java)
URL: http://svn.apache.org/viewvc/aries/trunk/cdi/cdi-extender/src/main/java/org/apache/aries/cdi/container/internal/model/Model.java?p2=aries/trunk/cdi/cdi-extender/src/main/java/org/apache/aries/cdi/container/internal/model/Model.java&p1=aries/trunk/cdi/cdi-extender/src/main/java/org/apache/aries/cdi/container/internal/model/AbstractModel.java&r1=1806482&r2=1807424&rev=1807424&view=diff
==============================================================================
--- aries/trunk/cdi/cdi-extender/src/main/java/org/apache/aries/cdi/container/internal/model/AbstractModel.java (original)
+++ aries/trunk/cdi/cdi-extender/src/main/java/org/apache/aries/cdi/container/internal/model/Model.java Tue Sep  5 22:01:11 2017
@@ -16,9 +16,9 @@ package org.apache.aries.cdi.container.i
 
 import org.xml.sax.Attributes;
 
-public class AbstractModel {
+public class Model {
 
-	boolean getBoolean(String uri, String localName, Attributes attributes, boolean defaultValue) {
+	public static boolean getBoolean(String uri, String localName, Attributes attributes, boolean defaultValue) {
 		String value = getValue(uri, localName, attributes);
 
 		if (value == null) {
@@ -28,7 +28,11 @@ public class AbstractModel {
 		return Boolean.parseBoolean(value);
 	}
 
-	String getValue(String uri, String localName, Attributes attributes) {
+	public static String getValue(String uri, String localName, Attributes attributes) {
+		return getValue(uri, localName, attributes, "");
+	}
+
+	public static String getValue(String uri, String localName, Attributes attributes, String defaultValue) {
 		String value = attributes.getValue(uri, localName);
 
 		if (value == null) {
@@ -39,7 +43,29 @@ public class AbstractModel {
 			value = value.trim();
 		}
 
+		if (value == null) {
+			return defaultValue;
+		}
+
 		return value;
 	}
 
+	public static String[] getValues(String uri, String localName, Attributes attributes) {
+		return getValues(uri, localName, attributes, new String[0]);
+	}
+
+	public static String[] getValues(String uri, String localName, Attributes attributes, String[] defaultValue) {
+		String value = getValue(uri, localName, attributes, "");
+
+		if (value.length() == 0) {
+			return defaultValue;
+		}
+
+		return value.split("\\s+");
+	}
+
+	private Model() {
+		// TODO Auto-generated constructor stub
+	}
+
 }

Modified: aries/trunk/cdi/cdi-extender/src/main/java/org/apache/aries/cdi/container/internal/model/OSGiBeansHandler.java
URL: http://svn.apache.org/viewvc/aries/trunk/cdi/cdi-extender/src/main/java/org/apache/aries/cdi/container/internal/model/OSGiBeansHandler.java?rev=1807424&r1=1807423&r2=1807424&view=diff
==============================================================================
--- aries/trunk/cdi/cdi-extender/src/main/java/org/apache/aries/cdi/container/internal/model/OSGiBeansHandler.java (original)
+++ aries/trunk/cdi/cdi-extender/src/main/java/org/apache/aries/cdi/container/internal/model/OSGiBeansHandler.java Tue Sep  5 22:01:11 2017
@@ -15,9 +15,10 @@
 package org.apache.aries.cdi.container.internal.model;
 
 import static org.apache.aries.cdi.container.internal.model.Constants.ARRAY_ELEMENT;
-import static org.apache.aries.cdi.container.internal.model.Constants.BEAN_ELEMENT;
-import static org.apache.aries.cdi.container.internal.model.Constants.CDI_URIS;
 import static org.apache.aries.cdi.container.internal.model.Constants.CLASS_ATTRIBUTE;
+import static org.apache.aries.cdi.container.internal.model.Constants.CDI10_URI;
+import static org.apache.aries.cdi.container.internal.model.Constants.CDI_URIS;
+import static org.apache.aries.cdi.container.internal.model.Constants.COMPONENT_ELEMENT;
 import static org.apache.aries.cdi.container.internal.model.Constants.CONFIGURATION_ELEMENT;
 import static org.apache.aries.cdi.container.internal.model.Constants.INTERFACE_ATTRIBUTE;
 import static org.apache.aries.cdi.container.internal.model.Constants.LIST_ELEMENT;
@@ -25,30 +26,37 @@ import static org.apache.aries.cdi.conta
 import static org.apache.aries.cdi.container.internal.model.Constants.PROPERTY_ELEMENT;
 import static org.apache.aries.cdi.container.internal.model.Constants.PROVIDE_ELEMENT;
 import static org.apache.aries.cdi.container.internal.model.Constants.REFERENCE_ELEMENT;
-import static org.apache.aries.cdi.container.internal.model.Constants.SERVICE_ELEMENT;
+import static org.apache.aries.cdi.container.internal.model.Constants.SERVICE_ATTRIBUTE;
 import static org.apache.aries.cdi.container.internal.model.Constants.SET_ELEMENT;
+import static org.apache.aries.cdi.container.internal.model.Constants.TYPE_ATTRIBUTE;
 import static org.apache.aries.cdi.container.internal.model.Constants.VALUE_ATTRIBUTE;
 import static org.apache.aries.cdi.container.internal.model.Constants.VALUE_ELEMENT;
 import static org.apache.aries.cdi.container.internal.model.Constants.VALUE_TYPE_ATTRIBUTE;
 
 import java.net.URL;
-import java.util.ArrayList;
 import java.util.Formatter;
+import java.util.HashMap;
 import java.util.List;
+import java.util.Map;
 
+import org.apache.aries.cdi.container.internal.component.ComponentModel;
+import org.apache.aries.cdi.container.internal.configuration.ConfigurationModel;
+import org.apache.aries.cdi.container.internal.reference.ReferenceModel;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
 import org.xml.sax.Attributes;
 import org.xml.sax.SAXException;
 import org.xml.sax.helpers.DefaultHandler;
 
 public class OSGiBeansHandler extends DefaultHandler {
 
-	public OSGiBeansHandler(List<URL> beanDescriptorURLs) {
+	public OSGiBeansHandler(List<URL> beanDescriptorURLs, ClassLoader classLoader) {
 		_beanDescriptorURLs = beanDescriptorURLs;
+		_classLoader = classLoader;
 	}
 
 	public BeansModel createBeansModel() {
-		return new BeansModel(
-			_beanClasses, _configurationModels, _referenceModels, _serviceModels, _beanDescriptorURLs);
+		return new BeansModel(_components, _beanDescriptorURLs);
 	}
 
 	@Override
@@ -65,14 +73,31 @@ public class OSGiBeansHandler extends De
 		if (matches(ARRAY_ELEMENT, uri, localName) && (_propertyValue == null)) {
 			_collectionType = CollectionType.ARRAY;
 		}
-		if (matches(BEAN_ELEMENT, uri, localName)) {
-			_beanClass = attributes.getValue(CLASS_ATTRIBUTE).trim();
-			if (!_beanClasses.contains(_beanClass)) {
-				_beanClasses.add(_beanClass);
+		if (matches(COMPONENT_ELEMENT, uri, localName)) {
+			try {
+				Class<?> clazz = _classLoader.loadClass(
+					Model.getValue(CDI10_URI, CLASS_ATTRIBUTE, attributes));
+
+				_componentModel = new ComponentModel.Builder(clazz).attributes(attributes);
+			}
+			catch (ClassNotFoundException cnfe) {
+				if (_log.isErrorEnabled()) {
+					_log.error("CDIe - {}", cnfe.getMessage(), cnfe);
+				}
 			}
 		}
 		if (matches(CONFIGURATION_ELEMENT, uri, localName)) {
-			_configurationModel = new ConfigurationModel(attributes);
+			try {
+				Class<?> clazz = _classLoader.loadClass(
+					Model.getValue(CDI10_URI, TYPE_ATTRIBUTE, attributes));
+
+				_componentModel.configuration(new ConfigurationModel.Builder(clazz).attributes(attributes).build());
+			}
+			catch (ClassNotFoundException cnfe) {
+				if (_log.isErrorEnabled()) {
+					_log.error("CDIe - {}", cnfe.getMessage(), cnfe);
+				}
+			}
 		}
 		if (matches(LIST_ELEMENT, uri, localName) && (_propertyValue == null)) {
 			_collectionType = CollectionType.LIST;
@@ -93,12 +118,20 @@ public class OSGiBeansHandler extends De
 		}
 		if (matches(PROVIDE_ELEMENT, uri, localName)) {
 			String value = attributes.getValue(INTERFACE_ATTRIBUTE).trim();
-			_serviceModel.addProvide(value);		}
-		if (matches(REFERENCE_ELEMENT, uri, localName)) {
-			_referenceModel = new ReferenceModel(attributes);
+			_componentModel.provide(value);
 		}
-		if (matches(SERVICE_ELEMENT, uri, localName)) {
-			_serviceModel = new ServiceModel(_beanClass);
+		if (matches(REFERENCE_ELEMENT, uri, localName)) {
+			try {
+				Class<?> clazz = _classLoader.loadClass(
+					Model.getValue(CDI10_URI, SERVICE_ATTRIBUTE, attributes));
+
+				_referenceModel = new ReferenceModel.Builder(attributes).service(clazz).build();
+			}
+			catch (ClassNotFoundException cnfe) {
+				if (_log.isErrorEnabled()) {
+					_log.error("CDIe - {}", cnfe.getMessage(), cnfe);
+				}
+			}
 		}
 		if (matches(SET_ELEMENT, uri, localName) && (_propertyValue == null)) {
 			_collectionType = CollectionType.SET;
@@ -113,9 +146,10 @@ public class OSGiBeansHandler extends De
 		if (matches(ARRAY_ELEMENT, uri, localName)) {
 			_collectionType = null;
 		}
-		if (matches(CONFIGURATION_ELEMENT, uri, localName)) {
-			_configurationModels.add(_configurationModel);
-			_configurationModel = null;
+		if (matches(COMPONENT_ELEMENT, uri, localName)) {
+			ComponentModel componentModel = _componentModel.build();
+			_components.put(componentModel.getBeanClass().getName(), componentModel);
+			_componentModel = null;
 		}
 		if (matches(LIST_ELEMENT, uri, localName)) {
 			_collectionType = null;
@@ -127,7 +161,7 @@ public class OSGiBeansHandler extends De
 			if (_propertyValue != null) {
 				try (Formatter f = new Formatter()) {
 					f.format("%s:%s=%s", _propertyName, _propertyType, _propertyValue);
-					_serviceModel.addProperty(f.toString());
+					_componentModel.property(f.toString());
 				}
 			}
 			_propertySB = null;
@@ -136,14 +170,9 @@ public class OSGiBeansHandler extends De
 			_propertyValue = null;
 		}
 		if (matches(REFERENCE_ELEMENT, uri, localName)) {
-			_referenceModels.add(_referenceModel);
+			_componentModel.reference(_referenceModel);
 			_referenceModel = null;
 		}
-		if (matches(SERVICE_ELEMENT, uri, localName)) {
-			_serviceModels.add(_serviceModel);
-			_serviceModel = null;
-			_beanClass = null;
-		}
 		if (matches(SET_ELEMENT, uri, localName)) {
 			_collectionType = null;
 		}
@@ -167,7 +196,7 @@ public class OSGiBeansHandler extends De
 			sb.append("=");
 			sb.append(_propertySB.toString().trim());
 
-			_serviceModel.addProperty(sb.toString());
+			_componentModel.property(sb.toString());
 			_propertySB = null;
 		}
 	}
@@ -183,19 +212,18 @@ public class OSGiBeansHandler extends De
 		ARRAY, LIST, SET
 	}
 
-	private String _beanClass;
-	private final List<String> _beanClasses = new ArrayList<String>();
+	private final static Logger _log = LoggerFactory.getLogger(
+		OSGiBeansHandler.class);
+
+	private final ClassLoader _classLoader;
+	private final Map<String, ComponentModel> _components = new HashMap<>();
 	private final List<URL> _beanDescriptorURLs;
-	private ConfigurationModel _configurationModel;
-	private final List<ConfigurationModel> _configurationModels = new ArrayList<>();
 	private String _propertyName;
 	private StringBuilder _propertySB;
 	private String _propertyType;
 	private String _propertyValue;
 	private CollectionType _collectionType;
 	private ReferenceModel _referenceModel;
-	private final List<ReferenceModel> _referenceModels = new ArrayList<>();
-	private ServiceModel _serviceModel;
-	private final List<ServiceModel> _serviceModels = new ArrayList<>();
+	private ComponentModel.Builder _componentModel;
 
 }

Added: aries/trunk/cdi/cdi-extender/src/main/java/org/apache/aries/cdi/container/internal/model/ObserverMethodAnnotated.java
URL: http://svn.apache.org/viewvc/aries/trunk/cdi/cdi-extender/src/main/java/org/apache/aries/cdi/container/internal/model/ObserverMethodAnnotated.java?rev=1807424&view=auto
==============================================================================
--- aries/trunk/cdi/cdi-extender/src/main/java/org/apache/aries/cdi/container/internal/model/ObserverMethodAnnotated.java (added)
+++ aries/trunk/cdi/cdi-extender/src/main/java/org/apache/aries/cdi/container/internal/model/ObserverMethodAnnotated.java Tue Sep  5 22:01:11 2017
@@ -0,0 +1,58 @@
+package org.apache.aries.cdi.container.internal.model;
+
+import java.lang.annotation.Annotation;
+import java.lang.reflect.Type;
+import java.util.Set;
+
+import javax.enterprise.inject.spi.Annotated;
+import javax.enterprise.inject.spi.ObserverMethod;
+
+import org.apache.aries.cdi.container.internal.util.Sets;
+import org.osgi.service.cdi.annotations.ServiceEvent;
+
+public class ObserverMethodAnnotated implements Annotated {
+
+	public ObserverMethodAnnotated(ObserverMethod<ServiceEvent<?>> observerMethod) {
+		_observerMethod = observerMethod;
+		_qualifiers = _observerMethod.getObservedQualifiers();
+	}
+
+	@Override
+	public boolean isAnnotationPresent(Class<? extends Annotation> annotationType) {
+		for (Annotation annotation : _qualifiers) {
+			if (annotationType.isInstance(annotation)) {
+				return true;
+			}
+		}
+		return false;
+	}
+
+	@Override
+	public Set<Type> getTypeClosure() {
+		return Sets.immutableHashSet(getBaseType());
+	}
+
+	@Override
+	public Type getBaseType() {
+		return _observerMethod.getObservedType();
+	}
+
+	@Override
+	public Set<Annotation> getAnnotations() {
+		return _qualifiers;
+	}
+
+	@Override
+	public <T extends Annotation> T getAnnotation(Class<T> annotationType) {
+		for (Annotation annotation : _qualifiers) {
+			if (annotationType.isInstance(annotation)) {
+				return (T)annotation;
+			}
+		}
+		return null;
+	}
+
+	private final ObserverMethod<ServiceEvent<?>> _observerMethod;
+	private final Set<Annotation> _qualifiers;
+
+}
\ No newline at end of file

Added: aries/trunk/cdi/cdi-extender/src/main/java/org/apache/aries/cdi/container/internal/model/Registrator.java
URL: http://svn.apache.org/viewvc/aries/trunk/cdi/cdi-extender/src/main/java/org/apache/aries/cdi/container/internal/model/Registrator.java?rev=1807424&view=auto
==============================================================================
--- aries/trunk/cdi/cdi-extender/src/main/java/org/apache/aries/cdi/container/internal/model/Registrator.java (added)
+++ aries/trunk/cdi/cdi-extender/src/main/java/org/apache/aries/cdi/container/internal/model/Registrator.java Tue Sep  5 22:01:11 2017
@@ -0,0 +1,69 @@
+/**
+ * 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.model;
+
+import java.util.Dictionary;
+import java.util.Hashtable;
+import java.util.List;
+import java.util.concurrent.CopyOnWriteArrayList;
+
+import org.osgi.framework.ServiceRegistration;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+public abstract class Registrator<T> {
+
+	public abstract void registerService(String[] classNames, T service, Dictionary<String, ?> properties);
+
+	public void registerService(T service, Object... keyValues) {
+		if ((keyValues.length % 2) != 0) throw new IllegalArgumentException("keyValues must be [String, Object]+");
+
+		Dictionary<String, Object> properties = new Hashtable<>();
+
+		if (keyValues.length > 0) {
+			for (int i = 0; i < keyValues.length; i += 2) {
+				properties.put(String.valueOf(keyValues[i]), keyValues[i + 1]);
+			}
+		}
+
+		registerService(null, service, properties);
+	}
+
+	public int size() {
+		return registrations.size();
+	}
+
+	public void close() {
+		registrations.removeIf(
+			r -> {
+				try {
+					r.unregister();
+				}
+				catch (IllegalStateException ise) {
+					if (_log.isTraceEnabled()) {
+						_log.trace("Service already unregistered {}", r);
+					}
+				}
+
+				return true;
+			}
+		);
+	}
+
+	private static final Logger _log = LoggerFactory.getLogger(Registrator.class);
+
+	protected final List<ServiceRegistration<?>> registrations = new CopyOnWriteArrayList<>();
+
+}

Added: aries/trunk/cdi/cdi-extender/src/main/java/org/apache/aries/cdi/container/internal/model/ServiceEventImpl.java
URL: http://svn.apache.org/viewvc/aries/trunk/cdi/cdi-extender/src/main/java/org/apache/aries/cdi/container/internal/model/ServiceEventImpl.java?rev=1807424&view=auto
==============================================================================
--- aries/trunk/cdi/cdi-extender/src/main/java/org/apache/aries/cdi/container/internal/model/ServiceEventImpl.java (added)
+++ aries/trunk/cdi/cdi-extender/src/main/java/org/apache/aries/cdi/container/internal/model/ServiceEventImpl.java Tue Sep  5 22:01:11 2017
@@ -0,0 +1,55 @@
+/**
+ * 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.model;
+
+import org.osgi.service.cdi.annotations.ServiceEvent;
+
+public class ServiceEventImpl<T> implements ServiceEvent<T> {
+
+	public static enum Event { ADDING, MODIFIED, REMOVED }
+
+	private final T _t;
+	private final ServiceEventImpl.Event _event;
+
+	public ServiceEventImpl(T t, ServiceEventImpl.Event event) {
+		_t = t;
+		_event = event;
+	}
+
+	@Override
+	public ServiceEvent<T> adding(Consumer<T> consumer) {
+		if (_event == Event.ADDING) {
+			consumer.accept(_t);
+		};
+		return this;
+	}
+
+	@Override
+	public ServiceEvent<T> modified(Consumer<T> consumer) {
+		if (_event == Event.MODIFIED) {
+			consumer.accept(_t);
+		}
+		return this;
+	}
+
+	@Override
+	public ServiceEvent<T> removed(Consumer<T> consumer) {
+		if (_event == Event.REMOVED) {
+			consumer.accept(_t);
+		}
+		return this;
+	}
+
+}
\ No newline at end of file

Copied: aries/trunk/cdi/cdi-extender/src/main/java/org/apache/aries/cdi/container/internal/model/Tracker.java (from r1806482, aries/trunk/cdi/cdi-extender/src/main/java/org/apache/aries/cdi/container/internal/model/ServiceModel.java)
URL: http://svn.apache.org/viewvc/aries/trunk/cdi/cdi-extender/src/main/java/org/apache/aries/cdi/container/internal/model/Tracker.java?p2=aries/trunk/cdi/cdi-extender/src/main/java/org/apache/aries/cdi/container/internal/model/Tracker.java&p1=aries/trunk/cdi/cdi-extender/src/main/java/org/apache/aries/cdi/container/internal/model/ServiceModel.java&r1=1806482&r2=1807424&rev=1807424&view=diff
==============================================================================
--- aries/trunk/cdi/cdi-extender/src/main/java/org/apache/aries/cdi/container/internal/model/ServiceModel.java (original)
+++ aries/trunk/cdi/cdi-extender/src/main/java/org/apache/aries/cdi/container/internal/model/Tracker.java Tue Sep  5 22:01:11 2017
@@ -14,36 +14,34 @@
 
 package org.apache.aries.cdi.container.internal.model;
 
-import java.util.ArrayList;
 import java.util.List;
+import java.util.concurrent.CopyOnWriteArrayList;
 
-public class ServiceModel {
+import org.apache.aries.cdi.container.internal.reference.ReferenceCallback;
+import org.osgi.util.tracker.ServiceTracker;
 
-	public ServiceModel(String beanClass) {
-		_beanClass = beanClass;
-	}
+public abstract class Tracker {
 
-	public void addProvide(String className) {
-		_provides.add(className);
-	}
+	public abstract <T> void track(String targetFilter, ReferenceCallback callback);
 
-	public void addProperty(String property) {
-		_properties.add(property);
+	public int size() {
+		return trackers.size();
 	}
 
-	public String getBeanClass() {
-		return _beanClass;
-	}
+	public void close() {
+		trackers.removeIf(
+			t -> {
+				t.close();
 
-	public String[] getProperties() {
-		return _properties.toArray(new String[0]);
+				return true;
+			}
+		);
 	}
 
-	public List<String> getProvides() {
-		return _provides;
+	public void open() {
+		trackers.stream().forEach(t -> t.open());
 	}
 
-	private final String _beanClass;
-	private List<String> _properties = new ArrayList<>();
-	private List<String> _provides = new ArrayList<>();
+	protected final List<ServiceTracker<Object, ?>> trackers = new CopyOnWriteArrayList<>();
+
 }

Copied: aries/trunk/cdi/cdi-extender/src/main/java/org/apache/aries/cdi/container/internal/phase/Phase.java (from r1806482, aries/trunk/cdi/cdi-extender/src/main/java/org/apache/aries/cdi/container/internal/container/Phase.java)
URL: http://svn.apache.org/viewvc/aries/trunk/cdi/cdi-extender/src/main/java/org/apache/aries/cdi/container/internal/phase/Phase.java?p2=aries/trunk/cdi/cdi-extender/src/main/java/org/apache/aries/cdi/container/internal/phase/Phase.java&p1=aries/trunk/cdi/cdi-extender/src/main/java/org/apache/aries/cdi/container/internal/container/Phase.java&r1=1806482&r2=1807424&rev=1807424&view=diff
==============================================================================
--- aries/trunk/cdi/cdi-extender/src/main/java/org/apache/aries/cdi/container/internal/container/Phase.java (original)
+++ aries/trunk/cdi/cdi-extender/src/main/java/org/apache/aries/cdi/container/internal/phase/Phase.java Tue Sep  5 22:01:11 2017
@@ -12,7 +12,7 @@
  * limitations under the License.
  */
 
-package org.apache.aries.cdi.container.internal.container;
+package org.apache.aries.cdi.container.internal.phase;
 
 public interface Phase {
 

Added: aries/trunk/cdi/cdi-extender/src/main/java/org/apache/aries/cdi/container/internal/phase/Phase_Configuration.java
URL: http://svn.apache.org/viewvc/aries/trunk/cdi/cdi-extender/src/main/java/org/apache/aries/cdi/container/internal/phase/Phase_Configuration.java?rev=1807424&view=auto
==============================================================================
--- aries/trunk/cdi/cdi-extender/src/main/java/org/apache/aries/cdi/container/internal/phase/Phase_Configuration.java (added)
+++ aries/trunk/cdi/cdi-extender/src/main/java/org/apache/aries/cdi/container/internal/phase/Phase_Configuration.java Tue Sep  5 22:01:11 2017
@@ -0,0 +1,245 @@
+/**
+ * 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 java.util.Arrays;
+import java.util.Collection;
+import java.util.LinkedHashMap;
+import java.util.Map;
+import java.util.concurrent.atomic.AtomicInteger;
+import java.util.concurrent.locks.Lock;
+import java.util.concurrent.locks.ReentrantLock;
+import java.util.function.Consumer;
+
+import javax.enterprise.inject.spi.Extension;
+
+import org.apache.aries.cdi.container.internal.component.ComponentModel;
+import org.apache.aries.cdi.container.internal.configuration.ConfigurationCallback;
+import org.apache.aries.cdi.container.internal.configuration.ConfigurationManagedService;
+import org.apache.aries.cdi.container.internal.container.ContainerState;
+import org.jboss.weld.bootstrap.spi.Metadata;
+import org.osgi.framework.Constants;
+import org.osgi.service.cdi.CdiEvent;
+import org.osgi.service.cdi.annotations.Configuration;
+import org.osgi.service.cdi.annotations.ConfigurationPolicy;
+
+public class Phase_Configuration implements Phase {
+
+	public Phase_Configuration(
+		ContainerState containerState,
+		Collection<Metadata<Extension>> extensions) {
+
+		_containerState = containerState;
+		_extensions = extensions;
+
+		_componentModels = _containerState.beansModel().getComponentModels();
+	}
+
+	@Override
+	public void close() {
+		_lock.lock();
+
+		try {
+			if (_nextPhase != null) {
+				_nextPhase.close();
+
+				_nextPhase = null;
+			}
+
+			_containerState.managedServiceRegistrator().close();
+
+			_containerState.configurationCallbacks().clear();
+		}
+		finally {
+			_lock.unlock();
+		}
+	}
+
+	@Override
+
+	public void open() {
+		_lock.lock();
+
+		try {
+			_containerState.fire(CdiEvent.Type.WAITING_FOR_CONFIGURATIONS);
+
+			openConfigurations();
+
+			callbacksInit();
+		}
+		finally {
+			_lock.unlock();
+		}
+	}
+
+	boolean callbacksExist() {
+		return _containerState.configurationCallbacks().values().stream().flatMap(
+			entry -> entry.values().stream()
+		).findFirst().isPresent();
+	}
+
+	void callbacksInit() {
+		_containerState.configurationCallbacks().values().stream().flatMap(
+			valueMap -> valueMap.values().stream()
+		).forEach(
+			cc -> cc.init()
+		);
+	}
+
+	boolean callbacksResolved() {
+		return !_containerState.configurationCallbacks().values().stream().flatMap(
+			valueMap -> valueMap.values().stream()
+		).filter(
+			c -> !c.resolved()
+		).findFirst().isPresent();
+	}
+
+	void openConfigurations() {
+		Consumer<ConfigurationCallback> onAdd = cc -> {
+			_lock.lock();
+			try {
+				if (callbacksResolved()) {
+					if ((_nextPhase != null)) {
+						_nextPhase.close();
+						_nextPhase = null;
+					}
+
+					if ((_nextPhase == null)) {
+						_nextPhase = new Phase_Reference(_containerState, _extensions);
+						_nextPhase.open();
+					}
+				}
+			}
+			finally {
+				_lock.unlock();
+			}
+		},
+		onUpdate = cc -> {
+			_lock.lock();
+			try {
+				_nextPhase.close();
+				_nextPhase = new Phase_Reference(_containerState, _extensions);
+				_nextPhase.open();
+			}
+			finally {
+				_lock.unlock();
+			}
+		},
+		onRemove = cc -> {
+			_lock.lock();
+			try {
+				if (_nextPhase != null) {
+					_nextPhase.close();
+				}
+				if (!callbacksResolved()) {
+					_nextPhase = null;
+					_containerState.fire(CdiEvent.Type.WAITING_FOR_CONFIGURATIONS);
+				}
+				else {
+					_nextPhase = new Phase_Reference(_containerState, _extensions);
+					_nextPhase.open();
+				}
+			}
+			finally {
+				_lock.unlock();
+			}
+		};
+
+		_componentModels.stream().forEach(
+			componentModel -> openConfigurations(componentModel, onAdd, onUpdate, onRemove)
+		);
+	}
+
+	void openConfigurations(
+		ComponentModel componentModel,
+		Consumer<ConfigurationCallback> onAdd,
+		Consumer<ConfigurationCallback> onUpdate,
+		Consumer<ConfigurationCallback> onRemove) {
+
+		_lock.lock();
+
+		try {
+			componentModel.getConfigurations().stream().forEach(
+				configurationModel -> Arrays.stream(configurationModel.getPid()).distinct().forEach(
+					pid -> {
+						if (Configuration.NAME.equals(pid)) {
+							pid = componentModel.getName();
+						}
+
+						registerConfigurationCallback(
+							componentModel, pid, onAdd, onUpdate, onRemove, configurationModel.getConfigurationPolicy());
+					}
+				)
+			);
+
+			if (!_containerState.configurationCallbacks().containsKey(componentModel)) {
+
+				// Add a default callback for every Component using it's name as pid.
+
+				registerConfigurationCallback(
+					componentModel, componentModel.getName(), onAdd, onUpdate, onRemove, ConfigurationPolicy.OPTIONAL);
+			}
+		}
+		catch (Exception e) {
+			e.printStackTrace();
+		}
+		finally {
+			_lock.unlock();
+		}
+	}
+
+	void registerConfigurationCallback(
+		ComponentModel componentModel,
+		String pid,
+		Consumer<ConfigurationCallback> onAdd,
+		Consumer<ConfigurationCallback> onUpdate,
+		Consumer<ConfigurationCallback> onRemove,
+		ConfigurationPolicy policy) {
+
+		Map<String, ConfigurationCallback> valueMap = _containerState.configurationCallbacks().computeIfAbsent(
+			componentModel, k -> new LinkedHashMap<>());
+
+		ConfigurationCallback callback = valueMap.get(pid);
+
+		if ((callback == null) ||
+			(policy == ConfigurationPolicy.REQUIRE)) {
+
+			callback = new ConfigurationCallback.Builder().onAdd(
+				onAdd
+			).onRemove(
+				onRemove
+			).onUpdate(
+				onUpdate
+			).pid(
+				pid
+			).policy(
+				policy
+			).build();
+
+			valueMap.put(pid, callback);
+		}
+
+		_containerState.managedServiceRegistrator().registerService(
+			new ConfigurationManagedService(pid, callback),
+			Constants.SERVICE_PID, pid, "component.id", _counter.incrementAndGet());
+	}
+
+	private final Collection<ComponentModel> _componentModels;
+	private final ContainerState _containerState;
+	private final AtomicInteger _counter = new AtomicInteger();
+	private final Collection<Metadata<Extension>> _extensions;
+	private final Lock _lock = new ReentrantLock();
+	private volatile Phase _nextPhase;
+}
\ No newline at end of file

Copied: aries/trunk/cdi/cdi-extender/src/main/java/org/apache/aries/cdi/container/internal/phase/Phase_Extension.java (from r1806482, aries/trunk/cdi/cdi-extender/src/main/java/org/apache/aries/cdi/container/internal/container/Phase_Extension.java)
URL: http://svn.apache.org/viewvc/aries/trunk/cdi/cdi-extender/src/main/java/org/apache/aries/cdi/container/internal/phase/Phase_Extension.java?p2=aries/trunk/cdi/cdi-extender/src/main/java/org/apache/aries/cdi/container/internal/phase/Phase_Extension.java&p1=aries/trunk/cdi/cdi-extender/src/main/java/org/apache/aries/cdi/container/internal/container/Phase_Extension.java&r1=1806482&r2=1807424&rev=1807424&view=diff
==============================================================================
--- aries/trunk/cdi/cdi-extender/src/main/java/org/apache/aries/cdi/container/internal/container/Phase_Extension.java (original)
+++ aries/trunk/cdi/cdi-extender/src/main/java/org/apache/aries/cdi/container/internal/phase/Phase_Extension.java Tue Sep  5 22:01:11 2017
@@ -12,7 +12,7 @@
  * limitations under the License.
  */
 
-package org.apache.aries.cdi.container.internal.container;
+package org.apache.aries.cdi.container.internal.phase;
 
 import java.util.Comparator;
 import java.util.List;
@@ -22,9 +22,14 @@ import java.util.concurrent.CopyOnWriteA
 
 import javax.enterprise.inject.spi.Extension;
 
+import org.apache.aries.cdi.container.internal.container.ContainerState;
+import org.apache.aries.cdi.container.internal.extension.ExtensionDependency;
+import org.apache.aries.cdi.container.internal.extension.ExtensionMetadata;
 import org.jboss.weld.bootstrap.spi.Metadata;
 import org.osgi.framework.BundleContext;
 import org.osgi.framework.Filter;
+import org.osgi.framework.FrameworkUtil;
+import org.osgi.framework.InvalidSyntaxException;
 import org.osgi.framework.ServiceReference;
 import org.osgi.framework.wiring.BundleWire;
 import org.osgi.framework.wiring.BundleWiring;
@@ -37,20 +42,20 @@ import org.slf4j.LoggerFactory;
 
 public class Phase_Extension implements Phase {
 
-	public Phase_Extension(CdiContainerState cdiContainerState) {
-		_cdiContainerState = cdiContainerState;
-		_bundleContext = _cdiContainerState.getBundle().getBundleContext();
-		_extensionDependencies = findExtensionDependencies(
-			_cdiContainerState.getBundle().adapt(BundleWiring.class));
+	public Phase_Extension(ContainerState containerState) {
+		_containerState = containerState;
+		_bundleContext = _containerState.bundle().getBundleContext();
+
+		BundleWiring bundleWiring = _containerState.bundle().adapt(BundleWiring.class);
+
+		_extensionDependencies = findExtensionDependencies(bundleWiring);
 		_extensions = new ConcurrentSkipListMap<>(Comparator.reverseOrder());
 
-		_cdiContainerState.setExtensionDependencies(_extensionDependencies);
+		_containerState.setExtensionDependencies(_extensionDependencies);
 	}
 
 	@Override
 	public void close() {
-		_cdiContainerState.fire(CdiEvent.Type.DESTROYING);
-
 		if (_extensionTracker != null) {
 			_extensionTracker.close();
 
@@ -61,32 +66,47 @@ public class Phase_Extension implements
 
 			_nextPhase = null;
 		}
-
-		_cdiContainerState.fire(CdiEvent.Type.DESTROYED);
-
-		_cdiContainerState.close();
 	}
 
 	@Override
 	public void open() {
-		_cdiContainerState.fire(CdiEvent.Type.CREATING);
-
 		if (!_extensionDependencies.isEmpty()) {
-			Filter filter = FilterBuilder.createExtensionFilter(_extensionDependencies);
+			_containerState.fire(CdiEvent.Type.WAITING_FOR_EXTENSIONS);
 
-			_cdiContainerState.fire(CdiEvent.Type.WAITING_FOR_EXTENSIONS, filter.toString());
+			Filter filter = createExtensionFilter(_extensionDependencies);
 
 			_extensionTracker = new ServiceTracker<>(_bundleContext, filter, new ExtensionPhaseCustomizer());
 
 			_extensionTracker.open();
 		}
 		else {
-			_nextPhase = new Phase_Configuration(_cdiContainerState, _extensions);
+			_nextPhase = new Phase_Configuration(_containerState, _extensions.values());
 
 			_nextPhase.open();
 		}
 	}
 
+	Filter createExtensionFilter(List<ExtensionDependency> extentionDependencies) {
+		try {
+			StringBuilder sb = new StringBuilder("(&(objectClass=" + Extension.class.getName() + ")");
+
+			if (extentionDependencies.size() > 1) sb.append("(|");
+
+			for (ExtensionDependency dependency : extentionDependencies) {
+				sb.append(dependency.toString());
+			}
+
+			if (extentionDependencies.size() > 1) sb.append(")");
+
+			sb.append(")");
+
+			return FrameworkUtil.createFilter(sb.toString());
+		}
+		catch (InvalidSyntaxException ise) {
+			throw new RuntimeException(ise);
+		}
+	}
+
 	List<ExtensionDependency> findExtensionDependencies(BundleWiring bundleWiring) {
 		List<ExtensionDependency> extensionDependencies = new CopyOnWriteArrayList<>();
 		List<BundleWire> requiredWires = bundleWiring.getRequiredWires(CdiConstants.CDI_EXTENSION_NAMESPACE);
@@ -110,9 +130,9 @@ public class Phase_Extension implements
 	private static final Logger _log = LoggerFactory.getLogger(Phase_Extension.class);
 
 	private final BundleContext _bundleContext;
-	private final CdiContainerState _cdiContainerState;
-	private final Map<ServiceReference<Extension>, Metadata<Extension>> _extensions;
+	private final ContainerState _containerState;
 	private final List<ExtensionDependency> _extensionDependencies;
+	private final Map<ServiceReference<Extension>, Metadata<Extension>> _extensions;
 	private Phase _nextPhase;
 
 	private ServiceTracker<Extension, ExtensionDependency> _extensionTracker;
@@ -137,7 +157,7 @@ public class Phase_Extension implements
 			}
 
 			if ((trackedDependency != null) && _extensionDependencies.isEmpty()) {
-				_nextPhase = new Phase_Configuration(_cdiContainerState, _extensions);
+				_nextPhase = new Phase_Configuration(_containerState, _extensions.values());
 
 				_nextPhase.open();
 			}
@@ -154,13 +174,8 @@ public class Phase_Extension implements
 
 		@Override
 		public void removedService(ServiceReference<Extension> reference, ExtensionDependency extentionDependency) {
-			if (_extensionDependencies.isEmpty()) {
-				_nextPhase.close();
-
-				_nextPhase = null;
+			_extensionDependencies.add(extentionDependency);
 
-				_cdiContainerState.fire(CdiEvent.Type.WAITING_FOR_EXTENSIONS);
-			}
 			_extensions.remove(reference);
 
 			try {
@@ -172,7 +187,13 @@ public class Phase_Extension implements
 				}
 			}
 
-			_extensionDependencies.add(extentionDependency);
+			if (!_extensionDependencies.isEmpty()) {
+				_nextPhase.close();
+
+				_nextPhase = null;
+
+				_containerState.fire(CdiEvent.Type.WAITING_FOR_EXTENSIONS);
+			}
 		}
 
 	}

Added: aries/trunk/cdi/cdi-extender/src/main/java/org/apache/aries/cdi/container/internal/phase/Phase_Init.java
URL: http://svn.apache.org/viewvc/aries/trunk/cdi/cdi-extender/src/main/java/org/apache/aries/cdi/container/internal/phase/Phase_Init.java?rev=1807424&view=auto
==============================================================================
--- aries/trunk/cdi/cdi-extender/src/main/java/org/apache/aries/cdi/container/internal/phase/Phase_Init.java (added)
+++ aries/trunk/cdi/cdi-extender/src/main/java/org/apache/aries/cdi/container/internal/phase/Phase_Init.java Tue Sep  5 22:01:11 2017
@@ -0,0 +1,89 @@
+/**
+ * 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 java.util.concurrent.locks.Lock;
+import java.util.concurrent.locks.ReentrantLock;
+
+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.model.BeansModel;
+import org.apache.aries.cdi.container.internal.model.BeansModelBuilder;
+import org.osgi.framework.Bundle;
+import org.osgi.framework.wiring.BundleWiring;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+public class Phase_Init implements Phase {
+
+	public Phase_Init(Bundle bundle, ContainerState containerState) {
+		_containerState = containerState;
+
+		BundleWiring bundleWiring = bundle.adapt(BundleWiring.class);
+
+		BeansModel beansModel = new BeansModelBuilder(_containerState.classLoader(), bundleWiring).build();
+
+		_containerState.setBeansModel(beansModel);
+	}
+
+	@Override
+	public void close() {
+		_lock.lock();
+
+		try {
+			_extensionPhase.close();
+
+			_extensionPhase = null;
+		}
+		finally {
+			_lock.unlock();
+		}
+	}
+
+	@Override
+	public void open() {
+		_lock.lock();
+
+		try {
+			if (_log.isDebugEnabled()) {
+				_log.debug("CDIe - Starting discovery phase on {}", _containerState);
+			}
+
+			ContainerDiscovery.discover(_containerState);
+
+			if (_log.isDebugEnabled()) {
+				_log.debug("CDIe - Finished discovery phase on {}", _containerState);
+			}
+
+			if (_log.isDebugEnabled()) {
+				_log.debug("CDIe - Begin extension phase on {}", _containerState);
+			}
+
+			_extensionPhase = new Phase_Extension(_containerState);
+
+			_extensionPhase.open();
+		}
+		finally {
+			_lock.unlock();
+		}
+	}
+
+	private static final Logger _log = LoggerFactory.getLogger(Phase_Init.class);
+
+	private final ContainerState _containerState;
+	private volatile Phase _extensionPhase;
+	private final Lock _lock = new ReentrantLock();
+
+}
\ No newline at end of file

Added: aries/trunk/cdi/cdi-extender/src/main/java/org/apache/aries/cdi/container/internal/phase/Phase_Publish.java
URL: http://svn.apache.org/viewvc/aries/trunk/cdi/cdi-extender/src/main/java/org/apache/aries/cdi/container/internal/phase/Phase_Publish.java?rev=1807424&view=auto
==============================================================================
--- aries/trunk/cdi/cdi-extender/src/main/java/org/apache/aries/cdi/container/internal/phase/Phase_Publish.java (added)
+++ aries/trunk/cdi/cdi-extender/src/main/java/org/apache/aries/cdi/container/internal/phase/Phase_Publish.java Tue Sep  5 22:01:11 2017
@@ -0,0 +1,103 @@
+/**
+ * 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 java.util.Collection;
+
+import javax.enterprise.inject.spi.Extension;
+
+import org.apache.aries.cdi.container.internal.container.ContainerBootstrap;
+import org.apache.aries.cdi.container.internal.container.ContainerState;
+import org.jboss.weld.bootstrap.WeldBootstrap;
+import org.jboss.weld.bootstrap.spi.Metadata;
+import org.jboss.weld.manager.BeanManagerImpl;
+import org.osgi.service.cdi.CdiEvent;
+import org.osgi.service.cdi.annotations.ServiceScope;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+public class Phase_Publish implements Phase {
+
+	public Phase_Publish(
+		ContainerState containerState,
+		Collection<Metadata<Extension>> extensions) {
+
+		_containerState = containerState;
+		_extensions = extensions;
+	}
+
+	@Override
+	public void close() {
+		_containerState.serviceRegistrator().close();
+		_containerState.beanManagerRegistrator().close();
+		_containerState.serviceComponents().clear();
+		_cb.shutdown();
+	}
+
+	@Override
+	public void open() {
+		_containerState.fire(CdiEvent.Type.SATISFIED);
+
+		try {
+			_cb = new ContainerBootstrap(_containerState, _extensions);
+
+			BeanManagerImpl beanManagerImpl = _cb.getBeanManagerImpl();
+			WeldBootstrap bootstrap = _cb.getBootstrap();
+
+			bootstrap.validateBeans();
+			bootstrap.endInitialization();
+
+			_containerState.referenceCallbacks().values().stream().flatMap(
+				map -> map.values().stream()
+			).forEach(
+				callback -> callback.flush()
+			);
+
+			processServices(beanManagerImpl);
+
+			_containerState.beanManagerRegistrator().registerService(beanManagerImpl);
+
+			_containerState.fire(CdiEvent.Type.CREATED);
+		}
+		catch (Exception e) {
+			e.printStackTrace();
+		}
+	}
+
+	private void processServices(BeanManagerImpl beanManagerImpl) {
+		_containerState.serviceComponents().values().stream().filter(
+			serviceDeclaration ->
+				serviceDeclaration.getScope() == ServiceScope.BUNDLE ||
+				serviceDeclaration.getScope() == ServiceScope.PROTOTYPE ||
+				serviceDeclaration.getScope() == ServiceScope.SINGLETON
+		).forEach(
+			s -> {
+				if (_log.isDebugEnabled()) {
+					_log.debug("CDIe - Publishing component {} as '{}' service.", s.getName(), s.getScope());
+				}
+
+				_containerState.serviceRegistrator().registerService(
+					s.getClassNames(), s.getServiceInstance(), s.getServiceProperties());
+			}
+		);
+	}
+
+	private static final Logger _log = LoggerFactory.getLogger(Phase_Publish.class);
+
+	private volatile ContainerBootstrap _cb;
+	private final ContainerState _containerState;
+	private final Collection<Metadata<Extension>> _extensions;
+
+}
\ No newline at end of file

Added: aries/trunk/cdi/cdi-extender/src/main/java/org/apache/aries/cdi/container/internal/phase/Phase_Reference.java
URL: http://svn.apache.org/viewvc/aries/trunk/cdi/cdi-extender/src/main/java/org/apache/aries/cdi/container/internal/phase/Phase_Reference.java?rev=1807424&view=auto
==============================================================================
--- aries/trunk/cdi/cdi-extender/src/main/java/org/apache/aries/cdi/container/internal/phase/Phase_Reference.java (added)
+++ aries/trunk/cdi/cdi-extender/src/main/java/org/apache/aries/cdi/container/internal/phase/Phase_Reference.java Tue Sep  5 22:01:11 2017
@@ -0,0 +1,193 @@
+/**
+ * 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 java.util.Collection;
+import java.util.LinkedHashMap;
+import java.util.Map;
+import java.util.concurrent.locks.Lock;
+import java.util.concurrent.locks.ReentrantLock;
+import java.util.function.Consumer;
+
+import javax.enterprise.inject.spi.Extension;
+import javax.enterprise.inject.spi.ObserverMethod;
+
+import org.apache.aries.cdi.container.internal.component.ComponentModel;
+import org.apache.aries.cdi.container.internal.container.ContainerState;
+import org.apache.aries.cdi.container.internal.reference.ReferenceCallback;
+import org.apache.aries.cdi.container.internal.reference.ReferenceModel;
+import org.jboss.weld.bootstrap.spi.Metadata;
+import org.osgi.framework.InvalidSyntaxException;
+import org.osgi.service.cdi.CdiEvent;
+import org.osgi.service.cdi.annotations.ServiceEvent;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+public class Phase_Reference implements Phase {
+
+	public Phase_Reference(
+		ContainerState containerState,
+		Collection<Metadata<Extension>> extensions) {
+
+		_containerState = containerState;
+		_extensions = extensions;
+
+		_componentModels = _containerState.beansModel().getComponentModels();
+	}
+
+	@Override
+	public void close() {
+		_lock.lock();
+
+		try {
+			if (_nextPhase != null) {
+				_nextPhase.close();
+
+				_nextPhase = null;
+			}
+
+			_containerState.tracker().close();
+
+			_containerState.referenceCallbacks().clear();
+			_containerState.referenceObservers().clear();
+		}
+		finally {
+			_lock.unlock();
+		}
+	}
+
+	@Override
+	public void open() {
+		_lock.lock();
+
+		try {
+			_containerState.fire(CdiEvent.Type.WAITING_FOR_SERVICES);
+
+			openReferences();
+
+			_containerState.tracker().open();
+
+			if (referencesResolved()) {
+				if (_log.isDebugEnabled()) {
+					_log.debug("CDIe - There are no service dependencies. Moving on!");
+				}
+
+				_nextPhase = new Phase_Publish(_containerState, _extensions);
+
+				_nextPhase.open();
+			}
+		}
+		finally {
+			_lock.unlock();
+		}
+	}
+
+	void openReferences() {
+		Consumer<ReferenceCallback> onAdd = r -> {
+			if ((_nextPhase == null) && referencesResolved()) {
+				_nextPhase = new Phase_Publish(_containerState, _extensions);
+				_nextPhase.open();
+			}
+		},
+		onUpdate = r -> {
+			// TODO we may need to handle static greedy references by hard reset of _nextPhase
+		},
+		onRemove = r -> {
+			if ((_nextPhase != null) && !referencesResolved()) {
+				_nextPhase.close();
+				_nextPhase = null;
+				_containerState.fire(CdiEvent.Type.WAITING_FOR_SERVICES);
+			}
+		};
+
+		_componentModels.stream().forEach(
+			componentModel -> openReferences(componentModel, onAdd, onUpdate, onRemove)
+		);
+	}
+
+	private void openReferences(
+		ComponentModel componentModel,
+		Consumer<ReferenceCallback> onAdd,
+		Consumer<ReferenceCallback> onUpdate,
+		Consumer<ReferenceCallback> onRemove) {
+
+		_lock.lock();
+
+		try {
+			componentModel.getReferences().stream().forEach(
+				referenceModel -> {
+					Map<String, ReferenceCallback> map = _containerState.referenceCallbacks().computeIfAbsent(
+						componentModel, k -> new LinkedHashMap<>());
+
+					ReferenceCallback callback = new ReferenceCallback.Builder(
+						componentModel, _containerState, _containerState.context()
+					).cardinality(
+						referenceModel.getCardinality()
+					).collectionType(
+						referenceModel.getCollectionType()
+					).name(
+						referenceModel.getName()
+					).onAdd(
+						onAdd
+					).onRemove(
+						onRemove
+					).onUpdate(
+						onUpdate
+					).build();
+
+					map.put(referenceModel.getName(), callback);
+
+					try {
+						String targetFilter = ReferenceModel.buildFilter(
+							referenceModel.getServiceClass(), referenceModel.getTarget(), referenceModel.getScope(), referenceModel.getQualifiers());
+
+						_containerState.tracker().track(targetFilter, callback);
+					}
+					catch (InvalidSyntaxException ise) {
+						if (_log.isErrorEnabled()) {
+							_log.error("CDIe - {}", ise.getMessage(), ise);
+						}
+					}
+				}
+			);
+		}
+		finally {
+			_lock.unlock();
+		}
+	}
+
+	boolean referencesExist() {
+		return _containerState.referenceCallbacks().values().stream().flatMap(
+			entry -> entry.values().stream()
+		).findFirst().isPresent();
+	}
+
+	boolean referencesResolved() {
+		return !_containerState.referenceCallbacks().values().stream().flatMap(
+			valueMap -> valueMap.values().stream()
+		).filter(
+			c -> !c.resolved()
+		).findFirst().isPresent();
+	}
+
+	private static final Logger _log = LoggerFactory.getLogger(Phase_Reference.class);
+
+	private final Collection<ComponentModel> _componentModels;
+	private final ContainerState _containerState;
+	private final Collection<Metadata<Extension>> _extensions;
+	private final Lock _lock = new ReentrantLock(true);
+	private volatile Phase _nextPhase;
+
+}

Copied: aries/trunk/cdi/cdi-extender/src/main/java/org/apache/aries/cdi/container/internal/reference/Multiplicity.java (from r1806482, aries/trunk/cdi/cdi-extender/src/main/java/org/apache/aries/cdi/container/internal/container/BindType.java)
URL: http://svn.apache.org/viewvc/aries/trunk/cdi/cdi-extender/src/main/java/org/apache/aries/cdi/container/internal/reference/Multiplicity.java?p2=aries/trunk/cdi/cdi-extender/src/main/java/org/apache/aries/cdi/container/internal/reference/Multiplicity.java&p1=aries/trunk/cdi/cdi-extender/src/main/java/org/apache/aries/cdi/container/internal/container/BindType.java&r1=1806482&r2=1807424&rev=1807424&view=diff
==============================================================================
--- aries/trunk/cdi/cdi-extender/src/main/java/org/apache/aries/cdi/container/internal/container/BindType.java (original)
+++ aries/trunk/cdi/cdi-extender/src/main/java/org/apache/aries/cdi/container/internal/reference/Multiplicity.java Tue Sep  5 22:01:11 2017
@@ -12,8 +12,10 @@
  * limitations under the License.
  */
 
-package org.apache.aries.cdi.container.internal.container;
+package org.apache.aries.cdi.container.internal.reference;
 
-public enum BindType {
-	SERVICE, SERVICE_PROPERTIES, SERVICE_REFERENCE
-}
\ No newline at end of file
+public enum Multiplicity {
+
+	MULTIPLE, UNARY
+
+}

Copied: aries/trunk/cdi/cdi-extender/src/main/java/org/apache/aries/cdi/container/internal/reference/ReferenceBean.java (from r1806482, aries/trunk/cdi/cdi-extender/src/main/java/org/apache/aries/cdi/container/internal/bean/ConfigurationBean.java)
URL: http://svn.apache.org/viewvc/aries/trunk/cdi/cdi-extender/src/main/java/org/apache/aries/cdi/container/internal/reference/ReferenceBean.java?p2=aries/trunk/cdi/cdi-extender/src/main/java/org/apache/aries/cdi/container/internal/reference/ReferenceBean.java&p1=aries/trunk/cdi/cdi-extender/src/main/java/org/apache/aries/cdi/container/internal/bean/ConfigurationBean.java&r1=1806482&r2=1807424&rev=1807424&view=diff
==============================================================================
--- aries/trunk/cdi/cdi-extender/src/main/java/org/apache/aries/cdi/container/internal/bean/ConfigurationBean.java (original)
+++ aries/trunk/cdi/cdi-extender/src/main/java/org/apache/aries/cdi/container/internal/reference/ReferenceBean.java Tue Sep  5 22:01:11 2017
@@ -12,13 +12,12 @@
  * limitations under the License.
  */
 
-package org.apache.aries.cdi.container.internal.bean;
+package org.apache.aries.cdi.container.internal.reference;
 
 import static org.apache.aries.cdi.container.internal.util.Reflection.cast;
 
 import java.lang.annotation.Annotation;
 import java.lang.reflect.Type;
-import java.util.AbstractMap;
 import java.util.Collections;
 import java.util.List;
 import java.util.Map;
@@ -26,52 +25,63 @@ import java.util.Set;
 
 import javax.enterprise.context.Dependent;
 import javax.enterprise.context.spi.CreationalContext;
+import javax.enterprise.inject.spi.Annotated;
 import javax.enterprise.inject.spi.Bean;
 import javax.enterprise.inject.spi.Decorator;
 import javax.enterprise.inject.spi.InjectionPoint;
 import javax.inject.Named;
 
-import org.apache.aries.cdi.container.internal.container.ConfigurationDependency;
-import org.apache.aries.cdi.container.internal.literal.AnyLiteral;
-import org.apache.aries.cdi.container.internal.literal.DefaultLiteral;
-import org.apache.aries.cdi.container.internal.util.Conversions;
-import org.apache.aries.cdi.container.internal.util.Sets;
+import org.apache.aries.cdi.container.internal.component.ComponentModel;
+import org.apache.aries.cdi.container.internal.container.ContainerState;
 import org.jboss.weld.injection.CurrentInjectionPoint;
 import org.jboss.weld.injection.EmptyInjectionPoint;
 import org.jboss.weld.manager.BeanManagerImpl;
 import org.jboss.weld.util.Decorators;
+import org.osgi.service.cdi.annotations.ReferenceCardinality;
 
-public class ConfigurationBean implements Bean<Object> {
+public class ReferenceBean implements Bean<Object> {
 
-	public ConfigurationBean(
-		ConfigurationDependency configurationDependency, BeanManagerImpl beanManagerImpl, Type injectionPointType,
-		Set<Annotation> qualifiers) {
-
-		_configurationDependency = configurationDependency;
+	public ReferenceBean(
+		ContainerState containerState,
+		ReferenceModel referenceModel,
+		ComponentModel componentModel,
+		Annotated annotated,
+		Set<Annotation> qualifiers,
+		BeanManagerImpl beanManagerImpl) {
+
+		_containerState = containerState;
+		_referenceModel = referenceModel;
+		_componentModel = componentModel;
+		_qualifiers = qualifiers;
 		_beanManagerImpl = beanManagerImpl;
-		_typesForMatchingBeansToInjectionPoints = Sets.immutableHashSet(injectionPointType, Object.class);
-		_currentInjectionPoint = _beanManagerImpl.getServices().get(CurrentInjectionPoint.class);
-		_qualifiers = Sets.hashSet(qualifiers, DefaultLiteral.INSTANCE, AnyLiteral.INSTANCE);
-
-		for (Annotation qualifier : _qualifiers) {
-			if (qualifier.annotationType().equals(Named.class)) {
-				_name = ((Named)qualifier).value();
-			}
-		}
+
+		Named named = annotated.getAnnotation(Named.class);
+
+		_name = named != null ? named.value() : null;
 	}
 
 	@Override
 	public Object create(CreationalContext<Object> creationalContext) {
-		return create0(creationalContext);
+		Object instance = _getInjectedInstance();
+		InjectionPoint ip = _getInjectionPoint();
+		if (ip == null) {
+			return instance;
+		}
+		List<Decorator<?>> decorators = _getDecorators(ip);
+		if (decorators.isEmpty()) {
+			return instance;
+		}
+		return Decorators.getOuterDelegate(
+			cast(this), instance, creationalContext, cast(getBeanClass()), ip, _beanManagerImpl, decorators);
 	}
 
 	@Override
-	public void destroy(Object arg0, CreationalContext<Object> arg1) {
+	public void destroy(Object instance, CreationalContext<Object> creationalContext) {
 	}
 
 	@Override
 	public Class<?> getBeanClass() {
-		return _configurationDependency.getBeanClass();
+		return _referenceModel.getBeanClass();
 	}
 
 	@Override
@@ -81,7 +91,7 @@ public class ConfigurationBean implement
 
 	@Override
 	public String getName() {
-		return _name;
+		return _name; //_referenceModel.getName();
 	}
 
 	@Override
@@ -101,7 +111,7 @@ public class ConfigurationBean implement
 
 	@Override
 	public Set<Type> getTypes() {
-		return _typesForMatchingBeansToInjectionPoints;
+		return _referenceModel.getTypes();
 	}
 
 	@Override
@@ -111,51 +121,59 @@ public class ConfigurationBean implement
 
 	@Override
 	public boolean isNullable() {
-		return false;
+		return _referenceModel.getCardinality() == ReferenceCardinality.OPTIONAL ? true : false;
 	}
 
 	@Override
 	public String toString() {
-		return "ConfigurationBean[" + _currentInjectionPoint + "]";
+		return "ReferenceBean[" + _referenceModel + "]";
 	}
 
-	protected <T> T create0(CreationalContext<T> creationalContext) {
-		Map<String, Object> map = new AbstractMap<String, Object>() {
+	private List<Decorator<?>> _getDecorators(InjectionPoint ip) {
+		return _beanManagerImpl.resolveDecorators(Collections.singleton(ip.getType()), getQualifiers());
+	}
 
-			@Override
-			public Set<java.util.Map.Entry<String, Object>> entrySet() {
-				return _configurationDependency.getConfiguration().entrySet();
-			}
+	private Object _getInjectedInstance() {
+		Object instance = null;
 
-		};
+		Map<String, ReferenceCallback> map = _containerState.referenceCallbacks().get(_componentModel);
 
-		T instance = cast(Conversions.c().convert(map).to(_configurationDependency.getBeanClass()));
-		InjectionPoint ip = getInjectionPoint(_currentInjectionPoint);
-		if (ip == null) {
-			return instance;
-		}
-		List<Decorator<?>> decorators = getDecorators(ip);
-		if (decorators.isEmpty()) {
-			return instance;
+		ReferenceCallback referenceCallback = map.get(_referenceModel.getName());
+
+		Type injectionPointType = _referenceModel.getInjectionPointType();
+
+		switch (_referenceModel.getCollectionType()) {
+			case PROPERTIES:
+				instance = referenceCallback.tracked().values().iterator().next();
+				break;
+			case REFERENCE:
+				instance = referenceCallback.tracked().values().iterator().next();
+				break;
+			case SERVICE:
+				instance = referenceCallback.tracked().values().iterator().next();
+				break;
+			case SERVICEOBJECTS:
+				instance = referenceCallback.tracked().values().iterator().next();
+				break;
+			case TUPLE:
+				instance = referenceCallback.tracked().values().iterator().next();
+				break;
 		}
-		return Decorators.getOuterDelegate(
-			cast(this), instance, creationalContext, cast(getBeanClass()), ip, _beanManagerImpl, decorators);
-	}
 
-	protected List<Decorator<?>> getDecorators(InjectionPoint ip) {
-		return _beanManagerImpl.resolveDecorators(Collections.singleton(ip.getType()), getQualifiers());
+		return instance;
 	}
 
-	protected InjectionPoint getInjectionPoint(CurrentInjectionPoint currentInjectionPoint) {
+	private InjectionPoint _getInjectionPoint() {
+		CurrentInjectionPoint currentInjectionPoint = _beanManagerImpl.getServices().get(CurrentInjectionPoint.class);
 		InjectionPoint ip = currentInjectionPoint.peek();
 		return EmptyInjectionPoint.INSTANCE.equals(ip) ? null : ip;
 	}
 
 	private final BeanManagerImpl _beanManagerImpl;
-	private final ConfigurationDependency _configurationDependency;
-	private final CurrentInjectionPoint _currentInjectionPoint;
-	private String _name;
+	private final ComponentModel _componentModel;
+	private final ContainerState _containerState;
+	private final String _name;
 	private final Set<Annotation> _qualifiers;
-	private final Set<Type> _typesForMatchingBeansToInjectionPoints;
+	private final ReferenceModel _referenceModel;
 
-}
+}
\ No newline at end of file

Added: aries/trunk/cdi/cdi-extender/src/main/java/org/apache/aries/cdi/container/internal/reference/ReferenceCallback.java
URL: http://svn.apache.org/viewvc/aries/trunk/cdi/cdi-extender/src/main/java/org/apache/aries/cdi/container/internal/reference/ReferenceCallback.java?rev=1807424&view=auto
==============================================================================
--- aries/trunk/cdi/cdi-extender/src/main/java/org/apache/aries/cdi/container/internal/reference/ReferenceCallback.java (added)
+++ aries/trunk/cdi/cdi-extender/src/main/java/org/apache/aries/cdi/container/internal/reference/ReferenceCallback.java Tue Sep  5 22:01:11 2017
@@ -0,0 +1,408 @@
+/**
+ * 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.reference;
+
+import java.util.AbstractMap;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.HashSet;
+import java.util.LinkedHashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.Objects;
+import java.util.Optional;
+import java.util.Set;
+import java.util.concurrent.ConcurrentHashMap;
+import java.util.concurrent.atomic.AtomicBoolean;
+import java.util.concurrent.locks.Lock;
+import java.util.concurrent.locks.ReentrantLock;
+import java.util.function.Consumer;
+
+import javax.enterprise.inject.spi.ObserverMethod;
+
+import org.apache.aries.cdi.container.internal.component.ComponentModel;
+import org.apache.aries.cdi.container.internal.container.ContainerState;
+import org.apache.aries.cdi.container.internal.model.CollectionType;
+import org.apache.aries.cdi.container.internal.model.Context;
+import org.apache.aries.cdi.container.internal.model.ServiceEventImpl;
+import org.osgi.framework.ServiceReference;
+import org.osgi.service.cdi.annotations.ReferenceCardinality;
+import org.osgi.service.cdi.annotations.ServiceEvent;
+import org.osgi.util.tracker.ServiceTrackerCustomizer;
+
+public class ReferenceCallback implements ServiceTrackerCustomizer<Object, Object> {
+
+	public static class Builder {
+
+		public Builder(Context context) {
+			this(null, null, context);
+		}
+
+		public Builder(
+			ComponentModel componentModel,
+			ContainerState containerState,
+			Context context) {
+
+			Objects.requireNonNull(context);
+			_componentModel = componentModel;
+			_containerState = containerState;
+			_context = context;
+		}
+
+		public ReferenceCallback build() {
+			Objects.requireNonNull(_cardinality);
+			Objects.requireNonNull(_collectionType);
+			return new ReferenceCallback(_componentModel, _containerState, _context, _name, _cardinality, _collectionType, _onAdd, _onUpdate, _onRemove);
+		}
+
+		public Builder cardinality(ReferenceCardinality cardinality) {
+			_cardinality = cardinality;
+			return this;
+		}
+
+		public Builder collectionType(CollectionType collectionType) {
+			_collectionType = collectionType;
+			return this;
+		}
+
+		public Builder name(String name) {
+			_name = name;
+			return this;
+		}
+
+		public Builder onAdd(Consumer<ReferenceCallback> onAdd) {
+			_onAdd = onAdd;
+			return this;
+		}
+
+		public Builder onUpdate(Consumer<ReferenceCallback> onUpdate) {
+			_onUpdate = onUpdate;
+			return this;
+		}
+
+		public Builder onRemove(Consumer<ReferenceCallback> onRemove) {
+			_onRemove = onRemove;
+			return this;
+		}
+
+		private ReferenceCardinality _cardinality;
+		private CollectionType _collectionType;
+		private ComponentModel _componentModel;
+		private ContainerState _containerState;
+		private Context _context;
+		private String _name;
+		private Consumer<ReferenceCallback> _onAdd;
+		private Consumer<ReferenceCallback> _onUpdate;
+		private Consumer<ReferenceCallback> _onRemove;
+
+	}
+
+	private ReferenceCallback(
+		ComponentModel componentModel,
+		ContainerState containerState,
+		Context context,
+		String name,
+		ReferenceCardinality cardinality,
+		CollectionType collectionType,
+		Consumer<ReferenceCallback> onAdd,
+		Consumer<ReferenceCallback> onUpdate,
+		Consumer<ReferenceCallback> onRemove) {
+
+		_componentModel = Optional.ofNullable(componentModel);
+		_containerState = Optional.ofNullable(containerState);
+		_context = context;
+		_name = Optional.ofNullable(name);
+		_cardinality = cardinality;
+		_collectionType = collectionType;
+		_onAdd = Optional.ofNullable(onAdd);
+		_onUpdate = Optional.ofNullable(onUpdate);
+		_onRemove = Optional.ofNullable(onRemove);
+	}
+
+	Optional<ObserverMethod<ServiceEvent<?>>> observer() {
+		return _componentModel.flatMap(
+			cm -> _containerState.flatMap(
+				cs -> _name.flatMap(
+					n -> {
+						Map<String, ObserverMethod<ServiceEvent<?>>> map = cs.referenceObservers().computeIfAbsent(
+							cm, k -> new LinkedHashMap<>());
+
+						return Optional.ofNullable(map.get(n));
+					}
+				)
+			)
+		);
+	}
+
+	@Override
+	public Object addingService(ServiceReference<Object> reference) {
+		_lock.lock();
+
+		try {
+			Object instance;
+
+			switch (_collectionType) {
+				case PROPERTIES:
+					instance = new UnmodifiableMap(reference);
+					break;
+				case REFERENCE:
+					instance = reference;
+					break;
+				case SERVICEOBJECTS:
+					instance = _context.getServiceObjects(reference);
+					break;
+				case TUPLE:
+					instance = new AbstractMap.SimpleImmutableEntry<Map<String, Object>, Object>(
+						new UnmodifiableMap(reference), _context.getService(reference));
+					break;
+				default:
+					instance = _context.getService(reference);
+					break;
+			}
+
+			final Object object = instance;
+
+			if (_queueing.get()) {
+				_queue.put(reference, object);
+			}
+			else {
+				_tracked.put(reference, object);
+
+				observer().ifPresent(o -> o.notify(event(object, ServiceEventImpl.Event.ADDING)));
+			}
+
+			_onAdd.ifPresent(f -> f.accept(this));
+
+			return instance;
+		}
+		finally {
+			_lock.unlock();
+		}
+	}
+
+	public void flush() {
+		_lock.lock();
+
+		try {
+			_queueing.set(false);
+
+			_queue.entrySet().removeIf(
+				entry -> {
+					_tracked.put(entry.getKey(), entry.getValue());
+
+					observer().ifPresent(o -> o.notify(event(entry.getValue(), ServiceEventImpl.Event.ADDING)));
+
+					return true;
+				}
+			);
+		}
+		finally {
+			_lock.unlock();
+		}
+	}
+
+	@Override
+	public void modifiedService(ServiceReference<Object> reference, Object service) {
+		_lock.lock();
+
+		try {
+			Object instance = null;
+
+			switch (_collectionType) {
+				case PROPERTIES:
+					instance = new UnmodifiableMap(reference);
+					break;
+				case REFERENCE:
+					instance = reference;
+					break;
+				case SERVICEOBJECTS:
+					break;
+				case TUPLE:
+					@SuppressWarnings("unchecked")
+					Map.Entry<Map<String, Object>, Object> entry = (Map.Entry<Map<String, Object>, Object>)service;
+
+					instance = new AbstractMap.SimpleImmutableEntry<Map<String, Object>, Object>(
+						new UnmodifiableMap(reference), entry.getValue());
+					break;
+				default:
+					break;
+			}
+
+			if (instance != null) {
+				final Object object = instance;
+
+				if (_queueing.get()) {
+					_queue.put(reference, object);
+				}
+				else {
+					_tracked.put(reference, object);
+
+					observer().ifPresent(o -> o.notify(event(object, ServiceEventImpl.Event.MODIFIED)));
+				}
+			}
+
+			_onUpdate.ifPresent(f -> f.accept(this));
+		}
+		finally {
+			_lock.unlock();
+		}
+	}
+
+	@Override
+	public void removedService(ServiceReference<Object> reference, Object service) {
+		_lock.lock();
+
+		try {
+			_context.ungetService(reference);
+
+			if (_queueing.get()) {
+				_queue.remove(reference);
+			}
+			else {
+				final Object instance = _tracked.remove(reference);
+
+				observer().ifPresent(o -> o.notify(event(instance, ServiceEventImpl.Event.REMOVED)));
+			}
+
+			_onRemove.ifPresent(f -> f.accept(this));
+		}
+		finally {
+			_lock.unlock();
+		}
+	}
+
+	<T> ServiceEvent<T> event(T t, ServiceEventImpl.Event event) {
+		return new ServiceEventImpl<T>(t, event);
+	}
+
+	public boolean resolved() {
+		if (((_cardinality == ReferenceCardinality.MANDATORY) ||
+			(_cardinality == ReferenceCardinality.AT_LEAST_ONE))) {
+
+			if (_queue.size() + _tracked.size() >= 1) {
+				return true;
+			}
+
+			return false;
+		}
+
+		return true;
+	}
+
+	public Map<ServiceReference<?>, Object> tracked() {
+		return _tracked;
+	}
+
+	private final ReferenceCardinality _cardinality;
+	private final CollectionType _collectionType;
+	private final Optional<ComponentModel> _componentModel;
+	private final Optional<ContainerState> _containerState;
+	private final Context _context;
+	private final Lock _lock = new ReentrantLock();
+	private final Optional<String> _name;
+	private final Optional<Consumer<ReferenceCallback>> _onAdd;
+	private final Optional<Consumer<ReferenceCallback>> _onUpdate;
+	private final Optional<Consumer<ReferenceCallback>> _onRemove;
+	private final AtomicBoolean _queueing = new AtomicBoolean(true);
+	private final Map<ServiceReference<?>, Object> _queue = new ConcurrentHashMap<>();
+	private final Map<ServiceReference<?>, Object> _tracked = new ConcurrentHashMap<>();
+
+	private static class UnmodifiableMap implements Map<String, Object> {
+
+		public UnmodifiableMap(ServiceReference<?> sr) {
+			_sr = sr;;
+			_keys = Arrays.asList(_sr.getPropertyKeys());
+		}
+
+		@Override
+		public int size() {
+			return _keys.size();
+		}
+
+		@Override
+		public boolean isEmpty() {
+			return _keys.isEmpty();
+		}
+
+		@Override
+		public boolean containsKey(Object key) {
+			return _keys.contains(key);
+		}
+
+		@Override
+		public boolean containsValue(Object value) {
+			return values().contains(value);
+		}
+
+		@Override
+		public Object get(Object key) {
+			return _sr.getProperty((String)key);
+		}
+
+		@Override
+		public Object put(String key, Object value) {
+			throw new UnsupportedOperationException();
+		}
+
+		@Override
+		public Object remove(Object key) {
+			throw new UnsupportedOperationException();
+		}
+
+		@Override
+		public void putAll(Map<? extends String, ? extends Object> m) {
+			throw new UnsupportedOperationException();
+		}
+
+		@Override
+		public void clear() {
+			throw new UnsupportedOperationException();
+		}
+
+		@Override
+		public Set<String> keySet() {
+			return new HashSet<>(_keys);
+		}
+
+		@Override
+		public Collection<Object> values() {
+			List<Object> values = new ArrayList<>();
+
+			for (String key : _keys) {
+				values.add(_sr.getProperty(key));
+			}
+
+			return Collections.unmodifiableCollection(values);
+		}
+
+		@Override
+		public Set<Entry<String, Object>> entrySet() {
+			Set<Map.Entry<String, Object>> entries = new HashSet<>();
+
+			for (String key : _keys) {
+				entries.add(new AbstractMap.SimpleImmutableEntry<>(key, _sr.getProperty(key)));
+			}
+
+			return Collections.unmodifiableSet(entries);
+		}
+
+		private final ServiceReference<?> _sr;
+		private List<String> _keys;
+
+	}
+
+}