You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@sling.apache.org by kw...@apache.org on 2019/06/26 10:21:03 UTC

[sling-org-apache-sling-models-impl] branch master updated: SLING-8452 migrate to OSGi annotations (#13)

This is an automated email from the ASF dual-hosted git repository.

kwin pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/sling-org-apache-sling-models-impl.git


The following commit(s) were added to refs/heads/master by this push:
     new 398a382  SLING-8452 migrate to OSGi annotations (#13)
398a382 is described below

commit 398a382724154eb6bd80bd9d4142f100fee2532c
Author: Konrad Windszus <kw...@apache.org>
AuthorDate: Wed Jun 26 12:20:58 2019 +0200

    SLING-8452 migrate to OSGi annotations (#13)
    
    * SLING-8452 migrate to OSGi annotations
    
    also update to the most recent Sling parent which required to increase
    the minimum java version to 8
---
 bnd.bnd                                            |  12 ++
 pom.xml                                            | 142 +++++++++-----------
 .../models/impl/FirstImplementationPicker.java     |   8 +-
 .../sling/models/impl/ModelAdapterFactory.java     | 144 ++++++---------------
 .../impl/ModelAdapterFactoryConfiguration.java     |  28 ++++
 .../impl/ResourceTypeBasedResourcePicker.java      |   8 +-
 .../models/impl/injectors/BindingsInjector.java    |   8 +-
 .../impl/injectors/ChildResourceInjector.java      |   8 +-
 .../models/impl/injectors/OSGiServiceInjector.java |  33 ++---
 .../impl/injectors/RequestAttributeInjector.java   |   8 +-
 .../impl/injectors/ResourcePathInjector.java       |   8 +-
 .../sling/models/impl/injectors/SelfInjector.java  |   8 +-
 .../models/impl/injectors/SlingObjectInjector.java |   8 +-
 .../models/impl/injectors/ValueMapInjector.java    |   8 +-
 .../apache/sling/models/impl/model/ModelClass.java |   6 +-
 .../models/impl/via/BeanPropertyViaProvider.java   |  14 +-
 .../models/impl/via/ChildResourceViaProvider.java  |   6 +-
 .../impl/via/ForcedResourceTypeViaProvider.java    |   7 +-
 .../impl/via/ResourceSuperTypeViaProvider.java     |   7 +-
 .../sling/models/impl/AdapterFactoryTest.java      |  42 +++---
 .../sling/models/impl/AnnotationConflictsTest.java |  33 ++---
 .../org/apache/sling/models/impl/CachingTest.java  |  20 +--
 .../apache/sling/models/impl/ConstructorTest.java  |  16 +--
 .../sling/models/impl/CustomInjectorTest.java      |  25 +---
 .../org/apache/sling/models/impl/DefaultTest.java  |  16 +--
 .../sling/models/impl/ExtraDefaultTests.java       |  20 +--
 .../sling/models/impl/ImplementsExtendsTest.java   |  14 +-
 .../impl/InjectorSpecificAnnotationTest.java       |  27 ++--
 .../models/impl/InterfaceInheritanceTest.java      |  22 +---
 .../sling/models/impl/InvalidAdaptationsTest.java  |  22 +---
 .../sling/models/impl/MultipleInjectorTest.java    |  16 +--
 .../sling/models/impl/OSGiInjectionTest.java       |  15 +--
 .../sling/models/impl/OptionalPrimitivesTest.java  |  17 +--
 .../ParameterizedTypeFromRequestAttributeTest.java |  20 +--
 .../sling/models/impl/PostConstructTest.java       |  19 +--
 .../sling/models/impl/RequestDisposalTest.java     |  15 +--
 .../sling/models/impl/RequestInjectionTest.java    |  17 +--
 .../sling/models/impl/RequestWrapperTest.java      |  35 +++--
 .../models/impl/ResourceModelClassesTest.java      |  22 +---
 .../models/impl/ResourceModelConstructorTest.java  |  16 +--
 .../models/impl/ResourceModelInterfacesTest.java   |  16 +--
 .../models/impl/ResourcePathInjectionTest.java     |  23 +---
 .../sling/models/impl/SelfDependencyTest.java      |  16 +--
 .../java/org/apache/sling/models/impl/ViaTest.java |  15 +--
 44 files changed, 312 insertions(+), 678 deletions(-)

diff --git a/bnd.bnd b/bnd.bnd
new file mode 100644
index 0000000..0b1929d
--- /dev/null
+++ b/bnd.bnd
@@ -0,0 +1,12 @@
+# Remove those package imports because embedded and relocated via shade plugin (see below)
+Import-Package:\
+    !org.apache.sling.commons.osgi,\
+    !org.apache.sling.scripting.core.impl.helper,\
+    *
+Provide-Capability:\
+    osgi.service;objectClass=java.lang.Runnable,\
+    osgi.service;objectClass=javax.servlet.Servlet,\
+    osgi.service;objectClass=org.apache.sling.api.adapter.AdapterFactory,\
+    osgi.service;objectClass=org.apache.sling.models.factory.ModelFactory
+# Overwrite bundle description due to https://github.com/bndtools/bnd/issues/3282
+Bundle-Description: Apache Sling Models Implementation
\ No newline at end of file
diff --git a/pom.xml b/pom.xml
index 6ef84dc..5b8b548 100644
--- a/pom.xml
+++ b/pom.xml
@@ -1,32 +1,32 @@
 <?xml version="1.0" encoding="ISO-8859-1"?>
 <!--
-  Licensed to the Apache Software Foundation (ASF) under one
-  or more contributor license agreements.  See the NOTICE file
-  distributed with this work for additional information
-  regarding copyright ownership.  The ASF licenses this file
-  to you 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
+    Licensed to the Apache Software Foundation (ASF) under one
+    or more contributor license agreements. See the NOTICE file
+    distributed with this work for additional information
+    regarding copyright ownership. The ASF licenses this file
+    to you 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
+    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.
+    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.
 -->
-<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+    xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
     <modelVersion>4.0.0</modelVersion>
     <parent>
         <groupId>org.apache.sling</groupId>
-        <artifactId>sling</artifactId>
-        <version>26</version>
-        <relativePath />
+        <artifactId>sling-bundle-parent</artifactId>
+        <version>35</version>
+        <relativePath/>
     </parent>
     <artifactId>org.apache.sling.models.impl</artifactId>
-    <packaging>bundle</packaging>
     <version>1.4.11-SNAPSHOT</version>
     <name>Apache Sling Models Implementation</name>
     <description>Apache Sling Models Implementation</description>
@@ -35,42 +35,16 @@
         <connection>scm:git:https://gitbox.apache.org/repos/asf/sling-org-apache-sling-models-impl.git</connection>
         <developerConnection>scm:git:https://gitbox.apache.org/repos/asf/sling-org-apache-sling-models-impl.git</developerConnection>
         <url>https://gitbox.apache.org/repos/asf?p=sling-org-apache-sling-models-impl.git</url>
-      <tag>HEAD</tag>
-  </scm>
+        <tag>HEAD</tag>
+    </scm>
     <properties>
-        <sling.java.version>7</sling.java.version>
+        <sling.java.version>8</sling.java.version>
     </properties>
     <build>
         <plugins>
             <plugin>
-                <groupId>org.apache.felix</groupId>
-                <artifactId>maven-scr-plugin</artifactId>
-            </plugin>
-            <plugin>
-                <groupId>org.apache.felix</groupId>
-                <artifactId>maven-bundle-plugin</artifactId>
-                <extensions>true</extensions>
-                <configuration>
-                  <instructions>
-                    <!-- Remove those package imports because embedded and relocated via shade plugin (see below) -->
-                    <Import-Package>
-                      !org.apache.sling.commons.osgi,
-                      !org.apache.sling.scripting.core.impl.helper,
-                      *
-                    </Import-Package>
-                    <Provide-Capability>
-                      osgi.service;objectClass=java.lang.Runnable,
-                      osgi.service;objectClass=javax.servlet.Servlet,
-                      osgi.service;objectClass=org.apache.sling.api.adapter.AdapterFactory,
-                      osgi.service;objectClass=org.apache.sling.models.factory.ModelFactory
-                    </Provide-Capability>
-                  </instructions>
-                </configuration>
-            </plugin>
-            <plugin>
                 <groupId>org.apache.maven.plugins</groupId>
                 <artifactId>maven-shade-plugin</artifactId>
-                <version>2.4.3</version>
                 <executions>
                     <execution>
                         <phase>package</phase>
@@ -139,27 +113,30 @@
             <version>1.3.6</version>
             <scope>provided</scope>
         </dependency>
+        <!-- OSGi annotations -->
         <dependency>
-            <groupId>javax.servlet</groupId>
-            <artifactId>servlet-api</artifactId>
+            <groupId>org.osgi</groupId>
+            <artifactId>org.osgi.service.component.annotations</artifactId>
+            <version>1.3.0</version> <!-- downgrade to DS 1.3 (OSGi R6), as this leads to a run time dependency -->
             <scope>provided</scope>
         </dependency>
         <dependency>
             <groupId>org.osgi</groupId>
-            <artifactId>osgi.cmpn</artifactId>
-            <version>6.0.0</version>
+            <artifactId>org.osgi.service.metatype.annotations</artifactId>
+            <version>1.3.0</version> <!-- downgrade to metatype 1.3 (OSGi R6) -->
             <scope>provided</scope>
         </dependency>
+        <!-- regular compile-time dependencies -->
         <dependency>
-            <groupId>org.apache.commons</groupId>
-            <artifactId>commons-lang3</artifactId>
-            <version>3.4</version>
+            <groupId>javax.servlet</groupId>
+            <artifactId>servlet-api</artifactId>
+            <version>2.4</version><!-- still Servlet 2.4 -->
             <scope>provided</scope>
         </dependency>
         <dependency>
-            <groupId>org.osgi</groupId>
-            <artifactId>osgi.core</artifactId>
-            <version>6.0.0</version>
+            <groupId>org.apache.commons</groupId>
+            <artifactId>commons-lang3</artifactId>
+            <version>3.4</version>
             <scope>provided</scope>
         </dependency>
         <dependency>
@@ -185,6 +162,26 @@
             <version>1</version>
             <scope>provided</scope>
         </dependency>
+        <!-- Artifact is shaded and inlined, only some classes included (see above) -->
+        <dependency>
+            <groupId>org.apache.sling</groupId>
+            <artifactId>org.apache.sling.commons.osgi</artifactId>
+            <version>2.4.0</version>
+            <scope>compile</scope>
+        </dependency>
+        <!-- Artifact is shaded and inlined, only some classes included (see above) -->
+        <dependency>
+            <groupId>org.apache.sling</groupId>
+            <artifactId>org.apache.sling.scripting.core</artifactId>
+            <version>2.0.20</version>
+            <scope>compile</scope>
+        </dependency>
+        <dependency>
+            <groupId>org.jetbrains</groupId>
+            <artifactId>annotations</artifactId>
+            <scope>provided</scope>
+        </dependency>
+        <!-- Test dependencies -->
         <dependency>
             <groupId>junit</groupId>
             <artifactId>junit</artifactId>
@@ -213,31 +210,12 @@
             <artifactId>slf4j-simple</artifactId>
             <scope>test</scope>
         </dependency>
-        <!-- Artifact is shaded and inlined, only some classes included (see above) -->
+        <!-- for testing the annotations -->
         <dependency>
-            <groupId>org.apache.sling</groupId>
-            <artifactId>org.apache.sling.commons.osgi</artifactId>
-            <version>2.4.0</version>
-            <scope>compile</scope>
-        </dependency>
-        <!-- Artifact is shaded and inlined, only some classes included (see above) -->
-        <dependency>
-            <groupId>org.apache.sling</groupId>
-            <artifactId>org.apache.sling.scripting.core</artifactId>
-            <version>2.0.20</version>
-            <scope>compile</scope>
-        </dependency>
-        <dependency>
-            <groupId>commons-lang</groupId>
-            <artifactId>commons-lang</artifactId>
-            <version>2.5</version>
-            <scope>provided</scope>
-        </dependency>
-        <dependency>
-            <groupId>org.jetbrains</groupId>
-            <artifactId>annotations</artifactId>
-            <version>16.0.2</version>
-            <scope>provided</scope>
+            <groupId>org.apache.felix</groupId>
+            <artifactId>org.apache.felix.converter</artifactId>
+            <version>1.0.8</version>
+            <scope>test</scope>
         </dependency>
     </dependencies>
 </project>
diff --git a/src/main/java/org/apache/sling/models/impl/FirstImplementationPicker.java b/src/main/java/org/apache/sling/models/impl/FirstImplementationPicker.java
index 230ba2c..2963739 100644
--- a/src/main/java/org/apache/sling/models/impl/FirstImplementationPicker.java
+++ b/src/main/java/org/apache/sling/models/impl/FirstImplementationPicker.java
@@ -18,11 +18,9 @@
  */
 package org.apache.sling.models.impl;
 
-import org.apache.felix.scr.annotations.Component;
-import org.apache.felix.scr.annotations.Property;
-import org.apache.felix.scr.annotations.Service;
 import org.apache.sling.models.spi.ImplementationPicker;
 import org.osgi.framework.Constants;
+import org.osgi.service.component.annotations.Component;
 
 /**
  * Picks first implementation.
@@ -31,9 +29,7 @@ import org.osgi.framework.Constants;
  * But at least it gives a consistent behavior.
  * It's service ranking is set to the highest value to allow more intelligent implementations to step in.
  */
-@Component
-@Service
-@Property(name = Constants.SERVICE_RANKING, intValue = Integer.MAX_VALUE)
+@Component(property=Constants.SERVICE_RANKING+":Integer="+Integer.MAX_VALUE, service=ImplementationPicker.class)
 public class FirstImplementationPicker implements ImplementationPicker {
 
     @Override
diff --git a/src/main/java/org/apache/sling/models/impl/ModelAdapterFactory.java b/src/main/java/org/apache/sling/models/impl/ModelAdapterFactory.java
index cf60a09..5f231f6 100644
--- a/src/main/java/org/apache/sling/models/impl/ModelAdapterFactory.java
+++ b/src/main/java/org/apache/sling/models/impl/ModelAdapterFactory.java
@@ -29,7 +29,6 @@ import java.util.ArrayList;
 import java.util.Arrays;
 import java.util.Collection;
 import java.util.Collections;
-import java.util.Dictionary;
 import java.util.HashMap;
 import java.util.HashSet;
 import java.util.Hashtable;
@@ -47,23 +46,11 @@ import javax.servlet.ServletRequestListener;
 import javax.servlet.ServletRequestWrapper;
 
 import org.apache.commons.lang3.StringUtils;
-import org.apache.felix.scr.annotations.Activate;
-import org.apache.felix.scr.annotations.Component;
-import org.apache.felix.scr.annotations.Deactivate;
-import org.apache.felix.scr.annotations.Properties;
-import org.apache.felix.scr.annotations.Property;
-import org.apache.felix.scr.annotations.Reference;
-import org.apache.felix.scr.annotations.ReferenceCardinality;
-import org.apache.felix.scr.annotations.ReferencePolicy;
-import org.apache.felix.scr.annotations.ReferencePolicyOption;
-import org.apache.felix.scr.annotations.References;
-import org.apache.felix.scr.annotations.Service;
 import org.apache.sling.api.SlingHttpServletRequest;
 import org.apache.sling.api.adapter.Adaptable;
 import org.apache.sling.api.adapter.AdapterFactory;
 import org.apache.sling.api.adapter.AdapterManager;
 import org.apache.sling.api.resource.Resource;
-import org.apache.sling.commons.osgi.PropertiesUtil;
 import org.apache.sling.commons.osgi.RankedServices;
 import org.apache.sling.models.annotations.Model;
 import org.apache.sling.models.annotations.ValidationStrategy;
@@ -105,29 +92,22 @@ import org.osgi.framework.BundleContext;
 import org.osgi.framework.Constants;
 import org.osgi.framework.ServiceRegistration;
 import org.osgi.service.component.ComponentContext;
+import org.osgi.service.component.annotations.Activate;
+import org.osgi.service.component.annotations.Component;
+import org.osgi.service.component.annotations.Deactivate;
+import org.osgi.service.component.annotations.Reference;
+import org.osgi.service.component.annotations.ReferenceCardinality;
+import org.osgi.service.component.annotations.ReferencePolicy;
+import org.osgi.service.component.annotations.ReferencePolicyOption;
 import org.osgi.service.http.whiteboard.HttpWhiteboardConstants;
+import org.osgi.service.metatype.annotations.Designate;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
-@Component(metatype = true, immediate = true,
-        label = "Apache Sling Model Adapter Factory")
-@Service(value = { ModelFactory.class, ServletRequestListener.class })
-@Properties({
-    @Property(name = HttpWhiteboardConstants.HTTP_WHITEBOARD_LISTENER, value = "true"),
-    @Property(name = HttpWhiteboardConstants.HTTP_WHITEBOARD_CONTEXT_SELECT, value = "(" + HttpWhiteboardConstants.HTTP_WHITEBOARD_CONTEXT_NAME + "=*)")
-})
-@References({
-    @Reference(
-        name = "injector",
-        referenceInterface = Injector.class,
-        cardinality = ReferenceCardinality.OPTIONAL_MULTIPLE,
-        policy = ReferencePolicy.DYNAMIC),
-    @Reference(
-            name = "viaProvider",
-            referenceInterface = ViaProvider.class,
-            cardinality = ReferenceCardinality.OPTIONAL_MULTIPLE,
-            policy = ReferencePolicy.DYNAMIC)
-})
+@Component(immediate = true, service={ ModelFactory.class, ServletRequestListener.class }, 
+    property= { HttpWhiteboardConstants.HTTP_WHITEBOARD_LISTENER+"=true", 
+                HttpWhiteboardConstants.HTTP_WHITEBOARD_CONTEXT_SELECT+"=(" + HttpWhiteboardConstants.HTTP_WHITEBOARD_CONTEXT_NAME + "=*)" })
+@Designate(ocd=ModelAdapterFactoryConfiguration.class)
 @SuppressWarnings("deprecation")
 public class ModelAdapterFactory implements AdapterFactory, Runnable, ModelFactory, ServletRequestListener {
 
@@ -233,49 +213,32 @@ public class ModelAdapterFactory implements AdapterFactory, Runnable, ModelFacto
 
     private static final Logger log = LoggerFactory.getLogger(ModelAdapterFactory.class);
 
-    private static final int DEFAULT_MAX_RECURSION_DEPTH = 20;
-
-    private static final long DEFAULT_CLEANUP_JOB_PERIOD = 30l;
-
-    @Property(label = "Maximum Recursion Depth", description = "Maximum depth adaptation will be attempted.", intValue = DEFAULT_MAX_RECURSION_DEPTH)
-    private static final String PROP_MAX_RECURSION_DEPTH = "max.recursion.depth";
-
-    @Property(label = "Cleanup Job Period", description = "Period at which OSGi service references from ThreadLocals will be cleaned up.", longValue = DEFAULT_CLEANUP_JOB_PERIOD)
-    private static final String PROP_CLEANUP_JOB_PERIOD = "cleanup.job.period";
-
     private final @NotNull ConcurrentMap<String, RankedServices<Injector>> injectors = new ConcurrentHashMap<>();
     private final @NotNull RankedServices<Injector> sortedInjectors = new RankedServices<>();
     private final @NotNull ConcurrentMap<Class<? extends ViaProviderType>, ViaProvider> viaProviders = new ConcurrentHashMap<>();
 
-    @Reference(name = "injectAnnotationProcessorFactory", referenceInterface = InjectAnnotationProcessorFactory.class,
-            cardinality = ReferenceCardinality.OPTIONAL_MULTIPLE, policy = ReferencePolicy.DYNAMIC)
-    private final @NotNull RankedServices<InjectAnnotationProcessorFactory> injectAnnotationProcessorFactories = new RankedServices<>();
+    @Reference(name="injectAnnotationProcessorFactory", cardinality = ReferenceCardinality.MULTIPLE, policy = ReferencePolicy.DYNAMIC)
+    volatile @NotNull Collection<InjectAnnotationProcessorFactory> injectAnnotationProcessorFactories; // this must be non-final for fieldOption=replace!
 
-    @Reference(name = "injectAnnotationProcessorFactory2", referenceInterface = InjectAnnotationProcessorFactory2.class,
-            cardinality = ReferenceCardinality.OPTIONAL_MULTIPLE, policy = ReferencePolicy.DYNAMIC)
-    private final @NotNull RankedServices<InjectAnnotationProcessorFactory2> injectAnnotationProcessorFactories2 = new RankedServices<>();
+    @Reference(name="injectAnnotationProcessorFactory2", cardinality = ReferenceCardinality.MULTIPLE, policy = ReferencePolicy.DYNAMIC)
+    volatile @NotNull Collection<InjectAnnotationProcessorFactory2> injectAnnotationProcessorFactories2; // this must be non-final for fieldOption=replace!
 
-    @Reference(name = "staticInjectAnnotationProcessorFactory", referenceInterface = StaticInjectAnnotationProcessorFactory.class,
-            cardinality = ReferenceCardinality.OPTIONAL_MULTIPLE, policy = ReferencePolicy.DYNAMIC)
     private final @NotNull RankedServices<StaticInjectAnnotationProcessorFactory> staticInjectAnnotationProcessorFactories = new RankedServices<>();
 
-    @Reference(name = "implementationPicker", referenceInterface = ImplementationPicker.class,
-            cardinality = ReferenceCardinality.OPTIONAL_MULTIPLE, policy = ReferencePolicy.DYNAMIC)
     private final @NotNull RankedServices<ImplementationPicker> implementationPickers = new RankedServices<>();
 
     // bind the service with the highest priority (if a new one comes in this service gets restarted)
-    @Reference(cardinality=ReferenceCardinality.OPTIONAL_UNARY, policyOption=ReferencePolicyOption.GREEDY)
+    @Reference(cardinality=ReferenceCardinality.OPTIONAL, policyOption=ReferencePolicyOption.GREEDY)
     private ModelValidation modelValidation = null;
 
-    @Reference(name = "modelExporter", cardinality = ReferenceCardinality.OPTIONAL_MULTIPLE, policy = ReferencePolicy.DYNAMIC,
-            referenceInterface = ModelExporter.class)
-    private final @NotNull RankedServices<ModelExporter> modelExporters = new RankedServices<>();
+    @Reference(name = "modelExporter", cardinality = ReferenceCardinality.MULTIPLE, policy = ReferencePolicy.DYNAMIC)
+    volatile @NotNull Collection<ModelExporter> modelExporters; // this must be non-final for fieldOption=replace!
 
     @Reference
-    private BindingsValuesProvidersByContext bindingsValuesProvidersByContext;
+    BindingsValuesProvidersByContext bindingsValuesProvidersByContext;
 
-    @Reference
-    private AdapterManager adapterManager;
+    @Reference 
+    AdapterManager adapterManager;
 
     ModelPackageBundleListener listener;
 
@@ -288,7 +251,7 @@ public class ModelAdapterFactory implements AdapterFactory, Runnable, ModelFacto
     // Use threadlocal to count recursive invocations and break recursing if a max. limit is reached (to avoid cyclic dependencies)
     private ThreadLocal<ThreadInvocationCounter> invocationCountThreadLocal;
 
-    private Map<Object, Map<Class, SoftReference<Object>>> adapterCache;
+    private Map<Object, Map<Class<?>, SoftReference<Object>>> adapterCache;
 
     private SlingModelsScriptEngineFactory scriptEngineFactory;
 
@@ -401,7 +364,7 @@ public class ModelAdapterFactory implements AdapterFactory, Runnable, ModelFacto
             Model modelAnnotation = modelClass.getModelAnnotation();
 
             if (modelAnnotation.cache()) {
-                Map<Class, SoftReference<Object>> adaptableCache = adapterCache.get(adaptable);
+                Map<Class<?>, SoftReference<Object>> adaptableCache = adapterCache.get(adaptable);
                 if (adaptableCache != null) {
                     SoftReference<Object> SoftReference = adaptableCache.get(requestedType);
                     ModelType cachedObject = (ModelType) SoftReference.get();
@@ -431,9 +394,9 @@ public class ModelAdapterFactory implements AdapterFactory, Runnable, ModelFacto
                         ModelType model = (ModelType) Proxy.newProxyInstance(modelClass.getType().getClassLoader(), new Class<?>[] { modelClass.getType() }, handlerResult.getValue());
 
                         if (modelAnnotation.cache()) {
-                            Map<Class, SoftReference<Object>> adaptableCache = adapterCache.get(adaptable);
+                            Map<Class<?>, SoftReference<Object>> adaptableCache = adapterCache.get(adaptable);
                             if (adaptableCache == null) {
-                                adaptableCache = Collections.synchronizedMap(new WeakHashMap<Class, SoftReference<Object>>());
+                                adaptableCache = Collections.synchronizedMap(new WeakHashMap<Class<?>, SoftReference<Object>>());
                                 adapterCache.put(adaptable, adaptableCache);
                             }
                             adaptableCache.put(requestedType, new SoftReference<Object>(model));
@@ -448,9 +411,9 @@ public class ModelAdapterFactory implements AdapterFactory, Runnable, ModelFacto
                         result = createObject(adaptable, modelClass);
 
                         if (result.wasSuccessful() && modelAnnotation.cache()) {
-                            Map<Class, SoftReference<Object>> adaptableCache = adapterCache.get(adaptable);
+                            Map<Class<?>, SoftReference<Object>> adaptableCache = adapterCache.get(adaptable);
                             if (adaptableCache == null) {
-                                adaptableCache = Collections.synchronizedMap(new WeakHashMap<Class, SoftReference<Object>>());
+                                adaptableCache = Collections.synchronizedMap(new WeakHashMap<Class<?>, SoftReference<Object>>());
                                 adapterCache.put(adaptable, adaptableCache);
                             }
                             adaptableCache.put(requestedType, new SoftReference<Object>(result.getValue()));
@@ -1130,17 +1093,15 @@ public class ModelAdapterFactory implements AdapterFactory, Runnable, ModelFacto
     }
 
     @Activate
-    protected void activate(final ComponentContext ctx) {
-        Dictionary<?, ?> props = ctx.getProperties();
-        final int maxRecursionDepth = PropertiesUtil.toInteger(props.get(PROP_MAX_RECURSION_DEPTH), DEFAULT_MAX_RECURSION_DEPTH);
+    protected void activate(final ComponentContext ctx, final ModelAdapterFactoryConfiguration configuration) {
         this.invocationCountThreadLocal = new ThreadLocal<ThreadInvocationCounter>() {
             @Override
             protected ThreadInvocationCounter initialValue() {
-                return new ThreadInvocationCounter(maxRecursionDepth);
+                return new ThreadInvocationCounter(configuration.max_recursion_depth());
             }
         };
 
-        this.adapterCache = Collections.synchronizedMap(new WeakHashMap<Object, Map<Class, SoftReference<Object>>>());
+        this.adapterCache = Collections.synchronizedMap(new WeakHashMap<Object, Map<Class<?>, SoftReference<Object>>>());
 
         BundleContext bundleContext = ctx.getBundleContext();
         this.queue = new ReferenceQueue<>();
@@ -1151,7 +1112,7 @@ public class ModelAdapterFactory implements AdapterFactory, Runnable, ModelFacto
         properties.put(Constants.SERVICE_DESCRIPTION, "Sling Models OSGi Service Disposal Job");
         properties.put("scheduler.name", "Sling Models OSGi Service Disposal Job");
         properties.put("scheduler.concurrent", false);
-        properties.put("scheduler.period", PropertiesUtil.toLong(props.get(PROP_CLEANUP_JOB_PERIOD), DEFAULT_CLEANUP_JOB_PERIOD));
+        properties.put("scheduler.period", configuration.cleanup_job_period());
 
         this.jobRegistration = bundleContext.registerService(Runnable.class, this, properties);
 
@@ -1192,6 +1153,8 @@ public class ModelAdapterFactory implements AdapterFactory, Runnable, ModelFacto
         }
     }
 
+    @Reference(cardinality = ReferenceCardinality.MULTIPLE,
+            policy = ReferencePolicy.DYNAMIC)
     protected void bindInjector(final Injector injector, final Map<String, Object> props) {
         RankedServices<Injector> newRankedServices = new RankedServices<>();
         RankedServices<Injector> injectorsPerInjectorName = injectors.putIfAbsent(injector.getName(), newRankedServices);
@@ -1210,22 +1173,7 @@ public class ModelAdapterFactory implements AdapterFactory, Runnable, ModelFacto
         sortedInjectors.unbind(injector, props);
     }
 
-    protected void bindInjectAnnotationProcessorFactory(final InjectAnnotationProcessorFactory factory, final Map<String, Object> props) {
-        injectAnnotationProcessorFactories.bind(factory, props);
-    }
-
-    protected void unbindInjectAnnotationProcessorFactory(final InjectAnnotationProcessorFactory factory, final Map<String, Object> props) {
-        injectAnnotationProcessorFactories.unbind(factory, props);
-    }
-
-    protected void bindInjectAnnotationProcessorFactory2(final InjectAnnotationProcessorFactory2 factory, final Map<String, Object> props) {
-        injectAnnotationProcessorFactories2.bind(factory, props);
-    }
-
-    protected void unbindInjectAnnotationProcessorFactory2(final InjectAnnotationProcessorFactory2 factory, final Map<String, Object> props) {
-        injectAnnotationProcessorFactories2.unbind(factory, props);
-    }
-
+    @Reference(cardinality = ReferenceCardinality.MULTIPLE, policy = ReferencePolicy.DYNAMIC)
     protected void bindStaticInjectAnnotationProcessorFactory(final StaticInjectAnnotationProcessorFactory factory, final Map<String, Object> props) {
         synchronized (staticInjectAnnotationProcessorFactories) {
             staticInjectAnnotationProcessorFactories.bind(factory, props);
@@ -1240,6 +1188,7 @@ public class ModelAdapterFactory implements AdapterFactory, Runnable, ModelFacto
         }
     }
 
+    @Reference(name="implementationPicker", cardinality = ReferenceCardinality.MULTIPLE, policy = ReferencePolicy.DYNAMIC)
     protected void bindImplementationPicker(final ImplementationPicker implementationPicker, final Map<String, Object> props) {
         synchronized (implementationPickers) {
             implementationPickers.bind(implementationPicker, props);
@@ -1254,18 +1203,11 @@ public class ModelAdapterFactory implements AdapterFactory, Runnable, ModelFacto
         }
     }
 
-    protected void bindModelExporter(final ModelExporter s, final Map<String, Object> props) {
-        synchronized (modelExporters) {
-            modelExporters.bind(s, props);
-        }
-    }
-
-    protected void unbindModelExporter(final ModelExporter s, final Map<String, Object> props) {
-        synchronized (modelExporters) {
-            modelExporters.unbind(s, props);
-        }
-    }
-
+    @Reference(
+            name = "viaProvider",
+            cardinality = ReferenceCardinality.MULTIPLE,
+            policy = ReferencePolicy.DYNAMIC
+            )
     protected void bindViaProvider(final ViaProvider viaProvider, final Map<String, Object> props) {
         Class<? extends ViaProviderType> type = viaProvider.getType();
         viaProviders.put(type, viaProvider);
@@ -1281,11 +1223,11 @@ public class ModelAdapterFactory implements AdapterFactory, Runnable, ModelFacto
     }
 
     @NotNull Collection<InjectAnnotationProcessorFactory> getInjectAnnotationProcessorFactories() {
-        return injectAnnotationProcessorFactories.get();
+        return injectAnnotationProcessorFactories;
     }
 
     @NotNull Collection<InjectAnnotationProcessorFactory2> getInjectAnnotationProcessorFactories2() {
-        return injectAnnotationProcessorFactories2.get();
+        return injectAnnotationProcessorFactories2;
     }
 
     @NotNull Collection<StaticInjectAnnotationProcessorFactory> getStaticInjectAnnotationProcessorFactories() {
diff --git a/src/main/java/org/apache/sling/models/impl/ModelAdapterFactoryConfiguration.java b/src/main/java/org/apache/sling/models/impl/ModelAdapterFactoryConfiguration.java
new file mode 100644
index 0000000..9433265
--- /dev/null
+++ b/src/main/java/org/apache/sling/models/impl/ModelAdapterFactoryConfiguration.java
@@ -0,0 +1,28 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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.sling.models.impl;
+
+import org.osgi.service.metatype.annotations.AttributeDefinition;
+import org.osgi.service.metatype.annotations.ObjectClassDefinition;
+
+@ObjectClassDefinition(name = "Apache Sling Model Adapter Factory")
+public @interface ModelAdapterFactoryConfiguration {
+    @AttributeDefinition(name="Maximum Recursion Depth", description= "Maximum depth adaptation will be attempted.")
+    int max_recursion_depth() default 20;
+    @AttributeDefinition(name="Cleanup Job Period", description= "Period in seconds at which OSGi service references from ThreadLocals will be cleaned up.")
+    long cleanup_job_period() default 30l;
+}
diff --git a/src/main/java/org/apache/sling/models/impl/ResourceTypeBasedResourcePicker.java b/src/main/java/org/apache/sling/models/impl/ResourceTypeBasedResourcePicker.java
index 82b1337..7bf313a 100644
--- a/src/main/java/org/apache/sling/models/impl/ResourceTypeBasedResourcePicker.java
+++ b/src/main/java/org/apache/sling/models/impl/ResourceTypeBasedResourcePicker.java
@@ -19,19 +19,15 @@ package org.apache.sling.models.impl;
 import java.util.HashMap;
 import java.util.Map;
 
-import org.apache.felix.scr.annotations.Component;
-import org.apache.felix.scr.annotations.Property;
-import org.apache.felix.scr.annotations.Service;
 import org.apache.sling.api.SlingHttpServletRequest;
 import org.apache.sling.api.resource.Resource;
 import org.apache.sling.models.annotations.Model;
 import org.apache.sling.models.spi.ImplementationPicker;
 import org.jetbrains.annotations.NotNull;
 import org.osgi.framework.Constants;
+import org.osgi.service.component.annotations.Component;
 
-@Component
-@Service
-@Property(name = Constants.SERVICE_RANKING, intValue = 0) // this must come before FirstImplementationPicker
+@Component(property=Constants.SERVICE_RANKING+":Integer=0") // this must come before FirstImplementationPicker
 public class ResourceTypeBasedResourcePicker implements ImplementationPicker {
 
     @Override
diff --git a/src/main/java/org/apache/sling/models/impl/injectors/BindingsInjector.java b/src/main/java/org/apache/sling/models/impl/injectors/BindingsInjector.java
index 077ff39..4562217 100644
--- a/src/main/java/org/apache/sling/models/impl/injectors/BindingsInjector.java
+++ b/src/main/java/org/apache/sling/models/impl/injectors/BindingsInjector.java
@@ -22,9 +22,6 @@ import java.lang.reflect.Type;
 import javax.servlet.ServletRequest;
 
 import org.apache.commons.lang3.ObjectUtils;
-import org.apache.felix.scr.annotations.Component;
-import org.apache.felix.scr.annotations.Property;
-import org.apache.felix.scr.annotations.Service;
 import org.apache.sling.api.scripting.SlingBindings;
 import org.apache.sling.models.annotations.injectorspecific.InjectionStrategy;
 import org.apache.sling.models.annotations.injectorspecific.ScriptVariable;
@@ -36,10 +33,9 @@ import org.apache.sling.models.spi.injectorspecific.InjectAnnotationProcessor2;
 import org.apache.sling.models.spi.injectorspecific.StaticInjectAnnotationProcessorFactory;
 import org.jetbrains.annotations.NotNull;
 import org.osgi.framework.Constants;
+import org.osgi.service.component.annotations.Component;
 
-@Component
-@Service
-@Property(name = Constants.SERVICE_RANKING, intValue = 1000)
+@Component(property=Constants.SERVICE_RANKING+":Integer=1000", service={Injector.class, StaticInjectAnnotationProcessorFactory.class, ValuePreparer.class})
 public class BindingsInjector implements Injector, StaticInjectAnnotationProcessorFactory, ValuePreparer {
 
     @Override
diff --git a/src/main/java/org/apache/sling/models/impl/injectors/ChildResourceInjector.java b/src/main/java/org/apache/sling/models/impl/injectors/ChildResourceInjector.java
index 24a53dc..967a531 100644
--- a/src/main/java/org/apache/sling/models/impl/injectors/ChildResourceInjector.java
+++ b/src/main/java/org/apache/sling/models/impl/injectors/ChildResourceInjector.java
@@ -24,9 +24,6 @@ import java.util.Iterator;
 import java.util.List;
 
 import org.apache.commons.lang3.StringUtils;
-import org.apache.felix.scr.annotations.Component;
-import org.apache.felix.scr.annotations.Property;
-import org.apache.felix.scr.annotations.Service;
 import org.apache.sling.api.SlingHttpServletRequest;
 import org.apache.sling.api.resource.Resource;
 import org.apache.sling.models.annotations.injectorspecific.ChildResource;
@@ -38,10 +35,9 @@ import org.apache.sling.models.spi.injectorspecific.InjectAnnotationProcessor2;
 import org.apache.sling.models.spi.injectorspecific.InjectAnnotationProcessorFactory2;
 import org.jetbrains.annotations.NotNull;
 import org.osgi.framework.Constants;
+import org.osgi.service.component.annotations.Component;
 
-@Component
-@Service
-@Property(name = Constants.SERVICE_RANKING, intValue = 3000)
+@Component(property=Constants.SERVICE_RANKING+":Integer=3000", service={Injector.class, InjectAnnotationProcessorFactory2.class})
 public class ChildResourceInjector extends AbstractInjector implements Injector, InjectAnnotationProcessorFactory2 {
 
     @Override
diff --git a/src/main/java/org/apache/sling/models/impl/injectors/OSGiServiceInjector.java b/src/main/java/org/apache/sling/models/impl/injectors/OSGiServiceInjector.java
index bfea88e..c4d0127 100644
--- a/src/main/java/org/apache/sling/models/impl/injectors/OSGiServiceInjector.java
+++ b/src/main/java/org/apache/sling/models/impl/injectors/OSGiServiceInjector.java
@@ -27,10 +27,6 @@ import java.util.Collections;
 import java.util.List;
 
 import org.apache.commons.lang3.StringUtils;
-import org.apache.felix.scr.annotations.Activate;
-import org.apache.felix.scr.annotations.Component;
-import org.apache.felix.scr.annotations.Property;
-import org.apache.felix.scr.annotations.Service;
 import org.apache.sling.models.annotations.Filter;
 import org.apache.sling.models.annotations.injectorspecific.InjectionStrategy;
 import org.apache.sling.models.annotations.injectorspecific.OSGiService;
@@ -46,13 +42,12 @@ import org.osgi.framework.BundleContext;
 import org.osgi.framework.Constants;
 import org.osgi.framework.InvalidSyntaxException;
 import org.osgi.framework.ServiceReference;
-import org.osgi.service.component.ComponentContext;
+import org.osgi.service.component.annotations.Activate;
+import org.osgi.service.component.annotations.Component;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
-@Component
-@Service
-@Property(name = Constants.SERVICE_RANKING, intValue = 5000)
+@Component(property=Constants.SERVICE_RANKING+":Integer=5000", service={Injector.class, StaticInjectAnnotationProcessorFactory.class, AcceptsNullName.class})
 public class OSGiServiceInjector implements Injector, StaticInjectAnnotationProcessorFactory, AcceptsNullName {
 
     private static final Logger log = LoggerFactory.getLogger(OSGiServiceInjector.class);
@@ -65,8 +60,8 @@ public class OSGiServiceInjector implements Injector, StaticInjectAnnotationProc
     }
 
     @Activate
-    public void activate(ComponentContext ctx) {
-        this.bundleContext = ctx.getBundleContext();
+    public void activate(BundleContext ctx) {
+        this.bundleContext = ctx;
     }
 
     @Override
@@ -87,17 +82,16 @@ public class OSGiServiceInjector implements Injector, StaticInjectAnnotationProc
         return getValue(adaptable, type, filterString, callbackRegistry);
     }
 
-    @SuppressWarnings("unchecked")
     private <T> Object getService(Object adaptable, Class<T> type, String filter,
             DisposalCallbackRegistry callbackRegistry) {
         // cannot use SlingScriptHelper since it does not support ordering by service ranking due to https://issues.apache.org/jira/browse/SLING-5665
         try {
-            ServiceReference[] refs = bundleContext.getServiceReferences(type.getName(), filter);
+            ServiceReference<?>[] refs = bundleContext.getServiceReferences(type.getName(), filter);
             if (refs == null || refs.length == 0) {
                 return null;
             } else {
                 // sort by service ranking (lowest first) (see ServiceReference.compareTo)
-                List<ServiceReference> references = Arrays.asList(refs);
+                List<ServiceReference<?>> references = Arrays.asList(refs);
                 Collections.sort(references);
                 callbackRegistry.addDisposalCallback(new Callback(refs, bundleContext));
                 return bundleContext.getService(references.get(references.size() - 1));
@@ -108,23 +102,22 @@ public class OSGiServiceInjector implements Injector, StaticInjectAnnotationProc
         }
     }
 
-    @SuppressWarnings("unchecked")
     private <T> Object[] getServices(Object adaptable, Class<T> type, String filter,
             DisposalCallbackRegistry callbackRegistry) {
         // cannot use SlingScriptHelper since it does not support ordering by service ranking due to https://issues.apache.org/jira/browse/SLING-5665
         try {
-            ServiceReference[] refs = bundleContext.getServiceReferences(type.getName(), filter);
+            ServiceReference<?>[] refs = bundleContext.getServiceReferences(type.getName(), filter);
             if (refs == null || refs.length == 0) {
                 return null;
             } else {
                 // sort by service ranking (lowest first) (see ServiceReference.compareTo)
-                List<ServiceReference> references = Arrays.asList(refs);
+                List<ServiceReference<?>> references = Arrays.asList(refs);
                 Collections.sort(references);
                 // make highest service ranking being returned first
                 Collections.reverse(references);
                 callbackRegistry.addDisposalCallback(new Callback(refs, bundleContext));
                 List<Object> services = new ArrayList<>();
-                for (ServiceReference ref : references) {
+                for (ServiceReference<?> ref : references) {
                     Object service = bundleContext.getService(ref);
                     if (service != null) {
                         services.add(service);
@@ -178,10 +171,10 @@ public class OSGiServiceInjector implements Injector, StaticInjectAnnotationProc
     }
 
     private static class Callback implements DisposalCallback {
-        private final ServiceReference[] refs;
+        private final ServiceReference<?>[] refs;
         private final BundleContext context;
 
-        public Callback(ServiceReference[] refs, BundleContext context) {
+        public Callback(ServiceReference<?>[] refs, BundleContext context) {
             this.refs = refs;
             this.context = context;
         }
@@ -189,7 +182,7 @@ public class OSGiServiceInjector implements Injector, StaticInjectAnnotationProc
         @Override
         public void onDisposed() {
             if (refs != null) {
-                for (ServiceReference ref : refs) {
+                for (ServiceReference<?> ref : refs) {
                     context.ungetService(ref);
                 }
             }
diff --git a/src/main/java/org/apache/sling/models/impl/injectors/RequestAttributeInjector.java b/src/main/java/org/apache/sling/models/impl/injectors/RequestAttributeInjector.java
index 4353988..93109dc 100644
--- a/src/main/java/org/apache/sling/models/impl/injectors/RequestAttributeInjector.java
+++ b/src/main/java/org/apache/sling/models/impl/injectors/RequestAttributeInjector.java
@@ -21,9 +21,6 @@ import java.lang.reflect.Type;
 
 import javax.servlet.ServletRequest;
 
-import org.apache.felix.scr.annotations.Component;
-import org.apache.felix.scr.annotations.Property;
-import org.apache.felix.scr.annotations.Service;
 import org.apache.sling.models.annotations.injectorspecific.InjectionStrategy;
 import org.apache.sling.models.annotations.injectorspecific.RequestAttribute;
 import org.apache.sling.models.spi.DisposalCallbackRegistry;
@@ -33,10 +30,9 @@ import org.apache.sling.models.spi.injectorspecific.InjectAnnotationProcessor2;
 import org.apache.sling.models.spi.injectorspecific.StaticInjectAnnotationProcessorFactory;
 import org.jetbrains.annotations.NotNull;
 import org.osgi.framework.Constants;
+import org.osgi.service.component.annotations.Component;
 
-@Component
-@Service
-@Property(name = Constants.SERVICE_RANKING, intValue = 4000)
+@Component(property=Constants.SERVICE_RANKING+":Integer=4000", service={Injector.class, StaticInjectAnnotationProcessorFactory.class})
 public class RequestAttributeInjector implements Injector, StaticInjectAnnotationProcessorFactory {
 
     @Override
diff --git a/src/main/java/org/apache/sling/models/impl/injectors/ResourcePathInjector.java b/src/main/java/org/apache/sling/models/impl/injectors/ResourcePathInjector.java
index ea4a480..2b3ff71 100644
--- a/src/main/java/org/apache/sling/models/impl/injectors/ResourcePathInjector.java
+++ b/src/main/java/org/apache/sling/models/impl/injectors/ResourcePathInjector.java
@@ -25,9 +25,6 @@ import java.util.List;
 
 import org.apache.commons.lang3.ArrayUtils;
 import org.apache.commons.lang3.StringUtils;
-import org.apache.felix.scr.annotations.Component;
-import org.apache.felix.scr.annotations.Property;
-import org.apache.felix.scr.annotations.Service;
 import org.apache.sling.api.resource.Resource;
 import org.apache.sling.api.resource.ResourceResolver;
 import org.apache.sling.api.resource.ValueMap;
@@ -42,12 +39,11 @@ import org.apache.sling.models.spi.injectorspecific.InjectAnnotationProcessor2;
 import org.apache.sling.models.spi.injectorspecific.StaticInjectAnnotationProcessorFactory;
 import org.jetbrains.annotations.NotNull;
 import org.osgi.framework.Constants;
+import org.osgi.service.component.annotations.Component;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
-@Component
-@Service
-@Property(name = Constants.SERVICE_RANKING, intValue = 2500)
+@Component(property=Constants.SERVICE_RANKING+":Integer=2500", service={Injector.class, StaticInjectAnnotationProcessorFactory.class, AcceptsNullName.class})
 public class ResourcePathInjector extends AbstractInjector implements Injector, AcceptsNullName,
         StaticInjectAnnotationProcessorFactory {
 
diff --git a/src/main/java/org/apache/sling/models/impl/injectors/SelfInjector.java b/src/main/java/org/apache/sling/models/impl/injectors/SelfInjector.java
index c7bde9a..9439d6d 100644
--- a/src/main/java/org/apache/sling/models/impl/injectors/SelfInjector.java
+++ b/src/main/java/org/apache/sling/models/impl/injectors/SelfInjector.java
@@ -19,9 +19,6 @@ package org.apache.sling.models.impl.injectors;
 import java.lang.reflect.AnnotatedElement;
 import java.lang.reflect.Type;
 
-import org.apache.felix.scr.annotations.Component;
-import org.apache.felix.scr.annotations.Property;
-import org.apache.felix.scr.annotations.Service;
 import org.apache.sling.models.annotations.injectorspecific.InjectionStrategy;
 import org.apache.sling.models.annotations.injectorspecific.Self;
 import org.apache.sling.models.impl.model.ConstructorParameter;
@@ -33,13 +30,12 @@ import org.apache.sling.models.spi.injectorspecific.InjectAnnotationProcessor2;
 import org.apache.sling.models.spi.injectorspecific.StaticInjectAnnotationProcessorFactory;
 import org.jetbrains.annotations.NotNull;
 import org.osgi.framework.Constants;
+import org.osgi.service.component.annotations.Component;
 
 /**
  * Injects the adaptable object itself.
  */
-@Component
-@Service
-@Property(name = Constants.SERVICE_RANKING, intValue = Integer.MAX_VALUE)
+@Component(property=Constants.SERVICE_RANKING+":Integer="+Integer.MAX_VALUE, service={Injector.class, StaticInjectAnnotationProcessorFactory.class, AcceptsNullName.class})
 public class SelfInjector implements Injector, StaticInjectAnnotationProcessorFactory, AcceptsNullName {
 
     @Override
diff --git a/src/main/java/org/apache/sling/models/impl/injectors/SlingObjectInjector.java b/src/main/java/org/apache/sling/models/impl/injectors/SlingObjectInjector.java
index a2ab4b8..0f9124d 100644
--- a/src/main/java/org/apache/sling/models/impl/injectors/SlingObjectInjector.java
+++ b/src/main/java/org/apache/sling/models/impl/injectors/SlingObjectInjector.java
@@ -22,9 +22,6 @@ import java.lang.reflect.Type;
 import javax.servlet.http.HttpServletRequest;
 import javax.servlet.http.HttpServletResponse;
 
-import org.apache.felix.scr.annotations.Component;
-import org.apache.felix.scr.annotations.Property;
-import org.apache.felix.scr.annotations.Service;
 import org.apache.sling.api.SlingHttpServletRequest;
 import org.apache.sling.api.SlingHttpServletResponse;
 import org.apache.sling.api.resource.Resource;
@@ -41,15 +38,14 @@ import org.apache.sling.models.spi.injectorspecific.InjectAnnotationProcessor2;
 import org.apache.sling.models.spi.injectorspecific.StaticInjectAnnotationProcessorFactory;
 import org.jetbrains.annotations.NotNull;
 import org.osgi.framework.Constants;
+import org.osgi.service.component.annotations.Component;
 
 /**
  * Injects common Sling objects that can be derived from either a SlingHttpServletRequest, a ResourceResolver or a
  * Resource.
  * Documentation see {@link SlingObject}.
  */
-@Component
-@Service
-@Property(name = Constants.SERVICE_RANKING, intValue = Integer.MAX_VALUE)
+@Component(property=Constants.SERVICE_RANKING+":Integer="+Integer.MAX_VALUE, service={Injector.class, StaticInjectAnnotationProcessorFactory.class, AcceptsNullName.class})
 public final class SlingObjectInjector implements Injector, StaticInjectAnnotationProcessorFactory, AcceptsNullName {
 
     /**
diff --git a/src/main/java/org/apache/sling/models/impl/injectors/ValueMapInjector.java b/src/main/java/org/apache/sling/models/impl/injectors/ValueMapInjector.java
index 6606585..f24b367 100644
--- a/src/main/java/org/apache/sling/models/impl/injectors/ValueMapInjector.java
+++ b/src/main/java/org/apache/sling/models/impl/injectors/ValueMapInjector.java
@@ -27,9 +27,6 @@ import java.util.List;
 import org.apache.commons.lang3.ClassUtils;
 import org.apache.commons.lang3.ObjectUtils;
 import org.apache.commons.lang3.StringUtils;
-import org.apache.felix.scr.annotations.Component;
-import org.apache.felix.scr.annotations.Property;
-import org.apache.felix.scr.annotations.Service;
 import org.apache.sling.api.SlingHttpServletRequest;
 import org.apache.sling.api.resource.ValueMap;
 import org.apache.sling.models.annotations.injectorspecific.InjectionStrategy;
@@ -42,12 +39,11 @@ import org.apache.sling.models.spi.injectorspecific.InjectAnnotationProcessor;
 import org.apache.sling.models.spi.injectorspecific.InjectAnnotationProcessorFactory;
 import org.jetbrains.annotations.NotNull;
 import org.osgi.framework.Constants;
+import org.osgi.service.component.annotations.Component;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
-@Component
-@Service
-@Property(name = Constants.SERVICE_RANKING, intValue = 2000)
+@Component(property=Constants.SERVICE_RANKING+":Integer=2000", service={Injector.class, InjectAnnotationProcessorFactory.class, ValuePreparer.class})
 @SuppressWarnings("deprecation")
 public class ValueMapInjector extends AbstractInjector implements Injector, InjectAnnotationProcessorFactory, ValuePreparer {
 
diff --git a/src/main/java/org/apache/sling/models/impl/model/ModelClass.java b/src/main/java/org/apache/sling/models/impl/model/ModelClass.java
index ece0af8..6c17e47 100644
--- a/src/main/java/org/apache/sling/models/impl/model/ModelClass.java
+++ b/src/main/java/org/apache/sling/models/impl/model/ModelClass.java
@@ -34,7 +34,7 @@ public class ModelClass<ModelType> {
     private final Class<ModelType> type;
     private final Model modelAnnotation;
     final DefaultInjectionStrategy defaultInjectionStrategy;
-    private volatile ModelClassConstructor[] constructors;
+    private volatile ModelClassConstructor<?>[] constructors;
     private volatile InjectableField[] injectableFields;
     private volatile InjectableMethod[] injectableMethods;
 
@@ -60,7 +60,7 @@ public class ModelClass<ModelType> {
     }
     
     @SuppressWarnings("unchecked")
-    private static ModelClassConstructor[] getConstructors(Class<?> type, StaticInjectAnnotationProcessorFactory[] processorFactories, DefaultInjectionStrategy defaultInjectionStrategy) {
+    private static ModelClassConstructor<?>[] getConstructors(Class<?> type, StaticInjectAnnotationProcessorFactory[] processorFactories, DefaultInjectionStrategy defaultInjectionStrategy) {
         if (type.isInterface()) {
             return new ModelClassConstructor[0];
         }
@@ -69,7 +69,7 @@ public class ModelClass<ModelType> {
         // sort the constructor list in order from most params to least params, and constructors with @Inject annotation first
         Arrays.sort(constructors, new ParameterCountInjectComparator());
 
-        ModelClassConstructor[] array = new ModelClassConstructor[constructors.length];
+        ModelClassConstructor<?>[] array = new ModelClassConstructor[constructors.length];
         for (int i=0; i<array.length; i++) {
             array[i] = new ModelClassConstructor(constructors[i], processorFactories, defaultInjectionStrategy);
         }
diff --git a/src/main/java/org/apache/sling/models/impl/via/BeanPropertyViaProvider.java b/src/main/java/org/apache/sling/models/impl/via/BeanPropertyViaProvider.java
index e05b04b..3051fa1 100644
--- a/src/main/java/org/apache/sling/models/impl/via/BeanPropertyViaProvider.java
+++ b/src/main/java/org/apache/sling/models/impl/via/BeanPropertyViaProvider.java
@@ -16,21 +16,19 @@
  */
 package org.apache.sling.models.impl.via;
 
+import java.beans.BeanInfo;
+import java.beans.Introspector;
+import java.beans.PropertyDescriptor;
+
 import org.apache.commons.lang3.StringUtils;
-import org.apache.felix.scr.annotations.Component;
-import org.apache.felix.scr.annotations.Service;
 import org.apache.sling.models.annotations.ViaProviderType;
 import org.apache.sling.models.annotations.via.BeanProperty;
 import org.apache.sling.models.spi.ViaProvider;
+import org.osgi.service.component.annotations.Component;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
-import java.beans.BeanInfo;
-import java.beans.Introspector;
-import java.beans.PropertyDescriptor;
-
-@Component
-@Service
+@Component(service=ViaProvider.class)
 public class BeanPropertyViaProvider implements ViaProvider {
 
     private static final Logger log = LoggerFactory.getLogger(BeanPropertyViaProvider.class);
diff --git a/src/main/java/org/apache/sling/models/impl/via/ChildResourceViaProvider.java b/src/main/java/org/apache/sling/models/impl/via/ChildResourceViaProvider.java
index f80a1a0..6ccc9a4 100644
--- a/src/main/java/org/apache/sling/models/impl/via/ChildResourceViaProvider.java
+++ b/src/main/java/org/apache/sling/models/impl/via/ChildResourceViaProvider.java
@@ -17,19 +17,17 @@
 package org.apache.sling.models.impl.via;
 
 import org.apache.commons.lang3.StringUtils;
-import org.apache.felix.scr.annotations.Component;
-import org.apache.felix.scr.annotations.Service;
 import org.apache.sling.api.SlingHttpServletRequest;
 import org.apache.sling.api.resource.Resource;
 import org.apache.sling.api.wrappers.SlingHttpServletRequestWrapper;
 import org.apache.sling.models.annotations.ViaProviderType;
 import org.apache.sling.models.annotations.via.ChildResource;
 import org.apache.sling.models.spi.ViaProvider;
+import org.osgi.service.component.annotations.Component;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
-@Component
-@Service
+@Component(service=ViaProvider.class)
 public class ChildResourceViaProvider implements ViaProvider {
 
     private static final Logger log = LoggerFactory.getLogger(ChildResourceViaProvider.class);
diff --git a/src/main/java/org/apache/sling/models/impl/via/ForcedResourceTypeViaProvider.java b/src/main/java/org/apache/sling/models/impl/via/ForcedResourceTypeViaProvider.java
index 07b865a..d6c29ec 100644
--- a/src/main/java/org/apache/sling/models/impl/via/ForcedResourceTypeViaProvider.java
+++ b/src/main/java/org/apache/sling/models/impl/via/ForcedResourceTypeViaProvider.java
@@ -17,15 +17,14 @@
 package org.apache.sling.models.impl.via;
 
 import org.apache.commons.lang3.StringUtils;
-import org.apache.felix.scr.annotations.Component;
-import org.apache.felix.scr.annotations.Service;
 import org.apache.sling.api.resource.Resource;
 import org.apache.sling.models.annotations.ViaProviderType;
 import org.apache.sling.models.annotations.via.ForcedResourceType;
+import org.apache.sling.models.spi.ViaProvider;
 import org.jetbrains.annotations.NotNull;
+import org.osgi.service.component.annotations.Component;
 
-@Component
-@Service
+@Component(service=ViaProvider.class)
 public class ForcedResourceTypeViaProvider extends AbstractResourceTypeViaProvider {
     @Override
     public Class<? extends ViaProviderType> getType() {
diff --git a/src/main/java/org/apache/sling/models/impl/via/ResourceSuperTypeViaProvider.java b/src/main/java/org/apache/sling/models/impl/via/ResourceSuperTypeViaProvider.java
index 38481f1..2ed229b 100644
--- a/src/main/java/org/apache/sling/models/impl/via/ResourceSuperTypeViaProvider.java
+++ b/src/main/java/org/apache/sling/models/impl/via/ResourceSuperTypeViaProvider.java
@@ -16,15 +16,14 @@
  */
 package org.apache.sling.models.impl.via;
 
-import org.apache.felix.scr.annotations.Component;
-import org.apache.felix.scr.annotations.Service;
 import org.apache.sling.api.resource.Resource;
 import org.apache.sling.models.annotations.ViaProviderType;
 import org.apache.sling.models.annotations.via.ResourceSuperType;
+import org.apache.sling.models.spi.ViaProvider;
 import org.jetbrains.annotations.NotNull;
+import org.osgi.service.component.annotations.Component;
 
-@Component
-@Service
+@Component(service=ViaProvider.class)
 public class ResourceSuperTypeViaProvider extends AbstractResourceTypeViaProvider {
 
     @Override
diff --git a/src/test/java/org/apache/sling/models/impl/AdapterFactoryTest.java b/src/test/java/org/apache/sling/models/impl/AdapterFactoryTest.java
index aee908e..409c449 100644
--- a/src/test/java/org/apache/sling/models/impl/AdapterFactoryTest.java
+++ b/src/test/java/org/apache/sling/models/impl/AdapterFactoryTest.java
@@ -18,12 +18,14 @@ package org.apache.sling.models.impl;
 
 import static org.mockito.Mockito.mock;
 import static org.mockito.Mockito.when;
+
 import java.lang.reflect.Field;
 import java.lang.reflect.Modifier;
+import java.util.Arrays;
 import java.util.Collections;
 import java.util.HashMap;
-import java.util.Hashtable;
 import java.util.Map;
+
 import org.apache.sling.api.SlingHttpServletRequest;
 import org.apache.sling.api.resource.Resource;
 import org.apache.sling.api.resource.ValueMap;
@@ -50,17 +52,15 @@ import org.junit.Before;
 import org.junit.Test;
 import org.junit.runner.RunWith;
 import org.mockito.Mock;
+import org.mockito.Mockito;
 import org.mockito.runners.MockitoJUnitRunner;
 import org.osgi.framework.BundleContext;
 import org.osgi.service.component.ComponentContext;
+import org.osgi.util.converter.Converter;
+import org.osgi.util.converter.Converters;
 
 @RunWith(MockitoJUnitRunner.class)
 public class AdapterFactoryTest {
-    @Mock
-    private ComponentContext componentCtx;
-
-    @Mock
-    private BundleContext bundleContext;
 
     @Mock
     private Resource resource;
@@ -70,19 +70,31 @@ public class AdapterFactoryTest {
 
     private ModelAdapterFactory factory;
 
-    @Before
-    public void setup() {
+    public static ModelAdapterFactory createModelAdapterFactory() {
+        BundleContext bundleContext = Mockito.mock(BundleContext.class);
+        return createModelAdapterFactory(bundleContext);
+    }
+    
+    public static ModelAdapterFactory createModelAdapterFactory(BundleContext bundleContext) {
+        ComponentContext componentCtx = Mockito.mock(ComponentContext.class);
         when(componentCtx.getBundleContext()).thenReturn(bundleContext);
-        when(componentCtx.getProperties()).thenReturn(new Hashtable<String, Object>());
 
-        factory = new ModelAdapterFactory();
-        factory.activate(componentCtx);
+        ModelAdapterFactory factory = new ModelAdapterFactory();
+        Converter c = Converters.standardConverter();
+        Map<String, String> map = new HashMap<>();
+        ModelAdapterFactoryConfiguration config = c.convert(map).to(ModelAdapterFactoryConfiguration.class);
+        factory.activate(componentCtx, config);
+        factory.injectAnnotationProcessorFactories = Collections.emptyList();
+        factory.injectAnnotationProcessorFactories2 = Collections.emptyList();
+        return factory;
+    }
+
+    @Before
+    public void setup() {
+        factory = createModelAdapterFactory();
         factory.bindInjector(new ValueMapInjector(), new ServicePropertiesMap(0, 0));
         factory.bindInjector(new SelfInjector(), new ServicePropertiesMap(1, 1));
-        factory.bindModelExporter(new FirstStringExporter(), new ServicePropertiesMap(2, 0));
-        factory.bindModelExporter(new SecondStringExporter(), new ServicePropertiesMap(3, 1));
-        factory.bindModelExporter(new FirstIntegerExporter(), new ServicePropertiesMap(4, 2));
-        
+        factory.modelExporters = Arrays.<ModelExporter>asList(new FirstStringExporter(), new SecondStringExporter(), new FirstIntegerExporter());
         factory.adapterImplementations.addClassesAsAdapterAndImplementation(DefaultStringModel.class, ConstructorWithExceptionModel.class, NestedModel.class, NestedModelWithInvalidAdaptable.class, NestedModelWithInvalidAdaptable2.class, ResourceModelWithRequiredField.class, CachedModelWithSelfReference.class) ;
     }
 
diff --git a/src/test/java/org/apache/sling/models/impl/AnnotationConflictsTest.java b/src/test/java/org/apache/sling/models/impl/AnnotationConflictsTest.java
index fef63b1..f4e0a9d 100644
--- a/src/test/java/org/apache/sling/models/impl/AnnotationConflictsTest.java
+++ b/src/test/java/org/apache/sling/models/impl/AnnotationConflictsTest.java
@@ -18,6 +18,14 @@
  */
 package org.apache.sling.models.impl;
 
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertNull;
+import static org.junit.Assert.assertTrue;
+import static org.mockito.Mockito.when;
+
+import java.util.Collections;
+
 import org.apache.sling.api.resource.Resource;
 import org.apache.sling.api.resource.ValueMap;
 import org.apache.sling.api.wrappers.ValueMapDecorator;
@@ -30,29 +38,17 @@ import org.apache.sling.models.annotations.injectorspecific.ValueMapValue;
 import org.apache.sling.models.factory.MissingElementException;
 import org.apache.sling.models.factory.MissingElementsException;
 import org.apache.sling.models.impl.injectors.ValueMapInjector;
+import org.apache.sling.models.spi.injectorspecific.InjectAnnotationProcessorFactory;
 import org.junit.Before;
 import org.junit.Test;
 import org.junit.runner.RunWith;
 import org.mockito.Mock;
 import org.mockito.runners.MockitoJUnitRunner;
-import org.osgi.framework.BundleContext;
-import org.osgi.service.component.ComponentContext;
-
-import java.util.Collections;
-import java.util.Hashtable;
-
-import static org.mockito.Mockito.when;
-import static org.junit.Assert.*;
 
+@SuppressWarnings("deprecation")
 @RunWith(MockitoJUnitRunner.class)
 public class AnnotationConflictsTest {
 
-    @Mock
-    private ComponentContext componentCtx;
-
-    @Mock
-    private BundleContext bundleContext;
-
     private ModelAdapterFactory factory;
 
     @Mock
@@ -60,15 +56,10 @@ public class AnnotationConflictsTest {
 
     @Before
     public void setup() {
-        when(componentCtx.getBundleContext()).thenReturn(bundleContext);
-        when(componentCtx.getProperties()).thenReturn(new Hashtable<String, Object>());
-
-        factory = new ModelAdapterFactory();
-        factory.activate(componentCtx);
+        factory = AdapterFactoryTest.createModelAdapterFactory();
         ValueMapInjector injector = new ValueMapInjector();
-
         factory.bindInjector(injector, new ServicePropertiesMap(1, 1));
-        factory.bindInjectAnnotationProcessorFactory(injector, new ServicePropertiesMap(1, 1));
+        factory.injectAnnotationProcessorFactories = Collections.<InjectAnnotationProcessorFactory>singletonList(new ValueMapInjector());
 
         for (Class<?> clazz : this.getClass().getDeclaredClasses()) {
             if (!clazz.isInterface()) {
diff --git a/src/test/java/org/apache/sling/models/impl/CachingTest.java b/src/test/java/org/apache/sling/models/impl/CachingTest.java
index d9e4782..f8d9d4a 100644
--- a/src/test/java/org/apache/sling/models/impl/CachingTest.java
+++ b/src/test/java/org/apache/sling/models/impl/CachingTest.java
@@ -18,7 +18,9 @@ package org.apache.sling.models.impl;
 
 import static org.junit.Assert.assertEquals;
 import static org.junit.Assert.assertTrue;
-import static org.mockito.Mockito.*;
+import static org.mockito.Mockito.times;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
 
 import org.apache.sling.api.SlingHttpServletRequest;
 import org.apache.sling.models.impl.injectors.RequestAttributeInjector;
@@ -29,10 +31,6 @@ import org.junit.Test;
 import org.junit.runner.RunWith;
 import org.mockito.Mock;
 import org.mockito.runners.MockitoJUnitRunner;
-import org.osgi.framework.BundleContext;
-import org.osgi.service.component.ComponentContext;
-
-import java.util.Hashtable;
 
 @RunWith(MockitoJUnitRunner.class)
 public class CachingTest {
@@ -40,21 +38,11 @@ public class CachingTest {
     @Mock
     private SlingHttpServletRequest request;
 
-    @Mock
-    private ComponentContext componentCtx;
-
-    @Mock
-    private BundleContext bundleContext;
-
     private ModelAdapterFactory factory;
 
     @Before
     public void setup() {
-        when(componentCtx.getBundleContext()).thenReturn(bundleContext);
-        when(componentCtx.getProperties()).thenReturn(new Hashtable<String, Object>());
-
-        factory = new ModelAdapterFactory();
-        factory.activate(componentCtx);
+        factory = AdapterFactoryTest.createModelAdapterFactory();
         factory.bindInjector(new RequestAttributeInjector(), new ServicePropertiesMap(0, 0));
         factory.adapterImplementations.addClassesAsAdapterAndImplementation(CachedModel.class, UncachedModel.class,
                 org.apache.sling.models.testmodels.interfaces.CachedModel.class, org.apache.sling.models.testmodels.interfaces.UncachedModel.class);
diff --git a/src/test/java/org/apache/sling/models/impl/ConstructorTest.java b/src/test/java/org/apache/sling/models/impl/ConstructorTest.java
index 1d28125..ec62954 100644
--- a/src/test/java/org/apache/sling/models/impl/ConstructorTest.java
+++ b/src/test/java/org/apache/sling/models/impl/ConstructorTest.java
@@ -20,7 +20,6 @@ import static org.junit.Assert.*;
 import static org.mockito.Mockito.*;
 
 import java.util.ArrayList;
-import java.util.Hashtable;
 import java.util.List;
 import java.util.concurrent.Callable;
 import java.util.concurrent.ExecutionException;
@@ -49,18 +48,10 @@ import org.junit.Test;
 import org.junit.runner.RunWith;
 import org.mockito.Mock;
 import org.mockito.runners.MockitoJUnitRunner;
-import org.osgi.framework.BundleContext;
-import org.osgi.service.component.ComponentContext;
 
 @RunWith(MockitoJUnitRunner.class)
 public class ConstructorTest {
 
-    @Mock
-    private ComponentContext componentCtx;
-
-    @Mock
-    private BundleContext bundleContext;
-
     private ModelAdapterFactory factory;
 
     @Mock
@@ -72,14 +63,11 @@ public class ConstructorTest {
 
     @Before
     public void setup() {
-        when(componentCtx.getBundleContext()).thenReturn(bundleContext);
-        when(componentCtx.getProperties()).thenReturn(new Hashtable<String, Object>());
-
+        
         when(request.getAttribute("attribute")).thenReturn(INT_VALUE);
         when(request.getAttribute("attribute2")).thenReturn(STRING_VALUE);
 
-        factory = new ModelAdapterFactory();
-        factory.activate(componentCtx);
+        factory = AdapterFactoryTest.createModelAdapterFactory();
         factory.bindInjector(new RequestAttributeInjector(), new ServicePropertiesMap(1, 1));
         factory.bindInjector(new SelfInjector(), new ServicePropertiesMap(2, 2));
         factory.bindViaProvider(new BeanPropertyViaProvider(), null);
diff --git a/src/test/java/org/apache/sling/models/impl/CustomInjectorTest.java b/src/test/java/org/apache/sling/models/impl/CustomInjectorTest.java
index 5ea8d06..d737674 100644
--- a/src/test/java/org/apache/sling/models/impl/CustomInjectorTest.java
+++ b/src/test/java/org/apache/sling/models/impl/CustomInjectorTest.java
@@ -16,10 +16,10 @@
  */
 package org.apache.sling.models.impl;
 
-import static org.junit.Assert.*;
-import static org.mockito.Mockito.*;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
 
-import java.util.Hashtable;
+import java.util.Collections;
 
 import javax.inject.Inject;
 
@@ -27,32 +27,21 @@ import org.apache.sling.models.annotations.Model;
 import org.apache.sling.models.impl.injector.CustomAnnotation;
 import org.apache.sling.models.impl.injector.CustomAnnotationInjector;
 import org.apache.sling.models.impl.injector.SimpleInjector;
+import org.apache.sling.models.spi.injectorspecific.InjectAnnotationProcessorFactory;
 import org.junit.Before;
 import org.junit.Test;
 import org.junit.runner.RunWith;
-import org.mockito.Mock;
 import org.mockito.runners.MockitoJUnitRunner;
-import org.osgi.framework.BundleContext;
-import org.osgi.service.component.ComponentContext;
 
+@SuppressWarnings("deprecation")
 @RunWith(MockitoJUnitRunner.class)
 public class CustomInjectorTest {
 
-    @Mock
-    private ComponentContext componentCtx;
-
-    @Mock
-    private BundleContext bundleContext;
-
     private ModelAdapterFactory factory;
 
     @Before
     public void setup() {
-        when(componentCtx.getBundleContext()).thenReturn(bundleContext);
-        when(componentCtx.getProperties()).thenReturn(new Hashtable<String, Object>());
-
-        factory = new ModelAdapterFactory();
-        factory.activate(componentCtx);
+        factory = AdapterFactoryTest.createModelAdapterFactory();
         factory.adapterImplementations.addClassesAsAdapterAndImplementation(TestModel.class, CustomAnnotationModel.class);
     }
 
@@ -71,7 +60,7 @@ public class CustomInjectorTest {
 
         factory.bindInjector(new SimpleInjector(), new ServicePropertiesMap(1, 1));
         factory.bindInjector(injector, new ServicePropertiesMap(1, 1));
-        factory.bindInjectAnnotationProcessorFactory(injector, new ServicePropertiesMap(1, 1));
+        factory.injectAnnotationProcessorFactories = factory.injectAnnotationProcessorFactories = Collections.<InjectAnnotationProcessorFactory>singletonList(injector);
 
         CustomAnnotationModel model = factory.getAdapter(new Object(), CustomAnnotationModel.class);
         assertNotNull(model);
diff --git a/src/test/java/org/apache/sling/models/impl/DefaultTest.java b/src/test/java/org/apache/sling/models/impl/DefaultTest.java
index dc3abf5..57e130d 100644
--- a/src/test/java/org/apache/sling/models/impl/DefaultTest.java
+++ b/src/test/java/org/apache/sling/models/impl/DefaultTest.java
@@ -25,7 +25,6 @@ import static org.mockito.Mockito.when;
 
 import java.util.Arrays;
 import java.util.Collections;
-import java.util.Hashtable;
 
 import org.apache.sling.api.resource.Resource;
 import org.apache.sling.api.resource.ValueMap;
@@ -38,29 +37,16 @@ import org.apache.sling.models.testmodels.interfaces.PropertyModelWithDefaults;
 import org.junit.Before;
 import org.junit.Test;
 import org.junit.runner.RunWith;
-import org.mockito.Mock;
 import org.mockito.runners.MockitoJUnitRunner;
-import org.osgi.framework.BundleContext;
-import org.osgi.service.component.ComponentContext;
 
 @RunWith(MockitoJUnitRunner.class)
 public class DefaultTest {
 
-    @Mock
-    private ComponentContext componentCtx;
-
-    @Mock
-    private BundleContext bundleContext;
-
     private ModelAdapterFactory factory;
 
     @Before
     public void setup() {
-        when(componentCtx.getBundleContext()).thenReturn(bundleContext);
-        when(componentCtx.getProperties()).thenReturn(new Hashtable<String, Object>());
-
-        factory = new ModelAdapterFactory();
-        factory.activate(componentCtx);
+        factory = AdapterFactoryTest.createModelAdapterFactory();
         factory.bindInjector(new ValueMapInjector(), new ServicePropertiesMap(0, 0));
         factory.adapterImplementations.addClassesAsAdapterAndImplementation(DefaultStringModel.class, PropertyModelWithDefaults.class, DefaultPrimitivesModel.class, DefaultWrappersModel.class,  org.apache.sling.models.testmodels.classes.constructorinjection.DefaultPrimitivesModel.class, org.apache.sling.models.testmodels.classes.constructorinjection.DefaultStringModel.class, org.apache.sling.models.testmodels.classes.constructorinjection.DefaultWrappersModel.class);
     }
diff --git a/src/test/java/org/apache/sling/models/impl/ExtraDefaultTests.java b/src/test/java/org/apache/sling/models/impl/ExtraDefaultTests.java
index eff1d51..b55520c 100644
--- a/src/test/java/org/apache/sling/models/impl/ExtraDefaultTests.java
+++ b/src/test/java/org/apache/sling/models/impl/ExtraDefaultTests.java
@@ -16,10 +16,8 @@
  */
 package org.apache.sling.models.impl;
 
-import static org.mockito.Mockito.*;
-import static org.junit.Assert.*;
-
-import java.util.Hashtable;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
 
 import javax.inject.Inject;
 
@@ -31,30 +29,18 @@ import org.junit.Test;
 import org.junit.runner.RunWith;
 import org.mockito.Mock;
 import org.mockito.runners.MockitoJUnitRunner;
-import org.osgi.framework.BundleContext;
-import org.osgi.service.component.ComponentContext;
 
 @RunWith(MockitoJUnitRunner.class)
 public class ExtraDefaultTests {
 
     @Mock
-    private ComponentContext componentCtx;
-
-    @Mock
-    private BundleContext bundleContext;
-
-    @Mock
     private Resource resource;
 
     private ModelAdapterFactory factory;
 
     @Before
     public void setup() {
-        when(componentCtx.getBundleContext()).thenReturn(bundleContext);
-        when(componentCtx.getProperties()).thenReturn(new Hashtable<String, Object>());
-
-        factory = new ModelAdapterFactory();
-        factory.activate(componentCtx);
+        factory = AdapterFactoryTest.createModelAdapterFactory();
         factory.adapterImplementations.addClassesAsAdapterAndImplementation(EmptyDefaultsModel.class, WrongTypeDefaultsModel.class);
     }
 
diff --git a/src/test/java/org/apache/sling/models/impl/ImplementsExtendsTest.java b/src/test/java/org/apache/sling/models/impl/ImplementsExtendsTest.java
index 014282c..1cd6cd9 100644
--- a/src/test/java/org/apache/sling/models/impl/ImplementsExtendsTest.java
+++ b/src/test/java/org/apache/sling/models/impl/ImplementsExtendsTest.java
@@ -34,6 +34,7 @@ import java.util.Hashtable;
 import java.util.Map;
 import java.util.Vector;
 
+import org.apache.sling.api.adapter.AdapterFactory;
 import org.apache.sling.api.resource.Resource;
 import org.apache.sling.api.resource.ValueMap;
 import org.apache.sling.api.wrappers.ValueMapDecorator;
@@ -62,15 +63,11 @@ import org.osgi.framework.BundleContext;
 import org.osgi.framework.BundleEvent;
 import org.osgi.framework.ServiceReference;
 import org.osgi.framework.ServiceRegistration;
-import org.osgi.service.component.ComponentContext;
 
 @RunWith(MockitoJUnitRunner.class)
 public class ImplementsExtendsTest {
 
     @Mock
-    private ComponentContext componentCtx;
-
-    @Mock
     private BundleContext bundleContext;
 
     @Mock
@@ -81,7 +78,7 @@ public class ImplementsExtendsTest {
 
     private ModelAdapterFactory factory;
 
-    private ServiceRegistration[] registeredAdapterFactories;
+    private ServiceRegistration<AdapterFactory>[] registeredAdapterFactories;
 
     private ImplementationPicker firstImplementationPicker = new FirstImplementationPicker();
 
@@ -90,11 +87,9 @@ public class ImplementsExtendsTest {
     @SuppressWarnings("unchecked")
     @Before
     public void setup() throws ClassNotFoundException, MalformedURLException {
-        when(componentCtx.getBundleContext()).thenReturn(bundleContext);
-        when(componentCtx.getProperties()).thenReturn(new Hashtable<String, Object>());
         when(bundleContext.registerService(anyString(), anyObject(), any(Dictionary.class))).then(new Answer<ServiceRegistration>() {
             @Override
-            public ServiceRegistration answer(InvocationOnMock invocation) throws Throwable {
+            public ServiceRegistration<?> answer(InvocationOnMock invocation) throws Throwable {
                 final Dictionary<String, Object> props = (Dictionary<String, Object>)invocation.getArguments()[2];
                 ServiceRegistration reg = mock(ServiceRegistration.class);
                 ServiceReference ref = mock(ServiceReference.class);
@@ -110,8 +105,7 @@ public class ImplementsExtendsTest {
             }
         });
 
-        factory = new ModelAdapterFactory();
-        factory.activate(componentCtx);
+        factory = AdapterFactoryTest.createModelAdapterFactory(bundleContext);
         factory.bindInjector(new ValueMapInjector(), new ServicePropertiesMap(2, 2));
         factory.bindImplementationPicker(firstImplementationPicker, firstImplementationPickerProps);
 
diff --git a/src/test/java/org/apache/sling/models/impl/InjectorSpecificAnnotationTest.java b/src/test/java/org/apache/sling/models/impl/InjectorSpecificAnnotationTest.java
index 63445e0..29e7335 100644
--- a/src/test/java/org/apache/sling/models/impl/InjectorSpecificAnnotationTest.java
+++ b/src/test/java/org/apache/sling/models/impl/InjectorSpecificAnnotationTest.java
@@ -16,12 +16,13 @@
  */
 package org.apache.sling.models.impl;
 
-import static org.junit.Assert.*;
-import static org.mockito.Mockito.*;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.when;
 
 import java.util.Collections;
 import java.util.HashMap;
-import java.util.Hashtable;
 import java.util.Map;
 
 import org.apache.sling.api.SlingHttpServletRequest;
@@ -36,6 +37,8 @@ import org.apache.sling.models.impl.injectors.OSGiServiceInjector;
 import org.apache.sling.models.impl.injectors.RequestAttributeInjector;
 import org.apache.sling.models.impl.injectors.ValueMapInjector;
 import org.apache.sling.models.impl.via.BeanPropertyViaProvider;
+import org.apache.sling.models.spi.injectorspecific.InjectAnnotationProcessorFactory;
+import org.apache.sling.models.spi.injectorspecific.InjectAnnotationProcessorFactory2;
 import org.apache.sling.models.testmodels.classes.InjectorSpecificAnnotationModel;
 import org.junit.Before;
 import org.junit.Test;
@@ -47,7 +50,6 @@ import org.osgi.framework.BundleContext;
 import org.osgi.framework.Constants;
 import org.osgi.framework.InvalidSyntaxException;
 import org.osgi.framework.ServiceReference;
-import org.osgi.service.component.ComponentContext;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
@@ -55,9 +57,6 @@ import org.slf4j.LoggerFactory;
 public class InjectorSpecificAnnotationTest {
 
     @Mock
-    private ComponentContext componentCtx;
-
-    @Mock
     private BundleContext bundleContext;
 
     @Mock
@@ -72,14 +71,10 @@ public class InjectorSpecificAnnotationTest {
 
     @Before
     public void setup() {
-        when(componentCtx.getBundleContext()).thenReturn(bundleContext);
-        when(componentCtx.getProperties()).thenReturn(new Hashtable<String, Object>());
-
-        factory = new ModelAdapterFactory();
-        factory.activate(componentCtx);
+        factory = AdapterFactoryTest.createModelAdapterFactory();
 
         osgiInjector = new OSGiServiceInjector();
-        osgiInjector.activate(componentCtx);
+        osgiInjector.activate(bundleContext);
 
         BindingsInjector bindingsInjector = new BindingsInjector();
         ValueMapInjector valueMapInjector = new ValueMapInjector();
@@ -98,10 +93,8 @@ public class InjectorSpecificAnnotationTest {
 
         factory.bindStaticInjectAnnotationProcessorFactory(bindingsInjector,
                 Collections.<String, Object> singletonMap(Constants.SERVICE_ID, 1L));
-        factory.bindInjectAnnotationProcessorFactory(valueMapInjector,
-                Collections.<String, Object> singletonMap(Constants.SERVICE_ID, 2L));
-        factory.bindInjectAnnotationProcessorFactory2(childResourceInjector,
-                Collections.<String, Object> singletonMap(Constants.SERVICE_ID, 3L));
+        factory.injectAnnotationProcessorFactories = Collections.<InjectAnnotationProcessorFactory>singletonList(valueMapInjector);
+        factory.injectAnnotationProcessorFactories2 = Collections.<InjectAnnotationProcessorFactory2>singletonList(childResourceInjector);
         factory.bindStaticInjectAnnotationProcessorFactory(requestAttributeInjector,
                 Collections.<String, Object> singletonMap(Constants.SERVICE_ID, 4L));
         factory.bindStaticInjectAnnotationProcessorFactory(osgiInjector,
diff --git a/src/test/java/org/apache/sling/models/impl/InterfaceInheritanceTest.java b/src/test/java/org/apache/sling/models/impl/InterfaceInheritanceTest.java
index 5ff64e8..e9b97c7 100644
--- a/src/test/java/org/apache/sling/models/impl/InterfaceInheritanceTest.java
+++ b/src/test/java/org/apache/sling/models/impl/InterfaceInheritanceTest.java
@@ -23,47 +23,33 @@ import static org.mockito.Mockito.when;
 
 import java.util.Collections;
 import java.util.HashMap;
-import java.util.Hashtable;
 import java.util.Map;
 
 import org.apache.sling.api.resource.Resource;
 import org.apache.sling.api.resource.ValueMap;
 import org.apache.sling.api.wrappers.ValueMapDecorator;
 import org.apache.sling.models.impl.injectors.ValueMapInjector;
+import org.apache.sling.models.spi.injectorspecific.InjectAnnotationProcessorFactory;
 import org.apache.sling.models.testmodels.interfaces.SubClassModel;
 import org.apache.sling.models.testmodels.interfaces.SuperClassModel;
 import org.junit.Before;
 import org.junit.Test;
 import org.junit.runner.RunWith;
-import org.mockito.Mock;
 import org.mockito.runners.MockitoJUnitRunner;
-import org.osgi.framework.BundleContext;
-import org.osgi.framework.Constants;
-import org.osgi.service.component.ComponentContext;
 
+@SuppressWarnings("deprecation")
 @RunWith(MockitoJUnitRunner.class)
 public class InterfaceInheritanceTest {
-
-    @Mock
-    private ComponentContext componentCtx;
-
-    @Mock
-    private BundleContext bundleContext;
-
     private ModelAdapterFactory factory;
 
     @Before
     public void setup() {
-        when(componentCtx.getBundleContext()).thenReturn(bundleContext);
-        when(componentCtx.getProperties()).thenReturn(new Hashtable<String, Object>());
 
-        factory = new ModelAdapterFactory();
-        factory.activate(componentCtx);
+        factory = AdapterFactoryTest.createModelAdapterFactory();
         ValueMapInjector valueMapInjector = new ValueMapInjector();
         factory.bindInjector(valueMapInjector, new ServicePropertiesMap(1, 2));
 
-        factory.bindInjectAnnotationProcessorFactory(valueMapInjector,
-                Collections.<String, Object> singletonMap(Constants.SERVICE_ID, 2L));
+        factory.injectAnnotationProcessorFactories = Collections.<InjectAnnotationProcessorFactory>singletonList(valueMapInjector);
         factory.adapterImplementations.addClassesAsAdapterAndImplementation(SuperClassModel.class, SubClassModel.class);
     }
 
diff --git a/src/test/java/org/apache/sling/models/impl/InvalidAdaptationsTest.java b/src/test/java/org/apache/sling/models/impl/InvalidAdaptationsTest.java
index 8cc9c41..50b9fe7 100644
--- a/src/test/java/org/apache/sling/models/impl/InvalidAdaptationsTest.java
+++ b/src/test/java/org/apache/sling/models/impl/InvalidAdaptationsTest.java
@@ -16,11 +16,11 @@
  */
 package org.apache.sling.models.impl;
 
-import static org.junit.Assert.*;
-import static org.mockito.Mockito.*;
+import static org.junit.Assert.assertNull;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.when;
 
 import java.util.Collections;
-import java.util.Hashtable;
 import java.util.Map;
 
 import org.apache.sling.api.SlingHttpServletRequest;
@@ -35,29 +35,15 @@ import org.apache.sling.models.impl.injectors.ValueMapInjector;
 import org.junit.Before;
 import org.junit.Test;
 import org.junit.runner.RunWith;
-import org.mockito.Mock;
 import org.mockito.runners.MockitoJUnitRunner;
-import org.osgi.framework.BundleContext;
-import org.osgi.service.component.ComponentContext;
 
 @RunWith(MockitoJUnitRunner.class)
 public class InvalidAdaptationsTest {
-
-    @Mock
-    private ComponentContext componentCtx;
-
-    @Mock
-    private BundleContext bundleContext;
-
     private ModelAdapterFactory factory;
 
     @Before
     public void setup() {
-        when(componentCtx.getBundleContext()).thenReturn(bundleContext);
-        when(componentCtx.getProperties()).thenReturn(new Hashtable<String, Object>());
-
-        factory = new ModelAdapterFactory();
-        factory.activate(componentCtx);
+        factory = AdapterFactoryTest.createModelAdapterFactory();
         factory.bindInjector(new ValueMapInjector(), new ServicePropertiesMap(1, 1));
         factory.bindInjector(new ChildResourceInjector(), new ServicePropertiesMap(2, 0));
         factory.adapterImplementations.addClassesAsAdapterAndImplementation(NonModel.class, RequestModel.class);
diff --git a/src/test/java/org/apache/sling/models/impl/MultipleInjectorTest.java b/src/test/java/org/apache/sling/models/impl/MultipleInjectorTest.java
index 9e1b57b..6b70827 100644
--- a/src/test/java/org/apache/sling/models/impl/MultipleInjectorTest.java
+++ b/src/test/java/org/apache/sling/models/impl/MultipleInjectorTest.java
@@ -21,8 +21,6 @@ import static org.junit.Assert.assertNotNull;
 import static org.junit.Assert.assertNull;
 import static org.mockito.Mockito.when;
 
-import java.util.Hashtable;
-
 import javax.inject.Inject;
 
 import org.apache.sling.api.SlingHttpServletRequest;
@@ -38,8 +36,6 @@ import org.junit.runner.RunWith;
 import org.mockito.Mock;
 import org.mockito.Spy;
 import org.mockito.runners.MockitoJUnitRunner;
-import org.osgi.framework.BundleContext;
-import org.osgi.service.component.ComponentContext;
 
 @RunWith(MockitoJUnitRunner.class)
 public class MultipleInjectorTest {
@@ -53,25 +49,15 @@ public class MultipleInjectorTest {
     @Mock
     private SlingHttpServletRequest request;
 
-    @Mock
-    private ComponentContext componentCtx;
-
-    @Mock
-    private BundleContext bundleContext;
-
     private ModelAdapterFactory factory;
 
     private SlingBindings bindings;
 
     @Before
     public void setup() {
-        when(componentCtx.getBundleContext()).thenReturn(bundleContext);
-        when(componentCtx.getProperties()).thenReturn(new Hashtable<String, Object>());
-
         bindings = new SlingBindings();
 
-        factory = new ModelAdapterFactory();
-        factory.activate(componentCtx);
+        factory = AdapterFactoryTest.createModelAdapterFactory();
         // binding injector should be asked first as it has a lower service ranking!
         factory.bindInjector(bindingsInjector, new ServicePropertiesMap(1, 1));
         factory.bindInjector(attributesInjector, new ServicePropertiesMap(2, 2));
diff --git a/src/test/java/org/apache/sling/models/impl/OSGiInjectionTest.java b/src/test/java/org/apache/sling/models/impl/OSGiInjectionTest.java
index ec04a57..2b8149e 100644
--- a/src/test/java/org/apache/sling/models/impl/OSGiInjectionTest.java
+++ b/src/test/java/org/apache/sling/models/impl/OSGiInjectionTest.java
@@ -29,7 +29,6 @@ import static org.mockito.Mockito.when;
 
 import java.util.Arrays;
 import java.util.Dictionary;
-import java.util.Hashtable;
 
 import org.apache.sling.api.resource.Resource;
 import org.apache.sling.api.scripting.SlingBindings;
@@ -53,18 +52,12 @@ import org.mockito.runners.MockitoJUnitRunner;
 import org.osgi.framework.BundleContext;
 import org.osgi.framework.BundleListener;
 import org.osgi.framework.ServiceReference;
-import org.osgi.service.component.ComponentContext;
-
-import javax.servlet.ServletRequestListener;
 
 @RunWith(MockitoJUnitRunner.class)
 public class OSGiInjectionTest {
     private ModelAdapterFactory factory;
 
     @Mock
-    private ComponentContext componentCtx;
-
-    @Mock
     private BundleContext bundleContext;
 
     @Mock
@@ -74,14 +67,10 @@ public class OSGiInjectionTest {
 
     @Before
     public void setup() {
-        when(componentCtx.getBundleContext()).thenReturn(bundleContext);
-        when(componentCtx.getProperties()).thenReturn(new Hashtable<String, Object>());
-
-        factory = new ModelAdapterFactory();
-        factory.activate(componentCtx);
+        factory = AdapterFactoryTest.createModelAdapterFactory(bundleContext);
 
         OSGiServiceInjector injectorFactory = new OSGiServiceInjector();
-        injectorFactory.activate(componentCtx);
+        injectorFactory.activate(bundleContext);
         factory.bindInjector(injectorFactory, new ServicePropertiesMap(1, 1));
 
         bindings.setSling(helper);
diff --git a/src/test/java/org/apache/sling/models/impl/OptionalPrimitivesTest.java b/src/test/java/org/apache/sling/models/impl/OptionalPrimitivesTest.java
index ab184b7..3c98943 100644
--- a/src/test/java/org/apache/sling/models/impl/OptionalPrimitivesTest.java
+++ b/src/test/java/org/apache/sling/models/impl/OptionalPrimitivesTest.java
@@ -22,8 +22,6 @@ import static org.junit.Assert.assertNull;
 import static org.mockito.Mockito.mock;
 import static org.mockito.Mockito.when;
 
-import java.util.Hashtable;
-
 import org.apache.sling.api.resource.Resource;
 import org.apache.sling.api.resource.ValueMap;
 import org.apache.sling.models.impl.injectors.ChildResourceInjector;
@@ -31,10 +29,7 @@ import org.apache.sling.models.impl.injectors.ValueMapInjector;
 import org.junit.Before;
 import org.junit.Test;
 import org.junit.runner.RunWith;
-import org.mockito.Mock;
 import org.mockito.runners.MockitoJUnitRunner;
-import org.osgi.framework.BundleContext;
-import org.osgi.service.component.ComponentContext;
 
 /**
  * Validates that @Optional annotations works with primitive values which do not support null
@@ -42,21 +37,11 @@ import org.osgi.service.component.ComponentContext;
 @RunWith(MockitoJUnitRunner.class)
 public class OptionalPrimitivesTest {
 
-    @Mock
-    private ComponentContext componentCtx;
-
-    @Mock
-    private BundleContext bundleContext;
-
     private ModelAdapterFactory factory;
 
     @Before
     public void setup() {
-        when(componentCtx.getBundleContext()).thenReturn(bundleContext);
-        when(componentCtx.getProperties()).thenReturn(new Hashtable<String, Object>());
-
-        factory = new ModelAdapterFactory();
-        factory.activate(componentCtx);
+        factory = AdapterFactoryTest.createModelAdapterFactory();
         factory.bindInjector(new ValueMapInjector(), new ServicePropertiesMap(2, 2));
         factory.bindInjector(new ChildResourceInjector(), new ServicePropertiesMap(1, 1));
         factory.adapterImplementations.addClassesAsAdapterAndImplementation(org.apache.sling.models.testmodels.classes.OptionalPrimitivesModel.class, org.apache.sling.models.testmodels.interfaces.OptionalPrimitivesModel.class, org.apache.sling.models.testmodels.classes.constructorinjection.OptionalPrimitivesModel.class);
diff --git a/src/test/java/org/apache/sling/models/impl/ParameterizedTypeFromRequestAttributeTest.java b/src/test/java/org/apache/sling/models/impl/ParameterizedTypeFromRequestAttributeTest.java
index c35a712..5396a64 100644
--- a/src/test/java/org/apache/sling/models/impl/ParameterizedTypeFromRequestAttributeTest.java
+++ b/src/test/java/org/apache/sling/models/impl/ParameterizedTypeFromRequestAttributeTest.java
@@ -18,11 +18,11 @@
  */
 package org.apache.sling.models.impl;
 
-import static org.junit.Assert.*;
-import static org.mockito.Mockito.*;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
+import static org.mockito.Mockito.when;
 
 import java.util.Collections;
-import java.util.Hashtable;
 import java.util.Iterator;
 
 import javax.inject.Inject;
@@ -36,29 +36,17 @@ import org.junit.Test;
 import org.junit.runner.RunWith;
 import org.mockito.Mock;
 import org.mockito.runners.MockitoJUnitRunner;
-import org.osgi.framework.BundleContext;
-import org.osgi.service.component.ComponentContext;
 
 @RunWith(MockitoJUnitRunner.class)
 public class ParameterizedTypeFromRequestAttributeTest {
     private ModelAdapterFactory factory;
 
     @Mock
-    private ComponentContext componentCtx;
-
-    @Mock
-    private BundleContext bundleContext;
-
-    @Mock
     private SlingHttpServletRequest request;
 
     @Before
     public void setup() {
-        when(componentCtx.getBundleContext()).thenReturn(bundleContext);
-        when(componentCtx.getProperties()).thenReturn(new Hashtable<String, Object>());
-
-        factory = new ModelAdapterFactory();
-        factory.activate(componentCtx);
+        factory = AdapterFactoryTest.createModelAdapterFactory();
 
         RequestAttributeInjector injector = new RequestAttributeInjector();
         factory.bindInjector(injector, new ServicePropertiesMap(1, 1));
diff --git a/src/test/java/org/apache/sling/models/impl/PostConstructTest.java b/src/test/java/org/apache/sling/models/impl/PostConstructTest.java
index 8b476f2..5fb8045 100644
--- a/src/test/java/org/apache/sling/models/impl/PostConstructTest.java
+++ b/src/test/java/org/apache/sling/models/impl/PostConstructTest.java
@@ -17,12 +17,9 @@
 package org.apache.sling.models.impl;
 
 import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertNull;
 import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertNull;
 import static org.junit.Assert.assertTrue;
-import static org.mockito.Mockito.when;
-
-import java.util.Hashtable;
 
 import org.apache.sling.api.resource.Resource;
 import org.apache.sling.models.factory.PostConstructException;
@@ -36,28 +33,18 @@ import org.junit.Test;
 import org.junit.runner.RunWith;
 import org.mockito.Mock;
 import org.mockito.runners.MockitoJUnitRunner;
-import org.osgi.framework.BundleContext;
-import org.osgi.service.component.ComponentContext;
 
 @RunWith(MockitoJUnitRunner.class)
 public class PostConstructTest {
 
     @Mock
-    private ComponentContext componentCtx;
-
-    @Mock
-    private BundleContext bundleContext;
-
-    @Mock
     private Resource resource;
 
-    ModelAdapterFactory factory = new ModelAdapterFactory();
+    private ModelAdapterFactory factory;
 
     @Before
     public void setup() {
-        when(componentCtx.getBundleContext()).thenReturn(bundleContext);
-        when(componentCtx.getProperties()).thenReturn(new Hashtable<String, Object>());
-        factory.activate(componentCtx);
+        factory = AdapterFactoryTest.createModelAdapterFactory();
         // no injectors are necessary
         factory.adapterImplementations.addClassesAsAdapterAndImplementation(SubClass.class, SubClassOverriddenPostConstruct.class, FailingPostConstuctModel.class, FalsePostConstuctModel.class, TruePostConstuctModel.class);
     }
diff --git a/src/test/java/org/apache/sling/models/impl/RequestDisposalTest.java b/src/test/java/org/apache/sling/models/impl/RequestDisposalTest.java
index 753b644..6967c6d 100644
--- a/src/test/java/org/apache/sling/models/impl/RequestDisposalTest.java
+++ b/src/test/java/org/apache/sling/models/impl/RequestDisposalTest.java
@@ -32,8 +32,6 @@ import org.mockito.Mock;
 import org.mockito.invocation.InvocationOnMock;
 import org.mockito.runners.MockitoJUnitRunner;
 import org.mockito.stubbing.Answer;
-import org.osgi.framework.BundleContext;
-import org.osgi.service.component.ComponentContext;
 
 import javax.annotation.Nonnull;
 import javax.inject.Inject;
@@ -43,7 +41,6 @@ import java.lang.reflect.AnnotatedElement;
 import java.lang.reflect.Type;
 import java.util.HashMap;
 import java.util.HashSet;
-import java.util.Hashtable;
 import java.util.Map;
 import java.util.Set;
 
@@ -53,12 +50,6 @@ import static org.junit.Assert.*;
 @RunWith(MockitoJUnitRunner.class)
 public class RequestDisposalTest {
     @Mock
-    private ComponentContext componentCtx;
-
-    @Mock
-    private BundleContext bundleContext;
-
-    @Mock
     private Resource resource;
 
     @Mock
@@ -73,11 +64,7 @@ public class RequestDisposalTest {
 
     @Before
     public void setup() {
-        when(componentCtx.getBundleContext()).thenReturn(bundleContext);
-        when(componentCtx.getProperties()).thenReturn(new Hashtable<String, Object>());
-
-        factory = new ModelAdapterFactory();
-        factory.activate(componentCtx);
+        factory = AdapterFactoryTest.createModelAdapterFactory();
         factory.bindInjector(new DisposedInjector(), new ServicePropertiesMap(0, 0));
         factory.adapterImplementations.addClassesAsAdapterAndImplementation(TestModel.class);
 
diff --git a/src/test/java/org/apache/sling/models/impl/RequestInjectionTest.java b/src/test/java/org/apache/sling/models/impl/RequestInjectionTest.java
index 0fae27d..3b06844 100644
--- a/src/test/java/org/apache/sling/models/impl/RequestInjectionTest.java
+++ b/src/test/java/org/apache/sling/models/impl/RequestInjectionTest.java
@@ -22,8 +22,6 @@ import static org.mockito.Mockito.when;
 import static org.mockito.Mockito.verify;
 import static org.mockito.Mockito.times;
 
-import java.util.Hashtable;
-
 import org.apache.sling.api.SlingHttpServletRequest;
 import org.apache.sling.api.scripting.SlingBindings;
 import org.apache.sling.api.scripting.SlingScriptHelper;
@@ -34,19 +32,11 @@ import org.junit.Test;
 import org.junit.runner.RunWith;
 import org.mockito.Mock;
 import org.mockito.runners.MockitoJUnitRunner;
-import org.osgi.framework.BundleContext;
-import org.osgi.service.component.ComponentContext;
 import org.slf4j.LoggerFactory;
 
 @RunWith(MockitoJUnitRunner.class)
 public class RequestInjectionTest {
 
-    @Mock
-    private ComponentContext componentCtx;
-
-    @Mock
-    private BundleContext bundleContext;
-
     private ModelAdapterFactory factory;
 
     @Mock
@@ -57,18 +47,13 @@ public class RequestInjectionTest {
 
     @Before
     public void setup() {
-        when(componentCtx.getBundleContext()).thenReturn(bundleContext);
-        when(componentCtx.getProperties()).thenReturn(new Hashtable<String, Object>());
-
         SlingBindings bindings = new SlingBindings();
         bindings.setSling(sling);
         bindings.setLog(LoggerFactory.getLogger("test"));
         when(request.getAttribute(SlingBindings.class.getName())).thenReturn(bindings);
 
-        factory = new ModelAdapterFactory();
-        factory.activate(componentCtx);
+        factory = AdapterFactoryTest.createModelAdapterFactory();
         factory.bindInjector(new BindingsInjector(), new ServicePropertiesMap(1, 1));
-        
         factory.adapterImplementations.addClassesAsAdapterAndImplementation(BindingsModel.class, org.apache.sling.models.testmodels.classes.constructorinjection.BindingsModel.class);
     }
 
diff --git a/src/test/java/org/apache/sling/models/impl/RequestWrapperTest.java b/src/test/java/org/apache/sling/models/impl/RequestWrapperTest.java
index ae8fd2a..68f7d3a 100644
--- a/src/test/java/org/apache/sling/models/impl/RequestWrapperTest.java
+++ b/src/test/java/org/apache/sling/models/impl/RequestWrapperTest.java
@@ -16,6 +16,19 @@
  */
 package org.apache.sling.models.impl;
 
+import static org.junit.Assert.assertEquals;
+import static org.mockito.Matchers.any;
+import static org.mockito.Matchers.argThat;
+import static org.mockito.Matchers.eq;
+import static org.mockito.Mockito.times;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
+
+import java.util.Collections;
+
+import javax.script.Bindings;
+import javax.script.ScriptEngineFactory;
+
 import org.apache.sling.api.SlingHttpServletRequest;
 import org.apache.sling.api.adapter.AdapterManager;
 import org.apache.sling.api.resource.Resource;
@@ -31,25 +44,9 @@ import org.junit.runner.RunWith;
 import org.mockito.InjectMocks;
 import org.mockito.Mock;
 import org.mockito.runners.MockitoJUnitRunner;
-import org.osgi.framework.BundleContext;
-import org.osgi.service.component.ComponentContext;
-
-import javax.script.Bindings;
-import javax.script.ScriptEngineFactory;
-import java.util.Collections;
-import java.util.Hashtable;
-
-import static org.mockito.Matchers.*;
-import static org.mockito.Mockito.*;
-import static org.junit.Assert.*;
 
 @RunWith(MockitoJUnitRunner.class)
 public class RequestWrapperTest {
-    @Mock
-    private ComponentContext componentCtx;
-
-    @Mock
-    private BundleContext bundleContext;
 
     @Mock
     private AdapterManager adapterManager;
@@ -71,9 +68,9 @@ public class RequestWrapperTest {
 
     @Before
     public void setup() {
-        when(componentCtx.getBundleContext()).thenReturn(bundleContext);
-        when(componentCtx.getProperties()).thenReturn(new Hashtable<String, Object>());
-        factory.activate(componentCtx);
+        factory = AdapterFactoryTest.createModelAdapterFactory();
+        factory.bindingsValuesProvidersByContext = bindingsValuesProvidersByContext;
+        factory.adapterManager = adapterManager;
         when(bindingsValuesProvidersByContext.getBindingsValuesProviders(any(ScriptEngineFactory.class), eq(BindingsValuesProvider.DEFAULT_CONTEXT))).
                 thenReturn(Collections.singleton(bindingsValuesProvider));
     }
diff --git a/src/test/java/org/apache/sling/models/impl/ResourceModelClassesTest.java b/src/test/java/org/apache/sling/models/impl/ResourceModelClassesTest.java
index 1e35c72..96b62b7 100644
--- a/src/test/java/org/apache/sling/models/impl/ResourceModelClassesTest.java
+++ b/src/test/java/org/apache/sling/models/impl/ResourceModelClassesTest.java
@@ -30,7 +30,6 @@ import java.lang.reflect.Field;
 import java.util.Arrays;
 import java.util.Collections;
 import java.util.HashMap;
-import java.util.Hashtable;
 import java.util.Map;
 
 import org.apache.commons.lang3.RandomStringUtils;
@@ -40,6 +39,7 @@ import org.apache.sling.api.wrappers.ValueMapDecorator;
 import org.apache.sling.models.factory.MissingElementsException;
 import org.apache.sling.models.impl.injectors.ChildResourceInjector;
 import org.apache.sling.models.impl.injectors.ValueMapInjector;
+import org.apache.sling.models.spi.injectorspecific.InjectAnnotationProcessorFactory;
 import org.apache.sling.models.testmodels.classes.ArrayPrimitivesModel;
 import org.apache.sling.models.testmodels.classes.ArrayWrappersModel;
 import org.apache.sling.models.testmodels.classes.ChildModel;
@@ -53,38 +53,24 @@ import org.apache.sling.models.testmodels.classes.SimplePropertyModel;
 import org.junit.Before;
 import org.junit.Test;
 import org.junit.runner.RunWith;
-import org.mockito.Mock;
 import org.mockito.invocation.InvocationOnMock;
 import org.mockito.runners.MockitoJUnitRunner;
 import org.mockito.stubbing.Answer;
-import org.osgi.framework.BundleContext;
-import org.osgi.framework.Constants;
-import org.osgi.service.component.ComponentContext;
 
+@SuppressWarnings("deprecation")
 @RunWith(MockitoJUnitRunner.class)
 public class ResourceModelClassesTest {
 
-    @Mock
-    private ComponentContext componentCtx;
-
-    @Mock
-    private BundleContext bundleContext;
-
     private ModelAdapterFactory factory;
 
     @Before
     public void setup() {
-        when(componentCtx.getBundleContext()).thenReturn(bundleContext);
-        when(componentCtx.getProperties()).thenReturn(new Hashtable<String, Object>());
-
-        factory = new ModelAdapterFactory();
-        factory.activate(componentCtx);
+        factory = AdapterFactoryTest.createModelAdapterFactory();
         ValueMapInjector valueMapInjector = new ValueMapInjector();
         factory.bindInjector(valueMapInjector, new ServicePropertiesMap(2, 2));
         factory.bindInjector(new ChildResourceInjector(), new ServicePropertiesMap(1, 1));
 
-        factory.bindInjectAnnotationProcessorFactory(valueMapInjector,
-                Collections.<String, Object> singletonMap(Constants.SERVICE_ID, 2L));
+        factory.injectAnnotationProcessorFactories = factory.injectAnnotationProcessorFactories = Collections.<InjectAnnotationProcessorFactory>singletonList(new ValueMapInjector());
         factory.adapterImplementations.addClassesAsAdapterAndImplementation(SimplePropertyModel.class, ArrayWrappersModel.class, ResourceModelWithRequiredField.class, ChildValueMapModel.class, ArrayPrimitivesModel.class, ChildResourceModel.class, ResourceModelWithRequiredFieldOptionalStrategy.class, ParentModel.class, ChildModel.class, ListModel.class);
     }
 
diff --git a/src/test/java/org/apache/sling/models/impl/ResourceModelConstructorTest.java b/src/test/java/org/apache/sling/models/impl/ResourceModelConstructorTest.java
index 879398d..185671c 100644
--- a/src/test/java/org/apache/sling/models/impl/ResourceModelConstructorTest.java
+++ b/src/test/java/org/apache/sling/models/impl/ResourceModelConstructorTest.java
@@ -23,7 +23,6 @@ import static org.mockito.Mockito.when;
 
 import java.util.Arrays;
 import java.util.Collections;
-import java.util.Hashtable;
 
 import org.apache.commons.lang3.RandomStringUtils;
 import org.apache.sling.api.resource.Resource;
@@ -36,31 +35,18 @@ import org.apache.sling.models.testmodels.classes.constructorinjection.ParentMod
 import org.junit.Before;
 import org.junit.Test;
 import org.junit.runner.RunWith;
-import org.mockito.Mock;
 import org.mockito.invocation.InvocationOnMock;
 import org.mockito.runners.MockitoJUnitRunner;
 import org.mockito.stubbing.Answer;
-import org.osgi.framework.BundleContext;
-import org.osgi.service.component.ComponentContext;
 
 @RunWith(MockitoJUnitRunner.class)
 public class ResourceModelConstructorTest {
 
-    @Mock
-    private ComponentContext componentCtx;
-
-    @Mock
-    private BundleContext bundleContext;
-
     private ModelAdapterFactory factory;
 
     @Before
     public void setup() {
-        when(componentCtx.getBundleContext()).thenReturn(bundleContext);
-        when(componentCtx.getProperties()).thenReturn(new Hashtable<String, Object>());
-
-        factory = new ModelAdapterFactory();
-        factory.activate(componentCtx);
+        factory = AdapterFactoryTest.createModelAdapterFactory();
         factory.bindInjector(new ValueMapInjector(), new ServicePropertiesMap(2, 2));
         factory.bindInjector(new ChildResourceInjector(), new ServicePropertiesMap(1, 1));
         factory.adapterImplementations.addClassesAsAdapterAndImplementation(ParentModel.class, ChildModel.class);
diff --git a/src/test/java/org/apache/sling/models/impl/ResourceModelInterfacesTest.java b/src/test/java/org/apache/sling/models/impl/ResourceModelInterfacesTest.java
index 9170c81..6ffcb5e 100644
--- a/src/test/java/org/apache/sling/models/impl/ResourceModelInterfacesTest.java
+++ b/src/test/java/org/apache/sling/models/impl/ResourceModelInterfacesTest.java
@@ -29,7 +29,6 @@ import static org.mockito.Mockito.when;
 import java.util.Arrays;
 import java.util.Collections;
 import java.util.HashMap;
-import java.util.Hashtable;
 import java.util.Map;
 
 import org.apache.commons.lang3.RandomStringUtils;
@@ -47,31 +46,18 @@ import org.apache.sling.models.testmodels.interfaces.SimplePropertyModel;
 import org.junit.Before;
 import org.junit.Test;
 import org.junit.runner.RunWith;
-import org.mockito.Mock;
 import org.mockito.invocation.InvocationOnMock;
 import org.mockito.runners.MockitoJUnitRunner;
 import org.mockito.stubbing.Answer;
-import org.osgi.framework.BundleContext;
-import org.osgi.service.component.ComponentContext;
 
 @RunWith(MockitoJUnitRunner.class)
 public class ResourceModelInterfacesTest {
 
-    @Mock
-    private ComponentContext componentCtx;
-
-    @Mock
-    private BundleContext bundleContext;
-
     private ModelAdapterFactory factory;
 
     @Before
     public void setup() {
-        when(componentCtx.getBundleContext()).thenReturn(bundleContext);
-        when(componentCtx.getProperties()).thenReturn(new Hashtable<String, Object>());
-
-        factory = new ModelAdapterFactory();
-        factory.activate(componentCtx);
+        factory = AdapterFactoryTest.createModelAdapterFactory();
         factory.bindInjector(new ValueMapInjector(), new ServicePropertiesMap(2, 2));
         factory.bindInjector(new ChildResourceInjector(), new ServicePropertiesMap(1, 1));
         factory.adapterImplementations.addClassesAsAdapterAndImplementation(SimplePropertyModel.class, ResourceModelWithRequiredField.class, ChildResourceModel.class, ChildValueMapModel.class, ParentModel.class, ChildModel.class);
diff --git a/src/test/java/org/apache/sling/models/impl/ResourcePathInjectionTest.java b/src/test/java/org/apache/sling/models/impl/ResourcePathInjectionTest.java
index 787bef9..686c23a 100644
--- a/src/test/java/org/apache/sling/models/impl/ResourcePathInjectionTest.java
+++ b/src/test/java/org/apache/sling/models/impl/ResourcePathInjectionTest.java
@@ -18,11 +18,13 @@
  */
 package org.apache.sling.models.impl;
 
-import static org.junit.Assert.*;
-import static org.mockito.Mockito.*;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertNull;
+import static org.junit.Assert.assertTrue;
+import static org.mockito.Mockito.when;
 
 import java.util.HashMap;
-import java.util.Hashtable;
 import java.util.List;
 import java.util.Map;
 
@@ -43,18 +45,9 @@ import org.junit.Test;
 import org.junit.runner.RunWith;
 import org.mockito.Mock;
 import org.mockito.runners.MockitoJUnitRunner;
-import org.osgi.framework.BundleContext;
-import org.osgi.service.component.ComponentContext;
 
 @RunWith(MockitoJUnitRunner.class)
 public class ResourcePathInjectionTest {
-
-    @Mock
-    private ComponentContext componentCtx;
-
-    @Mock
-    private BundleContext bundleContext;
-
     private ModelAdapterFactory factory;
 
     @Mock
@@ -96,9 +89,6 @@ public class ResourcePathInjectionTest {
 
         ValueMap properties = new ValueMapDecorator(map);
 
-        when(componentCtx.getBundleContext()).thenReturn(bundleContext);
-        when(componentCtx.getProperties()).thenReturn(new Hashtable<String, Object>());
-
         when(adaptable.getResourceResolver()).thenReturn(resourceResolver);
         when(adaptable.adaptTo(ValueMap.class)).thenReturn(properties);
 
@@ -107,8 +97,7 @@ public class ResourcePathInjectionTest {
         when(resourceResolver.getResource("/some/other/path")).thenReturn(byPropertyValueResource);
         when(resourceResolver.getResource("/some/other/path2")).thenReturn(byPropertyValueResource2);
 
-        factory = new ModelAdapterFactory();
-        factory.activate(componentCtx);
+        factory = AdapterFactoryTest.createModelAdapterFactory();
         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));
diff --git a/src/test/java/org/apache/sling/models/impl/SelfDependencyTest.java b/src/test/java/org/apache/sling/models/impl/SelfDependencyTest.java
index 2fc8b99..854bf5b 100644
--- a/src/test/java/org/apache/sling/models/impl/SelfDependencyTest.java
+++ b/src/test/java/org/apache/sling/models/impl/SelfDependencyTest.java
@@ -22,8 +22,6 @@ import static org.junit.Assert.assertSame;
 import static org.mockito.Matchers.any;
 import static org.mockito.Mockito.when;
 
-import java.util.Hashtable;
-
 import org.apache.sling.api.SlingHttpServletRequest;
 import org.apache.sling.models.impl.injectors.SelfInjector;
 import org.apache.sling.models.testmodels.classes.DirectCyclicSelfDependencyModel;
@@ -38,18 +36,10 @@ import org.mockito.Mock;
 import org.mockito.invocation.InvocationOnMock;
 import org.mockito.runners.MockitoJUnitRunner;
 import org.mockito.stubbing.Answer;
-import org.osgi.framework.BundleContext;
-import org.osgi.service.component.ComponentContext;
 
 @RunWith(MockitoJUnitRunner.class)
 public class SelfDependencyTest {
 
-    @Mock
-    private ComponentContext componentCtx;
-
-    @Mock
-    private BundleContext bundleContext;
-
     private ModelAdapterFactory factory;
 
     @Mock
@@ -58,9 +48,6 @@ public class SelfDependencyTest {
     @SuppressWarnings("unchecked")
     @Before
     public void setup() {
-        when(componentCtx.getBundleContext()).thenReturn(bundleContext);
-        when(componentCtx.getProperties()).thenReturn(new Hashtable<String, Object>());
-
         when(request.adaptTo(any(Class.class))).then(new Answer<Object>() {
             @Override
             public Object answer(InvocationOnMock invocation) throws Throwable {
@@ -69,8 +56,7 @@ public class SelfDependencyTest {
             }
         });
 
-        factory = new ModelAdapterFactory();
-        factory.activate(componentCtx);
+        factory = AdapterFactoryTest.createModelAdapterFactory();
         factory.bindInjector(new SelfInjector(), new ServicePropertiesMap(1, 1));
         factory.adapterImplementations.addClassesAsAdapterAndImplementation(SelfDependencyModelA.class, SelfDependencyModelB.class, DirectCyclicSelfDependencyModel.class, IndirectCyclicSelfDependencyModelA.class, IndirectCyclicSelfDependencyModelB.class);
     }
diff --git a/src/test/java/org/apache/sling/models/impl/ViaTest.java b/src/test/java/org/apache/sling/models/impl/ViaTest.java
index 0e01e81..a72ac4e 100644
--- a/src/test/java/org/apache/sling/models/impl/ViaTest.java
+++ b/src/test/java/org/apache/sling/models/impl/ViaTest.java
@@ -21,7 +21,6 @@ import static org.junit.Assert.assertNotNull;
 import static org.mockito.Mockito.when;
 
 import java.util.Collections;
-import java.util.Hashtable;
 
 import org.apache.commons.lang3.RandomStringUtils;
 import org.apache.sling.api.SlingHttpServletRequest;
@@ -38,8 +37,6 @@ import org.junit.Test;
 import org.junit.runner.RunWith;
 import org.mockito.Mock;
 import org.mockito.runners.MockitoJUnitRunner;
-import org.osgi.framework.BundleContext;
-import org.osgi.service.component.ComponentContext;
 
 @RunWith(MockitoJUnitRunner.class)
 public class ViaTest {
@@ -53,23 +50,13 @@ public class ViaTest {
     @Mock
     private SlingHttpServletRequest request;
 
-    @Mock
-    private ComponentContext componentCtx;
-
-    @Mock
-    private BundleContext bundleContext;
-
     private ModelAdapterFactory factory;
 
     @Before
     public void setup() {
-        when(componentCtx.getBundleContext()).thenReturn(bundleContext);
-        when(componentCtx.getProperties()).thenReturn(new Hashtable<String, Object>());
-
         when(request.getResource()).thenReturn(resource);
         when(resource.getChild("jcr:content")).thenReturn(childResource);
-        factory = new ModelAdapterFactory();
-        factory.activate(componentCtx);
+        factory = AdapterFactoryTest.createModelAdapterFactory();
         factory.bindInjector(new ValueMapInjector(), new ServicePropertiesMap(1, 1));
         factory.bindViaProvider(new BeanPropertyViaProvider(), null);
         factory.bindViaProvider(new ChildResourceViaProvider(), null);