Added: 
aries/trunk/cdi/cdi-extender/src/main/java/org/apache/aries/cdi/container/internal/container/ConfigurationListener.java
URL: 
http://svn.apache.org/viewvc/aries/trunk/cdi/cdi-extender/src/main/java/org/apache/aries/cdi/container/internal/container/ConfigurationListener.java?rev=1829115&view=auto
==============================================================================
--- 
aries/trunk/cdi/cdi-extender/src/main/java/org/apache/aries/cdi/container/internal/container/ConfigurationListener.java
 (added)
+++ 
aries/trunk/cdi/cdi-extender/src/main/java/org/apache/aries/cdi/container/internal/container/ConfigurationListener.java
 Sat Apr 14 01:10:27 2018
@@ -0,0 +1,310 @@
+/**
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.aries.cdi.container.internal.container;
+
+import java.util.Arrays;
+import java.util.Dictionary;
+import java.util.Hashtable;
+import java.util.List;
+import java.util.Objects;
+import java.util.concurrent.CopyOnWriteArrayList;
+import java.util.concurrent.atomic.AtomicBoolean;
+
+import org.apache.aries.cdi.container.internal.container.Op.Mode;
+import org.apache.aries.cdi.container.internal.container.Op.Type;
+import org.apache.aries.cdi.container.internal.model.Component;
+import 
org.apache.aries.cdi.container.internal.model.ExtendedComponentInstanceDTO;
+import org.apache.aries.cdi.container.internal.model.ExtendedConfigurationDTO;
+import org.apache.aries.cdi.container.internal.util.Maps;
+import org.apache.aries.cdi.container.internal.util.Predicates;
+import org.apache.aries.cdi.container.internal.util.Throw;
+import org.jboss.weld.exceptions.IllegalArgumentException;
+import org.osgi.framework.ServiceRegistration;
+import org.osgi.service.cdi.MaximumCardinality;
+import org.osgi.service.cdi.runtime.dto.ComponentInstanceDTO;
+import org.osgi.service.cdi.runtime.dto.template.ConfigurationTemplateDTO;
+import org.osgi.service.cm.ConfigurationEvent;
+import org.osgi.service.log.Logger;
+import org.osgi.util.promise.Promise;
+
+public class ConfigurationListener extends Phase implements 
org.osgi.service.cm.ConfigurationListener {
+
+       public static class Builder {
+
+               public Builder(ContainerState containerState) {
+                       _containerState = containerState;
+               }
+
+               public Builder component(Component component) {
+                       _component = component;
+                       return this;
+               }
+
+               public ConfigurationListener build() {
+                       Objects.requireNonNull(_component);
+                       return new ConfigurationListener(_containerState, 
_component);
+               }
+
+               private Component _component;
+               private final ContainerState _containerState;
+
+       }
+
+       protected ConfigurationListener(
+               ContainerState containerState,
+               Component component) {
+
+               super(containerState, component);
+               _component = component;
+               _log = containerState.containerLogs().getLogger(getClass());
+       }
+
+       @Override
+       public boolean close() {
+               if (_listenerService != null) {
+                       _listenerService.unregister();
+                       _listenerService = null;
+               }
+
+               return next.map(
+                       next -> {
+                               submit(next.closeOp(), next::close).onFailure(
+                                       f -> {
+                                               _log.error(l -> l.error("CCR 
Failure in configuration listener close on {}", next, f));
+
+                                               error(f);
+                                       }
+                               );
+
+                               return true;
+                       }
+               ).orElse(true);
+       }
+
+       @Override
+       public Op closeOp() {
+               return Op.of(Mode.CLOSE, Type.CONFIGURATION_LISTENER, 
_component.template().name);
+       }
+
+       @Override
+       public void configurationEvent(ConfigurationEvent event) {
+               next.map(next -> (Component)next).ifPresent(
+                       next -> next.configurationTemplates().stream().filter(
+                               t -> 
Predicates.isMatchingConfiguration(event).test(t)
+                       ).findFirst().ifPresent(
+                               t -> {
+                                       String eventString = 
Arrays.asList(event.getPid(), event.getFactoryPid(), type(event)).toString();
+
+                                       Promise<Boolean> result = 
containerState.submit(
+                                               Op.of(Mode.OPEN, 
Type.CONFIGURATION_EVENT, eventString),
+                                               () -> {
+                                                       _log.debug(l -> 
l.debug("CCR Event {} matched {} because of {}", eventString, 
_component.template().name, _component.template().configurations));
+                                                       processEvent(next, t, 
event);
+                                                       return true;
+                                               }
+                                       );
+
+                                       try {
+                                               result.getValue();
+                                       }
+                                       catch (Exception e) {
+                                               Throw.exception(e);
+                                       }
+                               }
+                       )
+               );
+       }
+
+       @Override
+       public boolean open() {
+               Dictionary<String, Object> properties = new Hashtable<>();
+               properties.put("name", toString());
+               _listenerService = 
containerState.bundleContext().registerService(
+                       org.osgi.service.cm.ConfigurationListener.class, this, 
properties);
+
+               return next.map(next -> (Component)next).map(
+                       component -> {
+                               
component.configurationTemplates().stream().filter(
+                                       ct -> Objects.nonNull(ct.pid)
+                               ).forEach(
+                                       template -> {
+                                               if (template.maximumCardinality 
== MaximumCardinality.ONE) {
+                                                       
containerState.findConfig(template.pid).ifPresent(
+                                                               c -> 
processEvent(
+                                                                               
component,
+                                                                               
template,
+                                                                               
new ConfigurationEvent(
+                                                                               
        containerState.caTracker().getServiceReference(),
+                                                                               
        ConfigurationEvent.CM_UPDATED,
+                                                                               
        null,
+                                                                               
        c.getPid()))
+                                                       );
+                                               }
+                                               else {
+                                                       
containerState.findConfigs(template.pid, true).ifPresent(
+                                                               arr -> 
Arrays.stream(arr).forEach(
+                                                                       c -> 
processEvent(
+                                                                               
        component,
+                                                                               
        template,
+                                                                               
        new ConfigurationEvent(
+                                                                               
                containerState.caTracker().getServiceReference(),
+                                                                               
                ConfigurationEvent.CM_UPDATED,
+                                                                               
                c.getFactoryPid(),
+                                                                               
                c.getPid())))
+                                                       );
+                                               }
+                                       }
+                               );
+
+                               submit(component.openOp(), 
component::open).onFailure(
+                                       f -> {
+                                               _log.error(l -> l.error("CCR 
Failure during configuration start on {}", next, f));
+
+                                               error(f);
+                                       }
+                               );
+
+                               return true;
+                       }
+               ).orElse(true);
+       }
+
+       @Override
+       public Op openOp() {
+               return Op.of(Mode.OPEN, Type.CONFIGURATION_LISTENER, 
_component.template().name);
+       }
+
+       @Override
+       public String toString() {
+               return Arrays.asList(getClass().getSimpleName(), 
_component).toString();
+       }
+
+       private void processEvent(Component component, ConfigurationTemplateDTO 
t, ConfigurationEvent event) {
+               final AtomicBoolean needToRefresh = new AtomicBoolean(false);
+
+               List<ComponentInstanceDTO> instances = component.instances();
+
+               instances.stream().forEach(
+                       instance -> instance.configurations.stream().filter(
+                               c -> c.template.equals(t)
+                       ).map(ExtendedConfigurationDTO.class::cast).filter(
+                               c -> c.pid.equals(event.getPid())
+                       ).forEach(
+                               c -> {
+                                       instance.configurations.remove(c);
+                                       needToRefresh.set(true);
+                               }
+                       )
+               );
+
+               switch (event.getType()) {
+                       case ConfigurationEvent.CM_DELETED:
+                               if (t.maximumCardinality == 
MaximumCardinality.MANY) {
+                                       instances.stream().map(
+                                               instance -> 
(ExtendedComponentInstanceDTO)instance
+                                       ).filter(
+                                               instance -> 
event.getPid().equals(instance.pid)
+                                       ).forEach(
+                                               instance -> {
+                                                       if 
(instances.remove(instance)) {
+                                                               
submit(instance.closeOp(), instance::close).onFailure(
+                                                                       f -> {
+                                                                               
_log.error(l -> l.error("CCR Error closing {} on {}", instance.ident(), 
bundle()));
+                                                                       }
+                                                               );
+                                                       }
+                                               }
+                                       );
+                               }
+                               break;
+                       case ConfigurationEvent.CM_LOCATION_CHANGED:
+                       case ConfigurationEvent.CM_UPDATED:
+                               if ((t.maximumCardinality == 
MaximumCardinality.MANY) &&
+                                       !instances.stream().map(
+                                               instance -> 
(ExtendedComponentInstanceDTO)instance
+                                       ).filter(
+                                               instance -> 
event.getPid().equals(instance.pid)
+                                       ).findFirst().isPresent()) {
+
+                                       ExtendedComponentInstanceDTO 
instanceDTO = new ExtendedComponentInstanceDTO(
+                                               containerState, 
_component.activatorBuilder());
+                                       instanceDTO.activations = new 
CopyOnWriteArrayList<>();
+                                       instanceDTO.configurations = new 
CopyOnWriteArrayList<>();
+                                       instanceDTO.pid = event.getPid();
+                                       instanceDTO.properties = null;
+                                       instanceDTO.references = new 
CopyOnWriteArrayList<>();
+                                       instanceDTO.template = 
component.template();
+
+                                       instances.add(instanceDTO);
+                               }
+
+                               
containerState.findConfig(event.getPid()).ifPresent(
+                                       configuration -> {
+                                               ExtendedConfigurationDTO 
configurationDTO2 = new ExtendedConfigurationDTO();
+
+                                               configurationDTO2.configuration 
= configuration;
+                                               configurationDTO2.pid = 
event.getPid();
+                                               configurationDTO2.properties = 
Maps.of(configuration.getProcessedProperties(event.getReference()));
+                                               configurationDTO2.template = t;
+
+                                               instances.stream().forEach(
+                                                       instance -> {
+                                                               
instance.configurations.add(configurationDTO2);
+                                                               
needToRefresh.set(true);
+                                                       }
+                                               );
+                                       }
+                               );
+                               break;
+               }
+
+               if (needToRefresh.get()) {
+                       startComponent(component);
+               }
+       }
+
+       private String type(ConfigurationEvent event) {
+               if (event.getType() == ConfigurationEvent.CM_DELETED)
+                       return "DELETED";
+               if (event.getType() == ConfigurationEvent.CM_LOCATION_CHANGED)
+                       return "LOCATION_CHANGED";
+               if (event.getType() == ConfigurationEvent.CM_UPDATED)
+                       return "UPDATED";
+               throw new IllegalArgumentException("CM Event type " + 
event.getType());
+       }
+
+       private void startComponent(Component component) {
+               submit(component.closeOp(), component::close).then(
+                       s -> submit(component.openOp(), 
component::open).onFailure(
+                               f -> {
+                                       _log.error(l -> l.error("CCR Error in 
configuration listener start on {}", component, f));
+
+                                       error(f);
+                               }
+                       ),
+                       f -> {
+                               _log.error(l -> l.error("CCR Error in 
configuration listener close on {}", component, f.getFailure()));
+
+                               error(f.getFailure());
+                       }
+               );
+       }
+
+       private volatile 
ServiceRegistration<org.osgi.service.cm.ConfigurationListener> _listenerService;
+
+       private final Component _component;
+       private final Logger _log;
+
+}
\ No newline at end of file

Modified: 
aries/trunk/cdi/cdi-extender/src/main/java/org/apache/aries/cdi/container/internal/container/ContainerBootstrap.java
URL: 
http://svn.apache.org/viewvc/aries/trunk/cdi/cdi-extender/src/main/java/org/apache/aries/cdi/container/internal/container/ContainerBootstrap.java?rev=1829115&r1=1829114&r2=1829115&view=diff
==============================================================================
--- 
aries/trunk/cdi/cdi-extender/src/main/java/org/apache/aries/cdi/container/internal/container/ContainerBootstrap.java
 (original)
+++ 
aries/trunk/cdi/cdi-extender/src/main/java/org/apache/aries/cdi/container/internal/container/ContainerBootstrap.java
 Sat Apr 14 01:10:27 2018
@@ -14,88 +14,128 @@
 
 package org.apache.aries.cdi.container.internal.container;
 
-import java.util.Collection;
 import java.util.List;
 import java.util.concurrent.CopyOnWriteArrayList;
 
-import javax.enterprise.inject.spi.BeanManager;
 import javax.enterprise.inject.spi.Extension;
 
-import org.apache.aries.cdi.container.internal.context.BundleContextExtension;
-import org.apache.aries.cdi.container.internal.extension.ExtensionMetadata;
-import org.apache.aries.cdi.container.internal.model.BeansModel;
+import org.apache.aries.cdi.container.internal.container.Op.Mode;
+import org.apache.aries.cdi.container.internal.container.Op.Type;
+import org.apache.aries.cdi.container.internal.model.ExtendedExtensionDTO;
+import org.apache.aries.cdi.container.internal.model.FactoryComponent;
+import org.apache.aries.cdi.container.internal.model.SingleComponent;
+import org.apache.aries.cdi.container.internal.util.Syncro;
 import org.jboss.weld.bootstrap.WeldBootstrap;
 import org.jboss.weld.bootstrap.spi.BeanDeploymentArchive;
 import org.jboss.weld.bootstrap.spi.Deployment;
 import org.jboss.weld.bootstrap.spi.Metadata;
 import org.jboss.weld.util.ServiceLoader;
+import org.osgi.service.log.Logger;
 
-public class ContainerBootstrap {
+public class ContainerBootstrap extends Phase {
 
        public ContainerBootstrap(
                ContainerState containerState,
-               Collection<Metadata<Extension>> externalExtensions) {
-
-               _containerState = containerState;
-               _externalExtensions = externalExtensions;
-
-               BeansModel beansModel = _containerState.beansModel();
+               ConfigurationListener.Builder configurationBuilder,
+               SingleComponent.Builder singleBuilder,
+               FactoryComponent.Builder factoryBuilder) {
+
+               super(containerState, null);
+
+               _configurationBuilder = configurationBuilder;
+               _singleBuilder = singleBuilder;
+               _factoryBuilder = factoryBuilder;
+               _log = containerState.containerLogs().getLogger(getClass());
+       }
 
-               List<Metadata<Extension>> extensions = new 
CopyOnWriteArrayList<>();
+       @Override
+       public boolean close() {
+               try (Syncro syncro = _lock.open()) {
+                       if (_bootstrap != null) {
+                               _log.debug(l -> l.debug("CCR container 
bootstrap shutdown on {}", _bootstrap));
+                               _bootstrap.shutdown();
+                               _bootstrap = null;
+                       }
 
-               // Add the internal extensions
-               extensions.add(
-                       new ExtensionMetadata(
-                               new 
BundleContextExtension(_containerState.bundleContext()),
-                               _containerState.id()));
-//             extensions.add(
-//                     new ExtensionMetadata(
-//                             new ComponentRuntimeExtension(_containerState),
-//                             _containerState.id()));
-
-               // Add extensions found from the bundle's classloader, such as 
those in the Bundle-ClassPath
-               for (Metadata<Extension> meta : 
ServiceLoader.load(Extension.class, _containerState.classLoader())) {
-                       extensions.add(meta);
+                       return true;
                }
+               catch (Throwable t) {
+                       _log.error(l -> l.error("CCR Failure in container 
bootstrap shutdown on {}", _bootstrap, t));
 
-               // Add external extensions
-               for (Metadata<Extension> meta : _externalExtensions) {
-                       extensions.add(meta);
+                       return false;
                }
-
-               BeanDeploymentArchive beanDeploymentArchive = new 
ContainerDeploymentArchive(
-                       _containerState.loader(), _containerState.id(), 
beansModel.getBeanClassNames(),
-                       beansModel.getBeansXml());
-
-               Deployment deployment = new ContainerDeployment(extensions, 
beanDeploymentArchive);
-
-               _bootstrap = new WeldBootstrap();
-
-               _bootstrap.startExtensions(extensions);
-               _bootstrap.startContainer(_containerState.id(), new 
ContainerEnvironment(), deployment);
-
-               _beanManager = _bootstrap.getManager(beanDeploymentArchive);
-//             _containerState.setBeanManager(_beanManager);
-
-               _bootstrap.startInitialization();
-               _bootstrap.deployBeans();
        }
 
-       public BeanManager getBeanManager() {
-               return _beanManager;
+       @Override
+       public Op closeOp() {
+               return Op.of(Mode.CLOSE, Type.CONTAINER_BOOTSTRAP, 
containerState.id());
        }
 
-       public WeldBootstrap getBootstrap() {
-               return _bootstrap;
+       @Override
+       public boolean open() {
+               try (Syncro syncro = _lock.open()) {
+                       if (_bootstrap != null) {
+                               return true;
+                       }
+
+                       List<Metadata<Extension>> extensions = new 
CopyOnWriteArrayList<>();
+
+                       // Add the internal extensions
+                       extensions.add(
+                                       new ExtensionMetadata(
+                                                       new 
BundleContextExtension(containerState.bundleContext()),
+                                                       containerState.id()));
+                       extensions.add(
+                                       new ExtensionMetadata(
+                                                       new 
RuntimeExtension(containerState, _configurationBuilder, _singleBuilder, 
_factoryBuilder),
+                                                       containerState.id()));
+                       extensions.add(
+                                       new ExtensionMetadata(
+                                                       new 
LoggerExtension(containerState),
+                                                       containerState.id()));
+
+                       // Add extensions found from the bundle's class loader, 
such as those in the Bundle-ClassPath
+                       ServiceLoader.load(Extension.class, 
containerState.classLoader()).forEach(extensions::add);
+
+                       // Add external extensions
+                       containerState.containerDTO().extensions.stream().map(
+                                       ExtendedExtensionDTO.class::cast
+                                       ).map(
+                                                       e -> new 
ExtensionMetadata(e.extension.getService(), e.template.serviceFilter)
+                                                       
).forEach(extensions::add);
+
+                       _bootstrap = new WeldBootstrap();
+
+                       BeanDeploymentArchive beanDeploymentArchive = new 
ContainerDeploymentArchive(
+                                       containerState.loader(),
+                                       containerState.id(),
+                                       
containerState.beansModel().getBeanClassNames(),
+                                       
containerState.beansModel().getBeansXml());
+
+                       Deployment deployment = new 
ContainerDeployment(extensions, beanDeploymentArchive);
+
+                       _bootstrap.startExtensions(extensions);
+                       _bootstrap.startContainer(containerState.id(), new 
ContainerEnvironment(), deployment);
+                       _bootstrap.startInitialization();
+                       _bootstrap.deployBeans();
+                       _bootstrap.validateBeans();
+                       _bootstrap.endInitialization();
+
+                       return true;
+               }
        }
 
-       public void shutdown() {
-               _bootstrap.shutdown();
+       @Override
+       public Op openOp() {
+               return Op.of(Mode.OPEN, Type.CONTAINER_BOOTSTRAP, 
containerState.id());
        }
 
-       private final BeanManager _beanManager;
-       private final WeldBootstrap _bootstrap;
-       private final ContainerState _containerState;
-       private final Collection<Metadata<Extension>> _externalExtensions;
+
+       private volatile WeldBootstrap _bootstrap;
+       private final ConfigurationListener.Builder _configurationBuilder;
+       private final FactoryComponent.Builder _factoryBuilder;
+       private final SingleComponent.Builder _singleBuilder;
+       private final Syncro _lock = new Syncro(true);
+       private final Logger _log;
 
 }
\ No newline at end of file

Modified: 
aries/trunk/cdi/cdi-extender/src/main/java/org/apache/aries/cdi/container/internal/container/ContainerDeploymentArchive.java
URL: 
http://svn.apache.org/viewvc/aries/trunk/cdi/cdi-extender/src/main/java/org/apache/aries/cdi/container/internal/container/ContainerDeploymentArchive.java?rev=1829115&r1=1829114&r2=1829115&view=diff
==============================================================================
--- 
aries/trunk/cdi/cdi-extender/src/main/java/org/apache/aries/cdi/container/internal/container/ContainerDeploymentArchive.java
 (original)
+++ 
aries/trunk/cdi/cdi-extender/src/main/java/org/apache/aries/cdi/container/internal/container/ContainerDeploymentArchive.java
 Sat Apr 14 01:10:27 2018
@@ -33,9 +33,7 @@ public class ContainerDeploymentArchive
 
                _id = id;
                _beanClassNames = beanClassNames;
-               _beanDeploymentArchives = Collections.emptyList();
                _beansXml = beansXml;
-               _ejbs = Collections.emptyList();
                _services = new SimpleServiceRegistry();
 
                if (loader != null) {
@@ -51,7 +49,7 @@ public class ContainerDeploymentArchive
 
        @Override
        public Collection<BeanDeploymentArchive> getBeanDeploymentArchives() {
-               return _beanDeploymentArchives;
+               return Collections.emptyList();
        }
 
        @Override
@@ -61,7 +59,7 @@ public class ContainerDeploymentArchive
 
        @Override
        public Collection<EjbDescriptor<?>> getEjbs() {
-               return _ejbs;
+               return Collections.emptyList();
        }
 
        @Override
@@ -75,9 +73,7 @@ public class ContainerDeploymentArchive
        }
 
        private final Collection<String> _beanClassNames;
-       private final Collection<BeanDeploymentArchive> _beanDeploymentArchives;
        private final BeansXml _beansXml;
-       private final Collection<EjbDescriptor<?>> _ejbs;
        private final String _id;
        private final ServiceRegistry _services;
 

Modified: 
aries/trunk/cdi/cdi-extender/src/main/java/org/apache/aries/cdi/container/internal/container/ContainerDiscovery.java
URL: 
http://svn.apache.org/viewvc/aries/trunk/cdi/cdi-extender/src/main/java/org/apache/aries/cdi/container/internal/container/ContainerDiscovery.java?rev=1829115&r1=1829114&r2=1829115&view=diff
==============================================================================
--- 
aries/trunk/cdi/cdi-extender/src/main/java/org/apache/aries/cdi/container/internal/container/ContainerDiscovery.java
 (original)
+++ 
aries/trunk/cdi/cdi-extender/src/main/java/org/apache/aries/cdi/container/internal/container/ContainerDiscovery.java
 Sat Apr 14 01:10:27 2018
@@ -17,13 +17,9 @@ package org.apache.aries.cdi.container.i
 import java.util.Collections;
 import java.util.List;
 
-import javax.enterprise.inject.spi.DefinitionException;
 import javax.enterprise.inject.spi.Extension;
 
-import org.apache.aries.cdi.container.internal.component.DiscoveryExtension;
-import org.apache.aries.cdi.container.internal.extension.ExtensionMetadata;
 import org.apache.aries.cdi.container.internal.model.BeansModel;
-import org.apache.aries.cdi.container.internal.v2.component.ContainerComponent;
 import org.jboss.weld.bootstrap.WeldBootstrap;
 import org.jboss.weld.bootstrap.spi.BeanDeploymentArchive;
 import org.jboss.weld.bootstrap.spi.Deployment;
@@ -31,7 +27,7 @@ import org.jboss.weld.bootstrap.spi.Meta
 
 public class ContainerDiscovery {
 
-       public static void discover(ContainerState containerState) {
+       public ContainerDiscovery(ContainerState containerState) {
                String id = containerState.id() + "-discovery";
 
                BeansModel beansModel = containerState.beansModel();
@@ -40,10 +36,8 @@ public class ContainerDiscovery {
                        containerState.loader(), id, 
beansModel.getBeanClassNames(),
                        beansModel.getBeansXml());
 
-               ContainerComponent containerComponent = new 
ContainerComponent(id);
-
                ExtensionMetadata extension = new ExtensionMetadata(
-                       new DiscoveryExtension(beansModel, containerComponent), 
id);
+                       new DiscoveryExtension(containerState), id);
 
                List<Metadata<Extension>> extensions = 
Collections.singletonList(extension);
 
@@ -52,31 +46,11 @@ public class ContainerDiscovery {
 
                WeldBootstrap _bootstrap = new WeldBootstrap();
 
-               try {
-                       _bootstrap.startExtensions(extensions);
-                       _bootstrap.startContainer(id, new 
ContainerEnvironment(), deployment);
-                       _bootstrap.startInitialization();
-                       _bootstrap.deployBeans();
-                       _bootstrap.shutdown();
-               }
-               catch (DefinitionException de) {
-                       throw de;
-               }
-
-               validate(containerState);
-       }
-
-       private static void validate(ContainerState containerState) {
-               containerState.beansModel().getOSGiBeans().stream().forEach(
-                       osgiBean -> {
-                               if (!osgiBean.found()) {
-                                       throw new DefinitionException(
-                                               String.format(
-                                                       "Did not find bean for 
<component> description %s",
-                                                       osgiBean));
-                               }
-                       }
-               );
+               _bootstrap.startExtensions(extensions);
+               _bootstrap.startContainer(id, new ContainerEnvironment(), 
deployment);
+               _bootstrap.startInitialization();
+               _bootstrap.deployBeans();
+               _bootstrap.shutdown();
        }
 
 }
\ No newline at end of file

Modified: 
aries/trunk/cdi/cdi-extender/src/main/java/org/apache/aries/cdi/container/internal/container/ContainerState.java
URL: 
http://svn.apache.org/viewvc/aries/trunk/cdi/cdi-extender/src/main/java/org/apache/aries/cdi/container/internal/container/ContainerState.java?rev=1829115&r1=1829114&r2=1829115&view=diff
==============================================================================
--- 
aries/trunk/cdi/cdi-extender/src/main/java/org/apache/aries/cdi/container/internal/container/ContainerState.java
 (original)
+++ 
aries/trunk/cdi/cdi-extender/src/main/java/org/apache/aries/cdi/container/internal/container/ContainerState.java
 Sat Apr 14 01:10:27 2018
@@ -14,42 +14,58 @@
 
 package org.apache.aries.cdi.container.internal.container;
 
-import java.util.Dictionary;
+import static org.apache.aries.cdi.container.internal.util.Filters.*;
+import static org.osgi.namespace.extender.ExtenderNamespace.*;
+import static org.osgi.service.cdi.CDIConstants.*;
+
+import java.lang.reflect.InvocationTargetException;
+import java.util.ArrayList;
+import java.util.Collections;
 import java.util.List;
 import java.util.Map;
+import java.util.Map.Entry;
 import java.util.Optional;
+import java.util.concurrent.Callable;
 import java.util.concurrent.ConcurrentHashMap;
+import java.util.concurrent.CopyOnWriteArrayList;
+import java.util.concurrent.atomic.AtomicBoolean;
 
 import javax.enterprise.inject.Any;
 import javax.enterprise.inject.spi.BeanManager;
-import javax.enterprise.inject.spi.ObserverMethod;
 import javax.enterprise.util.AnnotationLiteral;
 
-import org.apache.aries.cdi.container.internal.component.OSGiBean;
-import 
org.apache.aries.cdi.container.internal.configuration.ConfigurationCallback;
-import org.apache.aries.cdi.container.internal.extension.ExtensionDependency;
+import org.apache.aries.cdi.container.internal.ChangeCount;
 import org.apache.aries.cdi.container.internal.loader.BundleClassLoader;
 import org.apache.aries.cdi.container.internal.loader.BundleResourcesLoader;
 import org.apache.aries.cdi.container.internal.model.BeansModel;
-import org.apache.aries.cdi.container.internal.model.Context;
-import org.apache.aries.cdi.container.internal.model.Registrator;
-import org.apache.aries.cdi.container.internal.model.Tracker;
-import org.apache.aries.cdi.container.internal.reference.ReferenceCallback;
-import org.apache.aries.cdi.container.internal.service.ServiceDeclaration;
+import org.apache.aries.cdi.container.internal.model.BeansModelBuilder;
+import 
org.apache.aries.cdi.container.internal.model.ExtendedConfigurationTemplateDTO;
+import 
org.apache.aries.cdi.container.internal.model.ExtendedExtensionTemplateDTO;
+import org.apache.aries.cdi.container.internal.util.Logs;
+import org.apache.aries.cdi.container.internal.util.Throw;
 import org.jboss.weld.resources.spi.ResourceLoader;
 import org.jboss.weld.serialization.spi.ProxyServices;
 import org.osgi.framework.Bundle;
 import org.osgi.framework.BundleContext;
-import org.osgi.framework.Filter;
-import org.osgi.framework.InvalidSyntaxException;
-import org.osgi.framework.ServiceObjects;
-import org.osgi.framework.ServiceReference;
+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.service.cdi.reference.ReferenceEvent;
-import org.osgi.service.cm.ManagedService;
+import org.osgi.service.cdi.ComponentType;
+import org.osgi.service.cdi.ConfigurationPolicy;
+import org.osgi.service.cdi.MaximumCardinality;
+import org.osgi.service.cdi.runtime.dto.ContainerDTO;
+import org.osgi.service.cdi.runtime.dto.template.ComponentTemplateDTO;
+import org.osgi.service.cdi.runtime.dto.template.ContainerTemplateDTO;
+import org.osgi.service.cm.Configuration;
+import org.osgi.service.cm.ConfigurationAdmin;
+import org.osgi.service.log.Logger;
+import org.osgi.util.promise.Deferred;
+import org.osgi.util.promise.Promise;
+import org.osgi.util.promise.PromiseFactory;
 import org.osgi.util.tracker.ServiceTracker;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
 
 public class ContainerState {
 
@@ -57,86 +73,131 @@ public class ContainerState {
                private static final long serialVersionUID = 1L;
        };
 
+       @SuppressWarnings("unchecked")
        public ContainerState(
-               Bundle bundle, Bundle extenderBundle) {
+               Bundle bundle,
+               Bundle extenderBundle,
+               ChangeCount ccrChangeCount,
+               PromiseFactory promiseFactory,
+               ServiceTracker<ConfigurationAdmin, ConfigurationAdmin> 
caTracker,
+               Logs ccrLogs) {
 
-               _bundle = Optional.ofNullable(bundle);
+               _bundle = bundle;
                _extenderBundle = extenderBundle;
+               _ccrLogs = ccrLogs;
+               _log = _ccrLogs.getLogger(getClass());
+               _containerLogs = new 
Logs.Builder(_bundle.getBundleContext()).build();
 
-               _bundle.ifPresent(
-                       b -> {
-                               _classLoader = new BundleClassLoader(
-                                       
BundleResourcesLoader.getBundles(bundle, extenderBundle));
-                       }
-               );
+               _changeCount = new ChangeCount();
+               _changeCount.addObserver(ccrChangeCount);
 
-               _context = new Context() {
+               _promiseFactory = promiseFactory;
+               _caTracker = caTracker;
 
-                       @Override
-                       public <T> T getService(ServiceReference<T> reference) {
-                               return bundleContext().getService(reference);
-                       }
+               BundleWiring bundleWiring = _bundle.adapt(BundleWiring.class);
 
-                       @Override
-                       public <T> ServiceObjects<T> 
getServiceObjects(ServiceReference<T> reference) {
-                               return 
bundleContext().getServiceObjects(reference);
-                       }
-
-                       @Override
-                       public <T> boolean ungetService(ServiceReference<T> 
reference) {
-                               return bundleContext().ungetService(reference);
-                       }
+               List<BundleWire> wires = 
bundleWiring.getRequiredWires(EXTENDER_NAMESPACE);
 
-               };
+               Map<String, Object> cdiAttributes = Collections.emptyMap();
 
-               _msRegistrator = new Registrator<ManagedService>() {
+               for (BundleWire wire : wires) {
+                       BundleCapability capability = wire.getCapability();
+                       Map<String, Object> attributes = 
capability.getAttributes();
+                       String extender = 
(String)attributes.get(EXTENDER_NAMESPACE);
 
-                       @Override
-                       public void registerService(String[] classNames, 
ManagedService service, Dictionary<String, ?> properties) {
-                               
registrations.add(bundleContext().registerService(ManagedService.class, 
service, properties));
+                       if (extender.equals(CDI_CAPABILITY_NAME)) {
+                               BundleRequirement requirement = 
wire.getRequirement();
+                               cdiAttributes = requirement.getAttributes();
+                               break;
                        }
+               }
 
-               };
+               _containerDTO = new ContainerDTO();
+               _containerDTO.bundle = _bundle.adapt(BundleDTO.class);
+               _containerDTO.changeCount = _changeCount.get();
+               _containerDTO.components = new CopyOnWriteArrayList<>();
+               _containerDTO.errors = new CopyOnWriteArrayList<>();
+               _containerDTO.extensions = new CopyOnWriteArrayList<>();
+               _containerDTO.template = new ContainerTemplateDTO();
+               _containerDTO.template.components = new 
CopyOnWriteArrayList<>();
+               _containerDTO.template.extensions = new 
CopyOnWriteArrayList<>();
+               _containerDTO.template.id = Optional.ofNullable(
+                       (String)cdiAttributes.get(CDI_CONTAINER_ID)
+               ).orElse(
+                       _bundle.getSymbolicName()
+               );
 
-               _bmRegistrator = new Registrator<BeanManager>() {
+               Optional.ofNullable(
+                       
(List<String>)cdiAttributes.get(REQUIREMENT_EXTENSIONS_ATTRIBUTE)
+               ).ifPresent(
+                       list -> list.stream().forEach(
+                               extensionFilter -> {
+                                       ExtendedExtensionTemplateDTO 
extensionTemplateDTO = new ExtendedExtensionTemplateDTO();
+
+                                       try {
+                                               extensionTemplateDTO.filter = 
asFilter(extensionFilter);
+                                               
extensionTemplateDTO.serviceFilter = extensionFilter;
 
-                       @Override
-                       public void registerService(String[] classNames, 
BeanManager service, Dictionary<String, ?> properties) {
-                               
registrations.add(bundleContext().registerService(BeanManager.class, service, 
properties));
-                       }
+                                               
_containerDTO.template.extensions.add(extensionTemplateDTO);
+                                       }
+                                       catch (Exception e) {
+                                               
_containerDTO.errors.add(Throw.asString(e));
+                                       }
+                               }
+                       )
+               );
+
+               _containerComponentTemplateDTO = new ComponentTemplateDTO();
+               _containerComponentTemplateDTO.activations = new 
CopyOnWriteArrayList<>();
+               _containerComponentTemplateDTO.beans = new 
CopyOnWriteArrayList<>();
+               _containerComponentTemplateDTO.configurations = new 
CopyOnWriteArrayList<>();
+               _containerComponentTemplateDTO.name = _containerDTO.template.id;
+               _containerComponentTemplateDTO.properties = 
Collections.emptyMap();
+               _containerComponentTemplateDTO.references = new 
CopyOnWriteArrayList<>();
+               _containerComponentTemplateDTO.type = ComponentType.CONTAINER;
+
+               ExtendedConfigurationTemplateDTO configurationTemplate = new 
ExtendedConfigurationTemplateDTO();
+               configurationTemplate.componentConfiguration = true;
+               configurationTemplate.maximumCardinality = 
MaximumCardinality.ONE;
+               configurationTemplate.pid = Optional.ofNullable(
+                       (String)cdiAttributes.get(CDI_CONTAINER_ID)
+               ).orElse(
+                       "osgi.cdi." + _bundle.getSymbolicName()
+               );
+               configurationTemplate.policy = ConfigurationPolicy.OPTIONAL;
 
-               };
+               
_containerComponentTemplateDTO.configurations.add(configurationTemplate);
 
-               _serviceRegistrator = new Registrator<Object>() {
+               
_containerDTO.template.components.add(_containerComponentTemplateDTO);
 
-                       @Override
-                       public void registerService(String[] classNames, Object 
service, Dictionary<String, ?> properties) {
-                               
registrations.add(bundleContext().registerService(classNames, service, 
properties));
-                       }
+               _aggregateClassLoader = new 
BundleClassLoader(getBundles(_bundle, _extenderBundle));
 
-               };
+               _beansModel = new BeansModelBuilder(this, 
_aggregateClassLoader, bundleWiring, cdiAttributes).build();
 
-               _tracker = new Tracker() {
+               _bundleClassLoader = bundleWiring.getClassLoader();
 
-                       @Override
-                       public <T> void track(String targetFilter, 
ReferenceCallback callback) {
-                               try {
-                                       Filter filter = 
bundleContext().createFilter(targetFilter);
+               try {
+                       new ContainerDiscovery(this);
+               }
+               catch (Exception e) {
+                       _log.error(l -> l.error("CCR Discovery resulted in 
errors on {}", bundle, e));
 
-                                       trackers.add(new 
ServiceTracker<>(bundleContext(), filter, callback));
-                               }
-                               catch (InvalidSyntaxException ise) {
-                                       if (_log.isErrorEnabled()) {
-                                               _log.error("CDIe - Invalid 
filter syntax in {}", targetFilter, ise);
-                                       }
-                               }
-                       }
+                       _containerDTO.errors.add(Throw.asString(e));
+               }
+       }
 
-               };
+       public <T, R> Promise<R> addCallback(CheckedCallback<T, R> 
checkedCallback) {
+               Deferred<R> deferred = _promiseFactory.deferred();
+               _callbacks.put(checkedCallback, deferred);
+               return deferred.getPromise();
        }
 
-       public Registrator<BeanManager> beanManagerRegistrator() {
-               return _bmRegistrator;
+       public BeanManager beanManager() {
+               return _beanManager;
+       }
+
+       public void beanManager(BeanManager beanManager) {
+               _beanManager = beanManager;
        }
 
        public BeansModel beansModel() {
@@ -144,93 +205,186 @@ public class ContainerState {
        }
 
        public Bundle bundle() {
-               return _bundle.orElse(null);
+               return _bundle;
        }
 
        public ClassLoader bundleClassLoader() {
-               return _bundle.map(b -> 
b.adapt(BundleWiring.class).getClassLoader()).orElse(getClass().getClassLoader());
+               return _bundleClassLoader;
        }
 
        public BundleContext bundleContext() {
-               return _bundle.map(b -> b.getBundleContext()).orElse(null);
+               return _bundle.getBundleContext();
+       }
+
+       public ServiceTracker<ConfigurationAdmin, ConfigurationAdmin> 
caTracker() {
+               return _caTracker;
+       }
+
+       public Logs ccrLogs() {
+               return _ccrLogs;
        }
 
        public ClassLoader classLoader() {
-               return _bundle.map(b -> 
_classLoader).orElse(getClass().getClassLoader());
+               return _aggregateClassLoader;
        }
 
-       public Map<OSGiBean, Map<String, ConfigurationCallback>> 
configurationCallbacks() {
-               return _configurationCallbacksMap;
+       public void closing() {
+               try {
+                       _closing.set(_promiseFactory.submit(() -> 
Boolean.TRUE).getValue());
+               } catch (InvocationTargetException | InterruptedException e) {
+                       e.printStackTrace();
+               }
        }
 
-       public Context context() {
-               return _context;
+       public ComponentContext componentContext() {
+               return _componentContext;
        }
 
-       public Bundle extenderBundle() {
-               return _extenderBundle;
+       public ComponentTemplateDTO containerComponentTemplateDTO() {
+               return _containerComponentTemplateDTO;
        }
 
-       public List<ExtensionDependency> extensionDependencies() {
-               return _extensionDependencies;
+       public ContainerDTO containerDTO() {
+               _containerDTO.changeCount = _changeCount.get();
+               return _containerDTO;
        }
 
-       public String id() {
-               return _bundle.map(b -> b.getSymbolicName() + ":" + 
b.getBundleId()).orElse("null");
+       public Logs containerLogs() {
+               return _containerLogs;
        }
 
-       @SuppressWarnings("unchecked")
-       public <T extends ResourceLoader & ProxyServices> T loader() {
-               return (T)_bundle.map(b -> new BundleResourcesLoader(b, 
_extenderBundle)).orElse(null);
+       public void error(Throwable t) {
+               containerDTO().errors.add(Throw.asString(t));
        }
 
-       public Registrator<ManagedService> managedServiceRegistrator() {
-               return _msRegistrator;
+       public Bundle extenderBundle() {
+               return _extenderBundle;
        }
 
-       public Map<OSGiBean, Map<String, ReferenceCallback>> 
referenceCallbacks() {
-               return _referenceCallbacksMap;
+       public Optional<Configuration> findConfig(String pid) {
+               return findConfigs(pid, false).map(arr -> arr[0]);
        }
 
-       public Map<OSGiBean, Map<String, ObserverMethod<ReferenceEvent<?>>>> 
referenceObservers() {
-               return _referenceObserversMap;
+       public Optional<Configuration[]> findConfigs(String pid, boolean 
factory) {
+               try {
+                       String query = "(service.pid=".concat(pid).concat(")");
+
+                       if (factory) {
+                               query = "(factory.pid=".concat(pid).concat(")");
+                       }
+
+                       return Optional.ofNullable(
+                               
_caTracker.getService().listConfigurations(query)
+                       );
+               }
+               catch (Exception e) {
+                       _log.error(l -> l.error("CCR unexpected failure 
fetching configuration for {}", pid, e));
+
+                       return Throw.exception(e);
+               }
        }
 
-       public Map<OSGiBean, ServiceDeclaration> serviceComponents() {
-               return _serviceComponents;
+       public String id() {
+               return _containerDTO.template.id;
        }
 
-       public Registrator<Object> serviceRegistrator() {
-               return _serviceRegistrator;
+       public void incrementChangeCount() {
+               _changeCount.incrementAndGet();
        }
 
-       public void setBeansModel(BeansModel beansModel) {
-               _beansModel = beansModel;
+       @SuppressWarnings("unchecked")
+       public <T extends ResourceLoader & ProxyServices> T loader() {
+               return (T)new BundleResourcesLoader(_bundle, _extenderBundle);
        }
 
-       public void setExtensionDependencies(List<ExtensionDependency> 
extensionDependencies) {
-               _extensionDependencies = extensionDependencies;
+       public PromiseFactory promiseFactory() {
+               return _promiseFactory;
        }
 
-       public Tracker tracker() {
-               return _tracker;
+       @SuppressWarnings("unchecked")
+       public <T, R> Promise<T> submit(Op op, Callable<T> task) {
+               try {
+                       switch (op.mode) {
+                               case CLOSE: {
+                                       // always perform close synchronously
+                                       _log.debug(l -> l.debug("CCR submit 
{}", op));
+                                       return 
_promiseFactory.resolved(task.call());
+                               }
+                               case OPEN:
+                                       // when closing don't do perform any 
opens
+                                       // also, don't log it since it's just 
going to be noise
+                                       if (_closing.get()) {
+                                               return 
_promiseFactory.resolved((T)new Object());
+                                       }
+                       }
+               }
+               catch (Exception e) {
+                       return _promiseFactory.failed(e);
+               }
+
+               _log.debug(l -> l.debug("CCR submit {}", op));
+
+               Promise<T> promise = _promiseFactory.submit(task);
+
+               for (Entry<CheckedCallback<?, ?>, Deferred<?>> entry : 
_callbacks.entrySet()) {
+                       CheckedCallback<T, R> cc = (CheckedCallback<T, 
R>)entry.getKey();
+                       if (cc.test(op)) {
+                               
((Deferred<R>)entry.getValue()).resolveWith(promise.then(cc, cc)).then(
+                                       s -> {
+                                               _callbacks.remove(cc);
+                                               return s;
+                                       },
+                                       f -> _callbacks.remove(cc)
+                               );
+                       }
+               }
+
+               return promise;
        }
 
-       private static final Logger _log = 
LoggerFactory.getLogger(ContainerState.class);
+       private static Bundle[] getBundles(Bundle bundle, Bundle 
extenderBundle) {
+               List<Bundle> bundles = new ArrayList<>();
+
+               bundles.add(bundle);
+               bundles.add(extenderBundle);
+
+               BundleWiring extenderWiring = 
extenderBundle.adapt(BundleWiring.class);
+
+               List<BundleWire> requiredWires = 
extenderWiring.getRequiredWires(PackageNamespace.PACKAGE_NAMESPACE);
+
+               for (BundleWire bundleWire : requiredWires) {
+                       BundleCapability capability = 
bundleWire.getCapability();
+                       Map<String, Object> attributes = 
capability.getAttributes();
+                       String packageName = 
(String)attributes.get(PackageNamespace.PACKAGE_NAMESPACE);
+                       if (!packageName.startsWith("org.jboss.weld.")) {
+                               continue;
+                       }
+
+                       Bundle wireBundle = 
bundleWire.getProvider().getBundle();
+                       if (!bundles.contains(wireBundle)) {
+                               bundles.add(wireBundle);
+                       }
+               }
+
+               return bundles.toArray(new Bundle[0]);
+       }
 
-       private BeansModel _beansModel;
-       private final Registrator<BeanManager> _bmRegistrator;
-       private final Optional<Bundle> _bundle;
-       private ClassLoader _classLoader;
-       private final Map<OSGiBean, Map<String, ConfigurationCallback>> 
_configurationCallbacksMap = new ConcurrentHashMap<>();
-       private final Context _context;
+       private final ClassLoader _aggregateClassLoader;
+       private volatile BeanManager _beanManager;
+       private final BeansModel _beansModel;
+       private final Bundle _bundle;
+       private final ClassLoader _bundleClassLoader;
+       private final Map<CheckedCallback<?, ?>, Deferred<?>> _callbacks = new 
ConcurrentHashMap<>();
+       private final ServiceTracker<ConfigurationAdmin, ConfigurationAdmin> 
_caTracker;
+       private final Logger _log;
+       private final Logs _ccrLogs;
+       private final ChangeCount _changeCount;
+       private final AtomicBoolean _closing = new AtomicBoolean(false);
+       private final ComponentContext _componentContext = new 
ComponentContext();
+       private final ContainerDTO _containerDTO;
+       private final Logs _containerLogs;
+       private final ComponentTemplateDTO _containerComponentTemplateDTO;
        private final Bundle _extenderBundle;
-       private List<ExtensionDependency> _extensionDependencies;
-       private final Registrator<ManagedService> _msRegistrator;
-       private final Map<OSGiBean, Map<String, ReferenceCallback>> 
_referenceCallbacksMap = new ConcurrentHashMap<>();
-       private final Map<OSGiBean, Map<String, 
ObserverMethod<ReferenceEvent<?>>>> _referenceObserversMap = new 
ConcurrentHashMap<>();
-       private final Map<OSGiBean, ServiceDeclaration> _serviceComponents = 
new ConcurrentHashMap<>();
-       private final Registrator<Object> _serviceRegistrator;
-       private final Tracker _tracker;
+       private final PromiseFactory _promiseFactory;
 
 }
\ No newline at end of file

Added: 
aries/trunk/cdi/cdi-extender/src/main/java/org/apache/aries/cdi/container/internal/container/DiscoveryExtension.java
URL: 
http://svn.apache.org/viewvc/aries/trunk/cdi/cdi-extender/src/main/java/org/apache/aries/cdi/container/internal/container/DiscoveryExtension.java?rev=1829115&view=auto
==============================================================================
--- 
aries/trunk/cdi/cdi-extender/src/main/java/org/apache/aries/cdi/container/internal/container/DiscoveryExtension.java
 (added)
+++ 
aries/trunk/cdi/cdi-extender/src/main/java/org/apache/aries/cdi/container/internal/container/DiscoveryExtension.java
 Sat Apr 14 01:10:27 2018
@@ -0,0 +1,596 @@
+/**
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.aries.cdi.container.internal.container;
+
+import java.lang.annotation.Annotation;
+import java.lang.reflect.Executable;
+import java.lang.reflect.Parameter;
+import java.util.AbstractMap.SimpleEntry;
+import java.util.Collections;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Map.Entry;
+import java.util.Optional;
+import java.util.Set;
+import java.util.concurrent.CopyOnWriteArrayList;
+import java.util.stream.Collectors;
+
+import javax.enterprise.context.ApplicationScoped;
+import javax.enterprise.context.Dependent;
+import javax.enterprise.event.Observes;
+import javax.enterprise.inject.spi.AfterBeanDiscovery;
+import javax.enterprise.inject.spi.Annotated;
+import javax.enterprise.inject.spi.AnnotatedField;
+import javax.enterprise.inject.spi.AnnotatedMethod;
+import javax.enterprise.inject.spi.AnnotatedParameter;
+import javax.enterprise.inject.spi.AnnotatedType;
+import javax.enterprise.inject.spi.Bean;
+import javax.enterprise.inject.spi.BeanManager;
+import javax.enterprise.inject.spi.DefinitionException;
+import javax.enterprise.inject.spi.Extension;
+import javax.enterprise.inject.spi.InjectionPoint;
+import javax.enterprise.inject.spi.ObserverMethod;
+import javax.enterprise.inject.spi.ProcessAnnotatedType;
+import javax.enterprise.inject.spi.ProcessBean;
+import javax.enterprise.inject.spi.ProcessInjectionPoint;
+import javax.enterprise.inject.spi.ProcessManagedBean;
+import javax.enterprise.inject.spi.ProcessObserverMethod;
+import javax.enterprise.inject.spi.ProcessProducerField;
+import javax.enterprise.inject.spi.ProcessProducerMethod;
+import javax.enterprise.inject.spi.ProcessSessionBean;
+import javax.enterprise.inject.spi.ProcessSyntheticBean;
+
+import org.apache.aries.cdi.container.internal.model.BeansModel;
+import org.apache.aries.cdi.container.internal.model.ConfigurationModel;
+import 
org.apache.aries.cdi.container.internal.model.ExtendedActivationTemplateDTO;
+import 
org.apache.aries.cdi.container.internal.model.ExtendedComponentTemplateDTO;
+import 
org.apache.aries.cdi.container.internal.model.ExtendedConfigurationTemplateDTO;
+import org.apache.aries.cdi.container.internal.model.OSGiBean;
+import org.apache.aries.cdi.container.internal.model.ReferenceModel;
+import org.apache.aries.cdi.container.internal.model.ReferenceModel.Builder;
+import org.apache.aries.cdi.container.internal.util.Maps;
+import org.apache.aries.cdi.container.internal.util.Types;
+import org.osgi.service.cdi.ComponentType;
+import org.osgi.service.cdi.ConfigurationPolicy;
+import org.osgi.service.cdi.MaximumCardinality;
+import org.osgi.service.cdi.ServiceScope;
+import org.osgi.service.cdi.annotations.Bundle;
+import org.osgi.service.cdi.annotations.ComponentScoped;
+import org.osgi.service.cdi.annotations.Configuration;
+import org.osgi.service.cdi.annotations.FactoryComponent;
+import org.osgi.service.cdi.annotations.PID;
+import org.osgi.service.cdi.annotations.Prototype;
+import org.osgi.service.cdi.annotations.Reference;
+import org.osgi.service.cdi.annotations.SingleComponent;
+import org.osgi.service.cdi.reference.ReferenceEvent;
+import org.osgi.service.cdi.runtime.dto.template.ComponentTemplateDTO;
+
+public class DiscoveryExtension implements Extension {
+
+       public DiscoveryExtension(ContainerState containerState) {
+               _containerState = containerState;
+               _beansModel = _containerState.beansModel();
+               _containerTemplate = 
_containerState.containerDTO().template.components.get(0);
+       }
+
+       static Entry<Class<?>, Annotated> 
getBeanClassAndAnnotated(ProcessBean<?> pb) {
+               Annotated annotated = null;
+               Class<?> annotatedClass = null;
+
+               if (pb instanceof ProcessManagedBean) {
+                       ProcessManagedBean<?> bean = (ProcessManagedBean<?>)pb;
+
+                       annotated = bean.getAnnotated();
+                       annotatedClass = 
bean.getAnnotatedBeanClass().getJavaClass();
+               }
+               else if (pb instanceof ProcessSessionBean) {
+                       ProcessSessionBean<?> bean = (ProcessSessionBean<?>)pb;
+
+                       annotated = bean.getAnnotated();
+                       annotatedClass = 
bean.getAnnotatedBeanClass().getJavaClass();
+               }
+               else if (pb instanceof ProcessProducerMethod) {
+                       ProcessProducerMethod<?, ?> producer = 
(ProcessProducerMethod<?, ?>)pb;
+
+                       annotated = producer.getAnnotated();
+                       annotatedClass = 
producer.getAnnotatedProducerMethod().getDeclaringType().getJavaClass();
+               }
+               else if (pb instanceof ProcessProducerField) {
+                       ProcessProducerField<?, ?> producer = 
(ProcessProducerField<?, ?>)pb;
+
+                       annotated = producer.getAnnotated();
+                       annotatedClass = 
producer.getAnnotatedProducerField().getDeclaringType().getJavaClass();
+               }
+               else if (pb instanceof ProcessSyntheticBean) {
+                       ProcessSyntheticBean<?> synthetic = 
(ProcessSyntheticBean<?>)pb;
+
+                       annotated = synthetic.getAnnotated();
+                       annotatedClass = synthetic.getBean().getBeanClass();
+               }
+               else {
+                       annotated = pb.getAnnotated();
+                       annotatedClass = pb.getBean().getBeanClass();
+               }
+
+               return new SimpleEntry<>(annotatedClass, annotated);
+       }
+
+       static Class<?> getDeclaringClass(InjectionPoint injectionPoint) {
+               Annotated annotated = injectionPoint.getAnnotated();
+
+               Class<?> declaringClass = null;
+
+               if (annotated instanceof AnnotatedParameter) {
+                       AnnotatedParameter<?> ap = 
(AnnotatedParameter<?>)annotated;
+
+                       Parameter javaParameter = ap.getJavaParameter();
+
+                       Executable executable = 
javaParameter.getDeclaringExecutable();
+
+                       declaringClass = executable.getDeclaringClass();
+               }
+               else {
+                       AnnotatedField<?> af = (AnnotatedField<?>)annotated;
+
+                       declaringClass = af.getDeclaringType().getJavaClass();
+               }
+
+               return declaringClass;
+       }
+
+       void afterBeanDiscovery(@Observes AfterBeanDiscovery abd, BeanManager 
beanManager) {
+               
_containerState.containerDTO().template.components.stream().filter(
+                       template -> template.type != ComponentType.CONTAINER
+               ).map(
+                       template -> (ExtendedComponentTemplateDTO)template
+               ).forEach(
+                       template -> {
+                               Set<Bean<?>> visited = new HashSet<>();
+                               scanComponentBean(template, template.bean, 
beanManager, visited);
+                       }
+               );
+
+               _beansModel.getOSGiBeans().stream().forEach(
+                       osgiBean -> {
+                               if (!osgiBean.found()) {
+                                       abd.addDefinitionError(
+                                               new DefinitionException(
+                                                       String.format(
+                                                               "Did not find 
bean for <cdi:bean class=\"%s\">",
+                                                               
osgiBean.getBeanClass())));
+                               }
+                       }
+               );
+       }
+
+       <X> void processAnnotatedType(@Observes ProcessAnnotatedType<X> pat, 
BeanManager beanManager) {
+               final AnnotatedType<X> at = pat.getAnnotatedType();
+
+               Class<X> annotatedClass = at.getJavaClass();
+
+               final String className = annotatedClass.getName();
+
+               OSGiBean osgiBean = _beansModel.getOSGiBean(className);
+
+               if (osgiBean == null) {
+                       return;
+               }
+
+               osgiBean.found(true);
+       }
+
+       @SuppressWarnings("rawtypes")
+       void processBean(@Observes ProcessBean<?> pb) {
+               Entry<Class<?>, Annotated> beanClassAndAnnotated = 
getBeanClassAndAnnotated(pb);
+
+               final Class<?> annotatedClass = beanClassAndAnnotated.getKey();
+
+               String className = annotatedClass.getName();
+
+               OSGiBean osgiBean = _beansModel.getOSGiBean(className);
+
+               if (osgiBean == null) {
+                       return;
+               }
+
+               osgiBean.found(true);
+
+               final Annotated annotated = beanClassAndAnnotated.getValue();
+
+               try {
+                       List<Class<?>> serviceTypes = 
Types.collectServiceTypes(annotated);
+
+                       if ((annotated instanceof AnnotatedType) &&
+                               Optional.ofNullable(
+                                       
annotated.getAnnotation(SingleComponent.class)).isPresent()) {
+
+                               ExtendedComponentTemplateDTO componentTemplate 
= new ExtendedComponentTemplateDTO();
+                               componentTemplate.activations = new 
CopyOnWriteArrayList<>();
+
+                               ExtendedActivationTemplateDTO 
activationTemplate = new ExtendedActivationTemplateDTO();
+                               activationTemplate.declaringClass = 
annotatedClass;
+                               activationTemplate.properties = 
Collections.emptyMap();
+                               activationTemplate.scope = getScope(annotated);
+                               activationTemplate.serviceClasses = 
serviceTypes.stream().map(
+                                       st -> st.getName()
+                               ).collect(Collectors.toList());
+
+                               
componentTemplate.activations.add(activationTemplate);
+
+                               componentTemplate.bean = pb.getBean();
+                               componentTemplate.beans = new 
CopyOnWriteArrayList<>();
+                               componentTemplate.configurations = new 
CopyOnWriteArrayList<>();
+                               componentTemplate.name = pb.getBean().getName();
+                               componentTemplate.properties = 
Maps.componentProperties(annotated);
+                               componentTemplate.references = new 
CopyOnWriteArrayList<>();
+                               componentTemplate.type = ComponentType.SINGLE;
+
+                               
annotated.getAnnotations(PID.class).stream().forEach(
+                                       PID -> {
+                                               
ExtendedConfigurationTemplateDTO configurationTemplate = new 
ExtendedConfigurationTemplateDTO();
+
+                                               
configurationTemplate.componentConfiguration = true;
+                                               
configurationTemplate.declaringClass = annotatedClass;
+                                               
configurationTemplate.maximumCardinality = MaximumCardinality.ONE;
+                                               configurationTemplate.pid = 
Optional.of(PID.value()).map(
+                                                       s -> {
+                                                               if 
(s.equals("$") || s.equals("")) {
+                                                                       return 
componentTemplate.name;
+                                                               }
+                                                               return s;
+                                                       }
+                                               
).orElse(componentTemplate.name);
+
+                                               if (PID.value().equals("$") || 
PID.value().equals("")) {
+                                                       
configurationTemplate.pid = componentTemplate.name;
+                                               }
+                                               else {
+                                                       
configurationTemplate.pid = PID.value();
+                                               }
+
+                                               configurationTemplate.policy = 
PID.policy();
+
+                                               
componentTemplate.configurations.add(configurationTemplate);
+                                       }
+                               );
+
+                               if (componentTemplate.configurations.isEmpty()) 
{
+                                       ExtendedConfigurationTemplateDTO 
configurationTemplate = new ExtendedConfigurationTemplateDTO();
+
+                                       
configurationTemplate.componentConfiguration = true;
+                                       configurationTemplate.declaringClass = 
annotatedClass;
+                                       
configurationTemplate.maximumCardinality = MaximumCardinality.ONE;
+                                       configurationTemplate.pid = 
componentTemplate.name;
+                                       configurationTemplate.policy = 
ConfigurationPolicy.OPTIONAL;
+
+                                       
componentTemplate.configurations.add(configurationTemplate);
+                               }
+
+                               componentTemplate.beans.add(className);
+
+                               
_containerState.containerDTO().template.components.add(componentTemplate);
+
+                               osgiBean.setComponent(componentTemplate);
+                       }
+                       else if ((annotated instanceof AnnotatedType) &&
+                                       Optional.ofNullable(
+                                       
annotated.getAnnotation(FactoryComponent.class)).isPresent()) {
+
+                               ExtendedComponentTemplateDTO componentTemplate 
= new ExtendedComponentTemplateDTO();
+                               componentTemplate.activations = new 
CopyOnWriteArrayList<>();
+
+                               ExtendedActivationTemplateDTO 
activationTemplate = new ExtendedActivationTemplateDTO();
+                               activationTemplate.declaringClass = 
annotatedClass;
+                               activationTemplate.properties = 
Collections.emptyMap();
+                               activationTemplate.scope = getScope(annotated);
+                               activationTemplate.serviceClasses = 
serviceTypes.stream().map(
+                                       st -> st.getName()
+                               ).collect(Collectors.toList());
+
+                               
componentTemplate.activations.add(activationTemplate);
+
+                               componentTemplate.bean = pb.getBean();
+                               componentTemplate.beans = new 
CopyOnWriteArrayList<>();
+                               componentTemplate.configurations = new 
CopyOnWriteArrayList<>();
+                               componentTemplate.name = pb.getBean().getName();
+                               componentTemplate.properties = 
Maps.componentProperties(annotated);
+                               componentTemplate.references = new 
CopyOnWriteArrayList<>();
+                               componentTemplate.type = ComponentType.FACTORY;
+
+                               
annotated.getAnnotations(PID.class).stream().forEach(
+                                       PID -> {
+                                               
ExtendedConfigurationTemplateDTO configurationTemplate = new 
ExtendedConfigurationTemplateDTO();
+
+                                               
configurationTemplate.componentConfiguration = true;
+                                               
configurationTemplate.declaringClass = annotatedClass;
+                                               
configurationTemplate.maximumCardinality = MaximumCardinality.ONE;
+                                               configurationTemplate.pid = 
Optional.of(PID.value()).map(
+                                                       s -> {
+                                                               if 
(s.equals("$") || s.equals("")) {
+                                                                       return 
componentTemplate.name;
+                                                               }
+                                                               return s;
+                                                       }
+                                               
).orElse(componentTemplate.name);
+
+                                               configurationTemplate.policy = 
PID.policy();
+
+                                               
componentTemplate.configurations.add(configurationTemplate);
+                                       }
+                               );
+
+                               ExtendedConfigurationTemplateDTO 
configurationTemplate = new ExtendedConfigurationTemplateDTO();
+
+                               configurationTemplate.componentConfiguration = 
true;
+                               configurationTemplate.declaringClass = 
annotatedClass;
+                               configurationTemplate.maximumCardinality = 
MaximumCardinality.MANY;
+                               configurationTemplate.pid = Optional.ofNullable(
+                                       
annotated.getAnnotation(FactoryComponent.class)
+                               ).map(fc -> {
+                                       if (fc.value().equals("$") || 
fc.value().equals("")) {
+                                               return componentTemplate.name;
+                                       }
+                                       return fc.value();
+                               }).orElse(componentTemplate.name);
+                               configurationTemplate.policy = 
ConfigurationPolicy.REQUIRED;
+
+                               
componentTemplate.configurations.add(configurationTemplate);
+                               componentTemplate.beans.add(className);
+
+                               
_containerState.containerDTO().template.components.add(componentTemplate);
+
+                               osgiBean.setComponent(componentTemplate);
+                       }
+                       else if ((annotated instanceof AnnotatedType) &&
+                                       Optional.ofNullable(
+                                       
annotated.getAnnotation(ComponentScoped.class)).isPresent()) {
+
+                               // Explicitly ignore this case
+                       }
+                       else {
+                               if 
(!_containerTemplate.beans.contains(className)) {
+                                       _containerTemplate.beans.add(className);
+                               }
+
+                               if (!serviceTypes.isEmpty()) {
+                                       Class<? extends Annotation> scope = 
pb.getBean().getScope();
+                                       if 
(!scope.equals(ApplicationScoped.class) &&
+                                               !scope.equals(Dependent.class)) 
{
+
+                                               pb.addDefinitionError(
+                                                       new 
IllegalStateException(
+                                                               String.format(
+                                                                       
"@Service can only be used on @ApplicationScoped, @Dependent, @SingleComponent, 
and @FactoryComponent: %s",
+                                                                       
pb.getBean())));
+                                               return;
+                                       }
+
+                                       ExtendedActivationTemplateDTO 
activationTemplate = new ExtendedActivationTemplateDTO();
+                                       activationTemplate.cdiScope = scope;
+                                       activationTemplate.declaringClass = 
annotatedClass;
+                                       if (pb instanceof ProcessProducerField) 
{
+                                               activationTemplate.producer = 
((ProcessProducerField) pb).getAnnotatedProducerField();
+                                       }
+                                       else if (pb instanceof 
ProcessProducerMethod) {
+                                               activationTemplate.producer = 
((ProcessProducerMethod) pb).getAnnotatedProducerMethod();
+                                       }
+                                       activationTemplate.properties = 
Maps.componentProperties(annotated);
+                                       activationTemplate.scope = 
getScope(annotated);
+                                       activationTemplate.serviceClasses = 
serviceTypes.stream().map(
+                                               st -> st.getName()
+                                       ).collect(Collectors.toList());
+
+                                       
_containerTemplate.activations.add(activationTemplate);
+                               }
+
+                               osgiBean.setComponent(_containerTemplate);
+                       }
+               }
+               catch (Exception e) {
+                       pb.addDefinitionError(e);
+               }
+       }
+
+       void processInjectionPoint(@Observes ProcessInjectionPoint<?, ?> pip) {
+               InjectionPoint injectionPoint = pip.getInjectionPoint();
+
+               Class<?> declaringClass = getDeclaringClass(injectionPoint);
+
+               String className = declaringClass.getName();
+
+               OSGiBean osgiBean = _beansModel.getOSGiBean(className);
+
+               if (osgiBean == null) {
+                       return;
+               }
+
+               Annotated annotated = injectionPoint.getAnnotated();
+               Reference reference = annotated.getAnnotation(Reference.class);
+               Configuration configuration = 
annotated.getAnnotation(Configuration.class);
+
+               if (reference != null) {
+                       if (configuration != null) {
+                               _containerState.error(
+                                       new IllegalArgumentException(
+                                               String.format(
+                                                       "Cannot use @Reference 
and @Configuration on the same injection point {}",
+                                                       injectionPoint))
+                               );
+
+                               return;
+                       }
+
+                       Builder builder = null;
+
+                       if (annotated instanceof AnnotatedParameter) {
+                               builder = new 
ReferenceModel.Builder((AnnotatedParameter<?>)annotated);
+                       }
+                       else {
+                               builder = new 
ReferenceModel.Builder((AnnotatedField<?>)annotated);
+                       }
+
+                       try {
+                               ReferenceModel referenceModel = 
builder.type(injectionPoint.getType()).build();
+
+                               osgiBean.addReference(referenceModel.toDTO());
+                       }
+                       catch (Exception e) {
+                               _containerState.error(e);
+                       }
+               }
+               else if (configuration != null) {
+                       try {
+                               ConfigurationModel configurationModel = new 
ConfigurationModel.Builder(
+                                       injectionPoint.getType()
+                               ).declaringClass(
+                                       declaringClass
+                               ).injectionPoint(
+                                       injectionPoint
+                               ).build();
+
+                               
osgiBean.addConfiguration(configurationModel.toDTO());
+                       }
+                       catch (Exception e) {
+                               _containerState.error(e);
+                       }
+               }
+       }
+
+       void processObserverMethod(@Observes 
ProcessObserverMethod<ReferenceEvent<?>, ?> pom) {
+               ObserverMethod<ReferenceEvent<?>> observerMethod = 
pom.getObserverMethod();
+
+               AnnotatedMethod<?> annotatedMethod = pom.getAnnotatedMethod();
+
+               Configuration configuration = 
annotatedMethod.getAnnotation(Configuration.class);
+
+               if (configuration != null) {
+                       pom.addDefinitionError(
+                               new IllegalArgumentException(
+                                       String.format(
+                                               "Cannot use @Configuration on 
ReferenceEvent observer method {}",
+                                               observerMethod))
+                       );
+
+                       return;
+               }
+
+               Class<?> beanClass = observerMethod.getBeanClass();
+
+               final String className = beanClass.getName();
+
+               OSGiBean osgiBean = _beansModel.getOSGiBean(className);
+
+               if (osgiBean == null) {
+                       pom.addDefinitionError(
+                               new DefinitionException(
+                                       String.format(
+                                               "The observer method %s was not 
declared as <cdi:bean class=\"%s\">",
+                                               observerMethod, className))
+                       );
+
+                       return;
+               }
+
+               try {
+                       ReferenceModel referenceModel = new 
ReferenceModel.Builder(
+                               pom.getAnnotatedMethod().getParameters().get(0)
+                       ).type(observerMethod.getObservedType()).build();
+
+                       osgiBean.addReference(referenceModel.toDTO());
+               }
+               catch (Exception e) {
+                       pom.addDefinitionError(e);
+               }
+       }
+
+       ServiceScope getScope(Annotated annotated) {
+               Prototype prototype = annotated.getAnnotation(Prototype.class);
+               Bundle bundle = annotated.getAnnotation(Bundle.class);
+
+               if (prototype != null) {
+                       if (bundle != null) {
+                               throw new IllegalArgumentException(
+                                       String.format(
+                                               "@Prototype and @Bundle must 
not be used to gether: %s",
+                                               annotated));
+                       }
+
+                       return ServiceScope.PROTOTYPE;
+               }
+
+               if (bundle != null) {
+                       return ServiceScope.BUNDLE;
+               }
+
+               return ServiceScope.SINGLETON;
+       }
+
+       void scanComponentBean(
+               ExtendedComponentTemplateDTO template,
+               Bean<?> bean,
+               BeanManager beanManager,
+               Set<Bean<?>> visited) {
+
+               if (visited.contains(bean)) {
+                       return;
+               }
+
+               visited.add(bean);
+
+               Class<?> beanClass = bean.getBeanClass();
+
+               String className = beanClass.getName();
+
+               OSGiBean osgiBean = _beansModel.getOSGiBean(className);
+
+               ComponentTemplateDTO currentTemplate = osgiBean.getComponent();
+
+               if (currentTemplate == null) {
+                       osgiBean.setComponent(template);
+               }
+               else if (!currentTemplate.equals(template)) {
+                       throw new IllegalStateException("Something is wrong 
here");
+               }
+
+               if (!template.beans.contains(className)) {
+                       template.beans.add(className);
+               }
+
+               for (InjectionPoint injectionPoint : bean.getInjectionPoints()) 
{
+                       if 
((injectionPoint.getAnnotated().getAnnotation(Configuration.class) != null) ||
+                               
(injectionPoint.getAnnotated().getAnnotation(Reference.class) != null)) {
+
+                               continue;
+                       }
+
+                       Set<Bean<?>> beans = beanManager.getBeans(
+                               injectionPoint.getType(),
+                               injectionPoint.getQualifiers().toArray(new 
Annotation[0]));
+
+                       Bean<?> next = beanManager.resolve(beans);
+
+                       if ((next == null) || next.getScope() != 
ComponentScoped.class) {
+                               continue;
+                       }
+
+                       scanComponentBean(template, next, beanManager, visited);
+               }
+       }
+
+       private final BeansModel _beansModel;
+       private final ComponentTemplateDTO _containerTemplate;
+       private final ContainerState _containerState;
+
+}

Copied: 
aries/trunk/cdi/cdi-extender/src/main/java/org/apache/aries/cdi/container/internal/container/ExtensionMetadata.java
 (from r1829114, 
aries/trunk/cdi/cdi-extender/src/main/java/org/apache/aries/cdi/container/internal/extension/ExtensionMetadata.java)
URL: 
http://svn.apache.org/viewvc/aries/trunk/cdi/cdi-extender/src/main/java/org/apache/aries/cdi/container/internal/container/ExtensionMetadata.java?p2=aries/trunk/cdi/cdi-extender/src/main/java/org/apache/aries/cdi/container/internal/container/ExtensionMetadata.java&p1=aries/trunk/cdi/cdi-extender/src/main/java/org/apache/aries/cdi/container/internal/extension/ExtensionMetadata.java&r1=1829114&r2=1829115&rev=1829115&view=diff
==============================================================================
--- 
aries/trunk/cdi/cdi-extender/src/main/java/org/apache/aries/cdi/container/internal/extension/ExtensionMetadata.java
 (original)
+++ 
aries/trunk/cdi/cdi-extender/src/main/java/org/apache/aries/cdi/container/internal/container/ExtensionMetadata.java
 Sat Apr 14 01:10:27 2018
@@ -12,7 +12,7 @@
  * limitations under the License.
  */
 
