You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@sling.apache.org by ss...@apache.org on 2014/11/13 14:51:34 UTC

svn commit: r1639323 [1/2] - in /sling/trunk/bundles/extensions/models: ./ api/src/main/java/org/apache/sling/models/spi/injectorspecific/ impl/src/main/java/org/apache/sling/models/impl/ impl/src/main/java/org/apache/sling/models/impl/injectors/ impl/...

Author: sseifert
Date: Thu Nov 13 13:51:33 2014
New Revision: 1639323

URL: http://svn.apache.org/r1639323
Log:
SLING-4112 Sling Models: Optimize performance when read sling models annotations

Added:
    sling/trunk/bundles/extensions/models/api/src/main/java/org/apache/sling/models/spi/injectorspecific/StaticInjectAnnotationProcessorFactory.java
      - copied unchanged from r1639316, sling/whiteboard/sseifert/SLING-4112_models_tuning/api/src/main/java/org/apache/sling/models/spi/injectorspecific/StaticInjectAnnotationProcessorFactory.java
    sling/trunk/bundles/extensions/models/impl/src/main/java/org/apache/sling/models/impl/ReflectionUtil.java
      - copied unchanged from r1639316, sling/whiteboard/sseifert/SLING-4112_models_tuning/impl/src/main/java/org/apache/sling/models/impl/ReflectionUtil.java
    sling/trunk/bundles/extensions/models/impl/src/main/java/org/apache/sling/models/impl/model/
      - copied from r1639316, sling/whiteboard/sseifert/SLING-4112_models_tuning/impl/src/main/java/org/apache/sling/models/impl/model/
Removed:
    sling/trunk/bundles/extensions/models/impl/src/main/java/org/apache/sling/models/impl/ConstructorParameter.java
    sling/trunk/bundles/extensions/models/impl/src/main/java/org/apache/sling/models/impl/ParameterCountInjectComparator.java
Modified:
    sling/trunk/bundles/extensions/models/   (props changed)
    sling/trunk/bundles/extensions/models/api/src/main/java/org/apache/sling/models/spi/injectorspecific/AbstractInjectAnnotationProcessor.java
    sling/trunk/bundles/extensions/models/api/src/main/java/org/apache/sling/models/spi/injectorspecific/InjectAnnotationProcessorFactory.java
    sling/trunk/bundles/extensions/models/api/src/main/java/org/apache/sling/models/spi/injectorspecific/package-info.java
    sling/trunk/bundles/extensions/models/impl/src/main/java/org/apache/sling/models/impl/AdapterImplementations.java
    sling/trunk/bundles/extensions/models/impl/src/main/java/org/apache/sling/models/impl/ModelAdapterFactory.java
    sling/trunk/bundles/extensions/models/impl/src/main/java/org/apache/sling/models/impl/ModelPackageBundleListener.java
    sling/trunk/bundles/extensions/models/impl/src/main/java/org/apache/sling/models/impl/Result.java
    sling/trunk/bundles/extensions/models/impl/src/main/java/org/apache/sling/models/impl/injectors/BindingsInjector.java
    sling/trunk/bundles/extensions/models/impl/src/main/java/org/apache/sling/models/impl/injectors/OSGiServiceInjector.java
    sling/trunk/bundles/extensions/models/impl/src/main/java/org/apache/sling/models/impl/injectors/RequestAttributeInjector.java
    sling/trunk/bundles/extensions/models/impl/src/main/java/org/apache/sling/models/impl/injectors/ResourcePathInjector.java
    sling/trunk/bundles/extensions/models/impl/src/main/java/org/apache/sling/models/impl/injectors/SelfInjector.java
    sling/trunk/bundles/extensions/models/impl/src/main/java/org/apache/sling/models/impl/injectors/SlingObjectInjector.java
    sling/trunk/bundles/extensions/models/impl/src/test/java/org/apache/sling/models/impl/AdapterImplementationsTest.java
    sling/trunk/bundles/extensions/models/impl/src/test/java/org/apache/sling/models/impl/InjectorSpecificAnnotationTest.java
    sling/trunk/bundles/extensions/models/impl/src/test/java/org/apache/sling/models/impl/MultipleInjectorTest.java
    sling/trunk/bundles/extensions/models/impl/src/test/java/org/apache/sling/models/impl/ResourcePathInjectionTest.java
    sling/trunk/bundles/extensions/models/impl/src/test/java/org/apache/sling/models/impl/injectors/SelfInjectorTest.java
    sling/trunk/bundles/extensions/models/integration-tests/pom.xml

Propchange: sling/trunk/bundles/extensions/models/
------------------------------------------------------------------------------
--- svn:mergeinfo (added)
+++ svn:mergeinfo Thu Nov 13 13:51:33 2014
@@ -0,0 +1 @@
+/sling/whiteboard/sseifert/SLING-4112_models_tuning:1635259-1639316

