Added: 
aries/trunk/cdi/cdi-extender/src/main/java/org/apache/aries/cdi/container/internal/reference/ReferenceModel.java
URL: 
http://svn.apache.org/viewvc/aries/trunk/cdi/cdi-extender/src/main/java/org/apache/aries/cdi/container/internal/reference/ReferenceModel.java?rev=1807424&view=auto
==============================================================================
--- 
aries/trunk/cdi/cdi-extender/src/main/java/org/apache/aries/cdi/container/internal/reference/ReferenceModel.java
 (added)
+++ 
aries/trunk/cdi/cdi-extender/src/main/java/org/apache/aries/cdi/container/internal/reference/ReferenceModel.java
 Tue Sep  5 22:01:11 2017
@@ -0,0 +1,864 @@
+/**
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.aries.cdi.container.internal.reference;
+
+import static org.apache.aries.cdi.container.internal.model.Model.*;
+import static org.apache.aries.cdi.container.internal.util.Reflection.cast;
+import static java.lang.String.format;
+import static 
org.apache.aries.cdi.container.internal.model.Constants.CARDINALITY_ATTRIBUTE;
+import static 
org.apache.aries.cdi.container.internal.model.Constants.CDI10_URI;
+import static 
org.apache.aries.cdi.container.internal.model.Constants.NAME_ATTRIBUTE;
+import static 
org.apache.aries.cdi.container.internal.model.Constants.POLICY_ATTRIBUTE;
+import static 
org.apache.aries.cdi.container.internal.model.Constants.POLICY_OPTION_ATTRIBUTE;
+import static 
org.apache.aries.cdi.container.internal.model.Constants.SCOPE_ATTRIBUTE;
+import static 
org.apache.aries.cdi.container.internal.model.Constants.TARGET_ATTRIBUTE;
+
+import java.lang.annotation.Annotation;
+import java.lang.reflect.Field;
+import java.lang.reflect.Modifier;
+import java.lang.reflect.ParameterizedType;
+import java.lang.reflect.Type;
+import java.lang.reflect.WildcardType;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.LinkedHashSet;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+import java.util.concurrent.atomic.AtomicBoolean;
+
+import javax.enterprise.inject.Instance;
+import javax.enterprise.inject.spi.Annotated;
+import javax.enterprise.inject.spi.AnnotatedField;
+import javax.enterprise.inject.spi.AnnotatedParameter;
+
+import org.apache.aries.cdi.container.internal.model.CollectionType;
+import org.apache.aries.cdi.container.internal.util.Conversions;
+import org.apache.aries.cdi.container.internal.util.Maps;
+import org.apache.aries.cdi.container.internal.util.Sets;
+import org.apache.aries.cdi.container.internal.util.Types;
+import org.osgi.framework.Constants;
+import org.osgi.framework.FrameworkUtil;
+import org.osgi.framework.InvalidSyntaxException;
+import org.osgi.framework.ServiceObjects;
+import org.osgi.framework.ServiceReference;
+import org.osgi.service.cdi.annotations.Reference;
+import org.osgi.service.cdi.annotations.ReferenceCardinality;
+import org.osgi.service.cdi.annotations.ReferencePolicy;
+import org.osgi.service.cdi.annotations.ReferencePolicyOption;
+import org.osgi.service.cdi.annotations.ReferenceScope;
+import org.osgi.service.cdi.annotations.ServiceEvent;
+import org.osgi.util.converter.TypeReference;
+import org.xml.sax.Attributes;
+
+public class ReferenceModel {
+
+       public static class Builder {
+
+               public Builder(Attributes attributes) {
+                       _cardinality = _cardinality(attributes);
+                       _name = _name(attributes);
+                       _option = _option(attributes);
+                       _policy = _policy(attributes);
+                       _scope = _scope(attributes);
+                       _target = _target(attributes);
+               }
+
+               public Builder(Set<Annotation> qualifiers) {
+                       _qualifiers = qualifiers;
+                       Reference reference = getQualifier(_qualifiers, 
Reference.class);
+                       if (reference != null) {
+                               _cardinality = reference.cardinality();
+                               _name = reference.name();
+                               _option = reference.policyOption();
+                               _policy = reference.policy();
+                               _scope = reference.scope();
+                               _service = reference.service();
+                               _target = reference.target();
+                       }
+               }
+
+               public ReferenceModel build() {
+                       if ((_annotated == null) && (_service == null)) {
+                               throw new IllegalArgumentException(
+                                       "Either injectionPoint or service must 
be set!");
+                       }
+
+                       if (_annotated == null) {
+                               _annotated = new ReferenceAnnotated(_service);
+                       }
+
+                       Type type = upwrapCDITypes(_annotated.getBaseType());
+
+                       _policy = calculatePolicy(_policy);
+                       _option = calculatePolicyOption(_option);
+                       _scope = calculateScope(_scope);
+                       Multiplicity multiplicity = 
calculateMultiplicity(_annotated.getBaseType());// we need the pure type to 
check "Instance"
+                       _cardinality = calculateCardinality(_cardinality, 
multiplicity, type);
+                       CollectionType collectionType = 
calculateCollectionType(type);
+                       Class<?> beanClass = calculateBeanClass(type);
+                       _service = calculateServiceClass(_service, 
_cardinality, collectionType, type, _annotated);
+                       _name = calculateName(_name, _service, _annotated);
+
+                       return new ReferenceModel(_service, _cardinality, 
_name, _policy, _option, _target, _scope, _qualifiers, beanClass, type, 
collectionType);
+               }
+
+               public Builder cardinality(ReferenceCardinality cardinality) {
+                       _cardinality = cardinality;
+                       return this;
+               }
+
+               public Builder annotated(Annotated annotated) {
+                       _annotated = annotated;
+                       return this;
+               }
+
+               public Builder name(String name) {
+                       _name = name;
+                       return this;
+               }
+
+               public Builder option(ReferencePolicyOption option) {
+                       _option = option;
+                       return this;
+               }
+
+               public Builder policy(ReferencePolicy policy) {
+                       _policy = policy;
+                       return this;
+               }
+
+               public Builder scope(ReferenceScope scope) {
+                       _scope = scope;
+                       return this;
+               }
+
+               public Builder service(Class<?> service) {
+                       _service = service;
+                       return this;
+               }
+
+               public Builder target(String target) {
+                       _target = target;
+                       return this;
+               }
+
+               @SuppressWarnings("unchecked")
+               private static <T extends Annotation> T getQualifier(
+                       Set<Annotation> qualifiers, Class<T> clazz) {
+                       for (Annotation annotation : qualifiers) {
+                               if 
(clazz.isAssignableFrom(annotation.annotationType())) {
+                                       return (T)annotation;
+                               }
+                       }
+                       return null;
+               }
+
+               private ReferenceCardinality _cardinality;
+               private Annotated _annotated;
+               private String _name;
+               private ReferencePolicyOption _option;
+               private ReferencePolicy _policy;
+               private Set<Annotation> _qualifiers;
+               private ReferenceScope _scope;
+               private Class<?> _service;
+               private String _target;
+
+       }
+
+       private ReferenceModel(
+               Class<?> service,
+               ReferenceCardinality cardinality,
+               String name,
+               ReferencePolicy policy,
+               ReferencePolicyOption option,
+               String target,
+               ReferenceScope scope,
+               Set<Annotation> qualifiers,
+               Class<?> beanClass,
+               Type injectionPointType,
+               CollectionType collectionType) {
+
+               _service = service;
+               _cardinality = cardinality;
+               _name = name;
+               _policy = policy;
+               _option = option;
+               _target = target;
+               _scope = scope;
+               _qualifiers = new LinkedHashSet<>();
+               if (qualifiers != null) {
+                       _qualifiers.addAll(qualifiers);
+               }
+               _beanClass = beanClass;
+               _injectionPointType = injectionPointType;
+               _collectionType = collectionType;
+
+               _types = Sets.immutableHashSet(_injectionPointType, 
Object.class);
+       }
+
+       @Override
+       public int hashCode() {
+               final int prime = 31;
+               int result = 1;
+               result = prime * result + ((_beanClass == null) ? 0 : 
_beanClass.hashCode());
+               result = prime * result + ((_cardinality == null) ? 0 : 
_cardinality.hashCode());
+               result = prime * result + ((_name == null) ? 0 : 
_name.hashCode());
+               result = prime * result + ((_option == null) ? 0 : 
_option.hashCode());
+               result = prime * result + ((_policy == null) ? 0 : 
_policy.hashCode());
+               result = prime * result + ((_scope == null) ? 0 : 
_scope.hashCode());
+               result = prime * result + ((_service == null) ? 0 : 
_service.hashCode());
+               result = prime * result + ((_target == null) ? 0 : 
_target.hashCode());
+               return result;
+       }
+
+       @Override
+       public boolean equals(Object obj) {
+               if (this == obj)
+                       return true;
+               if (obj == null)
+                       return false;
+               if (getClass() != obj.getClass())
+                       return false;
+               ReferenceModel other = (ReferenceModel) obj;
+               if (_beanClass == null) {
+                       if (other._beanClass != null)
+                               return false;
+               } else if (!_beanClass.equals(other._beanClass))
+                       return false;
+               if (_cardinality != other._cardinality)
+                       return false;
+               if (_name == null) {
+                       if (other._name != null)
+                               return false;
+               } else if (!_name.equals(other._name))
+                       return false;
+               if (_option != other._option)
+                       return false;
+               if (_policy != other._policy)
+                       return false;
+               if (_scope != other._scope)
+                       return false;
+               if (_service == null) {
+                       if (other._service != null)
+                               return false;
+               } else if (!_service.equals(other._service))
+                       return false;
+               if (_target == null) {
+                       if (other._target != null)
+                               return false;
+               } else if (!_target.equals(other._target))
+                       return false;
+               return true;
+       }
+
+       public boolean found() {
+               return _found.get();
+       }
+
+       public void found(boolean found) {
+               _found.set(found);
+       }
+
+       public Class<?> getBeanClass() {
+               return _beanClass;
+       }
+
+       public ReferenceCardinality getCardinality() {
+               return _cardinality;
+       }
+
+       public CollectionType getCollectionType() {
+               return _collectionType;
+       }
+
+       public Type getInjectionPointType() {
+               return _injectionPointType;
+       }
+
+       public String getName() {
+               return _name;
+       }
+
+       public ReferencePolicy getPolicy() {
+               return _policy;
+       }
+
+       public ReferencePolicyOption getPolicyOption() {
+               return _option;
+       }
+
+       public Set<Annotation> getQualifiers() {
+               return _qualifiers;
+       }
+
+       public ReferenceScope getScope() {
+               return _scope;
+       }
+
+       public Class<?> getServiceClass() {
+               return _service;
+       }
+
+       public String getTarget() {
+               return _target;
+       }
+
+       public Set<Type> getTypes() {
+               return _types;
+       }
+
+       public void setQualifiers(Set<Annotation> qualifiers) {
+               _qualifiers.clear();
+               _qualifiers.addAll(qualifiers);
+       }
+
+       @Override
+       public String toString() {
+               if (_string == null) {
+                       _string = String.format("reference[name='%s', 
service='%s', scope='%s', target='%s']", _name, _service, _scope, _target);
+               }
+               return _string;
+       }
+
+       public static String buildFilter(
+                       Class<?> serviceType,
+                       String target,
+                       ReferenceScope scope,
+                       Set<Annotation> qualifiers)
+               throws InvalidSyntaxException {
+
+               StringBuilder sb = new StringBuilder();
+
+               sb.append("(&(");
+               sb.append(Constants.OBJECTCLASS);
+               sb.append("=");
+               sb.append(serviceType.getName());
+               sb.append(")");
+
+               if (scope == ReferenceScope.PROTOTYPE) {
+                       sb.append("(");
+                       sb.append(Constants.SERVICE_SCOPE);
+                       sb.append("=");
+                       sb.append(Constants.SCOPE_PROTOTYPE);
+                       sb.append(")");
+               }
+               else if (scope == ReferenceScope.SINGLETON) {
+                       sb.append("(");
+                       sb.append(Constants.SERVICE_SCOPE);
+                       sb.append("=");
+                       sb.append(Constants.SCOPE_SINGLETON);
+                       sb.append(")");
+               }
+               else if (scope == ReferenceScope.BUNDLE) {
+                       sb.append("(");
+                       sb.append(Constants.SERVICE_SCOPE);
+                       sb.append("=");
+                       sb.append(Constants.SCOPE_BUNDLE);
+                       sb.append(")");
+               }
+
+               String targetFilter = target == null ? "" : target;
+
+               int targetFilterLength = targetFilter.length();
+
+               if (targetFilterLength > 0) {
+                       FrameworkUtil.createFilter(targetFilter);
+
+                       sb.append(targetFilter);
+               }
+
+               if (qualifiers != null) {
+                       for (Annotation qualifier : qualifiers) {
+                               Class<? extends Annotation> annotationType = 
qualifier.annotationType();
+
+                               if (annotationType.equals(Reference.class)) {
+                                       continue;
+                               }
+
+                               Map<String, String> map = 
Conversions.convert(qualifier).sourceAs(qualifier.annotationType()).to(_mapType);
+
+                               Maps.appendFilter(sb, map);
+                       }
+               }
+
+               sb.append(")");
+
+               return sb.toString();
+       }
+
+       private static Class<?> calculateBeanClass(Type type) {
+               if (type instanceof ParameterizedType) {
+                       ParameterizedType pType = (ParameterizedType)type;
+
+                       type = pType.getRawType();
+               }
+               else if (type instanceof WildcardType) {
+                       throw new IllegalArgumentException(
+                               "Cannot use a wildcard as the bean: " + type);
+               }
+
+               return cast(type);
+       }
+
+       private static CollectionType calculateCollectionType(Type type) {
+               if (type instanceof ParameterizedType) {
+                       ParameterizedType parameterizedType = cast(type);
+
+                       Type rawType = parameterizedType.getRawType();
+
+                       if ((List.class == cast(rawType)) ||
+                               
Collection.class.isAssignableFrom(cast(rawType))) {
+
+                               Type[] actualTypeArguments = 
parameterizedType.getActualTypeArguments();
+
+                               return 
calculateCollectionType(actualTypeArguments[0]);
+                       }
+                       else if (Map.class == cast(rawType)) {
+                               Type[] actualTypeArguments = 
parameterizedType.getActualTypeArguments();
+
+                               Type first = actualTypeArguments[0];
+                               Type second = actualTypeArguments[1];
+
+                               if (!(first instanceof ParameterizedType) &&
+                                       
String.class.isAssignableFrom(cast(first))) {
+
+                                       if ((!(second instanceof 
ParameterizedType) && (second == Object.class)) ||
+                                               (second instanceof 
WildcardType)) {
+
+                                               return 
CollectionType.PROPERTIES;
+                                       }
+                               }
+                       }
+                       else if (Map.Entry.class == cast(rawType)) {
+                               return CollectionType.TUPLE;
+                       }
+                       else if (ServiceObjects.class == cast(rawType)) {
+                               return CollectionType.SERVICEOBJECTS;
+                       }
+                       else if (ServiceReference.class == cast(rawType)) {
+                               return CollectionType.REFERENCE;
+                       }
+               }
+               else if (Map.Entry.class == cast(type)) {
+                       return CollectionType.TUPLE;
+               }
+               else if (ServiceObjects.class == cast(type)) {
+                       return CollectionType.SERVICEOBJECTS;
+               }
+               else if (ServiceReference.class == cast(type)) {
+                       return CollectionType.REFERENCE;
+               }
+
+               return CollectionType.SERVICE;
+       }
+
+       private static ReferenceCardinality calculateCardinality(
+               ReferenceCardinality cardinality, Multiplicity multiplicity, 
Type type) {
+
+               if ((multiplicity == Multiplicity.UNARY) &&
+                       ((cardinality == ReferenceCardinality.AT_LEAST_ONE) || 
(cardinality == ReferenceCardinality.MULTIPLE))) {
+
+                       throw new IllegalArgumentException(
+                               format(
+                                       "Unary injection point type %s cannot 
be defined by multiple cardinality %s",
+                                       type, cardinality));
+               }
+               else if ((multiplicity == Multiplicity.MULTIPLE) &&
+                               ((cardinality == ReferenceCardinality.OPTIONAL) 
|| (cardinality == ReferenceCardinality.MANDATORY))) {
+
+                       throw new IllegalArgumentException(
+                               format(
+                                       "Multiple injection point type %s 
cannot be defined by unary cardinality %s",
+                                       type, cardinality));
+               }
+
+               if ((cardinality == null) || (cardinality == 
ReferenceCardinality.DEFAULT)) {
+                       switch(multiplicity) {
+                               case MULTIPLE:
+                                       return ReferenceCardinality.MULTIPLE;
+                               case UNARY:
+                                       return ReferenceCardinality.MANDATORY;
+                       }
+               }
+
+               return cardinality;
+       }
+
+       private static Multiplicity calculateMultiplicity(Type type) {
+               if (type instanceof ParameterizedType) {
+                       ParameterizedType parameterizedType = cast(type);
+
+                       Type rawType = parameterizedType.getRawType();
+
+                       if ((Instance.class == cast(rawType)) ||
+                               
Collection.class.isAssignableFrom(cast(rawType)) ||
+                               ServiceEvent.class == cast(rawType)) {
+
+                               return Multiplicity.MULTIPLE;
+                       }
+               }
+
+               return Multiplicity.UNARY;
+       }
+
+       public static String calculateName(String name, Class<?> service, 
Annotated annotated) {
+               if ((name != null) && (name.length() > 0)) {
+                       return name;
+               }
+
+               if (annotated != null) {
+                       if (annotated instanceof AnnotatedParameter) {
+                               AnnotatedParameter<?> annotatedParameter = 
(AnnotatedParameter<?>)annotated;
+
+                               return Types.getName(service) + 
annotatedParameter.getPosition();
+                       }
+                       if (annotated instanceof AnnotatedField) {
+                               AnnotatedField<?> annotatedField = 
(AnnotatedField<?>)annotated;
+
+                               return annotatedField.getJavaMember().getName();
+                       }
+               }
+
+               return Types.getName(service);
+       }
+
+       private static ReferencePolicy calculatePolicy(ReferencePolicy policy) {
+               if ((policy == null) || (policy == ReferencePolicy.DEFAULT)) {
+                       return ReferencePolicy.STATIC;
+               }
+
+               return policy;
+       }
+
+       private static ReferencePolicyOption 
calculatePolicyOption(ReferencePolicyOption option) {
+               if ((option == null) || (option == 
ReferencePolicyOption.DEFAULT)) {
+                       return ReferencePolicyOption.RELUCTANT;
+               }
+
+               return option;
+       }
+
+       private static ReferenceScope calculateScope(ReferenceScope scope) {
+               if ((scope == null) || (scope == ReferenceScope.DEFAULT)) {
+                       return ReferenceScope.DEFAULT;
+               }
+
+               return scope;
+       }
+
+       private static Class<?> calculateServiceClass(Type injectionPointType) {
+               Type type = injectionPointType;
+
+               if (!(type instanceof ParameterizedType)) {
+                       return cast(type);
+               }
+
+               ParameterizedType parameterizedType = cast(type);
+
+               Type rawType = parameterizedType.getRawType();
+
+               if ((List.class == cast(rawType)) ||
+                       Collection.class.isAssignableFrom(cast(rawType))) {
+
+                       Type[] actualTypeArguments = 
parameterizedType.getActualTypeArguments();
+
+                       type = actualTypeArguments[0];
+
+                       if (type instanceof ParameterizedType) {
+                               parameterizedType = (ParameterizedType)type;
+
+                               rawType = parameterizedType.getRawType();
+                       }
+                       else if ((type instanceof WildcardType) ||
+                                       
Map.Entry.class.isAssignableFrom(cast(type))) {
+
+                               return null;
+                       }
+                       else {
+                               rawType = type;
+                       }
+               }
+
+               if (!Map.Entry.class.isAssignableFrom(cast(rawType)) &&
+                       !ServiceObjects.class.isAssignableFrom(cast(rawType)) &&
+                       
!ServiceReference.class.isAssignableFrom(cast(rawType))) {
+
+                       return cast(rawType);
+               }
+
+               Type[] actualTypeArguments = 
parameterizedType.getActualTypeArguments();
+
+               Type argument = actualTypeArguments[0];
+
+               if (Map.Entry.class.isAssignableFrom(cast(rawType))) {
+                       if (!checkKey(argument)) {
+                               throw new IllegalArgumentException(
+                                       "Tuples must have a key of type 
Map<String, [? or Object]>: " + argument);
+                       }
+
+                       argument = actualTypeArguments[1];
+               }
+
+               if (argument instanceof ParameterizedType) {
+                       ParameterizedType parameterizedType1 = cast(argument);
+
+                       return cast(parameterizedType1.getRawType());
+               }
+               else if (argument instanceof WildcardType) {
+                       WildcardType wildcardType = (WildcardType)argument;
+
+                       if ((wildcardType.getUpperBounds().length == 1)) {
+                               argument = wildcardType.getUpperBounds()[0];
+
+                               if (Object.class.equals(argument)) {
+                                       return null;
+                               }
+                               else if (argument instanceof Class) {
+                                       return cast(argument);
+                               }
+                       }
+
+                       throw new IllegalArgumentException(
+                               "@Reference cannot use nested parameterized 
types or multiple upper bounds: " + injectionPointType);
+               }
+
+               return cast(argument);
+       }
+
+       private static Class<?> calculateServiceClass(
+               Class<?> service, ReferenceCardinality cardinality, 
CollectionType collectionType, Type injectionPointType, Annotated annotated) {
+
+               Class<?> calculatedServiceClass = 
calculateServiceClass(injectionPointType);
+
+               if ((service == null) || (service == Object.class)) {
+                       if (calculatedServiceClass == null) {
+                               throw new IllegalArgumentException(
+                                       "Could not determine the service type 
from @Reference on annotated " +
+                                               annotated);
+                       }
+
+                       switch(collectionType) {
+                               case PROPERTIES:
+                                       if (calculatedServiceClass == 
Map.class) {
+                                               throw new 
IllegalArgumentException(
+                                                       "A @Reference cannot 
bind service properties to a Map<String, Object> without " +
+                                                               "specifying the 
@Reference.service property: " + annotated);
+                                       }
+                                       break;
+                               case REFERENCE:
+                                       if (calculatedServiceClass == 
ServiceReference.class) {
+                                               throw new 
IllegalArgumentException(
+                                                       "A @Reference cannot 
bind a ServiceReference without specifying either the " +
+                                                               
"@Reference.service property or a generic type argument (e.g. 
ServiceReference<Foo>: " +
+                                                                       
annotated);
+                                       }
+                                       break;
+                               case SERVICEOBJECTS:
+                                       if      (calculatedServiceClass == 
ServiceObjects.class) {
+                                               throw new 
IllegalArgumentException(
+                                                       "A @Reference cannot 
bind a ServiceObjects without specifying either the " +
+                                                               
"@Reference.service property or a generic type argument (e.g. 
ServiceObjects<Foo>: " +
+                                                                       
annotated);
+                                       }
+                                       break;
+                               case TUPLE:
+                                       if (calculatedServiceClass == 
Map.Entry.class) {
+                                               throw new 
IllegalArgumentException(
+                                                       "A @Reference cannot 
bind a Map.Entry without specifying either the " +
+                                                               
"@Reference.service property or a generic type argument (e.g. 
Map.Entry<Map<String, Object>, Foo>: " +
+                                                                       
annotated);
+                                       }
+                                       break;
+                               default:
+                       }
+
+                       return calculatedServiceClass;
+               }
+
+               switch(collectionType) {
+                       case PROPERTIES:
+                               if 
(Map.class.isAssignableFrom(calculatedServiceClass)) {
+                                       return service;
+                               }
+                               break;
+                       case REFERENCE:
+                               if ((calculatedServiceClass == null) ||
+                                       
ServiceReference.class.isAssignableFrom(calculatedServiceClass)) {
+                                       return service;
+                               }
+                               break;
+                       case SERVICEOBJECTS:
+                               if ((calculatedServiceClass == null) ||
+                                       
ServiceObjects.class.isAssignableFrom(calculatedServiceClass)) {
+                                       return service;
+                               }
+                               break;
+                       case TUPLE:
+                               if ((calculatedServiceClass != null) &&
+                                       
Map.Entry.class.isAssignableFrom(calculatedServiceClass)) {
+
+                                       if (!checkKey(calculatedServiceClass)) {
+                                               throw new 
IllegalArgumentException(
+                                                       "Tuples must have a key 
of type Map<String, [? or Object]>: " + calculatedServiceClass);
+                                       }
+
+                                       return service;
+                               }
+                               else if ((calculatedServiceClass == null) ||
+                                       
calculatedServiceClass.isAssignableFrom(service)) {
+
+                                       return service;
+                               }
+                               break;
+                       case SERVICE:
+                               if (((calculatedServiceClass == null) &&
+                                               ((cardinality == 
ReferenceCardinality.MULTIPLE) ||
+                                               (cardinality == 
ReferenceCardinality.AT_LEAST_ONE))) ||
+                                       ((calculatedServiceClass != null) &&
+                                               
calculatedServiceClass.isAssignableFrom(service))) {
+                                       return service;
+                               }
+               }
+
+               throw new IllegalArgumentException(
+                       "@Reference.service " + service + " is not compatible 
with annotated " + annotated);
+       }
+
+       // check the key type to make sure it complies with Map<String, ?> OR 
Map<String, Object>
+       private static boolean checkKey(Type mapEntryType) {
+               if (!(mapEntryType instanceof ParameterizedType)) {
+                       return false;
+               }
+
+               ParameterizedType parameterizedKeyType = 
(ParameterizedType)mapEntryType;
+
+               if 
((!Map.class.isAssignableFrom(cast(parameterizedKeyType.getRawType()))) ||
+                       
(!parameterizedKeyType.getActualTypeArguments()[0].equals(String.class))) {
+
+                       return false;
+               }
+
+               Type valueType = 
parameterizedKeyType.getActualTypeArguments()[1];
+
+               if ((!valueType.equals(Object.class) &&
+                       (
+                               (!(valueType instanceof WildcardType)) ||
+                               
(((WildcardType)valueType).getUpperBounds().length != 1) ||
+                               
(!((WildcardType)valueType).getUpperBounds()[0].equals(Object.class))))) {
+
+                       return false;
+               }
+
+               return true;
+       }
+
+       private static ReferenceCardinality _cardinality(Attributes attributes) 
{
+               return ReferenceCardinality.get(
+                       getValue(CDI10_URI, CARDINALITY_ATTRIBUTE, attributes, 
ReferenceCardinality.DEFAULT.toString()));
+       }
+
+       private static String _name(Attributes attributes) {
+               return getValue(CDI10_URI, NAME_ATTRIBUTE, attributes);
+       }
+
+       private static ReferencePolicyOption _option(Attributes attributes) {
+               return ReferencePolicyOption.get(
+                       getValue(CDI10_URI, POLICY_OPTION_ATTRIBUTE, 
attributes, ReferencePolicyOption.DEFAULT.toString()));
+       }
+
+       private static ReferencePolicy _policy(Attributes attributes) {
+               return ReferencePolicy.get(
+                       getValue(CDI10_URI, POLICY_ATTRIBUTE, attributes, 
ReferencePolicy.DEFAULT.toString()));
+       }
+
+       private static ReferenceScope _scope(Attributes attributes) {
+               return ReferenceScope.get(getValue(
+                       CDI10_URI, SCOPE_ATTRIBUTE, attributes, 
ReferenceScope.DEFAULT.toString()));
+       }
+
+       private static String _target(Attributes attributes) {
+               return getValue(CDI10_URI, TARGET_ATTRIBUTE, attributes);
+       }
+
+       private static Type upwrapCDITypes(Type type) {
+               if (type instanceof ParameterizedType) {
+                       ParameterizedType pType = (ParameterizedType)type;
+
+                       Type rawType = pType.getRawType();
+
+                       if (Instance.class == cast(rawType) ||
+                               ServiceEvent.class == cast(rawType)) {
+
+                               type = pType.getActualTypeArguments()[0];
+                       }
+               }
+
+               return type;
+       }
+
+       private static final TypeReference<Map<String, String>> _mapType = new 
TypeReference<Map<String, String>>(){};
+
+       private final Class<?> _beanClass;
+       private final ReferenceCardinality _cardinality;
+       private final CollectionType _collectionType;
+       private final AtomicBoolean _found = new AtomicBoolean();
+       private final Type _injectionPointType;
+       private final String _name;
+       private final ReferencePolicyOption _option;
+       private final ReferencePolicy _policy;
+       private final Set<Annotation> _qualifiers;
+       private final ReferenceScope _scope;
+       private final Class<?> _service;
+       private String _string;
+       private final String _target;
+       private final Set<Type> _types;
+
+       private static class ReferenceAnnotated implements Annotated {
+
+               public ReferenceAnnotated(Class<?> service) {
+                       _service = service;
+               }
+
+               @Override
+               public <T extends Annotation> T getAnnotation(Class<T> 
annotationType) {
+                       return null;
+               }
+
+               @Override
+               public Set<Annotation> getAnnotations() {
+                       return Collections.emptySet();
+               }
+
+               @Override
+               public Type getBaseType() {
+                       return _service;
+               }
+
+               @Override
+               public Set<Type> getTypeClosure() {
+                       return Sets.hashSet(_service);
+               }
+
+               @Override
+               public boolean isAnnotationPresent(Class<? extends Annotation> 
annotationType) {
+                       return false;
+               }
+
+               private final Class<?> _service;
+
+       }
+
+}

Added: 
aries/trunk/cdi/cdi-extender/src/main/java/org/apache/aries/cdi/container/internal/service/ServiceDeclaration.java
URL: 
http://svn.apache.org/viewvc/aries/trunk/cdi/cdi-extender/src/main/java/org/apache/aries/cdi/container/internal/service/ServiceDeclaration.java?rev=1807424&view=auto
==============================================================================
--- 
aries/trunk/cdi/cdi-extender/src/main/java/org/apache/aries/cdi/container/internal/service/ServiceDeclaration.java
 (added)
+++ 
aries/trunk/cdi/cdi-extender/src/main/java/org/apache/aries/cdi/container/internal/service/ServiceDeclaration.java
 Tue Sep  5 22:01:11 2017
@@ -0,0 +1,173 @@
+/**
+ * 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.service;
+
+import static org.apache.aries.cdi.container.internal.util.Reflection.cast;
+
+import java.util.Arrays;
+import java.util.Dictionary;
+import java.util.stream.Collectors;
+
+import javax.enterprise.context.spi.CreationalContext;
+import javax.enterprise.inject.spi.Bean;
+
+import org.apache.aries.cdi.container.internal.component.ComponentModel;
+import org.apache.aries.cdi.container.internal.component.ComponentProperties;
+import org.apache.aries.cdi.container.internal.container.ContainerState;
+import org.apache.aries.cdi.container.internal.util.Types;
+import org.osgi.framework.Bundle;
+import org.osgi.framework.PrototypeServiceFactory;
+import org.osgi.framework.ServiceFactory;
+import org.osgi.framework.ServiceRegistration;
+import org.osgi.service.cdi.annotations.ServiceScope;
+
+public class ServiceDeclaration {
+
+       public ServiceDeclaration(
+               ContainerState containerState,
+               ComponentModel componentModel,
+               Bean<?> bean,
+               CreationalContext<?> creationalContext) {
+
+               _containerState = containerState;
+               _bean = bean;
+               _creationalContext = creationalContext;
+
+               _componentModel = componentModel;
+
+               Object instance = null;
+
+               if (_componentModel.getServiceScope() == 
ServiceScope.SINGLETON) {
+                       instance = new SingletonScopeWrapper();
+               }
+               else if (_componentModel.getServiceScope() == 
ServiceScope.BUNDLE) {
+                       instance = new BundleScopeWrapper();
+               }
+               else if (_componentModel.getServiceScope() == 
ServiceScope.PROTOTYPE) {
+                       instance = new PrototypeScopeWrapper();
+               }
+
+               _instance = instance;
+       }
+
+       public String[] getClassNames() {
+               return Arrays.stream(
+                       Types.types(_componentModel, 
_componentModel.getBeanClass(), _containerState.classLoader())
+               ).map(
+                       c -> c.getName()
+               ).collect(
+                       Collectors.toList()
+               ).toArray(
+                       new String[0]
+               );
+       }
+
+       public String getName() {
+               return _componentModel.getName();
+       }
+
+       public ServiceScope getScope() {
+               return _componentModel.getServiceScope();
+       }
+
+       public Object getServiceInstance() {
+               return _instance;
+       }
+
+       public Dictionary<String, ?> getServiceProperties() {
+               return new ComponentProperties().bean(
+                       _bean
+               ).componentModel(
+                       _componentModel
+               ).containerState(
+                       _containerState
+               ).build();
+       }
+
+       private final Bean<?> _bean;
+       private final ComponentModel _componentModel;
+       private final ContainerState _containerState;
+       private final CreationalContext<?> _creationalContext;
+       private final Object _instance;
+
+       @SuppressWarnings({"rawtypes"})
+       private class BundleScopeWrapper implements ServiceFactory {
+
+               @Override
+               public Object getService(Bundle bundle, ServiceRegistration 
registration) {
+                       return _bean.create(cast(_creationalContext));
+               }
+
+               @Override
+               public void ungetService(Bundle bundle, ServiceRegistration 
registration, Object service) {
+                       _bean.destroy(cast(service), cast(_creationalContext));
+               }
+
+       }
+
+       @SuppressWarnings({"rawtypes"})
+       private class PrototypeScopeWrapper implements PrototypeServiceFactory {
+
+               @Override
+               public Object getService(Bundle bundle, ServiceRegistration 
registration) {
+                       return _bean.create(cast(_creationalContext));
+               }
+
+               @Override
+               public void ungetService(Bundle bundle, ServiceRegistration 
registration, Object service) {
+                       _bean.destroy(cast(service), cast(_creationalContext));
+               }
+
+       }
+
+       @SuppressWarnings({"rawtypes"})
+       private class SingletonScopeWrapper implements ServiceFactory {
+
+               @Override
+               public Object getService(Bundle bundle, ServiceRegistration 
registration) {
+                       if (_instance == null) {
+                               _instance = 
_bean.create(cast(_creationalContext));
+                       }
+                       return _instance;
+               }
+
+               @Override
+               public void ungetService(Bundle bundle, ServiceRegistration 
registration, Object service) {
+               }
+
+               private Object _instance;
+
+       }
+
+//     private class ManagedServiceFactoryWrapper implements 
ManagedServiceFactory {
+//
+//             @Override
+//             public String getName() {
+//                     return _component.name();
+//             }
+//
+//             @Override
+//             public void updated(String pid, Dictionary<String, ?> 
properties) throws ConfigurationException {
+//             }
+//
+//             @Override
+//             public void deleted(String pid) {
+//             }
+//
+//             private final Map<String, Object> _instances = new 
ConcurrentHashMap<>();
+//
+//     }
+
+}

Modified: 
aries/trunk/cdi/cdi-extender/src/main/java/org/apache/aries/cdi/container/internal/util/Conversions.java
URL: 
http://svn.apache.org/viewvc/aries/trunk/cdi/cdi-extender/src/main/java/org/apache/aries/cdi/container/internal/util/Conversions.java?rev=1807424&r1=1807423&r2=1807424&view=diff
==============================================================================
--- 
aries/trunk/cdi/cdi-extender/src/main/java/org/apache/aries/cdi/container/internal/util/Conversions.java
 (original)
+++ 
aries/trunk/cdi/cdi-extender/src/main/java/org/apache/aries/cdi/container/internal/util/Conversions.java
 Tue Sep  5 22:01:11 2017
@@ -18,6 +18,7 @@ import java.util.Arrays;
 
 import org.osgi.util.converter.Converter;
 import org.osgi.util.converter.ConverterBuilder;
+import org.osgi.util.converter.Converting;
 import org.osgi.util.converter.StandardConverter;
 import org.osgi.util.converter.TypeRule;
 
@@ -27,8 +28,8 @@ public class Conversions {
                return 
INSTANCE._converter.convert(object).defaultValue("").to(String.class);
        }
 
-       public static Converter c() {
-               return INSTANCE._converter;
+       public static Converting convert(Object object) {
+               return INSTANCE._converter.convert(object);
        }
 
        private Conversions() {

Modified: 
aries/trunk/cdi/cdi-extender/src/main/java/org/apache/aries/cdi/container/internal/util/Maps.java
URL: 
http://svn.apache.org/viewvc/aries/trunk/cdi/cdi-extender/src/main/java/org/apache/aries/cdi/container/internal/util/Maps.java?rev=1807424&r1=1807423&r2=1807424&view=diff
==============================================================================
--- 
aries/trunk/cdi/cdi-extender/src/main/java/org/apache/aries/cdi/container/internal/util/Maps.java
 (original)
+++ 
aries/trunk/cdi/cdi-extender/src/main/java/org/apache/aries/cdi/container/internal/util/Maps.java
 Tue Sep  5 22:01:11 2017
@@ -70,20 +70,21 @@ public class Maps {
                map(map, key, type, value);
        }
 
+       @SuppressWarnings("unchecked")
        static void map(Map<String, Object> map, String key, String type, 
String value) {
                PropertyType propertyType = PropertyType.find(type);
 
                Object object = map.get(key);
 
                if (object == null) {
-                       Object valueObject = 
Conversions.c().convert(value).to(propertyType.getType());
+                       Object valueObject = 
Conversions.convert(value).to(propertyType.getType());
 
                        map.put(key, valueObject);
 
                        return;
                }
 
-               Object valueObject = 
Conversions.c().convert(value).to(propertyType.componentType());
+               Object valueObject = 
Conversions.convert(value).to(propertyType.componentType());
 
                if (propertyType.isRaw()) {
                        if (!object.getClass().isArray()) {
@@ -101,10 +102,12 @@ public class Maps {
                        }
                }
                else if (propertyType.isList()) {
+                       @SuppressWarnings("rawtypes")
                        List list = Collections.checkedList((List)object, 
propertyType.componentType());
                        list.add(valueObject);
                }
                else if (propertyType.isSet()) {
+                       @SuppressWarnings("rawtypes")
                        Set set = Collections.checkedSet((Set)object, 
propertyType.componentType());
                        set.add(valueObject);
                }

Modified: 
aries/trunk/cdi/cdi-extender/src/main/java/org/apache/aries/cdi/container/internal/util/Strings.java
URL: 
http://svn.apache.org/viewvc/aries/trunk/cdi/cdi-extender/src/main/java/org/apache/aries/cdi/container/internal/util/Strings.java?rev=1807424&r1=1807423&r2=1807424&view=diff
==============================================================================
--- 
aries/trunk/cdi/cdi-extender/src/main/java/org/apache/aries/cdi/container/internal/util/Strings.java
 (original)
+++ 
aries/trunk/cdi/cdi-extender/src/main/java/org/apache/aries/cdi/container/internal/util/Strings.java
 Tue Sep  5 22:01:11 2017
@@ -19,6 +19,8 @@ import java.util.regex.Pattern;
 
 public class Strings {
 
+       public static final String[] EMPTY_ARRAY = new String[0];
+
        private Strings() {
                // no instances
        }

Added: 
aries/trunk/cdi/cdi-extender/src/main/java/org/apache/aries/cdi/container/internal/util/Types.java
URL: 
http://svn.apache.org/viewvc/aries/trunk/cdi/cdi-extender/src/main/java/org/apache/aries/cdi/container/internal/util/Types.java?rev=1807424&view=auto
==============================================================================
--- 
aries/trunk/cdi/cdi-extender/src/main/java/org/apache/aries/cdi/container/internal/util/Types.java
 (added)
+++ 
aries/trunk/cdi/cdi-extender/src/main/java/org/apache/aries/cdi/container/internal/util/Types.java
 Tue Sep  5 22:01:11 2017
@@ -0,0 +1,134 @@
+/**
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.aries.cdi.container.internal.util;
+
+import java.lang.reflect.GenericArrayType;
+import java.lang.reflect.ParameterizedType;
+import java.lang.reflect.Type;
+import java.util.ArrayList;
+import java.util.List;
+
+import javax.enterprise.inject.spi.InjectionPoint;
+
+import org.apache.aries.cdi.container.internal.component.ComponentModel;
+import org.osgi.service.cdi.annotations.ServiceScope;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+public class Types {
+
+       public static String getName(InjectionPoint injectionPoint) {
+               return getName(injectionPoint.getType());
+       }
+
+       public static String getName(Type type) {
+               if (type instanceof ParameterizedType) {
+                       ParameterizedType pt = (ParameterizedType)type;
+
+                       Type rawType = pt.getRawType();
+
+                       if (rawType instanceof Class) {
+                               Class<?> clazz = (Class<?>)rawType;
+
+                               return clazz.getSimpleName();
+                       }
+                       else {
+                               return rawType.getTypeName();
+                       }
+               }
+               else if (type instanceof GenericArrayType) {
+                       GenericArrayType gat = (GenericArrayType)type;
+
+                       Type genericComponentType = 
gat.getGenericComponentType();
+
+                       if (genericComponentType instanceof ParameterizedType) {
+                               ParameterizedType pt = 
(ParameterizedType)genericComponentType;
+
+                               Type rawType = pt.getRawType();
+
+                               if (rawType instanceof Class) {
+                                       Class<?> clazz = (Class<?>)rawType;
+
+                                       return clazz.getSimpleName();
+                               }
+                               else {
+                                       return rawType.getTypeName();
+                               }
+                       }
+                       else if (genericComponentType instanceof Class) {
+                               Class<?> clazz = (Class<?>)genericComponentType;
+
+                               return clazz.getSimpleName();
+                       }
+                       else {
+                               return genericComponentType.getTypeName();
+                       }
+               }
+               else if (type instanceof Class) {
+                       Class<?> clazz = (Class<?>)type;
+
+                       String simpleName = clazz.getSimpleName();
+
+                       char lowerCase = 
Character.toLowerCase(simpleName.charAt(0));
+
+                       return lowerCase + simpleName.substring(1, 
simpleName.length());
+               }
+
+               return type.getTypeName();
+       }
+
+       public static Class<?>[] types(
+               ComponentModel componentModel, Class<?> beanClass, ClassLoader 
classLoader) {
+
+               List<Class<?>> classes = new ArrayList<>();
+
+               if ((componentModel.getServiceScope() == ServiceScope.DEFAULT) 
||
+                       (componentModel.getServiceScope() == 
ServiceScope.NONE)) {
+
+                       return new Class<?>[0];
+               }
+               else if (!componentModel.getProvides().isEmpty()) {
+                       for (String provide : componentModel.getProvides()) {
+                               try {
+                                       
classes.add(classLoader.loadClass(provide));
+                               }
+                               catch (ReflectiveOperationException roe) {
+                                       if (_log.isWarnEnabled()) {
+                                               _log.warn(
+                                                       "CDIe - component {} 
cannot load provided type {}. Skipping!",
+                                                       
componentModel.getBeanClass(), provide, roe);
+                                       }
+                               }
+                       }
+               }
+               else {
+                       Class<?>[] interfaces = beanClass.getInterfaces();
+
+                       if (interfaces.length > 0) {
+                               for (Class<?> iface : interfaces) {
+                                       classes.add(iface);
+                               }
+                       }
+                       else {
+                               classes.add(beanClass);
+                       }
+               }
+
+               return classes.toArray(new Class[0]);
+       }
+
+       public static final Logger _log = LoggerFactory.getLogger(Types.class);
+
+}
\ No newline at end of file

Modified: aries/trunk/cdi/cdi-extender/src/main/resources/META-INF/cdi.xsd
URL: 
http://svn.apache.org/viewvc/aries/trunk/cdi/cdi-extender/src/main/resources/META-INF/cdi.xsd?rev=1807424&r1=1807423&r2=1807424&view=diff
==============================================================================
--- aries/trunk/cdi/cdi-extender/src/main/resources/META-INF/cdi.xsd (original)
+++ aries/trunk/cdi/cdi-extender/src/main/resources/META-INF/cdi.xsd Tue Sep  5 
22:01:11 2017
@@ -29,46 +29,82 @@
                        the OSGi CDI Extender. OSGi Bean description documents
                        may be embedded in other XML documents. The OSGi CDI 
Extender
                        will process all XML documents listed in the osgi.beans
-                       attribute of the CDI extender requirement. XML 
documents containing
-                       OSGi Bean descriptions may contain one or more bean, 
configuration,
-                       and/or reference elements embedded in a larger 
document. Use of
-                       the namespace for bean descriptions is mandatory. The 
attributes
-                       and subelements of bean, configuration, and/or 
reference elements
-                       are always unqualified.
+                       attribute of the CDI extender requirement. CDI Beans 
named by the
+                       descriptor are described as components. XML documents 
containing
+                       OSGi Bean descriptions may contain one or more 
component elements.
+                       Use of the namespace for bean descriptions is 
mandatory. The
+                       attributes and subelements of component elements are 
always
+                       unqualified.
                </documentation>
        </annotation>
-       <element name="bean" type="cdi:Tbean" />
-       <complexType name="Tbean">
+       <element name="component" type="cdi:Tcomponent" />
+       <complexType name="Tcomponent">
                <sequence>
-                       <element name="service" maxOccurs="1" minOccurs="0"
-                               type="cdi:Tservice" />
-                       <any namespace="##other" minOccurs="0" 
maxOccurs="unbounded"
-                               processContents="lax" />
+                       <annotation>
+                               <documentation xml:lang="en">
+                                       Implementations of CDI Support must not 
require component
+                                       descriptions to specify the 
sub-elements of the component
+                                       element in the order as required by the 
schema. CDI Support
+                                       implementations must allow other 
orderings since
+                                       arbitrary orderings do not affect the 
meaning of the
+                                       component description. Only the 
relative ordering of
+                                       property elements have meaning.
+                               </documentation>
+                       </annotation>
+                       <element name="configuration" maxOccurs="unbounded" 
minOccurs="0" type="cdi:Tconfiguration" />
+                       <element name="property" maxOccurs="unbounded" 
minOccurs="0" type="cdi:Tproperty" />
+                       <element name="provide" maxOccurs="unbounded" 
minOccurs="0" type="cdi:Tprovide" />
+                       <element name="reference" maxOccurs="unbounded" 
minOccurs="0" type="cdi:Treference" />
+                       <any namespace="##other" maxOccurs="unbounded" 
minOccurs="0" processContents="lax" />
                </sequence>
                <attribute name="class" type="token" use="required" />
+               <attribute name="name" type="token" use="optional">
+                       <annotation>
+                               <documentation xml:lang="en">
+                                       The default value of this attribute is 
the value of
+                                       the class attribute. If multiple 
component elements use the same
+                                       value for the class attribute, then 
using the default value
+                                       for this attribute will result in 
duplicate names.
+                                       In this case, this attribute must be 
specified with
+                                       a unique value.
+                               </documentation>
+                       </annotation>
+               </attribute>
+               <attribute name="service-scope" default="none" 
type="cdi:Tservice_scope" use="optional" />
                <anyAttribute processContents="lax" />
        </complexType>
 
-       <element name="configuration" type="cdi:Tconfiguration" />
        <complexType name="Tconfiguration">
                <sequence>
-                       <any namespace="##other" minOccurs="0" 
maxOccurs="unbounded"
-                               processContents="lax" />
+                       <any namespace="##any" processContents="lax"
+                               minOccurs="0" maxOccurs="unbounded" />
                </sequence>
-               <attribute name="beanClass" type="token" use="required" />
-               <attribute name="pid" type="token" use="required" />
-               <attribute name="required" type="boolean" default="true" 
use="optional" />
+               <attribute name="configuration-policy" default="optional" 
type="cdi:Tconfiguration-policy" use="optional" />
+               <attribute name="configuration-pid" use="optional">
+                       <annotation>
+                               <documentation xml:lang="en">
+                                       The default value is the name attribute 
of the component.
+                               </documentation>
+                       </annotation>
+                       <simpleType>
+                               <restriction>
+                                       <simpleType>
+                                               <list itemType="token" />
+                                       </simpleType>
+                                       <minLength value="1" />
+                               </restriction>
+                       </simpleType>
+               </attribute>
+               <attribute name="type" type="token" use="required" />
                <anyAttribute processContents="lax" />
        </complexType>
 
-       <element name="reference" type="cdi:Treference" />
-       <complexType name="Treference">
+       <complexType name="Tmulti-value">
                <sequence>
-                       <any namespace="##any" processContents="lax"
-                               minOccurs="0" maxOccurs="unbounded" />
+               <element name="value" minOccurs="0" maxOccurs="unbounded" 
type="cdi:Tvalue"/>
+               <any namespace="##other" minOccurs="0" maxOccurs="unbounded"
+                       processContents="lax" />
                </sequence>
-               <attribute name="beanClass" type="token" use="required" />
-               <attribute name="target" type="token" use="required" />
                <anyAttribute processContents="lax" />
        </complexType>
 
@@ -79,52 +115,92 @@
                                <element name="list" type="cdi:Tmulti-value"/>
                                <element name="set" type="cdi:Tmulti-value"/>
                        </choice>
-                       <any namespace="##other" minOccurs="0" 
maxOccurs="unbounded"
-                               processContents="lax" />
+                       <any namespace="##other" minOccurs="0" 
maxOccurs="unbounded" processContents="lax" />
                </sequence>
                <attribute name="name" type="string" use="required" />
                <attribute name="value" type="string" use="optional" />
-               <attribute name="value-type" type="cdi:Tvalue-types" 
default="String" use="optional" />
+               <attribute name="value-type" default="String" 
type="cdi:Tvalue-types" use="optional" />
                <anyAttribute processContents="lax" />
        </complexType>
 
-       <complexType name="Tmulti-value">
+       <complexType name="Tprovide">
                <sequence>
-               <element name="value" minOccurs="0" maxOccurs="unbounded" 
type="cdi:Tvalue"/>
-               <any namespace="##other" minOccurs="0" maxOccurs="unbounded"
-                       processContents="lax" />
+                       <any namespace="##any" processContents="lax" 
minOccurs="0" maxOccurs="unbounded" />
                </sequence>
+               <attribute name="interface" type="token" use="required" />
                <anyAttribute processContents="lax" />
        </complexType>
 
-       <complexType name="Tvalue" mixed="true">
+       <complexType name="Treference">
                <sequence>
-               <any namespace="##other" minOccurs="0" maxOccurs="unbounded"
-                       processContents="lax" />
+                       <any namespace="##any" processContents="lax" 
minOccurs="0" maxOccurs="unbounded" />
                </sequence>
+               <attribute name="cardinality" default="1..1" 
type="cdi:Tcardinality" use="optional" />
+               <attribute name="name" type="token" use="optional" />
+               <attribute name="policy" default="static" type="cdi:Tpolicy" 
use="optional" />
+               <attribute name="policy-option" default="reluctant" 
type="cdi:Tpolicy-option" use="optional" />
+               <attribute name="scope" default="bundle" 
type="cdi:Treference_scope" use="optional" />
+               <attribute name="service" type="token" use="required" />
+               <attribute name="target" type="string" use="optional" />
                <anyAttribute processContents="lax" />
        </complexType>
 
-       <complexType name="Tprovide">
+       <complexType name="Tvalue" mixed="true">
                <sequence>
-                       <any namespace="##any" processContents="lax"
-                               minOccurs="0" maxOccurs="unbounded" />
+               <any namespace="##other" minOccurs="0" maxOccurs="unbounded"
+                       processContents="lax" />
                </sequence>
-               <attribute name="interface" type="token" use="required" />
                <anyAttribute processContents="lax" />
        </complexType>
 
-       <complexType name="Tservice">
-               <sequence>
-                       <element name="property" type="cdi:Tproperty"
-                               maxOccurs="unbounded" minOccurs="0" />
-                       <element name="provide" type="cdi:Tprovide"
-                               minOccurs="1" maxOccurs="unbounded" />
-                       <any namespace="##other" processContents="lax"
-                               minOccurs="0" maxOccurs="unbounded" />
-               </sequence>
-               <anyAttribute processContents="lax" />
-       </complexType>
+       <simpleType name="Tcardinality">
+               <restriction base="string">
+                       <enumeration value="0..1" />
+                       <enumeration value="0..n" />
+                       <enumeration value="1..1" />
+                       <enumeration value="1..n" />
+               </restriction>
+       </simpleType>
+
+       <simpleType name="Tconfiguration-policy">
+               <restriction base="string">
+                       <enumeration value="factory" />
+                       <enumeration value="ignore" />
+                       <enumeration value="optional" />
+                       <enumeration value="require" />
+               </restriction>
+       </simpleType>
+
+       <simpleType name="Tpolicy">
+               <restriction base="string">
+                       <enumeration value="dynamic" />
+                       <enumeration value="static" />
+               </restriction>
+       </simpleType>
+
+       <simpleType name="Tpolicy-option">
+               <restriction base="string">
+                       <enumeration value="greedy" />
+                       <enumeration value="reluctant" />
+               </restriction>
+       </simpleType>
+
+       <simpleType name="Treference_scope">
+               <restriction base="string">
+                       <enumeration value="bundle" />
+                       <enumeration value="prototype" />
+                       <enumeration value="prototype_required" />
+               </restriction>
+       </simpleType>
+
+       <simpleType name="Tservice_scope">
+               <restriction base="string">
+                       <enumeration value="bundle" />
+                       <enumeration value="none" />
+                       <enumeration value="prototype" />
+                       <enumeration value="singleton" />
+               </restriction>
+       </simpleType>
 
        <!-- Specifies the data type of a property or of the elements in a 
multi-value
                        property. Numerical and boolean values are trimmed 
before they are processed.
@@ -133,23 +209,23 @@
                        type of property it will automatically be boxed. -->
        <simpleType name="Tvalue-types">
                <restriction base="string">
-                       <enumeration value="String" />
-                       <enumeration value="long" />
-                       <enumeration value="Long" />
+                       <enumeration value="boolean" />
+                       <enumeration value="Boolean" />
+                       <enumeration value="byte" />
+                       <enumeration value="Byte" />
+                       <enumeration value="char" />
+                       <enumeration value="Character" />
                        <enumeration value="double" />
                        <enumeration value="Double" />
                        <enumeration value="float" />
                        <enumeration value="Float" />
                        <enumeration value="int" />
                        <enumeration value="Integer" />
-                       <enumeration value="byte" />
-                       <enumeration value="Byte" />
-                       <enumeration value="char" />
-                       <enumeration value="Character" />
-                       <enumeration value="boolean" />
-                       <enumeration value="Boolean" />
+                       <enumeration value="long" />
+                       <enumeration value="Long" />
                        <enumeration value="short" />
                        <enumeration value="Short" />
+                       <enumeration value="String" />
                </restriction>
        </simpleType>
 

Added: 
aries/trunk/cdi/cdi-extender/src/test/java/org/apache/aries/cdi/container/internal/component/ComponentExtension_Ctor_static_reluctant_Test.java
URL: 
http://svn.apache.org/viewvc/aries/trunk/cdi/cdi-extender/src/test/java/org/apache/aries/cdi/container/internal/component/ComponentExtension_Ctor_static_reluctant_Test.java?rev=1807424&view=auto
==============================================================================
--- 
aries/trunk/cdi/cdi-extender/src/test/java/org/apache/aries/cdi/container/internal/component/ComponentExtension_Ctor_static_reluctant_Test.java
 (added)
+++ 
aries/trunk/cdi/cdi-extender/src/test/java/org/apache/aries/cdi/container/internal/component/ComponentExtension_Ctor_static_reluctant_Test.java
 Tue Sep  5 22:01:11 2017
@@ -0,0 +1,318 @@
+/**
+ * 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.component;
+
+import static org.apache.aries.cdi.container.test.TestUtil.*;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Iterator;
+import java.util.List;
+
+import org.apache.aries.cdi.container.internal.model.BeansModel;
+import org.apache.aries.cdi.container.internal.reference.ReferenceModel;
+import org.apache.aries.cdi.container.test.MockCdiContainer;
+import org.apache.aries.cdi.container.test.MockCdiContainerAndComponents;
+import org.apache.aries.cdi.container.test.beans.Bar;
+import org.apache.aries.cdi.container.test.beans.CtorArrayListFoo;
+import org.apache.aries.cdi.container.test.beans.CtorFoo;
+import org.apache.aries.cdi.container.test.beans.CtorFooBar;
+import org.apache.aries.cdi.container.test.beans.CtorFooFoo;
+import org.apache.aries.cdi.container.test.beans.CtorFooFooNamed;
+import org.apache.aries.cdi.container.test.beans.CtorFooOptional;
+import org.apache.aries.cdi.container.test.beans.CtorListFoo;
+import org.apache.aries.cdi.container.test.beans.Foo;
+import org.apache.aries.cdi.container.test.beans.CtorCollectionFoo;
+import org.junit.Assert;
+import org.junit.Ignore;
+import org.junit.Test;
+import org.osgi.service.cdi.annotations.ReferenceCardinality;
+import org.osgi.service.cdi.annotations.ReferencePolicy;
+import org.osgi.service.cdi.annotations.ReferencePolicyOption;
+
+public class ComponentExtension_Ctor_static_reluctant_Test {
+
+       @Test
+       public void test_CtorArrayListFoo() throws Exception {
+               try (MockCdiContainerAndComponents container =
+                               new MockCdiContainerAndComponents(
+                                       "test", 
CtorArrayListFoo.class.getName())) {
+
+                       BeansModel beansModel = 
container.containerState().beansModel();
+
+                       Collection<ComponentModel> models = 
sort(beansModel.getComponentModels());
+
+                       Assert.assertEquals(1, models.size());
+
+//                     List<ReferenceModel> references = 
container.getTrackedReferences();
+//
+//                     Assert.assertEquals(1, references.size());
+//
+//                     ReferenceModel referenceModel = references.get(0);
+//
+//                     Assert.assertEquals(ArrayList.class, 
referenceModel.getBeanClass());
+//                     Assert.assertEquals(
+//                             ReferenceCardinality.MULTIPLE, 
referenceModel.getCardinality());
+//                     Assert.assertEquals("Foo0", referenceModel.getName());
+//                     Assert.assertEquals(ReferencePolicy.STATIC, 
referenceModel.getPolicy());
+//                     Assert.assertEquals(
+//                             ReferencePolicyOption.RELUCTANT, 
referenceModel.getPolicyOption());
+//                     Assert.assertNull(referenceModel.getScope());
+//                     Assert.assertEquals(Foo.class, 
referenceModel.getServiceClass());
+//                     Assert.assertEquals("", referenceModel.getTarget());
+               }
+       }
+
+       @Test
+       public void test_CtorCollectionFoo() throws Exception {
+               try (MockCdiContainerAndComponents container = new 
MockCdiContainerAndComponents(
+                               "test", CtorCollectionFoo.class.getName())) {
+
+                       BeansModel beansModel = 
container.containerState().beansModel();
+
+                       Collection<ComponentModel> models = 
sort(beansModel.getComponentModels());
+
+                       Assert.assertEquals(1, models.size());
+
+//                     List<ReferenceModel> references = 
container.getTrackedReferences();
+//
+//                     Assert.assertEquals(1, references.size());
+//
+//                     ReferenceModel referenceModel = references.get(0);
+//
+//                     Assert.assertEquals(Collection.class, 
referenceModel.getBeanClass());
+//                     Assert.assertEquals(
+//                             ReferenceCardinality.MULTIPLE, 
referenceModel.getCardinality());
+//                     Assert.assertEquals("Foo0", referenceModel.getName());
+//                     Assert.assertEquals(ReferencePolicy.STATIC, 
referenceModel.getPolicy());
+//                     Assert.assertEquals(
+//                             ReferencePolicyOption.RELUCTANT, 
referenceModel.getPolicyOption());
+//                     Assert.assertNull(referenceModel.getScope());
+//                     Assert.assertEquals(Foo.class, 
referenceModel.getServiceClass());
+//                     Assert.assertEquals("", referenceModel.getTarget());
+               }
+       }
+
+       @Test
+       public void test_CtorFooFoo() throws Exception {
+               try (MockCdiContainerAndComponents container = new 
MockCdiContainerAndComponents(
+                               "test", CtorFooFoo.class.getName())) {
+
+                       BeansModel beansModel = 
container.containerState().beansModel();
+
+                       Collection<ComponentModel> models = 
sort(beansModel.getComponentModels());
+
+                       Assert.assertEquals(1, models.size());
+
+//                     List<ReferenceModel> references = 
container.getTrackedReferences();
+//
+//                     Assert.assertEquals(2, references.size());
+//
+//                     ReferenceModel referenceModel = references.get(0);
+//
+//                     Assert.assertEquals(Foo.class, 
referenceModel.getBeanClass());
+//                     Assert.assertEquals(
+//                             ReferenceCardinality.MANDATORY, 
referenceModel.getCardinality());
+//                     Assert.assertEquals("Foo0", referenceModel.getName());
+//                     Assert.assertEquals(ReferencePolicy.STATIC, 
referenceModel.getPolicy());
+//                     Assert.assertEquals(
+//                             ReferencePolicyOption.RELUCTANT, 
referenceModel.getPolicyOption());
+//                     Assert.assertNull(referenceModel.getScope());
+//                     Assert.assertEquals(Foo.class, 
referenceModel.getServiceClass());
+//                     Assert.assertEquals("", referenceModel.getTarget());
+               }
+       }
+
+       @Test
+       public void test_CtorFoo() throws Exception {
+               try (MockCdiContainerAndComponents container = new 
MockCdiContainerAndComponents(
+                               "test", CtorFoo.class.getName())) {
+
+                       BeansModel beansModel = 
container.containerState().beansModel();
+
+                       Collection<ComponentModel> models = 
sort(beansModel.getComponentModels());
+
+                       Assert.assertEquals(1, models.size());
+
+//                     List<ReferenceModel> references = 
container.getTrackedReferences();
+//
+//                     Assert.assertEquals(1, references.size());
+//
+//                     ReferenceModel referenceModel = references.get(0);
+//
+//                     Assert.assertEquals(Foo.class, 
referenceModel.getBeanClass());
+//                     Assert.assertEquals(
+//                             ReferenceCardinality.MANDATORY, 
referenceModel.getCardinality());
+//                     Assert.assertEquals("Foo0", referenceModel.getName());
+//                     Assert.assertEquals(ReferencePolicy.STATIC, 
referenceModel.getPolicy());
+//                     Assert.assertEquals(
+//                             ReferencePolicyOption.RELUCTANT, 
referenceModel.getPolicyOption());
+//                     Assert.assertNull(referenceModel.getScope());
+//                     Assert.assertEquals(Foo.class, 
referenceModel.getServiceClass());
+//                     Assert.assertEquals("", referenceModel.getTarget());
+               }
+       }
+
+       @Test
+       public void test_CtorListFoo() throws Exception {
+               try (MockCdiContainerAndComponents container = new 
MockCdiContainerAndComponents(
+                               "test", CtorListFoo.class.getName())) {
+
+                       BeansModel beansModel = 
container.containerState().beansModel();
+
+                       Collection<ComponentModel> models = 
sort(beansModel.getComponentModels());
+
+                       Assert.assertEquals(1, models.size());
+
+//                     List<ReferenceModel> references = 
container.getTrackedReferences();
+//
+//                     Assert.assertEquals(1, references.size());
+//
+//                     ReferenceModel referenceModel = references.get(0);
+//
+//                     Assert.assertEquals(List.class, 
referenceModel.getBeanClass());
+//                     Assert.assertEquals(
+//                             ReferenceCardinality.MULTIPLE, 
referenceModel.getCardinality());
+//                     Assert.assertEquals("Foo0", referenceModel.getName());
+//                     Assert.assertEquals(ReferencePolicy.STATIC, 
referenceModel.getPolicy());
+//                     Assert.assertEquals(
+//                             ReferencePolicyOption.RELUCTANT, 
referenceModel.getPolicyOption());
+//                     Assert.assertNull(referenceModel.getScope());
+//                     Assert.assertEquals(Foo.class, 
referenceModel.getServiceClass());
+//                     Assert.assertEquals("", referenceModel.getTarget());
+               }
+       }
+
+       @Test
+       public void test_CtorFooBar() throws Exception {
+               try (MockCdiContainerAndComponents container = new 
MockCdiContainerAndComponents(
+                               "test", CtorFooBar.class.getName())) {
+
+                       BeansModel beansModel = 
container.containerState().beansModel();
+
+                       Collection<ComponentModel> models = 
sort(beansModel.getComponentModels());
+
+                       Assert.assertEquals(1, models.size());
+
+//                     List<ReferenceModel> references = 
container.getTrackedReferences();
+//
+//                     Assert.assertEquals(2, references.size());
+//
+//                     ReferenceModel referenceModel = references.get(0);
+//
+//                     Assert.assertEquals(Foo.class, 
referenceModel.getBeanClass());
+//                     Assert.assertEquals(
+//                             ReferenceCardinality.MANDATORY, 
referenceModel.getCardinality());
+//                     Assert.assertEquals("Foo0", referenceModel.getName());
+//                     Assert.assertEquals(ReferencePolicy.STATIC, 
referenceModel.getPolicy());
+//                     Assert.assertEquals(
+//                             ReferencePolicyOption.RELUCTANT, 
referenceModel.getPolicyOption());
+//                     Assert.assertNull(referenceModel.getScope());
+//                     Assert.assertEquals(Foo.class, 
referenceModel.getServiceClass());
+//                     Assert.assertEquals("", referenceModel.getTarget());
+
+//                     referenceModel = references.get(1);
+//
+//                     Assert.assertEquals(Bar.class, 
referenceModel.getBeanClass());
+//                     Assert.assertEquals(
+//                             ReferenceCardinality.MANDATORY, 
referenceModel.getCardinality());
+//                     Assert.assertEquals("Bar1", referenceModel.getName());
+//                     Assert.assertEquals(ReferencePolicy.STATIC, 
referenceModel.getPolicy());
+//                     Assert.assertEquals(
+//                             ReferencePolicyOption.RELUCTANT, 
referenceModel.getPolicyOption());
+//                     Assert.assertNull(referenceModel.getScope());
+//                     Assert.assertEquals(Bar.class, 
referenceModel.getServiceClass());
+//                     Assert.assertEquals("", referenceModel.getTarget());
+               }
+       }
+
+       @Test
+       public void test_CtorFooFooNamed() throws Exception {
+               try (MockCdiContainerAndComponents container = new 
MockCdiContainerAndComponents(
+                               "test", CtorFooFooNamed.class.getName())) {
+
+                       BeansModel beansModel = 
container.containerState().beansModel();
+
+                       Collection<ComponentModel> models = 
sort(beansModel.getComponentModels());
+
+                       Assert.assertEquals(1, models.size());
+
+//                     Collection<ReferenceModel> references = 
sort(container.getTrackedReferences(), (c1, c2) -> 
c1.toString().compareTo(c2.toString()));
+//
+//                     Assert.assertEquals(2, references.size());
+//
+//                     Iterator<ReferenceModel> referenceIterator = 
references.iterator();
+//
+//                     ReferenceModel referenceModel = 
referenceIterator.next();
+//
+//                     Assert.assertEquals(Foo.class, 
referenceModel.getBeanClass());
+//                     Assert.assertEquals(
+//                             ReferenceCardinality.MANDATORY, 
referenceModel.getCardinality());
+//                     Assert.assertEquals("foo_a", referenceModel.getName());
+//                     Assert.assertEquals(ReferencePolicy.STATIC, 
referenceModel.getPolicy());
+//                     Assert.assertEquals(
+//                             ReferencePolicyOption.RELUCTANT, 
referenceModel.getPolicyOption());
+//                     Assert.assertNull(referenceModel.getScope());
+//                     Assert.assertEquals(Foo.class, 
referenceModel.getServiceClass());
+//                     Assert.assertEquals("", referenceModel.getTarget());
+//
+//                     referenceModel = referenceIterator.next();
+//
+//                     Assert.assertEquals(Foo.class, 
referenceModel.getBeanClass());
+//                     Assert.assertEquals(
+//                             ReferenceCardinality.MANDATORY, 
referenceModel.getCardinality());
+//                     Assert.assertEquals("foo_b", referenceModel.getName());
+//                     Assert.assertEquals(ReferencePolicy.STATIC, 
referenceModel.getPolicy());
+//                     Assert.assertEquals(
+//                             ReferencePolicyOption.RELUCTANT, 
referenceModel.getPolicyOption());
+//                     Assert.assertNull(referenceModel.getScope());
+//                     Assert.assertEquals(Foo.class, 
referenceModel.getServiceClass());
+//                     Assert.assertEquals("", referenceModel.getTarget());
+               }
+       }
+
+       @Test
+       public void test_CtorFooOptional() throws Exception {
+               try (MockCdiContainerAndComponents container = new 
MockCdiContainerAndComponents(
+                               "test", CtorFooOptional.class.getName())) {
+
+                       BeansModel beansModel = 
container.containerState().beansModel();
+
+                       Collection<ComponentModel> models = 
sort(beansModel.getComponentModels());
+
+                       Assert.assertEquals(1, models.size());
+
+//                     Collection<ReferenceModel> references = 
container.getTrackedReferences();
+//
+//                     Assert.assertEquals(1, references.size());
+//
+//                     Iterator<ReferenceModel> referenceIterator = 
references.iterator();
+//
+//                     ReferenceModel referenceModel = 
referenceIterator.next();
+//
+//                     Assert.assertEquals(Foo.class, 
referenceModel.getBeanClass());
+//                     Assert.assertEquals(
+//                             ReferenceCardinality.OPTIONAL, 
referenceModel.getCardinality());
+//                     Assert.assertEquals("Foo0", referenceModel.getName());
+//                     Assert.assertEquals(ReferencePolicy.STATIC, 
referenceModel.getPolicy());
+//                     Assert.assertEquals(
+//                             ReferencePolicyOption.RELUCTANT, 
referenceModel.getPolicyOption());
+//                     Assert.assertNull(referenceModel.getScope());
+//                     Assert.assertEquals(Foo.class, 
referenceModel.getServiceClass());
+//                     Assert.assertEquals("", referenceModel.getTarget());
+               }
+       }
+
+}
\ No newline at end of file

Added: 
aries/trunk/cdi/cdi-extender/src/test/java/org/apache/aries/cdi/container/internal/configuration/ConfigurationCallbackTest_Ignore.java
URL: 
http://svn.apache.org/viewvc/aries/trunk/cdi/cdi-extender/src/test/java/org/apache/aries/cdi/container/internal/configuration/ConfigurationCallbackTest_Ignore.java?rev=1807424&view=auto
==============================================================================
--- 
aries/trunk/cdi/cdi-extender/src/test/java/org/apache/aries/cdi/container/internal/configuration/ConfigurationCallbackTest_Ignore.java
 (added)
+++ 
aries/trunk/cdi/cdi-extender/src/test/java/org/apache/aries/cdi/container/internal/configuration/ConfigurationCallbackTest_Ignore.java
 Tue Sep  5 22:01:11 2017
@@ -0,0 +1,355 @@
+/**
+ * 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.configuration;
+
+import static org.osgi.framework.Constants.SERVICE_PID;
+import static org.apache.aries.cdi.container.test.TestUtil.*;
+
+import java.util.Dictionary;
+import java.util.Hashtable;
+
+import org.junit.Assert;
+import org.junit.Test;
+import org.osgi.service.cdi.annotations.ConfigurationPolicy;
+
+public class ConfigurationCallbackTest_Ignore {
+
+       @Test
+       public void test_emptyAdd() throws Exception {
+               ConfigurationCallback callback = getCallback(POLICY);
+
+               Assert.assertTrue(callback.resolved());
+               Assert.assertNotNull(callback.properties());
+               Assert.assertTrue(callback.properties().isEmpty());
+
+               Dictionary<String, Object> properties = new Hashtable<>();
+
+               callback.added(properties);
+       }
+
+       @Test
+       public void test_emptyUpdate() throws Exception {
+               ConfigurationCallback callback = getCallback(POLICY);
+
+               Assert.assertTrue(callback.resolved());
+               Assert.assertNotNull(callback.properties());
+               Assert.assertTrue(callback.properties().isEmpty());
+
+               Dictionary<String, Object> properties = new Hashtable<>();
+
+               callback.updated(properties);
+       }
+
+       @Test
+       public void test_nullAdd() throws Exception {
+               ConfigurationCallback callback = getCallback(POLICY);
+
+               Assert.assertTrue(callback.resolved());
+               Assert.assertNotNull(callback.properties());
+               Assert.assertTrue(callback.properties().isEmpty());
+
+               callback.added(null);
+       }
+
+       @Test
+       public void test_nullUpdate() throws Exception {
+               ConfigurationCallback callback = getCallback(POLICY);
+
+               Assert.assertTrue(callback.resolved());
+               Assert.assertNotNull(callback.properties());
+               Assert.assertTrue(callback.properties().isEmpty());
+
+               callback.updated(null);
+       }
+
+       @Test
+       public void test_addAfterAdd() throws Exception {
+               ConfigurationCallback callback = getCallback(POLICY);
+
+               Assert.assertTrue(callback.resolved());
+               Assert.assertNotNull(callback.properties());
+               Assert.assertTrue(callback.properties().isEmpty());
+
+               Dictionary<String, Object> properties = new Hashtable<>();
+               properties.put(SERVICE_PID, "foo");
+
+               callback.added(properties);
+
+               Assert.assertTrue(callback.resolved());
+               Assert.assertNotNull(callback.properties());
+               Assert.assertTrue(callback.properties().isEmpty());
+
+               callback.added(properties);
+       }
+
+       @Test
+       public void test_addAfterRemove() throws Exception {
+               ConfigurationCallback callback = getCallback(POLICY);
+
+               Assert.assertTrue(callback.resolved());
+               Assert.assertNotNull(callback.properties());
+               Assert.assertTrue(callback.properties().isEmpty());
+
+               Dictionary<String, Object> properties = new Hashtable<>();
+               properties.put(SERVICE_PID, "foo");
+
+               callback.added(properties);
+
+               Assert.assertTrue(callback.resolved());
+               Assert.assertNotNull(callback.properties());
+               Assert.assertTrue(callback.properties().isEmpty());
+
+               callback.removed();
+
+               Assert.assertTrue(callback.resolved());
+               Assert.assertNotNull(callback.properties());
+               Assert.assertTrue(callback.properties().isEmpty());
+
+               callback.added(properties);
+
+               Assert.assertTrue(callback.resolved());
+               Assert.assertNotNull(callback.properties());
+               Assert.assertTrue(callback.properties().isEmpty());
+       }
+
+       @Test
+       public void test_addAfterUpdate() throws Exception {
+               ConfigurationCallback callback = getCallback(POLICY);
+
+               Assert.assertTrue(callback.resolved());
+               Assert.assertNotNull(callback.properties());
+               Assert.assertTrue(callback.properties().isEmpty());
+
+               Dictionary<String, Object> properties = new Hashtable<>();
+               properties.put(SERVICE_PID, "foo");
+
+               callback.added(properties);
+
+               Assert.assertTrue(callback.resolved());
+               Assert.assertNotNull(callback.properties());
+               Assert.assertTrue(callback.properties().isEmpty());
+
+               properties = new Hashtable<>();
+               properties.put(SERVICE_PID, "foo");
+
+               callback.updated(properties);
+
+               Assert.assertTrue(callback.resolved());
+               Assert.assertNotNull(callback.properties());
+               Assert.assertTrue(callback.properties().isEmpty());
+
+               callback.added(properties);
+       }
+
+       @Test
+       public void test_removeAfterAdd() throws Exception {
+               ConfigurationCallback callback = getCallback(POLICY);
+
+               Assert.assertTrue(callback.resolved());
+               Assert.assertNotNull(callback.properties());
+               Assert.assertTrue(callback.properties().isEmpty());
+
+               Dictionary<String, Object> properties = new Hashtable<>();
+               properties.put(SERVICE_PID, "foo");
+
+               callback.added(properties);
+
+               Assert.assertTrue(callback.resolved());
+               Assert.assertNotNull(callback.properties());
+               Assert.assertTrue(callback.properties().isEmpty());
+
+               callback.removed();
+
+               Assert.assertTrue(callback.resolved());
+               Assert.assertNotNull(callback.properties());
+               Assert.assertTrue(callback.properties().isEmpty());
+       }
+
+       @Test
+       public void test_removeAfterRemove() throws Exception {
+               ConfigurationCallback callback = getCallback(POLICY);
+
+               Assert.assertTrue(callback.resolved());
+               Assert.assertNotNull(callback.properties());
+               Assert.assertTrue(callback.properties().isEmpty());
+
+               Dictionary<String, Object> properties = new Hashtable<>();
+               properties.put(SERVICE_PID, "foo");
+
+               callback.added(properties);
+
+               Assert.assertTrue(callback.resolved());
+               Assert.assertNotNull(callback.properties());
+               Assert.assertTrue(callback.properties().isEmpty());
+
+               callback.removed();
+
+               Assert.assertTrue(callback.resolved());
+               Assert.assertNotNull(callback.properties());
+               Assert.assertTrue(callback.properties().isEmpty());
+
+               callback.removed();
+       }
+
+       @Test
+       public void test_removeAfterUpdate() throws Exception {
+               ConfigurationCallback callback = getCallback(POLICY);
+
+               Assert.assertTrue(callback.resolved());
+               Assert.assertNotNull(callback.properties());
+               Assert.assertTrue(callback.properties().isEmpty());
+
+               Dictionary<String, Object> properties = new Hashtable<>();
+               properties.put(SERVICE_PID, "foo");
+
+               callback.added(properties);
+
+               Assert.assertTrue(callback.resolved());
+               Assert.assertNotNull(callback.properties());
+               Assert.assertTrue(callback.properties().isEmpty());
+
+               properties = new Hashtable<>();
+               properties.put(SERVICE_PID, "fum");
+
+               callback.updated(properties);
+
+               Assert.assertTrue(callback.resolved());
+               Assert.assertNotNull(callback.properties());
+               Assert.assertTrue(callback.properties().isEmpty());
+
+               callback.removed();
+
+               Assert.assertTrue(callback.resolved());
+               Assert.assertNotNull(callback.properties());
+               Assert.assertTrue(callback.properties().isEmpty());
+       }
+
+       @Test
+       public void test_removeBeforeAdd() throws Exception {
+               ConfigurationCallback callback = getCallback(POLICY);
+
+               Assert.assertTrue(callback.resolved());
+               Assert.assertNotNull(callback.properties());
+               Assert.assertTrue(callback.properties().isEmpty());
+
+               callback.removed();
+       }
+
+       @Test
+       public void test_updateAfterAdd() throws Exception {
+               ConfigurationCallback callback = getCallback(POLICY);
+
+               Assert.assertTrue(callback.resolved());
+               Assert.assertNotNull(callback.properties());
+               Assert.assertTrue(callback.properties().isEmpty());
+
+               Dictionary<String, Object> properties = new Hashtable<>();
+               properties.put(SERVICE_PID, "foo");
+
+               callback.added(properties);
+
+               Assert.assertTrue(callback.resolved());
+               Assert.assertNotNull(callback.properties());
+               Assert.assertTrue(callback.properties().isEmpty());
+
+               properties = new Hashtable<>();
+               properties.put(SERVICE_PID, "fum");
+
+               callback.updated(properties);
+
+               Assert.assertTrue(callback.resolved());
+               Assert.assertNotNull(callback.properties());
+               Assert.assertTrue(callback.properties().isEmpty());
+       }
+
+       @Test
+       public void test_updateAfterRemove() throws Exception {
+               ConfigurationCallback callback = getCallback(POLICY);
+
+               Assert.assertTrue(callback.resolved());
+               Assert.assertNotNull(callback.properties());
+               Assert.assertTrue(callback.properties().isEmpty());
+
+               Dictionary<String, Object> properties = new Hashtable<>();
+               properties.put(SERVICE_PID, "foo");
+
+               callback.added(properties);
+
+               Assert.assertTrue(callback.resolved());
+               Assert.assertNotNull(callback.properties());
+               Assert.assertTrue(callback.properties().isEmpty());
+
+               callback.removed();
+
+               Assert.assertTrue(callback.resolved());
+               Assert.assertNotNull(callback.properties());
+               Assert.assertTrue(callback.properties().isEmpty());
+
+               callback.updated(properties);
+       }
+
+       @Test
+       public void test_updateAfterUpdate() throws Exception {
+               ConfigurationCallback callback = getCallback(POLICY);
+
+               Assert.assertTrue(callback.resolved());
+               Assert.assertNotNull(callback.properties());
+               Assert.assertTrue(callback.properties().isEmpty());
+
+               Dictionary<String, Object> properties = new Hashtable<>();
+               properties.put(SERVICE_PID, "foo");
+
+               callback.added(properties);
+
+               Assert.assertTrue(callback.resolved());
+               Assert.assertNotNull(callback.properties());
+               Assert.assertTrue(callback.properties().isEmpty());
+
+               properties = new Hashtable<>();
+               properties.put(SERVICE_PID, "fum");
+
+               callback.updated(properties);
+
+               Assert.assertTrue(callback.resolved());
+               Assert.assertNotNull(callback.properties());
+               Assert.assertTrue(callback.properties().isEmpty());
+
+               properties = new Hashtable<>();
+               properties.put(SERVICE_PID, "fee");
+
+               callback.updated(properties);
+
+               Assert.assertTrue(callback.resolved());
+               Assert.assertNotNull(callback.properties());
+               Assert.assertTrue(callback.properties().isEmpty());
+       }
+
+       @Test
+       public void test_updateBeforeAdd() throws Exception {
+               ConfigurationCallback callback = getCallback(POLICY);
+
+               Assert.assertTrue(callback.resolved());
+               Assert.assertNotNull(callback.properties());
+               Assert.assertTrue(callback.properties().isEmpty());
+
+               Dictionary<String, Object> properties = new Hashtable<>();
+               properties.put(SERVICE_PID, "foo");
+
+               callback.updated(properties);
+       }
+
+       private ConfigurationPolicy POLICY = ConfigurationPolicy.IGNORE;
+
+}

Added: 
aries/trunk/cdi/cdi-extender/src/test/java/org/apache/aries/cdi/container/internal/configuration/ConfigurationCallbackTest_Optional.java
URL: 
http://svn.apache.org/viewvc/aries/trunk/cdi/cdi-extender/src/test/java/org/apache/aries/cdi/container/internal/configuration/ConfigurationCallbackTest_Optional.java?rev=1807424&view=auto
==============================================================================
--- 
aries/trunk/cdi/cdi-extender/src/test/java/org/apache/aries/cdi/container/internal/configuration/ConfigurationCallbackTest_Optional.java
 (added)
+++ 
aries/trunk/cdi/cdi-extender/src/test/java/org/apache/aries/cdi/container/internal/configuration/ConfigurationCallbackTest_Optional.java
 Tue Sep  5 22:01:11 2017
@@ -0,0 +1,362 @@
+/**
+ * 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.configuration;
+
+import static org.osgi.framework.Constants.SERVICE_PID;
+import static org.apache.aries.cdi.container.test.TestUtil.*;
+
+import java.util.Dictionary;
+import java.util.Hashtable;
+
+import org.junit.Assert;
+import org.junit.Test;
+import org.osgi.service.cdi.annotations.ConfigurationPolicy;
+
+public class ConfigurationCallbackTest_Optional {
+
+       @Test(expected = IllegalArgumentException.class)
+       public void test_emptyAdd() throws Exception {
+               ConfigurationCallback callback = getCallback(POLICY);
+
+               Assert.assertTrue(callback.resolved());
+               Assert.assertNotNull(callback.properties());
+               Assert.assertTrue(callback.properties().isEmpty());
+
+               Dictionary<String, Object> properties = new Hashtable<>();
+
+               callback.added(properties);
+       }
+
+       @Test(expected = IllegalArgumentException.class)
+       public void test_emptyUpdate() throws Exception {
+               ConfigurationCallback callback = getCallback(POLICY);
+
+               Assert.assertTrue(callback.resolved());
+               Assert.assertNotNull(callback.properties());
+               Assert.assertTrue(callback.properties().isEmpty());
+
+               Dictionary<String, Object> properties = new Hashtable<>();
+
+               callback.updated(properties);
+       }
+
+       @Test(expected = IllegalArgumentException.class)
+       public void test_nullAdd() throws Exception {
+               ConfigurationCallback callback = getCallback(POLICY);
+
+               Assert.assertTrue(callback.resolved());
+               Assert.assertNotNull(callback.properties());
+               Assert.assertTrue(callback.properties().isEmpty());
+
+               callback.added(null);
+       }
+
+       @Test(expected = IllegalArgumentException.class)
+       public void test_nullUpdate() throws Exception {
+               ConfigurationCallback callback = getCallback(POLICY);
+
+               Assert.assertTrue(callback.resolved());
+               Assert.assertNotNull(callback.properties());
+               Assert.assertTrue(callback.properties().isEmpty());
+
+               callback.updated(null);
+       }
+
+       @Test(expected = IllegalStateException.class)
+       public void test_addAfterAdd() throws Exception {
+               ConfigurationCallback callback = getCallback(POLICY);
+
+               Assert.assertTrue(callback.resolved());
+               Assert.assertNotNull(callback.properties());
+               Assert.assertTrue(callback.properties().isEmpty());
+
+               Dictionary<String, Object> properties = new Hashtable<>();
+               properties.put(SERVICE_PID, "foo");
+
+               callback.added(properties);
+
+               Assert.assertTrue(callback.resolved());
+               Assert.assertNotNull(callback.properties());
+               Assert.assertFalse(callback.properties().isEmpty());
+
+               callback.added(properties);
+       }
+
+       @Test
+       public void test_addAfterRemove() throws Exception {
+               ConfigurationCallback callback = getCallback(POLICY);
+
+               Assert.assertTrue(callback.resolved());
+               Assert.assertNotNull(callback.properties());
+               Assert.assertTrue(callback.properties().isEmpty());
+
+               Dictionary<String, Object> properties = new Hashtable<>();
+               properties.put(SERVICE_PID, "foo");
+
+               callback.added(properties);
+
+               Assert.assertTrue(callback.resolved());
+               Assert.assertNotNull(callback.properties());
+               Assert.assertFalse(callback.properties().isEmpty());
+
+               callback.removed();
+
+               Assert.assertTrue(callback.resolved());
+               Assert.assertNotNull(callback.properties());
+               Assert.assertTrue(callback.properties().isEmpty());
+
+               callback.added(properties);
+
+               Assert.assertTrue(callback.resolved());
+               Assert.assertNotNull(callback.properties());
+               Assert.assertFalse(callback.properties().isEmpty());
+       }
+
+       @Test(expected = IllegalStateException.class)
+       public void test_addAfterUpdate() throws Exception {
+               ConfigurationCallback callback = getCallback(POLICY);
+
+               Assert.assertTrue(callback.resolved());
+               Assert.assertNotNull(callback.properties());
+               Assert.assertTrue(callback.properties().isEmpty());
+
+               Dictionary<String, Object> properties = new Hashtable<>();
+               properties.put(SERVICE_PID, "foo");
+
+               callback.added(properties);
+
+               Assert.assertTrue(callback.resolved());
+               Assert.assertNotNull(callback.properties());
+               Assert.assertFalse(callback.properties().isEmpty());
+
+               properties = new Hashtable<>();
+               properties.put(SERVICE_PID, "foo");
+
+               callback.updated(properties);
+
+               Assert.assertTrue(callback.resolved());
+               Assert.assertNotNull(callback.properties());
+               Assert.assertFalse(callback.properties().isEmpty());
+
+               callback.added(properties);
+       }
+
+       @Test
+       public void test_removeAfterAdd() throws Exception {
+               ConfigurationCallback callback = getCallback(POLICY);
+
+               Assert.assertTrue(callback.resolved());
+               Assert.assertNotNull(callback.properties());
+               Assert.assertTrue(callback.properties().isEmpty());
+
+               Dictionary<String, Object> properties = new Hashtable<>();
+               properties.put(SERVICE_PID, "foo");
+
+               callback.added(properties);
+
+               Assert.assertTrue(callback.resolved());
+               Assert.assertNotNull(callback.properties());
+               Assert.assertFalse(callback.properties().isEmpty());
+
+               callback.removed();
+
+               Assert.assertTrue(callback.resolved());
+               Assert.assertNotNull(callback.properties());
+               Assert.assertTrue(callback.properties().isEmpty());
+       }
+
+       @Test(expected = IllegalStateException.class)
+       public void test_removeAfterRemove() throws Exception {
+               ConfigurationCallback callback = getCallback(POLICY);
+
+               Assert.assertTrue(callback.resolved());
+               Assert.assertNotNull(callback.properties());
+               Assert.assertTrue(callback.properties().isEmpty());
+
+               Dictionary<String, Object> properties = new Hashtable<>();
+               properties.put(SERVICE_PID, "foo");
+
+               callback.added(properties);
+
+               Assert.assertTrue(callback.resolved());
+               Assert.assertNotNull(callback.properties());
+               Assert.assertFalse(callback.properties().isEmpty());
+
+               callback.removed();
+
+               Assert.assertTrue(callback.resolved());
+               Assert.assertNotNull(callback.properties());
+               Assert.assertTrue(callback.properties().isEmpty());
+
+               callback.removed();
+       }
+
+       @Test
+       public void test_removeAfterUpdate() throws Exception {
+               ConfigurationCallback callback = getCallback(POLICY);
+
+               Assert.assertTrue(callback.resolved());
+               Assert.assertNotNull(callback.properties());
+               Assert.assertTrue(callback.properties().isEmpty());
+
+               Dictionary<String, Object> properties = new Hashtable<>();
+               properties.put(SERVICE_PID, "foo");
+
+               callback.added(properties);
+
+               Assert.assertTrue(callback.resolved());
+               Assert.assertNotNull(callback.properties());
+               Assert.assertFalse(callback.properties().isEmpty());
+               Assert.assertEquals("foo", 
callback.properties().get(SERVICE_PID));
+
+               properties = new Hashtable<>();
+               properties.put(SERVICE_PID, "fum");
+
+               callback.updated(properties);
+
+               Assert.assertTrue(callback.resolved());
+               Assert.assertNotNull(callback.properties());
+               Assert.assertFalse(callback.properties().isEmpty());
+               Assert.assertEquals("fum", 
callback.properties().get(SERVICE_PID));
+
+               callback.removed();
+
+               Assert.assertTrue(callback.resolved());
+               Assert.assertNotNull(callback.properties());
+               Assert.assertTrue(callback.properties().isEmpty());
+       }
+
+       @Test(expected = IllegalStateException.class)
+       public void test_removeBeforeAdd() throws Exception {
+               ConfigurationCallback callback = getCallback(POLICY);
+
+               Assert.assertTrue(callback.resolved());
+               Assert.assertNotNull(callback.properties());
+               Assert.assertTrue(callback.properties().isEmpty());
+
+               callback.removed();
+       }
+
+       @Test
+       public void test_updateAfterAdd() throws Exception {
+               ConfigurationCallback callback = getCallback(POLICY);
+
+               Assert.assertTrue(callback.resolved());
+               Assert.assertNotNull(callback.properties());
+               Assert.assertTrue(callback.properties().isEmpty());
+
+               Dictionary<String, Object> properties = new Hashtable<>();
+               properties.put(SERVICE_PID, "foo");
+
+               callback.added(properties);
+
+               Assert.assertTrue(callback.resolved());
+               Assert.assertNotNull(callback.properties());
+               Assert.assertFalse(callback.properties().isEmpty());
+               Assert.assertEquals("foo", 
callback.properties().get(SERVICE_PID));
+
+               properties = new Hashtable<>();
+               properties.put(SERVICE_PID, "fum");
+
+               callback.updated(properties);
+
+               Assert.assertTrue(callback.resolved());
+               Assert.assertNotNull(callback.properties());
+               Assert.assertFalse(callback.properties().isEmpty());
+               Assert.assertEquals("fum", 
callback.properties().get(SERVICE_PID));
+       }
+
+       @Test(expected = IllegalStateException.class)
+       public void test_updateAfterRemove() throws Exception {
+               ConfigurationCallback callback = getCallback(POLICY);
+
+               Assert.assertTrue(callback.resolved());
+               Assert.assertNotNull(callback.properties());
+               Assert.assertTrue(callback.properties().isEmpty());
+
+               Dictionary<String, Object> properties = new Hashtable<>();
+               properties.put(SERVICE_PID, "foo");
+
+               callback.added(properties);
+
+               Assert.assertTrue(callback.resolved());
+               Assert.assertNotNull(callback.properties());
+               Assert.assertFalse(callback.properties().isEmpty());
+
+               callback.removed();
+
+               Assert.assertTrue(callback.resolved());
+               Assert.assertNotNull(callback.properties());
+               Assert.assertTrue(callback.properties().isEmpty());
+
+               callback.updated(properties);
+       }
+
+       @Test
+       public void test_updateAfterUpdate() throws Exception {
+               ConfigurationCallback callback = getCallback(POLICY);
+
+               Assert.assertTrue(callback.resolved());
+               Assert.assertNotNull(callback.properties());
+               Assert.assertTrue(callback.properties().isEmpty());
+
+               Dictionary<String, Object> properties = new Hashtable<>();
+               properties.put(SERVICE_PID, "foo");
+
+               callback.added(properties);
+
+               Assert.assertTrue(callback.resolved());
+               Assert.assertNotNull(callback.properties());
+               Assert.assertFalse(callback.properties().isEmpty());
+               Assert.assertEquals("foo", 
callback.properties().get(SERVICE_PID));
+
+               properties = new Hashtable<>();
+               properties.put(SERVICE_PID, "fum");
+
+               callback.updated(properties);
+
+               Assert.assertTrue(callback.resolved());
+               Assert.assertNotNull(callback.properties());
+               Assert.assertFalse(callback.properties().isEmpty());
+               Assert.assertEquals("fum", 
callback.properties().get(SERVICE_PID));
+
+               properties = new Hashtable<>();
+               properties.put(SERVICE_PID, "fee");
+
+               callback.updated(properties);
+
+               Assert.assertTrue(callback.resolved());
+               Assert.assertNotNull(callback.properties());
+               Assert.assertFalse(callback.properties().isEmpty());
+               Assert.assertEquals("fee", 
callback.properties().get(SERVICE_PID));
+       }
+
+       @Test(expected = IllegalStateException.class)
+       public void test_updateBeforeAdd() throws Exception {
+               ConfigurationCallback callback = getCallback(POLICY);
+
+               Assert.assertTrue(callback.resolved());
+               Assert.assertNotNull(callback.properties());
+               Assert.assertTrue(callback.properties().isEmpty());
+
+               Dictionary<String, Object> properties = new Hashtable<>();
+               properties.put(SERVICE_PID, "foo");
+
+               callback.updated(properties);
+       }
+
+       private ConfigurationPolicy POLICY = ConfigurationPolicy.OPTIONAL;
+
+}


Reply via email to