-package org.apache.aries.cdi.container.internal.extension;
+package org.apache.aries.cdi.container.internal.container;
 
 import javax.enterprise.inject.spi.Extension;
 

Added: 
aries/trunk/cdi/cdi-extender/src/main/java/org/apache/aries/cdi/container/internal/container/ExtensionPhase.java
URL: 
http://svn.apache.org/viewvc/aries/trunk/cdi/cdi-extender/src/main/java/org/apache/aries/cdi/container/internal/container/ExtensionPhase.java?rev=1829115&view=auto
==============================================================================
--- 
aries/trunk/cdi/cdi-extender/src/main/java/org/apache/aries/cdi/container/internal/container/ExtensionPhase.java
 (added)
+++ 
aries/trunk/cdi/cdi-extender/src/main/java/org/apache/aries/cdi/container/internal/container/ExtensionPhase.java
 Sat Apr 14 01:10:27 2018
@@ -0,0 +1,278 @@
+/**
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.aries.cdi.container.internal.container;
+
+import static org.apache.aries.cdi.container.internal.util.Filters.*;
+
+import java.util.Iterator;
+import java.util.List;
+import java.util.SortedSet;
+import java.util.concurrent.ConcurrentSkipListSet;
+
+import javax.enterprise.inject.spi.Extension;
+
+import org.apache.aries.cdi.container.internal.container.Op.Mode;
+import org.apache.aries.cdi.container.internal.container.Op.Type;
+import org.apache.aries.cdi.container.internal.model.ExtendedExtensionDTO;
+import 
org.apache.aries.cdi.container.internal.model.ExtendedExtensionTemplateDTO;
+import org.apache.aries.cdi.container.internal.util.Conversions;
+import org.apache.aries.cdi.container.internal.util.SRs;
+import org.apache.aries.cdi.container.internal.util.Throw;
+import org.osgi.framework.BundleContext;
+import org.osgi.framework.Filter;
+import org.osgi.framework.ServiceReference;
+import org.osgi.service.cdi.runtime.dto.ExtensionDTO;
+import org.osgi.service.cdi.runtime.dto.template.ExtensionTemplateDTO;
+import org.osgi.service.log.Logger;
+import org.osgi.util.promise.Promise;
+import org.osgi.util.tracker.ServiceTracker;
+import org.osgi.util.tracker.ServiceTrackerCustomizer;
+
+public class ExtensionPhase extends Phase {
+
+       public ExtensionPhase(ContainerState containerState, Phase next) {
+               super(containerState, next);
+               _log = containerState.containerLogs().getLogger(getClass());
+       }
+
+       @Override
+       public boolean close() {
+               if (!extensionTemplates().isEmpty()) {
+                       if (_extensionTracker != null) {
+                               _extensionTracker.close();
+
+                               _extensionTracker = null;
+                       }
+
+                       return true;
+               }
+               else {
+                       return next.map(
+                               next -> {
+                                       submit(next.closeOp(), 
next::close).onFailure(
+                                               f -> {
+                                                       _log.error(l -> 
l.error("CCR Error in extension CLOSE on {}", bundle(), f));
+
+                                                       error(f);
+                                               }
+                                       );
+
+                                       return true;
+                               }
+                       ).orElse(true);
+               }
+       }
+
+       @Override
+       public Op closeOp() {
+               return Op.of(Mode.CLOSE, Type.EXTENSION, containerState.id());
+       }
+
+       @Override
+       public boolean open() {
+               if (!extensionTemplates().isEmpty()) {
+                       _extensionTracker = new ServiceTracker<>(
+                               containerState.bundleContext(), 
createExtensionFilter(), new ExtensionPhaseCustomizer());
+
+                       _extensionTracker.open();
+
+                       return true;
+               }
+               else {
+                       return next.map(
+                               next -> {
+                                       submit(next.openOp(), next::open).then(
+                                               null,
+                                               f -> {
+                                                       _log.error(l -> 
l.error("CCR Error in extension OPEN on {}", bundle(), f.getFailure()));
+
+                                                       error(f.getFailure());
+                                               }
+                                       );
+
+                                       return true;
+                               }
+                       ).orElse(true);
+               }
+       }
+
+       @Override
+       public Op openOp() {
+               return Op.of(Mode.OPEN, Type.EXTENSION, containerState.id());
+       }
+
+       Filter createExtensionFilter() {
+               final List<ExtensionTemplateDTO> templates = 
extensionTemplates();
+
+               StringBuilder sb = new StringBuilder("(&(objectClass=" + 
Extension.class.getName() + ")");
+
+               if (templates.size() > 1) sb.append("(|");
+
+               for (ExtensionTemplateDTO tmpl : templates) {
+                       sb.append(tmpl.serviceFilter);
+               }
+
+               if (templates.size() > 1) sb.append(")");
+
+               sb.append(")");
+
+               return asFilter(sb.toString());
+       }
+
+       List<ExtensionTemplateDTO> extensionTemplates() {
+               return containerState.containerDTO().template.extensions;
+       }
+
+       List<ExtensionDTO> snapshots() {
+               return containerState.containerDTO().extensions;
+       }
+
+
+       private ServiceTracker<Extension, ExtendedExtensionDTO> 
_extensionTracker;
+       private final Logger _log;
+       private final SortedSet<ExtendedExtensionDTO> _references = new 
ConcurrentSkipListSet<>(
+               (e1, e2) -> e1.serviceReference.compareTo(e2.serviceReference)
+       );
+
+       private class ExtensionPhaseCustomizer implements 
ServiceTrackerCustomizer<Extension, ExtendedExtensionDTO> {
+
+               @Override
+               public ExtendedExtensionDTO 
addingService(ServiceReference<Extension> reference) {
+                       ExtendedExtensionTemplateDTO template = 
extensionTemplates().stream().map(
+                               t -> (ExtendedExtensionTemplateDTO)t
+                       ).filter(
+                               t -> t.filter.match(reference)
+                       ).findFirst().get();
+
+                       ExtendedExtensionDTO snapshot = 
snapshots().stream().map(
+                               s -> (ExtendedExtensionDTO)s
+                       ).filter(
+                               s -> s.template == template
+                       ).findFirst().orElse(null);
+
+                       if (snapshot != null) {
+                               if 
(reference.compareTo(snapshot.serviceReference) <= 0) {
+                                       return null;
+                               }
+
+                               if (snapshots().remove(snapshot)) {
+                                       _references.add(snapshot);
+                                       snapshot.extension = null;
+                                       
containerState.bundleContext().ungetService(snapshot.serviceReference);
+                               }
+                       }
+
+                       ExtendedExtensionDTO extensionDTO = new 
ExtendedExtensionDTO();
+
+                       BundleContext bc = containerState.bundleContext();
+
+                       extensionDTO.extension = 
bc.getServiceObjects(reference);
+                       extensionDTO.service = SRs.from(reference);
+                       extensionDTO.serviceReference = reference;
+                       extensionDTO.template = template;
+
+                       snapshots().add(extensionDTO);
+                       containerState.incrementChangeCount();
+
+                       if (snapshots().size() == extensionTemplates().size()) {
+                               next.ifPresent(
+                                       next -> submit(next.closeOp(), 
next::close).then(
+                                               s -> {
+                                                       return 
submit(next.openOp(), next::open).then(
+                                                               null,
+                                                               f -> {
+                                                                       
_log.error(l -> l.error("CCR Error in extension open TRACKING {} on {}", 
reference, bundle(), f.getFailure()));
+
+                                                                       
error(f.getFailure());
+                                                               }
+                                                       );
+                                               },
+                                               f -> {
+                                                       _log.error(l -> 
l.error("CCR Error extension close TRACKING {} on {}", reference, bundle(), 
f.getFailure()));
+
+                                                       error(f.getFailure());
+                                               }
+                                       )
+                               );
+                       }
+
+                       return extensionDTO;
+               }
+
+               @Override
+               public void modifiedService(ServiceReference<Extension> 
reference, ExtendedExtensionDTO extentionDTO) {
+                       removedService(reference, extentionDTO);
+                       addingService(reference);
+               }
+
+               @Override
+               public void removedService(ServiceReference<Extension> 
reference, final ExtendedExtensionDTO extensionDTO) {
+                       _log.debug(l -> l.debug("CCR Departing extension {} on 
{}", Conversions.convert(extensionDTO).to(ExtensionDTO.class), bundle()));
+
+                       containerState.bundleContext().ungetService(reference);
+
+                       if (!snapshots().removeIf(snap -> 
((ExtendedExtensionDTO)snap).serviceReference.equals(reference))) {
+                               return;
+                       }
+
+                       for (Iterator<ExtendedExtensionDTO> itr = 
_references.iterator();itr.hasNext();) {
+                               ExtendedExtensionDTO entry = itr.next();
+                               if 
(((ExtendedExtensionTemplateDTO)extensionDTO.template).filter.match(entry.serviceReference))
 {
+                                       entry.extension = 
containerState.bundleContext().getServiceObjects(entry.serviceReference);
+                                       itr.remove();
+                                       snapshots().add(entry);
+                                       break;
+                               }
+                       }
+
+                       containerState.incrementChangeCount();
+
+                       next.ifPresent(
+                               next -> {
+                                       Promise<Boolean> result = 
submit(next.closeOp(), next::close).then(
+                                               s -> {
+                                                       if (snapshots().size() 
== extensionTemplates().size()) {
+                                                               return 
submit(next.openOp(), next::open).then(
+                                                                       null,
+                                                                       f -> {
+                                                                               
_log.error(l -> l.error("CCR Error in extension open {} on {}", reference, 
bundle()));
+
+                                                                               
error(f.getFailure());
+                                                                       }
+                                                               );
+                                                       }
+
+                                                       return s;
+                                               },
+                                               f -> {
+                                                       _log.error(l -> 
l.error("CCR Error in extension close {} on {}", reference, bundle()));
+
+                                                       error(f.getFailure());
+                                               }
+                                       );
+
+                                       try {
+                                               result.getValue();
+                                       }
+                                       catch (Exception e) {
+                                               Throw.exception(e);
+                                       }
+                               }
+                       );
+               }
+
+       }
+
+}

Added: 
aries/trunk/cdi/cdi-extender/src/main/java/org/apache/aries/cdi/container/internal/container/LoggerExtension.java
URL: 
http://svn.apache.org/viewvc/aries/trunk/cdi/cdi-extender/src/main/java/org/apache/aries/cdi/container/internal/container/LoggerExtension.java?rev=1829115&view=auto
==============================================================================
--- 
aries/trunk/cdi/cdi-extender/src/main/java/org/apache/aries/cdi/container/internal/container/LoggerExtension.java
 (added)
+++ 
aries/trunk/cdi/cdi-extender/src/main/java/org/apache/aries/cdi/container/internal/container/LoggerExtension.java
 Sat Apr 14 01:10:27 2018
@@ -0,0 +1,61 @@
+/**
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.aries.cdi.container.internal.container;
+
+import javax.enterprise.event.Observes;
+import javax.enterprise.inject.spi.AfterBeanDiscovery;
+import javax.enterprise.inject.spi.Extension;
+import javax.enterprise.inject.spi.InjectionPoint;
+import javax.enterprise.inject.spi.configurator.BeanConfigurator;
+
+import org.osgi.service.log.FormatterLogger;
+import org.osgi.service.log.Logger;
+import org.osgi.service.log.LoggerFactory;
+
+public class LoggerExtension implements Extension {
+
+       public LoggerExtension(ContainerState containerState) {
+               _containerState = containerState;
+       }
+
+       void afterBeanDiscovery(@Observes AfterBeanDiscovery abd) {
+               final LoggerFactory lf = 
_containerState.containerLogs().getLoggerFactory();
+
+               BeanConfigurator<FormatterLogger> formatterLoggerBean = 
abd.addBean();
+               formatterLoggerBean.addType(FormatterLogger.class);
+               formatterLoggerBean.produceWith(
+                       i -> {
+                               InjectionPoint ip = 
i.select(InjectionPoint.class).get();
+                               return lf.getLogger(
+                                       
ip.getMember().getDeclaringClass().getName(),
+                                       FormatterLogger.class);
+                       }
+               );
+
+               BeanConfigurator<Logger> loggerBean = abd.addBean();
+               loggerBean.addType(Logger.class);
+               loggerBean.produceWith(
+                       i -> {
+                               InjectionPoint ip = 
i.select(InjectionPoint.class).get();
+                               return lf.getLogger(
+                                       
ip.getMember().getDeclaringClass().getName(),
+                                       Logger.class);
+                       }
+               );
+       }
+
+       private final ContainerState _containerState;
+
+}

Copied: 
aries/trunk/cdi/cdi-extender/src/main/java/org/apache/aries/cdi/container/internal/container/Mark.java
 (from r1829114, 
aries/trunk/cdi/cdi-extender/src/main/java/org/apache/aries/cdi/container/internal/literal/CdiMark.java)
URL: 
http://svn.apache.org/viewvc/aries/trunk/cdi/cdi-extender/src/main/java/org/apache/aries/cdi/container/internal/container/Mark.java?p2=aries/trunk/cdi/cdi-extender/src/main/java/org/apache/aries/cdi/container/internal/container/Mark.java&p1=aries/trunk/cdi/cdi-extender/src/main/java/org/apache/aries/cdi/container/internal/literal/CdiMark.java&r1=1829114&r2=1829115&rev=1829115&view=diff
==============================================================================
--- 
aries/trunk/cdi/cdi-extender/src/main/java/org/apache/aries/cdi/container/internal/literal/CdiMark.java
 (original)
+++ 
aries/trunk/cdi/cdi-extender/src/main/java/org/apache/aries/cdi/container/internal/container/Mark.java
 Sat Apr 14 01:10:27 2018
@@ -12,19 +12,41 @@
  * limitations under the License.
  */
 