Modified: sling/trunk/bundles/extensions/models/api/src/main/java/org/apache/sling/models/spi/injectorspecific/AbstractInjectAnnotationProcessor.java
URL: http://svn.apache.org/viewvc/sling/trunk/bundles/extensions/models/api/src/main/java/org/apache/sling/models/spi/injectorspecific/AbstractInjectAnnotationProcessor.java?rev=1639323&r1=1639322&r2=1639323&view=diff
==============================================================================
--- sling/trunk/bundles/extensions/models/api/src/main/java/org/apache/sling/models/spi/injectorspecific/AbstractInjectAnnotationProcessor.java (original)
+++ sling/trunk/bundles/extensions/models/api/src/main/java/org/apache/sling/models/spi/injectorspecific/AbstractInjectAnnotationProcessor.java Thu Nov 13 13:51:33 2014
@@ -17,8 +17,7 @@
 package org.apache.sling.models.spi.injectorspecific;
 
 /**
- * Default implementation of ModelAnnotationProcessor.
- *
+ * Default implementation of {@link InjectAnnotationProcessor}.
  */
 public class AbstractInjectAnnotationProcessor implements InjectAnnotationProcessor {
 

Modified: sling/trunk/bundles/extensions/models/api/src/main/java/org/apache/sling/models/spi/injectorspecific/InjectAnnotationProcessorFactory.java
URL: http://svn.apache.org/viewvc/sling/trunk/bundles/extensions/models/api/src/main/java/org/apache/sling/models/spi/injectorspecific/InjectAnnotationProcessorFactory.java?rev=1639323&r1=1639322&r2=1639323&view=diff
==============================================================================
--- sling/trunk/bundles/extensions/models/api/src/main/java/org/apache/sling/models/spi/injectorspecific/InjectAnnotationProcessorFactory.java (original)
+++ sling/trunk/bundles/extensions/models/api/src/main/java/org/apache/sling/models/spi/injectorspecific/InjectAnnotationProcessorFactory.java Thu Nov 13 13:51:33 2014
@@ -18,7 +18,12 @@ package org.apache.sling.models.spi.inje
 
 import java.lang.reflect.AnnotatedElement;
 
+/**
+ * Factory for {@link InjectAnnotationProcessor} that is evaluated at runtime for each
+ * sling model adaption and may depend on the adaptable. 
+ */
 public interface InjectAnnotationProcessorFactory {
+
     /**
      * 
      * @param adaptable the object from which this model is adapted
@@ -28,4 +33,5 @@ public interface InjectAnnotationProcess
      *         null
      */
     InjectAnnotationProcessor createAnnotationProcessor(Object adaptable, AnnotatedElement element);
+
 }

Modified: sling/trunk/bundles/extensions/models/api/src/main/java/org/apache/sling/models/spi/injectorspecific/package-info.java
URL: http://svn.apache.org/viewvc/sling/trunk/bundles/extensions/models/api/src/main/java/org/apache/sling/models/spi/injectorspecific/package-info.java?rev=1639323&r1=1639322&r2=1639323&view=diff
==============================================================================
--- sling/trunk/bundles/extensions/models/api/src/main/java/org/apache/sling/models/spi/injectorspecific/package-info.java (original)
+++ sling/trunk/bundles/extensions/models/api/src/main/java/org/apache/sling/models/spi/injectorspecific/package-info.java Thu Nov 13 13:51:33 2014
@@ -14,7 +14,7 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
-@Version("1.0.0")
+@Version("1.1.0")
 package org.apache.sling.models.spi.injectorspecific;
 
 import aQute.bnd.annotation.Version;
\ No newline at end of file

Modified: sling/trunk/bundles/extensions/models/impl/src/main/java/org/apache/sling/models/impl/AdapterImplementations.java
URL: http://svn.apache.org/viewvc/sling/trunk/bundles/extensions/models/impl/src/main/java/org/apache/sling/models/impl/AdapterImplementations.java?rev=1639323&r1=1639322&r2=1639323&view=diff
==============================================================================
--- sling/trunk/bundles/extensions/models/impl/src/main/java/org/apache/sling/models/impl/AdapterImplementations.java (original)
+++ sling/trunk/bundles/extensions/models/impl/src/main/java/org/apache/sling/models/impl/AdapterImplementations.java Thu Nov 13 13:51:33 2014
@@ -24,19 +24,27 @@ import java.util.concurrent.ConcurrentMa
 import java.util.concurrent.ConcurrentNavigableMap;
 import java.util.concurrent.ConcurrentSkipListMap;
 
+import org.apache.commons.lang.StringUtils;
+import org.apache.sling.models.impl.model.ModelClass;
 import org.apache.sling.models.spi.ImplementationPicker;
+import org.apache.sling.models.spi.injectorspecific.StaticInjectAnnotationProcessorFactory;
 
 /**
  * Collects alternative adapter implementations that may be defined in a @Model.adapters attribute.
  * If multiple models implement the same adapter they are all collected and can be chose via a ImplementationPicker.
+ * Additionally it acts as a cache for model classes without adapter definitions, where adapter and implementation type is the same.
  * The implementation is thread-safe.
  */
 final class AdapterImplementations {
     
-    private final ConcurrentMap<String,ConcurrentNavigableMap<String,Class<?>>> adapterImplementations
-            = new ConcurrentHashMap<String,ConcurrentNavigableMap<String,Class<?>>>();
+    private final ConcurrentMap<String,ConcurrentNavigableMap<String,ModelClass<?>>> adapterImplementations
+            = new ConcurrentHashMap<String,ConcurrentNavigableMap<String,ModelClass<?>>>();
 
+    private final ConcurrentMap<String,ModelClass<?>> modelClasses
+            = new ConcurrentHashMap<String,ModelClass<?>>();
+    
     private volatile ImplementationPicker[] sortedImplementationPickers = new ImplementationPicker[0];
+    private volatile StaticInjectAnnotationProcessorFactory[] sortedStaticInjectAnnotationProcessorFactories = new StaticInjectAnnotationProcessorFactory[0];
 
     public void setImplementationPickers(Collection<ImplementationPicker> implementationPickers) {
         this.sortedImplementationPickers = implementationPickers.toArray(new ImplementationPicker[implementationPickers.size()]);
@@ -45,23 +53,38 @@ final class AdapterImplementations {
     public ImplementationPicker[] getImplementationPickers() {
         return this.sortedImplementationPickers;
     }
+    
+    public StaticInjectAnnotationProcessorFactory[] getStaticInjectAnnotationProcessorFactories() {
+        return sortedStaticInjectAnnotationProcessorFactories;
+    }
+
+    public void setStaticInjectAnnotationProcessorFactories(
+            Collection<StaticInjectAnnotationProcessorFactory> factories) {
+        this.sortedStaticInjectAnnotationProcessorFactories = factories.toArray(new StaticInjectAnnotationProcessorFactory[factories.size()]);
+    }
 
     /**
      * Add implementation mapping for the given adapter type.
      * @param adapterType Adapter type
      * @param implType Implementation type
      */
+    @SuppressWarnings("unchecked")
     public void add(Class<?> adapterType, Class<?> implType) {
-        // although we already use a ConcurrentMap synchronize explicitly because we apply non-atomic operations on it
-        synchronized (adapterImplementations) {
-            String key = adapterType.getName();
-            ConcurrentNavigableMap<String,Class<?>> implementations = adapterImplementations.get(key);
-            if (implementations == null) {
-                // to have a consistent ordering independent of bundle loading use a ConcurrentSkipListMap that sorts by class name
-                implementations = new ConcurrentSkipListMap<String,Class<?>>();
-                adapterImplementations.put(key, implementations);
+        String key = adapterType.getName();
+        if (adapterType == implType) {
+            modelClasses.put(key, new ModelClass(implType, sortedStaticInjectAnnotationProcessorFactories));
+        }
+        else {
+            // although we already use a ConcurrentMap synchronize explicitly because we apply non-atomic operations on it
+            synchronized (adapterImplementations) {
+                ConcurrentNavigableMap<String,ModelClass<?>> implementations = adapterImplementations.get(key);
+                if (implementations == null) {
+                    // to have a consistent ordering independent of bundle loading use a ConcurrentSkipListMap that sorts by class name
+                    implementations = new ConcurrentSkipListMap<String,ModelClass<?>>();
+                    adapterImplementations.put(key, implementations);
+                }
+                implementations.put(implType.getName(), new ModelClass(implType, sortedStaticInjectAnnotationProcessorFactories));
             }
-            implementations.put(implType.getName(), implType);
         }
     }
     
@@ -71,14 +94,19 @@ final class AdapterImplementations {
      * @param implTypeName Implementation type name
      */
     public void remove(String adapterTypeName, String implTypeName) {
-        // although we already use a ConcurrentMap synchronize explicitly because we apply non-atomic operations on it
-        synchronized (adapterImplementations) {
-            String key = adapterTypeName;
-            ConcurrentNavigableMap<String,Class<?>> implementations = adapterImplementations.get(key);
-            if (implementations != null) {
-                implementations.remove(implTypeName);
-                if (implementations.isEmpty()) {
-                    adapterImplementations.remove(key);
+        String key = adapterTypeName;
+        if (StringUtils.equals(adapterTypeName, implTypeName)) {
+            modelClasses.remove(key);
+        }
+        else {
+            // although we already use a ConcurrentMap synchronize explicitly because we apply non-atomic operations on it
+            synchronized (adapterImplementations) {
+                ConcurrentNavigableMap<String,ModelClass<?>> implementations = adapterImplementations.get(key);
+                if (implementations != null) {
+                    implementations.remove(implTypeName);
+                    if (implementations.isEmpty()) {
+                        adapterImplementations.remove(key);
+                    }
                 }
             }
         }
@@ -88,6 +116,7 @@ final class AdapterImplementations {
      * Remove all implementation mappings.
      */
     public void removeAll() {
+        modelClasses.clear();
         adapterImplementations.clear();
     }
 
@@ -97,20 +126,38 @@ final class AdapterImplementations {
      * @param adaptable Adaptable for reference
      * @return Implementation type or null if none detected
      */
-    public Class<?> lookup(Class<?> adapterType, Object adaptable) {
+    @SuppressWarnings("unchecked")
+    public <ModelType> ModelClass<ModelType> lookup(Class<ModelType> adapterType, Object adaptable) {
         String key = adapterType.getName();
+        
+        // lookup in cache for models without adapter classes
+        ModelClass<ModelType> modelClass = (ModelClass<ModelType>)modelClasses.get(key);
+        if (modelClass!=null) {
+            return modelClass;
+        }
 
-        ConcurrentNavigableMap<String,Class<?>> implementations = adapterImplementations.get(key);
+        // not found? look in cache with adapter classes
+        ConcurrentNavigableMap<String,ModelClass<?>> implementations = adapterImplementations.get(key);
         if (implementations==null || implementations.isEmpty()) {
             return null;
         }
-        Collection<Class<?>> implementationsCollection = implementations.values();
-        Class<?>[] implementationsArray = implementationsCollection.toArray(new Class<?>[implementationsCollection.size()]);
+        Collection<ModelClass<?>> implementationsCollection = implementations.values();
+        ModelClass<?>[] implementationWrappersArray = implementationsCollection.toArray(new ModelClass<?>[implementationsCollection.size()]);
+        
+        // prepare array for implementation picker
+        Class<?>[] implementationsArray = new Class<?>[implementationsCollection.size()];
+        for (int i=0; i<implementationWrappersArray.length; i++) {
+            implementationsArray[i] = implementationWrappersArray[i].getType();
+        }
 
         for (ImplementationPicker picker : this.sortedImplementationPickers) {
             Class<?> implementation = picker.pick(adapterType, implementationsArray, adaptable);
             if (implementation != null) {
-                return implementation;
+                for (int i=0; i<implementationWrappersArray.length; i++) {
+                    if (implementation==implementationWrappersArray[i].getType()) {
+                        return (ModelClass<ModelType>)implementationWrappersArray[i];
+                    }
+                }
             }
         }
 

Modified: sling/trunk/bundles/extensions/models/impl/src/main/java/org/apache/sling/models/impl/ModelAdapterFactory.java
URL: http://svn.apache.org/viewvc/sling/trunk/bundles/extensions/models/impl/src/main/java/org/apache/sling/models/impl/ModelAdapterFactory.java?rev=1639323&r1=1639322&r2=1639323&view=diff
==============================================================================
--- sling/trunk/bundles/extensions/models/impl/src/main/java/org/apache/sling/models/impl/ModelAdapterFactory.java (original)
+++ sling/trunk/bundles/extensions/models/impl/src/main/java/org/apache/sling/models/impl/ModelAdapterFactory.java Thu Nov 13 13:51:33 2014
@@ -16,11 +16,9 @@
  */
 package org.apache.sling.models.impl;
 
-import java.lang.annotation.Annotation;
 import java.lang.ref.PhantomReference;
 import java.lang.ref.ReferenceQueue;
 import java.lang.reflect.AnnotatedElement;
-import java.lang.reflect.Constructor;
 import java.lang.reflect.Field;
 import java.lang.reflect.InvocationHandler;
 import java.lang.reflect.InvocationTargetException;
@@ -45,12 +43,8 @@ import java.util.concurrent.ConcurrentHa
 import java.util.concurrent.ConcurrentMap;
 
 import javax.annotation.PostConstruct;
-import javax.inject.Inject;
-import javax.inject.Named;
 
 import org.apache.commons.beanutils.PropertyUtils;
-import org.apache.commons.lang.ArrayUtils;
-import org.apache.commons.lang.ClassUtils;
 import org.apache.felix.scr.annotations.Activate;
 import org.apache.felix.scr.annotations.Component;
 import org.apache.felix.scr.annotations.Deactivate;
@@ -63,26 +57,27 @@ import org.apache.sling.api.adapter.Adap
 import org.apache.sling.api.adapter.AdapterFactory;
 import org.apache.sling.commons.osgi.PropertiesUtil;
 import org.apache.sling.commons.osgi.ServiceUtil;
-import org.apache.sling.models.annotations.Default;
 import org.apache.sling.models.annotations.DefaultInjectionStrategy;
 import org.apache.sling.models.annotations.Model;
-import org.apache.sling.models.annotations.Optional;
-import org.apache.sling.models.annotations.Required;
-import org.apache.sling.models.annotations.Source;
-import org.apache.sling.models.annotations.Via;
 import org.apache.sling.models.factory.InvalidAdaptableException;
 import org.apache.sling.models.factory.InvalidModelException;
-import org.apache.sling.models.factory.ModelFactory;
 import org.apache.sling.models.factory.MissingElementsException;
+import org.apache.sling.models.factory.ModelFactory;
 import org.apache.sling.models.impl.Result.FailureType;
+import org.apache.sling.models.impl.model.ConstructorParameter;
+import org.apache.sling.models.impl.model.InjectableElement;
+import org.apache.sling.models.impl.model.InjectableField;
+import org.apache.sling.models.impl.model.InjectableMethod;
+import org.apache.sling.models.impl.model.ModelClass;
+import org.apache.sling.models.impl.model.ModelClassConstructor;
 import org.apache.sling.models.spi.AcceptsNullName;
 import org.apache.sling.models.spi.DisposalCallback;
 import org.apache.sling.models.spi.DisposalCallbackRegistry;
 import org.apache.sling.models.spi.ImplementationPicker;
 import org.apache.sling.models.spi.Injector;
-import org.apache.sling.models.spi.injectorspecific.InjectAnnotation;
 import org.apache.sling.models.spi.injectorspecific.InjectAnnotationProcessor;
 import org.apache.sling.models.spi.injectorspecific.InjectAnnotationProcessorFactory;
+import org.apache.sling.models.spi.injectorspecific.StaticInjectAnnotationProcessorFactory;
 import org.osgi.framework.BundleContext;
 import org.osgi.framework.Constants;
 import org.osgi.framework.ServiceRegistration;
@@ -149,6 +144,10 @@ public class ModelAdapterFactory impleme
 
     private volatile InjectAnnotationProcessorFactory[] sortedInjectAnnotationProcessorFactories = new InjectAnnotationProcessorFactory[0];
 
+    @Reference(name = "staticInjectAnnotationProcessorFactory", referenceInterface = StaticInjectAnnotationProcessorFactory.class,
+            cardinality = ReferenceCardinality.OPTIONAL_MULTIPLE, policy = ReferencePolicy.DYNAMIC)
+    private final Map<Object, StaticInjectAnnotationProcessorFactory> staticInjectAnnotationProcessorFactories = new TreeMap<Object, StaticInjectAnnotationProcessorFactory>();
+
     @Reference(name = "implementationPicker", referenceInterface = ImplementationPicker.class,
             cardinality = ReferenceCardinality.OPTIONAL_MULTIPLE, policy = ReferencePolicy.DYNAMIC)
     private final Map<Object, ImplementationPicker> implementationPickers = new TreeMap<Object, ImplementationPicker>();
@@ -183,14 +182,13 @@ public class ModelAdapterFactory impleme
         return innerCanCreateFromAdaptable(adaptable, modelClass);
     }
 
-    private boolean innerCanCreateFromAdaptable(Object adaptable, Class<?> modelClass) throws InvalidModelException {
-        modelClass = getImplementationTypeForAdapterType(modelClass, adaptable);
-        Model modelAnnotation = modelClass.getAnnotation(Model.class);
-        if (modelAnnotation == null) {
+    private boolean innerCanCreateFromAdaptable(Object adaptable, Class<?> requestedType) throws InvalidModelException {
+        ModelClass<?> modelClass = getImplementationTypeForAdapterType(requestedType, adaptable);
+        if (!modelClass.hasModelAnnotation()) {
             throw new InvalidModelException(String.format("Model class '%s' does not have a model annotation", modelClass));
         }
 
-        Class<?>[] declaredAdaptable = modelAnnotation.adaptables();
+        Class<?>[] declaredAdaptable = modelClass.getModelAnnotation().adaptables();
         for (Class<?> clazz : declaredAdaptable) {
             if (clazz.isInstance(adaptable)) {
                 return true;
@@ -200,9 +198,9 @@ public class ModelAdapterFactory impleme
     }
 
     @Override
-    public boolean isModelClass(Object adaptable, Class<?> type) {
-        type = getImplementationTypeForAdapterType(type, adaptable);
-        return type.getAnnotation(Model.class) != null;
+    public boolean isModelClass(Object adaptable, Class<?> requestedType) {
+        ModelClass<?> type = getImplementationTypeForAdapterType(requestedType, adaptable);
+        return type.hasModelAnnotation();
     }
 
     /**
@@ -214,38 +212,41 @@ public class ModelAdapterFactory impleme
      *      href="http://sling.apache.org/documentation/bundles/models.html#specifying-an-alternate-adapter-class-since-sling-models-110">Specifying
      *      an Alternate Adapter Class</a>
      */
-    private Class<?> getImplementationTypeForAdapterType(Class<?> type, Object adaptable) {
-        // check if a different implementation class was registered for this adapter type
-        Class<?> implementationType = this.adapterImplementations.lookup(type, adaptable);
-        if (implementationType != null) {
-            log.debug("Using implementation type {} for requested adapter type {}", implementationType, type);
-            return implementationType;
-        }
-        return type;
+    private <ModelType> ModelClass<ModelType> getImplementationTypeForAdapterType(Class<ModelType> requestedType, Object adaptable) {
+        // lookup ModelClass wrapper for implementation type
+        // additionally check if a different implementation class was registered for this adapter type
+        ModelClass<ModelType> modelClass = this.adapterImplementations.lookup(requestedType, adaptable);
+        if (modelClass != null) {
+            log.debug("Using implementation type {} for requested adapter type {}", modelClass, requestedType);
+            return modelClass;
+        }
+        // normally this code path is not executed, because all types are cached in adapterImplementations
+        // it is still useful for unit testing
+        return new ModelClass<ModelType>(requestedType, this.adapterImplementations.getStaticInjectAnnotationProcessorFactories());
     }
 
     @SuppressWarnings("unchecked")
-    private <ModelType> Result<ModelType> internalCreateModel(Object adaptable, Class<ModelType> type) {
+    private <ModelType> Result<ModelType> internalCreateModel(Object adaptable, Class<ModelType> requestedType) {
         Result<ModelType> result = new Result<ModelType>();
         ThreadInvocationCounter threadInvocationCounter = invocationCountThreadLocal.get();
         if (threadInvocationCounter.isMaximumReached()) {
             String msg = String.format("Adapting %s to %s failed, too much recursive invocations (>=%s).",
-                    new Object[] { adaptable, type, threadInvocationCounter.maxRecursionDepth });
+                    new Object[] { adaptable, requestedType, threadInvocationCounter.maxRecursionDepth });
             result.addFailure(FailureType.OTHER, msg);
             return result;
         };
         threadInvocationCounter.increase();
         try {
             // check if a different implementation class was registered for this adapter type
-            type = (Class<ModelType>) getImplementationTypeForAdapterType(type, adaptable);
+            ModelClass<ModelType> modelClass = getImplementationTypeForAdapterType(requestedType, adaptable);
 
-            Model modelAnnotation = type.getAnnotation(Model.class);
-            if (modelAnnotation == null) {
-                result.addFailure(FailureType.NO_MODEL_ANNOTATION, type);
+            if (!modelClass.hasModelAnnotation()) {
+                result.addFailure(FailureType.NO_MODEL_ANNOTATION, modelClass.getType());
                 return result;
             }
             boolean isAdaptable = false;
 
+            Model modelAnnotation = modelClass.getModelAnnotation();
             Class<?>[] declaredAdaptable = modelAnnotation.adaptables();
             for (Class<?> clazz : declaredAdaptable) {
                 if (clazz.isInstance(adaptable)) {
@@ -253,16 +254,16 @@ public class ModelAdapterFactory impleme
                 }
             }
             if (!isAdaptable) {
-                result.addFailure(FailureType.ADAPTABLE_DOES_NOT_MATCH, type);
-            } else if (type.isInterface()) {
-                InvocationHandler handler = createInvocationHandler(adaptable, type, modelAnnotation, result);
+                result.addFailure(FailureType.ADAPTABLE_DOES_NOT_MATCH, modelClass.getType());
+            } else if (modelClass.getType().isInterface()) {
+                InvocationHandler handler = createInvocationHandler(adaptable, modelClass, result);
                 if (handler != null) {
-                    ModelType model = (ModelType) Proxy.newProxyInstance(type.getClassLoader(), new Class<?>[] { type }, handler);
+                    ModelType model = (ModelType) Proxy.newProxyInstance(modelClass.getType().getClassLoader(), new Class<?>[] { modelClass.getType() }, handler);
                     result.setModel(model);
                 }
             } else {
                 try {
-                    ModelType model = createObject(adaptable, type, modelAnnotation, result);
+                    ModelType model = createObject(adaptable, modelClass, result);
                     result.setModel(model);
                     return result;
                 } catch (Exception e) {
@@ -275,40 +276,6 @@ public class ModelAdapterFactory impleme
         }
     }
 
-    private Set<Field> collectInjectableFields(Class<?> type) {
-        Set<Field> result = new HashSet<Field>();
-        while (type != null) {
-            Field[] fields = type.getDeclaredFields();
-            addAnnotated(fields, result);
-            type = type.getSuperclass();
-        }
-        return result;
-    }
-
-    private Set<Method> collectInjectableMethods(Class<?> type) {
-        Set<Method> result = new HashSet<Method>();
-        while (type != null) {
-            Method[] methods = type.getDeclaredMethods();
-            addAnnotated(methods, result);
-            type = type.getSuperclass();
-        }
-        return result;
-    }
-
-    private <T extends AnnotatedElement> void addAnnotated(T[] elements, Set<T> set) {
-        for (T element : elements) {
-            Inject injection = getAnnotation(element, Inject.class);
-            if (injection != null) {
-                set.add(element);
-            } else {
-                InjectAnnotation modelInject = getAnnotation(element, InjectAnnotation.class);
-                if (modelInject != null) {
-                    set.add(element);
-                }
-            }
-        }
-    }
-
     private static interface InjectCallback {
         /**
          * Is called each time when the given value should be injected into the given element
@@ -317,7 +284,7 @@ public class ModelAdapterFactory impleme
          * @param result
          * @return true if injection was successful otherwise false
          */
-        public boolean inject(AnnotatedElement element, Object value, Result<?> result);
+        public boolean inject(InjectableElement element, Object value, Result<?> result);
     }
 
     private class SetFieldCallback implements InjectCallback {
@@ -329,8 +296,8 @@ public class ModelAdapterFactory impleme
         }
 
         @Override
-        public boolean inject(AnnotatedElement element, Object value, Result<?> result) {
-            return setField((Field) element, object, value, result);
+        public boolean inject(InjectableElement element, Object value, Result<?> result) {
+            return setField((InjectableField) element, object, value, result);
         }
     }
 
@@ -343,8 +310,8 @@ public class ModelAdapterFactory impleme
         }
 
         @Override
-        public boolean inject(AnnotatedElement element, Object value, Result<?> result) {
-            return setMethod((Method) element, methods, value, result);
+        public boolean inject(InjectableElement element, Object value, Result<?> result) {
+            return setMethod((InjectableMethod) element, methods, value, result);
         }
     }
 
@@ -357,22 +324,22 @@ public class ModelAdapterFactory impleme
         }
 
         @Override
-        public boolean inject(AnnotatedElement element, Object value, Result<?> result) {
+        public boolean inject(InjectableElement element, Object value, Result<?> result) {
             return setConstructorParameter((ConstructorParameter)element, parameterValues, value, result);
         }
     }
 
-    private boolean injectElement(final AnnotatedElement element, final Object adaptable, final Type type,
-            final boolean injectPrimitiveInitialValue, final Model modelAnnotation, final DisposalCallbackRegistry registry,
+    private boolean injectElement(final InjectableElement element, final Object adaptable, 
+            final Model modelAnnotation, final DisposalCallbackRegistry registry,
             final InjectCallback callback, Result<?> result) {
 
         InjectAnnotationProcessor annotationProcessor = null;
-        String source = getSource(element);
+        String source = element.getSource();
         boolean wasInjectionSuccessful = false;
 
         // find an appropriate annotation processor
         for (InjectAnnotationProcessorFactory factory : sortedInjectAnnotationProcessorFactories) {
-            annotationProcessor = factory.createAnnotationProcessor(adaptable, element);
+            annotationProcessor = factory.createAnnotationProcessor(adaptable, element.getAnnotatedElement());
             if (annotationProcessor != null) {
                 break;
             }
@@ -386,7 +353,7 @@ public class ModelAdapterFactory impleme
             for (Injector injector : sortedInjectors) {
                 if (source == null || source.equals(injector.getName())) {
                     if (name != null || injector instanceof AcceptsNullName) {
-                        Object value = injector.getValue(injectionAdaptable, name, type, element, registry);
+                        Object value = injector.getValue(injectionAdaptable, name, element.getType(), element.getAnnotatedElement(), registry);
                         if (callback.inject(element, value, result)) {
                             wasInjectionSuccessful = true;
                             break;
@@ -397,14 +364,14 @@ public class ModelAdapterFactory impleme
         }
         // if injection failed, use default
         if (!wasInjectionSuccessful) {
-            wasInjectionSuccessful = injectDefaultValue(element, type, annotationProcessor, callback, result);
+            wasInjectionSuccessful = injectDefaultValue(element, annotationProcessor, callback, result);
         }
 
         // if default is not set, check if mandatory
         if (!wasInjectionSuccessful) {
             if (isOptional(element, modelAnnotation, annotationProcessor)) {
-                if (injectPrimitiveInitialValue) {
-                    injectPrimitiveInitialValue(element, type, callback, result);
+                if (element.isPrimitive()) {
+                    injectPrimitiveInitialValue(element, callback, result);
                 }
             } else {
                 return false;
@@ -414,8 +381,8 @@ public class ModelAdapterFactory impleme
         return true;
     }
 
-    private <ModelType> InvocationHandler createInvocationHandler(final Object adaptable, final Class<ModelType> type, final Model modelAnnotation, final Result<ModelType> result) {
-        Set<Method> injectableMethods = collectInjectableMethods(type);
+    private <ModelType> InvocationHandler createInvocationHandler(final Object adaptable, final ModelClass<ModelType> modelClass, final Result<ModelType> result) {
+        InjectableMethod[] injectableMethods = modelClass.getInjectableMethods();
         final Map<Method, Object> methods = new HashMap<Method, Object>();
         SetMethodsCallback callback = new SetMethodsCallback(methods);
         MapBackedInvocationHandler handler = new MapBackedInvocationHandler(methods);
@@ -424,20 +391,14 @@ public class ModelAdapterFactory impleme
         registerCallbackRegistry(handler, registry);
         Set<Method> requiredMethods = new HashSet<Method>();
 
-        for (Method method : injectableMethods) {
-            Type genericReturnType = method.getGenericReturnType();
-            Type returnType = mapPrimitiveClasses(genericReturnType);
-            boolean isPrimitive = false;
-            if (returnType != genericReturnType) {
-                isPrimitive = true;
-            }
-            if (!injectElement(method, adaptable, returnType, isPrimitive, modelAnnotation, registry, callback, result)) {
-                requiredMethods.add(method);
+        for (InjectableMethod method : injectableMethods) {
+            if (!injectElement(method, adaptable, modelClass.getModelAnnotation(), registry, callback, result)) {
+                requiredMethods.add(method.getMethod());
             }
         }
         registry.seal();
         if (!requiredMethods.isEmpty()) {
-            result.addFailure(FailureType.MISSING_METHODS, requiredMethods, type);
+            result.addFailure(FailureType.MISSING_METHODS, requiredMethods, modelClass.getType());
             return null;
         }
         return handler;
@@ -448,57 +409,25 @@ public class ModelAdapterFactory impleme
         disposalCallbacks.put(reference, registry);
     }
 
-    private String getSource(AnnotatedElement element) {
-        Source source = getAnnotation(element, Source.class);
-        if (source != null) {
-            return source.value();
-        } else {
-            return null;
-        }
-    }
-
-    /**
-     * Get an annotation from either the element itself or on any of the
-     * element's annotations (meta-annotations).
-     * 
-     * @param element the element
-     * @param annotationClass the annotation class
-     * @return the found annotation or null
-     */
-    private <T extends Annotation> T getAnnotation(AnnotatedElement element, Class<T> annotationClass) {
-        T annotation = element.getAnnotation(annotationClass);
-        if (annotation != null) {
-            return annotation;
-        } else {
-            for (Annotation ann : element.getAnnotations()) {
-                annotation = ann.annotationType().getAnnotation(annotationClass);
-                if (annotation != null) {
-                    return annotation;
-                }
-            }
-        }
-        return null;
-    }
-
-    private <ModelType> ModelType createObject(final Object adaptable, final Class<ModelType> type, final Model modelAnnotation, final Result<ModelType> result)
+    private <ModelType> ModelType createObject(final Object adaptable, final ModelClass<ModelType> modelClass, final Result<ModelType> result)
             throws InstantiationException, InvocationTargetException, IllegalAccessException {
         DisposalCallbackRegistryImpl registry = new DisposalCallbackRegistryImpl();
 
-        Constructor<ModelType> constructorToUse = getBestMatchingConstructor(adaptable, type);
+        ModelClassConstructor<ModelType> constructorToUse = getBestMatchingConstructor(adaptable, modelClass);
         if (constructorToUse == null) {
-            result.addFailure(FailureType.NO_USABLE_CONSTRUCTOR, type);
+            result.addFailure(FailureType.NO_USABLE_CONSTRUCTOR, modelClass.getType());
             return null;
         }
 
         final ModelType object;
-        if (constructorToUse.getParameterTypes().length == 0) {
+        if (constructorToUse.getConstructor().getParameterTypes().length == 0) {
             // no parameters for constructor injection? instantiate it right away
-            object = constructorToUse.newInstance();
+            object = constructorToUse.getConstructor().newInstance();
         } else {
             // instantiate with constructor injection
             // if this fails, make sure resources that may be claimed by injectors are cleared up again
             try {
-                object = newInstanceWithConstructorInjection(constructorToUse, adaptable, type, modelAnnotation, registry, result);
+                object = newInstanceWithConstructorInjection(constructorToUse, adaptable, modelClass, registry, result);
                 if (object == null) {
                     registry.onDisposed();
                     return null;
@@ -521,17 +450,16 @@ public class ModelAdapterFactory impleme
 
         Set<Field> requiredFields = new HashSet<Field>();
 
-        Set<Field> injectableFields = collectInjectableFields(type);
-        for (Field field : injectableFields) {
-            Type fieldType = mapPrimitiveClasses(field.getGenericType());
-            if (!injectElement(field, adaptable, fieldType, false, modelAnnotation, registry, callback, result)) {
-                requiredFields.add(field);
+        InjectableField[] injectableFields = modelClass.getInjectableFields();
+        for (InjectableField field : injectableFields) {
+            if (!injectElement(field, adaptable, modelClass.getModelAnnotation(), registry, callback, result)) {
+                requiredFields.add(field.getField());
             }
         }
 
         registry.seal();
         if (!requiredFields.isEmpty()) {
-            result.addFailure(FailureType.MISSING_FIELDS, requiredFields, type);
+            result.addFailure(FailureType.MISSING_FIELDS, requiredFields, modelClass.getType());
             return null;
         }
         try {
@@ -554,64 +482,53 @@ public class ModelAdapterFactory impleme
      * @return Constructor or null if none found
      */
     @SuppressWarnings("unchecked")
-    private <ModelType> Constructor<ModelType> getBestMatchingConstructor(Object adaptable, Class<ModelType> type) {
-        Constructor<?>[] constructors = type.getConstructors();
+    private <ModelType> ModelClassConstructor<ModelType> getBestMatchingConstructor(Object adaptable, ModelClass<ModelType> type) {
+        ModelClassConstructor[] constructors = type.getConstructors();
 
-        // sort the constructor list in order from most params to least params, and constructors with @Inject annotation first
-        Arrays.sort(constructors, new ParameterCountInjectComparator());
-
-        for (Constructor<?> constructor : constructors) {
+        for (ModelClassConstructor constructor : constructors) {
             // first try to find the constructor with most parameters and @Inject annotation
-            if (constructor.isAnnotationPresent(Inject.class)) {
-                return (Constructor<ModelType>) constructor;
+            if (constructor.hasInjectAnnotation()) {
+                return constructor;
             }
             // compatibility mode for sling models implementation <= 1.0.6:
             // support constructor without @Inject if it has exactly one parameter matching the adaptable class
-            final Class<?>[] paramTypes = constructor.getParameterTypes();
+            final Class<?>[] paramTypes = constructor.getConstructor().getParameterTypes();
             if (paramTypes.length == 1) {
-                Class<?> paramType = constructor.getParameterTypes()[0];
+                Class<?> paramType = constructor.getConstructor().getParameterTypes()[0];
                 if (paramType.isInstance(adaptable)) {
-                    return (Constructor<ModelType>) constructor;
+                    return constructor;
                 }
             }
             // if no constructor for injection found use public constructor without any params
-            if (constructor.getParameterTypes().length == 0) {
-                return (Constructor<ModelType>) constructor;
+            if (constructor.getConstructor().getParameterTypes().length == 0) {
+                return constructor;
             }
         }
         return null;
     }
 
-    private <ModelType> ModelType newInstanceWithConstructorInjection(final Constructor<ModelType> constructor, final Object adaptable,
-            final Class<ModelType> type, final Model modelAnnotation, final DisposalCallbackRegistry registry,
-            final Result<ModelType> result)
+    private <ModelType> ModelType newInstanceWithConstructorInjection(final ModelClassConstructor<ModelType> constructor, final Object adaptable,
+            final ModelClass<ModelType> modelClass, final DisposalCallbackRegistry registry, final Result<ModelType> result)
             throws InstantiationException, InvocationTargetException, IllegalAccessException {
-        Set<ConstructorParameter> requiredParameters = new HashSet<ConstructorParameter>();
-        Type[] parameterTypes = constructor.getGenericParameterTypes();
-        List<Object> paramValues = new ArrayList<Object>(Arrays.asList(new Object[parameterTypes.length]));
-        InjectCallback callback = new SetConstructorParameterCallback(paramValues);
+        ConstructorParameter[] parameters = constructor.getConstructorParameters();
 
-        for (int i = 0; i < parameterTypes.length; i++) {
-            Type genericType = mapPrimitiveClasses(parameterTypes[i]);
+        Set<AnnotatedElement> requiredParameters = new HashSet<AnnotatedElement>();
+        List<Object> paramValues = new ArrayList<Object>(Arrays.asList(new Object[parameters.length]));
+        InjectCallback callback = new SetConstructorParameterCallback(paramValues);
 
-            boolean isPrimitive = false;
-            if (parameterTypes[i] != genericType) {
-                isPrimitive = true;
-            }
-            ConstructorParameter constructorParameter = new ConstructorParameter(
-                    constructor.getParameterAnnotations()[i], constructor.getParameterTypes()[i], genericType, i);
-            if (!injectElement(constructorParameter, adaptable, genericType, isPrimitive, modelAnnotation, registry, callback, result)) {
-                requiredParameters.add(constructorParameter);
+        for (int i = 0; i < parameters.length; i++) {
+            if (!injectElement(parameters[i], adaptable, modelClass.getModelAnnotation(), registry, callback, result)) {
+                requiredParameters.add(parameters[i].getAnnotatedElement());
             }
         }
         if (!requiredParameters.isEmpty()) {
-            result.addFailure(FailureType.MISSING_CONSTRUCTOR_PARAMS, requiredParameters, type);
+            result.addFailure(FailureType.MISSING_CONSTRUCTOR_PARAMS, requiredParameters, modelClass.getType());
             return null;
         }
-        return constructor.newInstance(paramValues.toArray(new Object[paramValues.size()]));
+        return constructor.getConstructor().newInstance(paramValues.toArray(new Object[paramValues.size()]));
     }
 
-    private boolean isOptional(AnnotatedElement point, Model modelAnnotation, InjectAnnotationProcessor annotationProcessor) {
+    private boolean isOptional(InjectableElement point, Model modelAnnotation, InjectAnnotationProcessor annotationProcessor) {
         if (annotationProcessor != null) {
             Boolean isOptional = annotationProcessor.isOptional();
             if (isOptional != null) {
@@ -619,14 +536,14 @@ public class ModelAdapterFactory impleme
             }
         }
         if (modelAnnotation.defaultInjectionStrategy() == DefaultInjectionStrategy.REQUIRED) {
-            return (point.getAnnotation(Optional.class) != null);
+            return (point.isOptional());
         } else {
-            return (point.getAnnotation(Required.class) == null);
+            return (!point.isRequired());
         }
         
     }
 
-    private boolean injectDefaultValue(AnnotatedElement point, Type type, InjectAnnotationProcessor processor,
+    private boolean injectDefaultValue(InjectableElement point, InjectAnnotationProcessor processor,
             InjectCallback callback, Result<?> result) {
 
         if (processor != null) {
@@ -634,73 +551,14 @@ public class ModelAdapterFactory impleme
                 return callback.inject(point, processor.getDefault(), result);
             }
         }
-        Default defaultAnnotation = point.getAnnotation(Default.class);
-        if (defaultAnnotation == null) {
-            return false;
-        }
 
-        type = mapPrimitiveClasses(type);
-        Object value = null;
-
-        if (type instanceof Class) {
-            Class<?> injectedClass = (Class<?>) type;
-            if (injectedClass.isArray()) {
-                Class<?> componentType = injectedClass.getComponentType();
-                if (componentType == String.class) {
-                    value = defaultAnnotation.values();
-                } else if (componentType == Integer.TYPE) {
-                    value = defaultAnnotation.intValues();
-                } else if (componentType == Integer.class) {
-                    value = ArrayUtils.toObject(defaultAnnotation.intValues());
-                } else if (componentType == Long.TYPE) {
-                    value = defaultAnnotation.longValues();
-                } else if (componentType == Long.class) {
-                    value = ArrayUtils.toObject(defaultAnnotation.longValues());
-                } else if (componentType == Boolean.TYPE) {
-                    value = defaultAnnotation.booleanValues();
-                } else if (componentType == Boolean.class) {
-                    value = ArrayUtils.toObject(defaultAnnotation.booleanValues());
-                } else if (componentType == Short.TYPE) {
-                    value = defaultAnnotation.shortValues();
-                } else if (componentType == Short.class) {
-                    value = ArrayUtils.toObject(defaultAnnotation.shortValues());
-                } else if (componentType == Float.TYPE) {
-                    value = defaultAnnotation.floatValues();
-                } else if (componentType == Float.class) {
-                    value = ArrayUtils.toObject(defaultAnnotation.floatValues());
-                } else if (componentType == Double.TYPE) {
-                    value = defaultAnnotation.doubleValues();
-                } else if (componentType == Double.class) {
-                    value = ArrayUtils.toObject(defaultAnnotation.doubleValues());
-                } else {
-                    log.warn("Default values for {} are not supported", componentType);
-                    return false;
-                }
-            } else {
-                if (injectedClass == String.class) {
-                    value = defaultAnnotation.values().length == 0 ? "" : defaultAnnotation.values()[0];
-                } else if (injectedClass == Integer.class) {
-                    value = defaultAnnotation.intValues().length == 0 ? 0 : defaultAnnotation.intValues()[0];
-                } else if (injectedClass == Long.class) {
-                    value = defaultAnnotation.longValues().length == 0 ? 0l : defaultAnnotation.longValues()[0];
-                } else if (injectedClass == Boolean.class) {
-                    value = defaultAnnotation.booleanValues().length == 0 ? false : defaultAnnotation.booleanValues()[0];
-                } else if (injectedClass == Short.class) {
-                    value = defaultAnnotation.shortValues().length == 0 ? ((short) 0) : defaultAnnotation.shortValues()[0];
-                } else if (injectedClass == Float.class) {
-                    value = defaultAnnotation.floatValues().length == 0 ? 0f : defaultAnnotation.floatValues()[0];
-                } else if (injectedClass == Double.class) {
-                    value = defaultAnnotation.doubleValues().length == 0 ? 0d : defaultAnnotation.doubleValues()[0];
-                } else {
-                    log.warn("Default values for {} are not supported", injectedClass);
-                    return false;
-                }
-            }
-        } else {
-            log.warn("Cannot provide default for {}", type);
+        Object value = point.getDefaultValue();
+        if (value != null) {
+            return callback.inject(point, value, result);
+        }
+        else {
             return false;
         }
-        return callback.inject(point, value, result);
     }
 
     /**
@@ -712,8 +570,8 @@ public class ModelAdapterFactory impleme
      * @param callback Inject callback
      * @param result
      */
-    private void injectPrimitiveInitialValue(AnnotatedElement point, Type wrapperType, InjectCallback callback, Result<?> result) {
-        Type primitiveType = mapWrapperClasses(wrapperType);
+    private void injectPrimitiveInitialValue(InjectableElement point, InjectCallback callback, Result<?> result) {
+        Type primitiveType = ReflectionUtil.mapWrapperClasses(point.getType());
         Object value = null;
         if (primitiveType == int.class) {
             value = Integer.valueOf(0);
@@ -737,17 +595,16 @@ public class ModelAdapterFactory impleme
         };
     }
     
-    private Object getAdaptable(Object adaptable, AnnotatedElement point, InjectAnnotationProcessor processor) {
+    private Object getAdaptable(Object adaptable, InjectableElement point, InjectAnnotationProcessor processor) {
         String viaPropertyName = null;
         if (processor != null) {
             viaPropertyName = processor.getVia();
         }
         if (viaPropertyName == null) {
-            Via viaAnnotation = point.getAnnotation(Via.class);
-            if (viaAnnotation == null) {
-                return adaptable;
-            }
-            viaPropertyName = viaAnnotation.value();
+            viaPropertyName = point.getVia();
+        }
+        if (viaPropertyName == null) {
+            return adaptable;
         }
         try {
             return PropertyUtils.getProperty(adaptable, viaPropertyName);
@@ -757,7 +614,7 @@ public class ModelAdapterFactory impleme
         }
     }
 
-    private String getName(AnnotatedElement element, InjectAnnotationProcessor processor) {
+    private String getName(InjectableElement element, InjectAnnotationProcessor processor) {
         // try to get the name from injector-specific annotation
         if (processor != null) {
             String name = processor.getName();
@@ -765,38 +622,10 @@ public class ModelAdapterFactory impleme
                 return name;
             }
         }
-        // alternative for name attribute
-        Named named = element.getAnnotation(Named.class);
-        if (named != null) {
-            return named.value();
-        }
-        if (element instanceof Method) {
-            return getNameFromMethod((Method) element);
-        } else if (element instanceof Field) {
-            return getNameFromField((Field) element);
-        } else if (element instanceof ConstructorParameter) {
-            // implicit name not supported for constructor parameters - but do not throw exception because class-based injection is still possible
-            return null;
-        } else {
-            throw new IllegalArgumentException("The given element must be either method or field but is " + element);
-        }
-    }
-
-    private String getNameFromField(Field field) {
-        return field.getName();
+        // get name from @Named annotation or element name
+        return element.getName();
     }
 
-    private String getNameFromMethod(Method method) {
-        String methodName = method.getName();
-        if (methodName.startsWith("get")) {
-            return methodName.substring(3, 4).toLowerCase() + methodName.substring(4);
-        } else if (methodName.startsWith("is")) {
-            return methodName.substring(2, 3).toLowerCase() + methodName.substring(3);
-        } else {
-            return methodName;
-        }
-    }
-    
     private boolean addMethodIfNotOverriden(List<Method> methods, Method newMethod) {
         for (Method method : methods) {
             if (method.getName().equals(newMethod.getName())) {
@@ -837,24 +666,9 @@ public class ModelAdapterFactory impleme
         }
     }
 
-    private static Type mapPrimitiveClasses(Type type) {
-        if (type instanceof Class<?>) {
-            return ClassUtils.primitiveToWrapper((Class<?>) type);
-        } else {
-            return type;
-        }
-    }
-
-    private static Type mapWrapperClasses(Type type) {
-        if (type instanceof Class<?>) {
-            return ClassUtils.wrapperToPrimitive((Class<?>) type);
-        } else {
-            return type;
-        }
-    }
-
-    private boolean setField(Field field, Object createdObject, Object value, Result<?> result) {
+    private boolean setField(InjectableField injectableField, Object createdObject, Object value, Result<?> result) {
         if (value != null) {
+            Field field = injectableField.getField();
             value = adaptIfNecessary(value, field.getType(), field.getGenericType(), result);
             // value may now be null due to the adaptation done above
             if (value == null) {
@@ -880,8 +694,9 @@ public class ModelAdapterFactory impleme
         }
     }
 
-    private boolean setMethod(Method method, Map<Method, Object> methods, Object value, Result<?> result) {
+    private boolean setMethod(InjectableMethod injectableMethod, Map<Method, Object> methods, Object value, Result<?> result) {
         if (value != null) {
+            Method method = injectableMethod.getMethod();
             value = adaptIfNecessary(value, method.getReturnType(), method.getGenericReturnType(), result);
             // value may now be null due to the adaptation done above
             if (value == null) {
@@ -895,8 +710,8 @@ public class ModelAdapterFactory impleme
     }
 
     private boolean setConstructorParameter(ConstructorParameter constructorParameter, List<Object> parameterValues, Object value, Result<?> result) {
-        if (value != null && constructorParameter.getType() instanceof Class<?>) {
-            value = adaptIfNecessary(value, (Class<?>) constructorParameter.getType(), constructorParameter.getGenericType(), result);
+        if (value != null && constructorParameter.getParameterType() instanceof Class<?>) {
+            value = adaptIfNecessary(value, (Class<?>) constructorParameter.getParameterType(), constructorParameter.getGenericType(), result);
             // value may now be null due to the adaptation done above
             if (value == null) {
                 return false;
@@ -1053,20 +868,34 @@ public class ModelAdapterFactory impleme
         }
     }
 
-    protected void bindInjectAnnotationProcessorFactory(final InjectAnnotationProcessorFactory injector, final Map<String, Object> props) {
+    protected void bindInjectAnnotationProcessorFactory(final InjectAnnotationProcessorFactory factory, final Map<String, Object> props) {
         synchronized (injectAnnotationProcessorFactories) {
-            injectAnnotationProcessorFactories.put(ServiceUtil.getComparableForServiceRanking(props), injector);
+            injectAnnotationProcessorFactories.put(ServiceUtil.getComparableForServiceRanking(props), factory);
             sortedInjectAnnotationProcessorFactories = injectAnnotationProcessorFactories.values().toArray(new InjectAnnotationProcessorFactory[injectAnnotationProcessorFactories.size()]);
         }
     }
 
-    protected void unbindInjectAnnotationProcessorFactory(final InjectAnnotationProcessorFactory injector, final Map<String, Object> props) {
+    protected void unbindInjectAnnotationProcessorFactory(final InjectAnnotationProcessorFactory factory, final Map<String, Object> props) {
         synchronized (injectAnnotationProcessorFactories) {
             injectAnnotationProcessorFactories.remove(ServiceUtil.getComparableForServiceRanking(props));
             sortedInjectAnnotationProcessorFactories = injectAnnotationProcessorFactories.values().toArray(new InjectAnnotationProcessorFactory[injectAnnotationProcessorFactories.size()]);
         }
     }
 
+    protected void bindStaticInjectAnnotationProcessorFactory(final StaticInjectAnnotationProcessorFactory factory, final Map<String, Object> props) {
+        synchronized (staticInjectAnnotationProcessorFactories) {
+            staticInjectAnnotationProcessorFactories.put(ServiceUtil.getComparableForServiceRanking(props), factory);
+            this.adapterImplementations.setStaticInjectAnnotationProcessorFactories(staticInjectAnnotationProcessorFactories.values());
+        }
+    }
+
+    protected void unbindStaticInjectAnnotationProcessorFactory(final StaticInjectAnnotationProcessorFactory factory, final Map<String, Object> props) {
+        synchronized (staticInjectAnnotationProcessorFactories) {
+            staticInjectAnnotationProcessorFactories.remove(ServiceUtil.getComparableForServiceRanking(props));
+            this.adapterImplementations.setStaticInjectAnnotationProcessorFactories(staticInjectAnnotationProcessorFactories.values());
+        }
+    }
+
     protected void bindImplementationPicker(final ImplementationPicker implementationPicker, final Map<String, Object> props) {
         synchronized (implementationPickers) {
             implementationPickers.put(ServiceUtil.getComparableForServiceRanking(props), implementationPicker);

Modified: sling/trunk/bundles/extensions/models/impl/src/main/java/org/apache/sling/models/impl/ModelPackageBundleListener.java
URL: http://svn.apache.org/viewvc/sling/trunk/bundles/extensions/models/impl/src/main/java/org/apache/sling/models/impl/ModelPackageBundleListener.java?rev=1639323&r1=1639322&r2=1639323&view=diff
==============================================================================
--- sling/trunk/bundles/extensions/models/impl/src/main/java/org/apache/sling/models/impl/ModelPackageBundleListener.java (original)
+++ sling/trunk/bundles/extensions/models/impl/src/main/java/org/apache/sling/models/impl/ModelPackageBundleListener.java Thu Nov 13 13:51:33 2014
@@ -107,9 +107,7 @@ public class ModelPackageBundleListener 
                             // register adapter only if given adapters are valid
                             if (validateAdapterClasses(implType, adapterTypes)) {
                                 for (Class<?> adapterType : adapterTypes) {
-                                    if (adapterType != implType) {
-                                        adapterImplementations.add(adapterType, implType);
-                                    }
+                                    adapterImplementations.add(adapterType, implType);
                                 }
                                 ServiceRegistration reg = registerAdapterFactory(adapterTypes, annotation.adaptables(), implType, annotation.condition());
                                 regs.add(reg);

Modified: sling/trunk/bundles/extensions/models/impl/src/main/java/org/apache/sling/models/impl/Result.java
URL: http://svn.apache.org/viewvc/sling/trunk/bundles/extensions/models/impl/src/main/java/org/apache/sling/models/impl/Result.java?rev=1639323&r1=1639322&r2=1639323&view=diff
==============================================================================
--- sling/trunk/bundles/extensions/models/impl/src/main/java/org/apache/sling/models/impl/Result.java (original)
+++ sling/trunk/bundles/extensions/models/impl/src/main/java/org/apache/sling/models/impl/Result.java Thu Nov 13 13:51:33 2014
@@ -171,11 +171,7 @@ public class Result<ModelType> {
     public void setModel(ModelType model) {
         this.model = model;
     }
-/*
-    public void setType(Class<? extends ModelType> type) {
-        this.type = type;
-    }
-*/
+
     public void throwException(Logger log) {
         for (int i = 0; i < failures.size() - 1; i++) {
             failures.get(i).log(log);

Modified: sling/trunk/bundles/extensions/models/impl/src/main/java/org/apache/sling/models/impl/injectors/BindingsInjector.java
URL: http://svn.apache.org/viewvc/sling/trunk/bundles/extensions/models/impl/src/main/java/org/apache/sling/models/impl/injectors/BindingsInjector.java?rev=1639323&r1=1639322&r2=1639323&view=diff
==============================================================================
--- sling/trunk/bundles/extensions/models/impl/src/main/java/org/apache/sling/models/impl/injectors/BindingsInjector.java (original)
+++ sling/trunk/bundles/extensions/models/impl/src/main/java/org/apache/sling/models/impl/injectors/BindingsInjector.java Thu Nov 13 13:51:33 2014
@@ -30,7 +30,7 @@ import org.apache.sling.models.spi.Dispo
 import org.apache.sling.models.spi.Injector;
 import org.apache.sling.models.spi.injectorspecific.AbstractInjectAnnotationProcessor;
 import org.apache.sling.models.spi.injectorspecific.InjectAnnotationProcessor;
-import org.apache.sling.models.spi.injectorspecific.InjectAnnotationProcessorFactory;
+import org.apache.sling.models.spi.injectorspecific.StaticInjectAnnotationProcessorFactory;
 import org.osgi.framework.Constants;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
@@ -38,7 +38,7 @@ import org.slf4j.LoggerFactory;
 @Component
 @Service
 @Property(name = Constants.SERVICE_RANKING, intValue = 1000)
-public class BindingsInjector implements Injector, InjectAnnotationProcessorFactory {
+public class BindingsInjector implements Injector, StaticInjectAnnotationProcessorFactory {
 
     private static final Logger log = LoggerFactory.getLogger(BindingsInjector.class);
 
@@ -76,7 +76,7 @@ public class BindingsInjector implements
     }
 
     @Override
-    public InjectAnnotationProcessor createAnnotationProcessor(Object adaptable, AnnotatedElement element) {
+    public InjectAnnotationProcessor createAnnotationProcessor(AnnotatedElement element) {
         // check if the element has the expected annotation
         ScriptVariable annotation = element.getAnnotation(ScriptVariable.class);
         if (annotation != null) {

Modified: sling/trunk/bundles/extensions/models/impl/src/main/java/org/apache/sling/models/impl/injectors/OSGiServiceInjector.java
URL: http://svn.apache.org/viewvc/sling/trunk/bundles/extensions/models/impl/src/main/java/org/apache/sling/models/impl/injectors/OSGiServiceInjector.java?rev=1639323&r1=1639322&r2=1639323&view=diff
==============================================================================
--- sling/trunk/bundles/extensions/models/impl/src/main/java/org/apache/sling/models/impl/injectors/OSGiServiceInjector.java (original)
+++ sling/trunk/bundles/extensions/models/impl/src/main/java/org/apache/sling/models/impl/injectors/OSGiServiceInjector.java Thu Nov 13 13:51:33 2014
@@ -36,13 +36,13 @@ import org.apache.sling.api.scripting.Sl
 import org.apache.sling.api.scripting.SlingScriptHelper;
 import org.apache.sling.models.annotations.Filter;
 import org.apache.sling.models.annotations.injectorspecific.OSGiService;
+import org.apache.sling.models.spi.AcceptsNullName;
 import org.apache.sling.models.spi.DisposalCallback;
 import org.apache.sling.models.spi.DisposalCallbackRegistry;
-import org.apache.sling.models.spi.AcceptsNullName;
 import org.apache.sling.models.spi.Injector;
 import org.apache.sling.models.spi.injectorspecific.AbstractInjectAnnotationProcessor;
 import org.apache.sling.models.spi.injectorspecific.InjectAnnotationProcessor;
-import org.apache.sling.models.spi.injectorspecific.InjectAnnotationProcessorFactory;
+import org.apache.sling.models.spi.injectorspecific.StaticInjectAnnotationProcessorFactory;
 import org.osgi.framework.BundleContext;
 import org.osgi.framework.Constants;
 import org.osgi.framework.InvalidSyntaxException;
@@ -54,7 +54,7 @@ import org.slf4j.LoggerFactory;
 @Component
 @Service
 @Property(name = Constants.SERVICE_RANKING, intValue = 5000)
-public class OSGiServiceInjector implements Injector, InjectAnnotationProcessorFactory, AcceptsNullName {
+public class OSGiServiceInjector implements Injector, StaticInjectAnnotationProcessorFactory, AcceptsNullName {
 
     private static final Logger log = LoggerFactory.getLogger(OSGiServiceInjector.class);
 
@@ -217,7 +217,7 @@ public class OSGiServiceInjector impleme
     }
 
     @Override
-    public InjectAnnotationProcessor createAnnotationProcessor(Object adaptable, AnnotatedElement element) {
+    public InjectAnnotationProcessor createAnnotationProcessor(AnnotatedElement element) {
         // check if the element has the expected annotation
         OSGiService annotation = element.getAnnotation(OSGiService.class);
         if (annotation != null) {

Modified: sling/trunk/bundles/extensions/models/impl/src/main/java/org/apache/sling/models/impl/injectors/RequestAttributeInjector.java
URL: http://svn.apache.org/viewvc/sling/trunk/bundles/extensions/models/impl/src/main/java/org/apache/sling/models/impl/injectors/RequestAttributeInjector.java?rev=1639323&r1=1639322&r2=1639323&view=diff
==============================================================================
--- sling/trunk/bundles/extensions/models/impl/src/main/java/org/apache/sling/models/impl/injectors/RequestAttributeInjector.java (original)
+++ sling/trunk/bundles/extensions/models/impl/src/main/java/org/apache/sling/models/impl/injectors/RequestAttributeInjector.java Thu Nov 13 13:51:33 2014
@@ -29,13 +29,13 @@ import org.apache.sling.models.spi.Dispo
 import org.apache.sling.models.spi.Injector;
 import org.apache.sling.models.spi.injectorspecific.AbstractInjectAnnotationProcessor;
 import org.apache.sling.models.spi.injectorspecific.InjectAnnotationProcessor;
-import org.apache.sling.models.spi.injectorspecific.InjectAnnotationProcessorFactory;
+import org.apache.sling.models.spi.injectorspecific.StaticInjectAnnotationProcessorFactory;
 import org.osgi.framework.Constants;
 
 @Component
 @Service
 @Property(name = Constants.SERVICE_RANKING, intValue = 4000)
-public class RequestAttributeInjector implements Injector, InjectAnnotationProcessorFactory {
+public class RequestAttributeInjector implements Injector, StaticInjectAnnotationProcessorFactory {
 
     @Override
     public String getName() {
@@ -53,7 +53,7 @@ public class RequestAttributeInjector im
     }
 
     @Override
-    public InjectAnnotationProcessor createAnnotationProcessor(Object adaptable, AnnotatedElement element) {
+    public InjectAnnotationProcessor createAnnotationProcessor(AnnotatedElement element) {
         // check if the element has the expected annotation
         RequestAttribute annotation = element.getAnnotation(RequestAttribute.class);
         if (annotation != null) {

Modified: sling/trunk/bundles/extensions/models/impl/src/main/java/org/apache/sling/models/impl/injectors/ResourcePathInjector.java
URL: http://svn.apache.org/viewvc/sling/trunk/bundles/extensions/models/impl/src/main/java/org/apache/sling/models/impl/injectors/ResourcePathInjector.java?rev=1639323&r1=1639322&r2=1639323&view=diff
==============================================================================
--- sling/trunk/bundles/extensions/models/impl/src/main/java/org/apache/sling/models/impl/injectors/ResourcePathInjector.java (original)
+++ sling/trunk/bundles/extensions/models/impl/src/main/java/org/apache/sling/models/impl/injectors/ResourcePathInjector.java Thu Nov 13 13:51:33 2014
@@ -33,14 +33,14 @@ import org.apache.sling.models.spi.Dispo
 import org.apache.sling.models.spi.Injector;
 import org.apache.sling.models.spi.injectorspecific.AbstractInjectAnnotationProcessor;
 import org.apache.sling.models.spi.injectorspecific.InjectAnnotationProcessor;
-import org.apache.sling.models.spi.injectorspecific.InjectAnnotationProcessorFactory;
+import org.apache.sling.models.spi.injectorspecific.StaticInjectAnnotationProcessorFactory;
 import org.osgi.framework.Constants;
 
 @Component
 @Service
 @Property(name = Constants.SERVICE_RANKING, intValue = 2500)
 public class ResourcePathInjector extends AbstractInjector implements Injector, AcceptsNullName,
-        InjectAnnotationProcessorFactory {
+        StaticInjectAnnotationProcessorFactory {
 
     @Override
     public String getName() {
@@ -83,11 +83,11 @@ public class ResourcePathInjector extend
     }
 
     @Override
-    public InjectAnnotationProcessor createAnnotationProcessor(Object adaptable, AnnotatedElement element) {
+    public InjectAnnotationProcessor createAnnotationProcessor(AnnotatedElement element) {
         // check if the element has the expected annotation
         ResourcePath annotation = element.getAnnotation(ResourcePath.class);
         if (annotation != null) {
-            return new ResourcePathAnnotationProcessor(annotation, adaptable);
+            return new ResourcePathAnnotationProcessor(annotation);
         }
         return null;
     }
@@ -96,7 +96,7 @@ public class ResourcePathInjector extend
 
         private final ResourcePath annotation;
 
-        public ResourcePathAnnotationProcessor(ResourcePath annotation, Object adaptable) {
+        public ResourcePathAnnotationProcessor(ResourcePath annotation) {
             this.annotation = annotation;
         }
 

Modified: sling/trunk/bundles/extensions/models/impl/src/main/java/org/apache/sling/models/impl/injectors/SelfInjector.java
URL: http://svn.apache.org/viewvc/sling/trunk/bundles/extensions/models/impl/src/main/java/org/apache/sling/models/impl/injectors/SelfInjector.java?rev=1639323&r1=1639322&r2=1639323&view=diff
==============================================================================
--- sling/trunk/bundles/extensions/models/impl/src/main/java/org/apache/sling/models/impl/injectors/SelfInjector.java (original)
+++ sling/trunk/bundles/extensions/models/impl/src/main/java/org/apache/sling/models/impl/injectors/SelfInjector.java Thu Nov 13 13:51:33 2014
@@ -23,13 +23,13 @@ import org.apache.felix.scr.annotations.
 import org.apache.felix.scr.annotations.Property;
 import org.apache.felix.scr.annotations.Service;
 import org.apache.sling.models.annotations.injectorspecific.Self;
-import org.apache.sling.models.impl.ConstructorParameter;
-import org.apache.sling.models.spi.DisposalCallbackRegistry;
+import org.apache.sling.models.impl.model.ConstructorParameter;
 import org.apache.sling.models.spi.AcceptsNullName;
+import org.apache.sling.models.spi.DisposalCallbackRegistry;
 import org.apache.sling.models.spi.Injector;
 import org.apache.sling.models.spi.injectorspecific.AbstractInjectAnnotationProcessor;
 import org.apache.sling.models.spi.injectorspecific.InjectAnnotationProcessor;
-import org.apache.sling.models.spi.injectorspecific.InjectAnnotationProcessorFactory;
+import org.apache.sling.models.spi.injectorspecific.StaticInjectAnnotationProcessorFactory;
 import org.osgi.framework.Constants;
 
 /**
@@ -38,7 +38,7 @@ import org.osgi.framework.Constants;
 @Component
 @Service
 @Property(name = Constants.SERVICE_RANKING, intValue = Integer.MAX_VALUE)
-public class SelfInjector implements Injector, InjectAnnotationProcessorFactory, AcceptsNullName {
+public class SelfInjector implements Injector, StaticInjectAnnotationProcessorFactory, AcceptsNullName {
 
     @Override
     public String getName() {
@@ -53,8 +53,8 @@ public class SelfInjector implements Inj
         } else {
             // special handling for the first constructor parameter
             // apply class-based injection only if class matches or is a superclass
-            if (element instanceof ConstructorParameter &&
-                    ((ConstructorParameter)element).getParameterIndex() == 0 &&
+            if (element instanceof ConstructorParameter.FakeAnnotatedElement &&
+                    ((ConstructorParameter.FakeAnnotatedElement)element).getParameterIndex() == 0 &&
                     type instanceof Class<?> &&
                     ((Class<?>)type).isAssignableFrom(adaptable.getClass())) {
                 return adaptable;
@@ -64,7 +64,7 @@ public class SelfInjector implements Inj
     }
 
     @Override
-    public InjectAnnotationProcessor createAnnotationProcessor(Object adaptable, AnnotatedElement element) {
+    public InjectAnnotationProcessor createAnnotationProcessor(AnnotatedElement element) {
         // check if the element has the expected annotation
         Self annotation = element.getAnnotation(Self.class);
         if (annotation != null) {

Modified: sling/trunk/bundles/extensions/models/impl/src/main/java/org/apache/sling/models/impl/injectors/SlingObjectInjector.java
URL: http://svn.apache.org/viewvc/sling/trunk/bundles/extensions/models/impl/src/main/java/org/apache/sling/models/impl/injectors/SlingObjectInjector.java?rev=1639323&r1=1639322&r2=1639323&view=diff
==============================================================================
--- sling/trunk/bundles/extensions/models/impl/src/main/java/org/apache/sling/models/impl/injectors/SlingObjectInjector.java (original)
+++ sling/trunk/bundles/extensions/models/impl/src/main/java/org/apache/sling/models/impl/injectors/SlingObjectInjector.java Thu Nov 13 13:51:33 2014
@@ -37,7 +37,7 @@ import org.apache.sling.models.spi.Dispo
 import org.apache.sling.models.spi.Injector;
 import org.apache.sling.models.spi.injectorspecific.AbstractInjectAnnotationProcessor;
 import org.apache.sling.models.spi.injectorspecific.InjectAnnotationProcessor;
-import org.apache.sling.models.spi.injectorspecific.InjectAnnotationProcessorFactory;
+import org.apache.sling.models.spi.injectorspecific.StaticInjectAnnotationProcessorFactory;
 import org.osgi.framework.Constants;
 
 /**
@@ -48,7 +48,7 @@ import org.osgi.framework.Constants;
 @Component
 @Service
 @Property(name = Constants.SERVICE_RANKING, intValue = Integer.MAX_VALUE)
-public final class SlingObjectInjector implements Injector, InjectAnnotationProcessorFactory, AcceptsNullName {
+public final class SlingObjectInjector implements Injector, StaticInjectAnnotationProcessorFactory, AcceptsNullName {
 
     /**
      * Injector name
@@ -124,7 +124,7 @@ public final class SlingObjectInjector i
     }
 
     @Override
-    public InjectAnnotationProcessor createAnnotationProcessor(final Object adaptable, final AnnotatedElement element) {
+    public InjectAnnotationProcessor createAnnotationProcessor(final AnnotatedElement element) {
         // check if the element has the expected annotation
         SlingObject annotation = element.getAnnotation(SlingObject.class);
         if (annotation != null) {

Modified: sling/trunk/bundles/extensions/models/impl/src/test/java/org/apache/sling/models/impl/AdapterImplementationsTest.java
URL: http://svn.apache.org/viewvc/sling/trunk/bundles/extensions/models/impl/src/test/java/org/apache/sling/models/impl/AdapterImplementationsTest.java?rev=1639323&r1=1639322&r2=1639323&view=diff
==============================================================================
--- sling/trunk/bundles/extensions/models/impl/src/test/java/org/apache/sling/models/impl/AdapterImplementationsTest.java (original)
+++ sling/trunk/bundles/extensions/models/impl/src/test/java/org/apache/sling/models/impl/AdapterImplementationsTest.java Thu Nov 13 13:51:33 2014
@@ -57,7 +57,7 @@ public class AdapterImplementationsTest 
     public void testSingleMapping() {
         underTest.add(SAMPLE_ADAPTER, String.class);
         
-        assertEquals(String.class, underTest.lookup(SAMPLE_ADAPTER, SAMPLE_ADAPTABLE));
+        assertEquals(String.class, underTest.lookup(SAMPLE_ADAPTER, SAMPLE_ADAPTABLE).getType());
         
         underTest.remove(SAMPLE_ADAPTER.getName(), String.class.getName());
 
@@ -70,11 +70,11 @@ public class AdapterImplementationsTest 
         underTest.add(SAMPLE_ADAPTER, Integer.class);
         underTest.add(SAMPLE_ADAPTER, Long.class);
         
-        assertEquals(Integer.class, underTest.lookup(SAMPLE_ADAPTER, SAMPLE_ADAPTABLE));
+        assertEquals(Integer.class, underTest.lookup(SAMPLE_ADAPTER, SAMPLE_ADAPTABLE).getType());
         
         underTest.remove(SAMPLE_ADAPTER.getName(), Integer.class.getName());
 
-        assertEquals(Long.class, underTest.lookup(SAMPLE_ADAPTER, SAMPLE_ADAPTABLE));
+        assertEquals(Long.class, underTest.lookup(SAMPLE_ADAPTER, SAMPLE_ADAPTABLE).getType());
 
         underTest.remove(SAMPLE_ADAPTER.getName(), Long.class.getName());
         underTest.remove(SAMPLE_ADAPTER.getName(), String.class.getName());
@@ -105,7 +105,14 @@ public class AdapterImplementationsTest 
         underTest.add(SAMPLE_ADAPTER, Integer.class);
         underTest.add(SAMPLE_ADAPTER, Long.class);
         
-        assertEquals(String.class, underTest.lookup(SAMPLE_ADAPTER, SAMPLE_ADAPTABLE));
+        assertEquals(String.class, underTest.lookup(SAMPLE_ADAPTER, SAMPLE_ADAPTABLE).getType());
+    }
+    
+    @Test
+    public void testSimpleModel() {
+        underTest.add(SAMPLE_ADAPTER, SAMPLE_ADAPTER);
+        
+        assertEquals(SAMPLE_ADAPTER, underTest.lookup(SAMPLE_ADAPTER, SAMPLE_ADAPTABLE).getType());
     }
     
     static final class NoneImplementationPicker implements ImplementationPicker {

Modified: sling/trunk/bundles/extensions/models/impl/src/test/java/org/apache/sling/models/impl/InjectorSpecificAnnotationTest.java
URL: http://svn.apache.org/viewvc/sling/trunk/bundles/extensions/models/impl/src/test/java/org/apache/sling/models/impl/InjectorSpecificAnnotationTest.java?rev=1639323&r1=1639322&r2=1639323&view=diff
==============================================================================
--- sling/trunk/bundles/extensions/models/impl/src/test/java/org/apache/sling/models/impl/InjectorSpecificAnnotationTest.java (original)
+++ sling/trunk/bundles/extensions/models/impl/src/test/java/org/apache/sling/models/impl/InjectorSpecificAnnotationTest.java Thu Nov 13 13:51:33 2014
@@ -95,15 +95,15 @@ public class InjectorSpecificAnnotationT
                 Collections.<String, Object> singletonMap(Constants.SERVICE_ID, 4L));
         factory.bindInjector(osgiInjector, Collections.<String, Object> singletonMap(Constants.SERVICE_ID, 5L));
 
-        factory.bindInjectAnnotationProcessorFactory(bindingsInjector,
+        factory.bindStaticInjectAnnotationProcessorFactory(bindingsInjector,
                 Collections.<String, Object> singletonMap(Constants.SERVICE_ID, 1L));
         factory.bindInjectAnnotationProcessorFactory(valueMapInjector,
                 Collections.<String, Object> singletonMap(Constants.SERVICE_ID, 2L));
         factory.bindInjectAnnotationProcessorFactory(childResourceInjector,
                 Collections.<String, Object> singletonMap(Constants.SERVICE_ID, 3L));
-        factory.bindInjectAnnotationProcessorFactory(requestAttributeInjector,
+        factory.bindStaticInjectAnnotationProcessorFactory(requestAttributeInjector,
                 Collections.<String, Object> singletonMap(Constants.SERVICE_ID, 4L));
-        factory.bindInjectAnnotationProcessorFactory(osgiInjector,
+        factory.bindStaticInjectAnnotationProcessorFactory(osgiInjector,
                 Collections.<String, Object> singletonMap(Constants.SERVICE_ID, 5L));
 
         SlingBindings bindings = new SlingBindings();

Modified: sling/trunk/bundles/extensions/models/impl/src/test/java/org/apache/sling/models/impl/MultipleInjectorTest.java
URL: http://svn.apache.org/viewvc/sling/trunk/bundles/extensions/models/impl/src/test/java/org/apache/sling/models/impl/MultipleInjectorTest.java?rev=1639323&r1=1639322&r2=1639323&view=diff
==============================================================================
--- sling/trunk/bundles/extensions/models/impl/src/test/java/org/apache/sling/models/impl/MultipleInjectorTest.java (original)
+++ sling/trunk/bundles/extensions/models/impl/src/test/java/org/apache/sling/models/impl/MultipleInjectorTest.java Thu Nov 13 13:51:33 2014
@@ -73,7 +73,7 @@ public class MultipleInjectorTest {
         factory.activate(componentCtx);
         factory.bindInjector(bindingsInjector, new ServicePropertiesMap(1, 1));
         factory.bindInjector(attributesInjector, new ServicePropertiesMap(2, 2));
-        factory.bindInjectAnnotationProcessorFactory(bindingsInjector, new ServicePropertiesMap(1, 1));
+        factory.bindStaticInjectAnnotationProcessorFactory(bindingsInjector, new ServicePropertiesMap(1, 1));
 
         when(request.getAttribute(SlingBindings.class.getName())).thenReturn(bindings);
     }
@@ -92,7 +92,7 @@ public class MultipleInjectorTest {
         assertEquals(obj.firstAttribute, bindingsValue);
 
         verifyNoMoreInteractions(attributesInjector);
-        verify(bindingsInjector).createAnnotationProcessor(any(), any(AnnotatedElement.class));
+        verify(bindingsInjector).createAnnotationProcessor(any(AnnotatedElement.class));
         verify(bindingsInjector).getValue(eq(request), eq("firstAttribute"), eq(String.class), any(AnnotatedElement.class), any(DisposalCallbackRegistry.class));
         verifyNoMoreInteractions(bindingsInjector);
     }
@@ -111,7 +111,7 @@ public class MultipleInjectorTest {
         assertEquals(obj.firstAttribute, attributeValue);
 
         verify(bindingsInjector).getName();
-        verify(bindingsInjector).createAnnotationProcessor(any(), any(AnnotatedElement.class));
+        verify(bindingsInjector).createAnnotationProcessor(any(AnnotatedElement.class));
         verifyNoMoreInteractions(bindingsInjector);
     }
 

Modified: sling/trunk/bundles/extensions/models/impl/src/test/java/org/apache/sling/models/impl/ResourcePathInjectionTest.java
URL: http://svn.apache.org/viewvc/sling/trunk/bundles/extensions/models/impl/src/test/java/org/apache/sling/models/impl/ResourcePathInjectionTest.java?rev=1639323&r1=1639322&r2=1639323&view=diff
==============================================================================
--- sling/trunk/bundles/extensions/models/impl/src/test/java/org/apache/sling/models/impl/ResourcePathInjectionTest.java (original)
+++ sling/trunk/bundles/extensions/models/impl/src/test/java/org/apache/sling/models/impl/ResourcePathInjectionTest.java Thu Nov 13 13:51:33 2014
@@ -96,7 +96,7 @@ public class ResourcePathInjectionTest {
         factory.bindInjector(new SelfInjector(), new ServicePropertiesMap(1, Integer.MAX_VALUE));
         factory.bindInjector(new ValueMapInjector(), new ServicePropertiesMap(2, 2000));
         factory.bindInjector(new ResourcePathInjector(), new ServicePropertiesMap(3, 2500));
-        factory.bindInjectAnnotationProcessorFactory(new ResourcePathInjector(), new ServicePropertiesMap(3, 2500));
+        factory.bindStaticInjectAnnotationProcessorFactory(new ResourcePathInjector(), new ServicePropertiesMap(3, 2500));
     }
 
     @Test