-package org.apache.aries.cdi.container.internal.literal;
+package org.apache.aries.cdi.container.internal.container;
 
 import java.lang.annotation.ElementType;
 import java.lang.annotation.Retention;
 import java.lang.annotation.RetentionPolicy;
 import java.lang.annotation.Target;
 
+import javax.enterprise.util.AnnotationLiteral;
 import javax.inject.Qualifier;
 
 @Qualifier
 @Target(value = {ElementType.FIELD, ElementType.METHOD, ElementType.PARAMETER, 
ElementType.TYPE})
 @Retention(value = RetentionPolicy.RUNTIME)
-public @interface CdiMark {
+public @interface Mark {
+
+       public class Literal extends AnnotationLiteral<Mark> implements Mark {
+
+               private static final long serialVersionUID = 1L;
+
+               public static Literal from(int i) {
+                       return new Literal(i);
+               }
+
+               public Literal(int i) {
+                       _value = i;
+               }
+
+               @Override
+               public int value() {
+                       return _value;
+               }
+
+               private final int _value;
+
+       }
 
        int value();
 

Copied: 
aries/trunk/cdi/cdi-extender/src/main/java/org/apache/aries/cdi/container/internal/container/MarkedInjectionPoint.java
 (from r1829114, 
aries/trunk/cdi/cdi-extender/src/main/java/org/apache/aries/cdi/container/internal/component/MarkedInjectionPoint.java)
URL: 
http://svn.apache.org/viewvc/aries/trunk/cdi/cdi-extender/src/main/java/org/apache/aries/cdi/container/internal/container/MarkedInjectionPoint.java?p2=aries/trunk/cdi/cdi-extender/src/main/java/org/apache/aries/cdi/container/internal/container/MarkedInjectionPoint.java&p1=aries/trunk/cdi/cdi-extender/src/main/java/org/apache/aries/cdi/container/internal/component/MarkedInjectionPoint.java&r1=1829114&r2=1829115&rev=1829115&view=diff
==============================================================================
--- 
aries/trunk/cdi/cdi-extender/src/main/java/org/apache/aries/cdi/container/internal/component/MarkedInjectionPoint.java
 (original)
+++ 
aries/trunk/cdi/cdi-extender/src/main/java/org/apache/aries/cdi/container/internal/container/MarkedInjectionPoint.java
 Sat Apr 14 01:10:27 2018
@@ -12,23 +12,23 @@
  * limitations under the License.
  */
 
-package org.apache.aries.cdi.container.internal.component;
+package org.apache.aries.cdi.container.internal.container;
 
 import java.lang.annotation.Annotation;
 import java.util.Set;
+import java.util.concurrent.atomic.AtomicInteger;
 
 import javax.enterprise.inject.spi.InjectionPoint;
 
-import org.apache.aries.cdi.container.internal.literal.CdiMarkLiteral;
 import org.apache.aries.cdi.container.internal.util.Sets;
 import org.jboss.weld.injection.ForwardingInjectionPoint;
 
 public class MarkedInjectionPoint extends ForwardingInjectionPoint {
 
-       public MarkedInjectionPoint(InjectionPoint injectionPoint, Annotation 
annotation, int mark) {
+       public MarkedInjectionPoint(InjectionPoint injectionPoint) {
                _delegate = injectionPoint;
-               _mark = mark;
-               _qualifiers = Sets.hashSet(injectionPoint.getQualifiers(), 
annotation, CdiMarkLiteral.from(_mark));
+               _mark = Mark.Literal.from(counter.incrementAndGet());
+               _qualifiers = Sets.hashSet(injectionPoint.getQualifiers(), 
_mark);
        }
 
        @Override
@@ -40,7 +40,7 @@ public class MarkedInjectionPoint extend
                return delegate();
        }
 
-       public int getMark() {
+       public Mark getMark() {
                return _mark;
        }
 
@@ -49,8 +49,10 @@ public class MarkedInjectionPoint extend
                return _qualifiers;
        }
 
+       private static final AtomicInteger counter = new AtomicInteger();
+
        private final InjectionPoint _delegate;
-       private final int _mark;
+       private final Mark _mark;
        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/container/Op.java
URL: 
http://svn.apache.org/viewvc/aries/trunk/cdi/cdi-extender/src/main/java/org/apache/aries/cdi/container/internal/container/Op.java?rev=1829115&view=auto
==============================================================================
--- 
aries/trunk/cdi/cdi-extender/src/main/java/org/apache/aries/cdi/container/internal/container/Op.java
 (added)
+++ 
aries/trunk/cdi/cdi-extender/src/main/java/org/apache/aries/cdi/container/internal/container/Op.java
 Sat Apr 14 01:10:27 2018
@@ -0,0 +1,62 @@
+/**
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.aries.cdi.container.internal.container;
+
+import java.util.Arrays;
+
+public class Op {
+
+       public static enum Mode {CLOSE, OPEN}
+
+       public static enum Type {
+               CONFIGURATION_EVENT,
+               CONFIGURATION_LISTENER,
+               CONTAINER_ACTIVATOR,
+               CONTAINER_BOOTSTRAP,
+               CONTAINER_COMPONENT,
+               CONTAINER_FIRE_EVENTS,
+               CONTAINER_INSTANCE,
+               CONTAINER_PUBLISH_SERVICES,
+               REFERENCES,
+               EXTENSION,
+               FACTORY_ACTIVATOR,
+               FACTORY_COMPONENT,
+               FACTORY_INSTANCE,
+               INIT,
+               SINGLE_ACTIVATOR,
+               SINGLE_COMPONENT,
+               SINGLE_INSTANCE,
+       }
+
+       public static Op of(Mode mode, Type type, String name) {
+               return new Op(mode, type, name);
+       }
+
+       private Op(Mode mode, Type type, String name) {
+               this.mode = mode;
+               this.type = type;
+               this.name = name;
+       }
+
+       public final Mode mode;
+       public final Type type;
+       public final String name;
+
+       @Override
+       public String toString() {
+               return Arrays.asList(getClass().getSimpleName(), mode, type, 
name).toString();
+       }
+
+}
\ No newline at end of file

Added: 
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/container/Phase.java?rev=1829115&view=auto
==============================================================================
--- 
aries/trunk/cdi/cdi-extender/src/main/java/org/apache/aries/cdi/container/internal/container/Phase.java
 (added)
+++ 
aries/trunk/cdi/cdi-extender/src/main/java/org/apache/aries/cdi/container/internal/container/Phase.java
 Sat Apr 14 01:10:27 2018
@@ -0,0 +1,53 @@
+/**
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.aries.cdi.container.internal.container;
+
+import java.util.Optional;
+import java.util.concurrent.Callable;
+
+import org.osgi.framework.Bundle;
+import org.osgi.util.promise.Promise;
+
+public abstract class Phase {
+
+       public Phase(ContainerState containerState, Phase next) {
+               this.containerState = containerState;
+               this.next = Optional.ofNullable(next);
+       }
+
+       public final Bundle bundle() {
+               return containerState.bundle();
+       }
+
+       public abstract Op closeOp();
+
+       public abstract boolean close();
+
+       public final void error(Throwable t) {
+               containerState.error(t);
+       }
+
+       public abstract boolean open();
+
+       public abstract Op openOp();
+
+       public final <T> Promise<T> submit(Op op, Callable<T> callable) {
+               return containerState.submit(op, callable);
+       }
+
+       protected final ContainerState containerState;
+       protected final Optional<Phase> next;
+
+}

Added: 
aries/trunk/cdi/cdi-extender/src/main/java/org/apache/aries/cdi/container/internal/container/ReferenceServiceObjectsImpl.java
URL: 
http://svn.apache.org/viewvc/aries/trunk/cdi/cdi-extender/src/main/java/org/apache/aries/cdi/container/internal/container/ReferenceServiceObjectsImpl.java?rev=1829115&view=auto
==============================================================================
--- 
aries/trunk/cdi/cdi-extender/src/main/java/org/apache/aries/cdi/container/internal/container/ReferenceServiceObjectsImpl.java
 (added)
+++ 
aries/trunk/cdi/cdi-extender/src/main/java/org/apache/aries/cdi/container/internal/container/ReferenceServiceObjectsImpl.java
 Sat Apr 14 01:10:27 2018
@@ -0,0 +1,59 @@
+/**
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.aries.cdi.container.internal.container;
+
+import java.util.Set;
+import java.util.concurrent.ConcurrentHashMap;
+
+import org.osgi.framework.ServiceObjects;
+import org.osgi.framework.ServiceReference;
+import org.osgi.service.cdi.reference.ReferenceServiceObjects;
+
+public class ReferenceServiceObjectsImpl<T> implements 
ReferenceServiceObjects<T> {
+
+       public ReferenceServiceObjectsImpl(ServiceObjects<T> so) {
+               _so = so;
+       }
+
+       public void close() {
+               _objects.removeIf(
+                       o -> {
+                               _so.ungetService(o);
+                               return true;
+                       }
+               );
+       }
+
+       @Override
+       public T getService() {
+               T service = _so.getService();
+               _objects.add(service);
+               return service;
+       }
+
+       @Override
+       public ServiceReference<T> getServiceReference() {
+               return _so.getServiceReference();
+       }
+
+       @Override
+       public void ungetService(T service) {
+               _objects.remove(service);
+               _so.ungetService(service);
+       }
+
+       private final Set<T> _objects = ConcurrentHashMap.newKeySet();
+       private final ServiceObjects<T> _so;
+}
\ No newline at end of file


Reply via email to