SLING-7536 : Refactor implementation
diff --git a/pom.xml b/pom.xml
index 28811f9..627f249 100644
--- a/pom.xml
+++ b/pom.xml
@@ -23,7 +23,7 @@
     <parent>
         <groupId>org.apache.sling</groupId>
         <artifactId>sling</artifactId>
-        <version>32</version>
+        <version>33</version>
         <relativePath />
     </parent>
 
@@ -84,13 +84,19 @@
     </build>
     <dependencies>
         <dependency>
+            <groupId>org.osgi</groupId>
+            <artifactId>org.osgi.annotation.versioning</artifactId>
+            <version>1.0.0</version>
+            <scope>provided</scope>
+        </dependency>
+        <dependency>
             <groupId>javax.servlet</groupId>
             <artifactId>javax.servlet-api</artifactId>
         </dependency>
         <dependency>
             <groupId>org.apache.sling</groupId>
             <artifactId>org.apache.sling.api</artifactId>
-            <version>2.16.2</version>
+            <version>2.18.0</version>
             <scope>provided</scope>
         </dependency>
         <!-- for ServiceUserMapped (SLING-4312) -->
diff --git a/src/main/java/org/apache/sling/servlets/resolver/internal/ResolverConfig.java b/src/main/java/org/apache/sling/servlets/resolver/internal/ResolverConfig.java
new file mode 100644
index 0000000..9159970
--- /dev/null
+++ b/src/main/java/org/apache/sling/servlets/resolver/internal/ResolverConfig.java
@@ -0,0 +1,61 @@
+/*
+ * 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.servlets.resolver.internal;
+
+import org.osgi.service.metatype.annotations.AttributeDefinition;
+import org.osgi.service.metatype.annotations.ObjectClassDefinition;
+
+@ObjectClassDefinition(name = "Apache Sling Servlet/Script Resolver and Error Handler",
+    description = "The Sling Servlet and Script Resolver has "
+        + "multiple tasks: One it is used as the ServletResolver to select the Servlet "
+        + "or Script to call to handle the request. Second it acts as the "
+        + "SlingScriptResolver and finally it manages error handling by implementing "
+        + "the ErrorHandler interface using the same algorithm to select error handling "
+        + "servlets and scripts as is used to resolve request processing servlets and " + "scripts.")
+public @interface ResolverConfig {
+
+    String PID = "org.apache.sling.servlets.resolver.SlingServletResolver";
+
+    /**
+     * The default servlet root is the first search path (which is usually
+     * /apps)
+     */
+    @AttributeDefinition(name = "Servlet Registration Root Path", description = "The default root path assumed when "
+            + "registering a servlet whose servlet registration properties define a relative "
+            + "resource type/path. It can either be a string starting with \"/\" (specifying a path prefix to be used) "
+            + "or a number which specifies the resource resolver's search path entry index. The default value "
+            + "is 0 (usually stands for \"/apps\" in the search paths). The number can be -1 which always "
+            + "points to the last search path entry.")
+    String servletresolver_servletRoot() default "0";
+
+    /** The default cache size for the script resolution. */
+    @AttributeDefinition(name = "Cache Size", description = "This property configures the size of the "
+            + "cache used for script resolution. A value lower than 5 disables the cache.")
+    int servletresolver_cacheSize() default 200;
+
+    @AttributeDefinition(name = "Execution Paths", description = "The paths to search for executable scripts. If no path is configured "
+            + "this is treated like the default (/ = root) which allows to execute all scripts. By configuring some "
+            + "paths the execution of scripts can be limited. If a configured value ends with a slash, the whole sub tree "
+            + "is allowed. Without a slash an exact matching script is allowed.")
+    String[] servletresolver_paths() default "/";
+
+    @AttributeDefinition(name = "Default Extensions", description = "The list of extensions for which the default behavior "
+            + "will be used. This means that the last path segment of the resource type can be used as the script name.")
+    String[] servletresolver_defaultExtensions() default "html";
+}
diff --git a/src/main/java/org/apache/sling/servlets/resolver/internal/SlingScriptResolverImpl.java b/src/main/java/org/apache/sling/servlets/resolver/internal/SlingScriptResolverImpl.java
index 5677aa4..1941cb2 100644
--- a/src/main/java/org/apache/sling/servlets/resolver/internal/SlingScriptResolverImpl.java
+++ b/src/main/java/org/apache/sling/servlets/resolver/internal/SlingScriptResolverImpl.java
@@ -39,7 +39,7 @@
  *
  */
 @Component(service = { SlingScriptResolver.class },
-           configurationPid = SlingServletResolver.Config.PID,
+           configurationPid = ResolverConfig.PID,
            property = {
                    Constants.SERVICE_DESCRIPTION + "=Apache Sling Script Resolver",
                    Constants.SERVICE_VENDOR + "=The Apache Software Foundation"
@@ -53,7 +53,7 @@
     private String[] executionPaths;
 
     @Activate
-    private void activate(final SlingServletResolver.Config config) {
+    private void activate(final ResolverConfig config) {
         this.executionPaths = AbstractResourceCollector.getExecutionPaths(config.servletresolver_paths());
     }
 
diff --git a/src/main/java/org/apache/sling/servlets/resolver/internal/SlingServletResolver.java b/src/main/java/org/apache/sling/servlets/resolver/internal/SlingServletResolver.java
index 536a0c7..187ee42 100644
--- a/src/main/java/org/apache/sling/servlets/resolver/internal/SlingServletResolver.java
+++ b/src/main/java/org/apache/sling/servlets/resolver/internal/SlingServletResolver.java
@@ -76,9 +76,7 @@
 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.metatype.annotations.AttributeDefinition;
 import org.osgi.service.metatype.annotations.Designate;
-import org.osgi.service.metatype.annotations.ObjectClassDefinition;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
@@ -89,60 +87,22 @@
  * The resolver uses an own session to find the scripts.
  *
  */
-@Component(name = SlingServletResolver.Config.PID,
+@Component(name = ResolverConfig.PID,
            service = { ServletResolver.class, ErrorHandler.class, SlingRequestListener.class },
            property = {
                    Constants.SERVICE_DESCRIPTION + "=Apache Sling Servlet Resolver and Error Handler",
                    Constants.SERVICE_VENDOR + "=The Apache Software Foundation"
            })
-@Designate(ocd = SlingServletResolver.Config.class)
+@Designate(ocd = ResolverConfig.class)
 public class SlingServletResolver
     implements ServletResolver,
                SlingRequestListener,
                ErrorHandler {
 
-    @ObjectClassDefinition(name = "Apache Sling Servlet/Script Resolver and Error Handler",
-            description= "The Sling Servlet and Script Resolver has "+
-                 "multiple tasks: One it is used as the ServletResolver to select the Servlet "+
-                 "or Script to call to handle the request. Second it acts as the "+
-                 "SlingScriptResolver and finally it manages error handling by implementing "+
-                 "the ErrorHandler interface using the same algorithm to select error handling "+
-                 "servlets and scripts as is used to resolve request processing servlets and "+
-                 "scripts.")
-    public @interface Config {
+    private static final String SERVICE_USER = "scripts";
 
-        String PID = "org.apache.sling.servlets.resolver.SlingServletResolver";
+    private static final String SERVICE_USER_CONSOLE = "console";
 
-        /**
-         * The default servlet root is the first search path (which is usually /apps)
-         */
-        @AttributeDefinition(name="Servlet Registration Root Path",
-                description = "The default root path assumed when "+
-                     "registering a servlet whose servlet registration properties define a relative "+
-                     "resource type/path. It can either be a string starting with \"/\" (specifying a path prefix to be used) "+
-                     "or a number which specifies the resource resolver's search path entry index. The default value "+
-                     "is 0 (usually stands for \"/apps\" in the search paths). The number can be -1 which always "+
-                     "points to the last search path entry.")
-        String servletresolver_servletRoot() default "0";
-
-        /** The default cache size for the script resolution. */
-        @AttributeDefinition(name = "Cache Size",
-                description = "This property configures the size of the " +
-                    "cache used for script resolution. A value lower than 5 disables the cache.")
-        int servletresolver_cacheSize() default 200;
-
-        @AttributeDefinition(name = "Execution Paths",
-                description = "The paths to search for executable scripts. If no path is configured " +
-                     "this is treated like the default (/ = root) which allows to execute all scripts. By configuring some " +
-                     "paths the execution of scripts can be limited. If a configured value ends with a slash, the whole sub tree " +
-                     "is allowed. Without a slash an exact matching script is allowed.")
-        String[] servletresolver_paths() default "/";
-
-        @AttributeDefinition(name = "Default Extensions",
-                description = "The list of extensions for which the default behavior " +
-                    "will be used. This means that the last path segment of the resource type can be used as the script name.")
-        String[] servletresolver_defaultExtensions() default "html";
-    }
 
     /** Servlet resolver logger */
     public static final Logger LOGGER = LoggerFactory.getLogger(SlingServletResolver.class);
@@ -150,10 +110,10 @@
     @Reference
     private ResourceResolverFactory resourceResolverFactory;
 
-    @Reference(target="("+ServiceUserMapped.SUBSERVICENAME+"=scripts)")
+    @Reference(target="("+ServiceUserMapped.SUBSERVICENAME+"=" + SERVICE_USER + ")")
     private ServiceUserMapped scriptServiceUserMapped;
 
-    @Reference(target="("+ServiceUserMapped.SUBSERVICENAME+"=console)")
+    @Reference(target="("+ServiceUserMapped.SUBSERVICENAME+"=" + SERVICE_USER_CONSOLE + ")")
     private ServiceUserMapped consoleServiceUserMapped;
 
     @Reference
@@ -697,9 +657,9 @@
      * Activate this component.
      */
     @Activate
-    protected void activate(final BundleContext context, final Config config) throws LoginException {
+    protected void activate(final BundleContext context, final ResolverConfig config) throws LoginException {
         this.sharedScriptResolver =
-                resourceResolverFactory.getServiceResourceResolver(Collections.singletonMap(ResourceResolverFactory.SUBSERVICE, (Object)"scripts"));
+                resourceResolverFactory.getServiceResourceResolver(Collections.singletonMap(ResourceResolverFactory.SUBSERVICE, (Object)SERVICE_USER));
 
         this.executionPaths = AbstractResourceCollector.getExecutionPaths(config.servletresolver_paths());
         this.defaultExtensions = config.servletresolver_defaultExtensions();
@@ -782,7 +742,7 @@
                     + "<br/>As a workaround, you can replace dots with underline characters, for example, when testing such an URL."
                     + "</em>";
 
-            try (final ResourceResolver resourceResolver = resourceResolverFactory.getServiceResourceResolver(Collections.singletonMap(ResourceResolverFactory.SUBSERVICE, (Object)"console"))) {
+            try (final ResourceResolver resourceResolver = resourceResolverFactory.getServiceResourceResolver(Collections.singletonMap(ResourceResolverFactory.SUBSERVICE, (Object)SERVICE_USER_CONSOLE))) {
 
                 final PrintWriter pw = response.getWriter();
 
diff --git a/src/main/java/org/apache/sling/servlets/resolver/internal/resolution/ResolutionCache.java b/src/main/java/org/apache/sling/servlets/resolver/internal/resolution/ResolutionCache.java
index 2162959..52fe1f1 100644
--- a/src/main/java/org/apache/sling/servlets/resolver/internal/resolution/ResolutionCache.java
+++ b/src/main/java/org/apache/sling/servlets/resolver/internal/resolution/ResolutionCache.java
@@ -37,7 +37,7 @@
 import org.apache.sling.api.resource.observation.ResourceChange;
 import org.apache.sling.api.resource.observation.ResourceChangeListener;
 import org.apache.sling.api.resource.path.Path;
-import org.apache.sling.servlets.resolver.internal.SlingServletResolver;
+import org.apache.sling.servlets.resolver.internal.ResolverConfig;
 import org.apache.sling.servlets.resolver.internal.helper.AbstractResourceCollector;
 import org.apache.sling.servlets.resolver.jmx.SlingServletResolverCacheMBean;
 import org.osgi.framework.BundleContext;
@@ -57,7 +57,7 @@
  * Cache for script resolution
  *
  */
-@Component(configurationPid = SlingServletResolver.Config.PID,
+@Component(configurationPid = ResolverConfig.PID,
            service = {ResolutionCache.class})
 public class ResolutionCache
     implements EventHandler, ResourceChangeListener, ExternalResourceChangeListener {
@@ -90,7 +90,7 @@
      */
     @Activate
     protected void activate(final BundleContext context,
-            final SlingServletResolver.Config config) throws LoginException {
+            final ResolverConfig config) throws LoginException {
         // create cache - if a cache size is configured
         this.cacheSize = config.servletresolver_cacheSize();
         if (this.cacheSize > 5) {
diff --git a/src/main/java/org/apache/sling/servlets/resolver/internal/ServletMounter.java b/src/main/java/org/apache/sling/servlets/resolver/internal/resource/ServletMounter.java
similarity index 90%
rename from src/main/java/org/apache/sling/servlets/resolver/internal/ServletMounter.java
rename to src/main/java/org/apache/sling/servlets/resolver/internal/resource/ServletMounter.java
index 094b40b..51adea9 100644
--- a/src/main/java/org/apache/sling/servlets/resolver/internal/ServletMounter.java
+++ b/src/main/java/org/apache/sling/servlets/resolver/internal/resource/ServletMounter.java
@@ -16,7 +16,7 @@
  * specific language governing permissions and limitations
  * under the License.
  */
-package org.apache.sling.servlets.resolver.internal;
+package org.apache.sling.servlets.resolver.internal.resource;
 
 import static org.apache.sling.api.servlets.ServletResolverConstants.SLING_SERVLET_NAME;
 import static org.osgi.framework.Constants.SERVICE_ID;
@@ -24,9 +24,7 @@
 import static org.osgi.service.component.ComponentConstants.COMPONENT_NAME;
 
 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.Hashtable;
@@ -39,15 +37,11 @@
 import javax.servlet.ServletException;
 
 import org.apache.sling.api.request.RequestUtil;
-import org.apache.sling.api.resource.LoginException;
-import org.apache.sling.api.resource.ResourceResolver;
 import org.apache.sling.api.resource.ResourceResolverFactory;
 import org.apache.sling.api.servlets.ServletResolver;
 import org.apache.sling.api.servlets.ServletResolverConstants;
-import org.apache.sling.serviceusermapping.ServiceUserMapped;
+import org.apache.sling.servlets.resolver.internal.ResolverConfig;
 import org.apache.sling.servlets.resolver.internal.helper.SlingServletConfig;
-import org.apache.sling.servlets.resolver.internal.resource.ServletResourceProvider;
-import org.apache.sling.servlets.resolver.internal.resource.ServletResourceProviderFactory;
 import org.apache.sling.spi.resource.provider.ResourceProvider;
 import org.osgi.framework.Bundle;
 import org.osgi.framework.BundleContext;
@@ -70,7 +64,7 @@
  * The resolver uses an own session to find the scripts.
  *
  */
-@Component(configurationPid = SlingServletResolver.Config.PID,
+@Component(configurationPid = ResolverConfig.PID,
            service = {})
 public class ServletMounter {
 
@@ -94,25 +88,20 @@
     @Reference
     private ResourceResolverFactory resourceResolverFactory;
 
-    @Reference(target="("+ServiceUserMapped.SUBSERVICENAME+"=scripts)")
-    private ServiceUserMapped scriptServiceUserMapped;
-
     /**
      * Activate this component.
      */
     @Activate
     protected void activate(final BundleContext context,
-            final SlingServletResolver.Config config)
-    throws LoginException {
+            final ResolverConfig config) {
         final Collection<PendingServlet> refs;
         synchronized (this.pendingServlets) {
 
             refs = new ArrayList<>(pendingServlets);
             pendingServlets.clear();
 
-            try ( final ResourceResolver scriptRR = resourceResolverFactory.getServiceResourceResolver(Collections.singletonMap(ResourceResolverFactory.SUBSERVICE, (Object)"scripts"))) {
-                servletResourceProviderFactory = new ServletResourceProviderFactory(config.servletresolver_servletRoot(), scriptRR.getSearchPath());
-            }
+            servletResourceProviderFactory = new ServletResourceProviderFactory(config.servletresolver_servletRoot(),
+                    resourceResolverFactory.getSearchPath());
 
             // register servlets immediately from now on
             this.context = context;
@@ -225,7 +214,7 @@
                         final ServiceRegistration<ResourceProvider<Object>> reg = (ServiceRegistration<ResourceProvider<Object>>) bundleContext.registerService(
                             ResourceProvider.class.getName(),
                             provider,
-                            createServiceProperties(reference, provider, root));
+                            createServiceProperties(reference, root));
                         regs.add(reg);
                     }
                     registered = true;
@@ -250,13 +239,12 @@
     }
 
     private Dictionary<String, Object> createServiceProperties(final ServiceReference<Servlet> reference,
-            final ServletResourceProvider provider,
             final String root) {
 
         final Dictionary<String, Object> params = new Hashtable<>();
         params.put(ResourceProvider.PROPERTY_ROOT, root);
         params.put(Constants.SERVICE_DESCRIPTION,
-            "ServletResourceProvider for Servlets at " + Arrays.asList(provider.getServletPaths()));
+            "ServletResourceProvider for Servlet at " + root);
 
         // inherit service ranking
         Object rank = reference.getProperty(Constants.SERVICE_RANKING);
diff --git a/src/main/java/org/apache/sling/servlets/resolver/internal/resource/ServletResource.java b/src/main/java/org/apache/sling/servlets/resolver/internal/resource/ServletResource.java
index b967a61..63704f2 100644
--- a/src/main/java/org/apache/sling/servlets/resolver/internal/resource/ServletResource.java
+++ b/src/main/java/org/apache/sling/servlets/resolver/internal/resource/ServletResource.java
@@ -41,35 +41,40 @@
 
     private final ResourceMetadata metadata;
 
-    ServletResource(ResourceResolver resourceResolver, Servlet servlet,
-            String path) {
+    ServletResource(final ResourceResolver resourceResolver,
+            final Servlet servlet,
+            final String path) {
         this.resourceResolver = resourceResolver;
         this.servlet = servlet;
         this.path = path;
         this.resourceType = ServletResourceProviderFactory.ensureServletNameExtension(path);
 
         this.metadata = new ResourceMetadata();
-        metadata.setResolutionPath(path);
     }
 
+    @Override
     public ResourceMetadata getResourceMetadata() {
         return metadata;
     }
 
+    @Override
     public ResourceResolver getResourceResolver() {
         return resourceResolver;
     }
 
+    @Override
     public String getResourceType() {
         return resourceType;
     }
 
     /** Servlet Resources always returns "sling/bundle/resource" as
      * the super type. */
+    @Override
     public String getResourceSuperType() {
         return "sling/bundle/resource";
     }
 
+    @Override
     public String getPath() {
         return path;
     }
@@ -88,12 +93,13 @@
         return servletName;
     }
 
+    @Override
     @SuppressWarnings("unchecked")
     public <AdapterType> AdapterType adaptTo(Class<AdapterType> type) {
         if (type == Servlet.class) {
             return (AdapterType) servlet; // unchecked cast
         } else if ( type == ValueMap.class ) {
-            final Map<String, Object> props = new HashMap<String, Object>();
+            final Map<String, Object> props = new HashMap<>();
             props.put("sling:resourceType", this.getResourceType());
             props.put("sling:resourceSuperType", this.getResourceSuperType());
             props.put("servletName", this.getServletName());
@@ -105,6 +111,7 @@
         return super.adaptTo(type);
     }
 
+    @Override
     public String toString() {
         return getClass().getSimpleName() + ", servlet=" + this.getServletName()
             + ", path=" + getPath();
diff --git a/src/main/java/org/apache/sling/servlets/resolver/internal/resource/ServletResourceProvider.java b/src/main/java/org/apache/sling/servlets/resolver/internal/resource/ServletResourceProvider.java
index 53715c0..f0d6bb9 100644
--- a/src/main/java/org/apache/sling/servlets/resolver/internal/resource/ServletResourceProvider.java
+++ b/src/main/java/org/apache/sling/servlets/resolver/internal/resource/ServletResourceProvider.java
@@ -18,7 +18,6 @@
  */
 package org.apache.sling.servlets.resolver.internal.resource;
 
-import java.util.Arrays;
 import java.util.Iterator;
 import java.util.Set;
 
@@ -31,22 +30,27 @@
 
 public class ServletResourceProvider extends ResourceProvider<Object> {
 
-    private Servlet servlet;
+    private final Servlet servlet;
 
-    private Set<String> resourcePaths;
+    private final Set<String> resourcePaths;
 
     ServletResourceProvider(final Servlet servlet, final Set<String> resourcePaths) {
         this.servlet = servlet;
         this.resourcePaths = resourcePaths;
     }
 
+    @SuppressWarnings("unchecked")
     @Override
-    public Resource getResource(final ResolveContext<Object> ctx, String path, ResourceContext resourceContext, Resource parent) {
+    public Resource getResource(final ResolveContext<Object> ctx,
+            final String path,
+            final ResourceContext resourceContext,
+            final Resource parent) {
         // only return a resource if the servlet has been assigned
         if (resourcePaths.contains(path)) {
             return new ServletResource(ctx.getResourceResolver(), servlet, path);
         }
 
+        @SuppressWarnings("rawtypes")
         final ResourceProvider parentProvider = ctx.getParentResourceProvider();
         if ( parentProvider != null ) {
             final Resource useParent = (parent instanceof ServletResource ? null : parent);
@@ -55,8 +59,9 @@
         return null;
     }
 
+    @SuppressWarnings({ "rawtypes", "unchecked" })
     @Override
-    public Iterator<Resource> listChildren(ResolveContext<Object> ctx, Resource parent) {
+    public Iterator<Resource> listChildren(final ResolveContext<Object> ctx, final Resource parent) {
         final ResourceProvider parentProvider = ctx.getParentResourceProvider();
         if ( parentProvider != null ) {
             return parentProvider.listChildren(ctx.getParentResolveContext(), parent);
@@ -64,16 +69,12 @@
         return null;
     }
 
-    Servlet getServlet() {
-        return servlet;
-    }
-
-    Iterator<String> getServletPathIterator() {
-        return resourcePaths.iterator();
-    }
-
-    public String[] getServletPaths() {
-        return resourcePaths.toArray(new String[resourcePaths.size()]);
+    /**
+     * The paths under which this servlet is mounted. Used by the servlet mounter
+     * @return The set of paths
+     */
+    Set<String> getServletPaths() {
+        return resourcePaths;
     }
 
     /** Return suitable info for logging */
@@ -81,6 +82,6 @@
     public String toString() {
         return getClass().getSimpleName() + ": servlet="
             + servlet.getClass().getName() + ", paths="
-            + Arrays.toString(getServletPaths());
+            + resourcePaths;
     }
 }
diff --git a/src/main/java/org/apache/sling/servlets/resolver/internal/resource/ServletResourceProviderFactory.java b/src/main/java/org/apache/sling/servlets/resolver/internal/resource/ServletResourceProviderFactory.java
index d049c88..128695c 100644
--- a/src/main/java/org/apache/sling/servlets/resolver/internal/resource/ServletResourceProviderFactory.java
+++ b/src/main/java/org/apache/sling/servlets/resolver/internal/resource/ServletResourceProviderFactory.java
@@ -28,6 +28,7 @@
 import static org.osgi.service.component.ComponentConstants.COMPONENT_NAME;
 
 import java.util.HashSet;
+import java.util.List;
 import java.util.Set;
 
 import javax.servlet.Servlet;
@@ -70,9 +71,9 @@
     /**
      * The search paths
      */
-    private final String[] searchPaths;
+    private final List<String> searchPath;
 
-    static String ensureServletNameExtension(String servletPath) {
+    static String ensureServletNameExtension(final String servletPath) {
         if (servletPath.endsWith(SERVLET_PATH_EXTENSION)) {
             return servletPath;
         }
@@ -84,35 +85,29 @@
      * Constructor
      * @param servletRoot The default value for the servlet root
      */
-    public ServletResourceProviderFactory(Object servletRoot, String[] paths) {
-        this.searchPaths = paths;
-        String value = servletRoot.toString();
-        // check if servlet root specifies a number
+    public ServletResourceProviderFactory(String servletRoot, final List<String> searchPath) {
+        this.searchPath = searchPath;
+        // check if servletRoot specifies a number
         boolean isNumber = false;
         int index = -1;
-        if ( servletRoot instanceof Number ) {
-            isNumber = true;
-            index = ((Number)servletRoot).intValue();
-        } else {
-            if (!value.startsWith("/") ) {
-                try {
-                    index = Integer.valueOf(value);
-                    isNumber = true;
-                } catch (NumberFormatException nfe) {
-                    // ignore
-                }
+        if (!servletRoot.startsWith("/") ) {
+            try {
+                index = Integer.valueOf(servletRoot);
+                isNumber = true;
+            } catch (NumberFormatException nfe) {
+                // ignore
             }
         }
         if ( !isNumber ) {
             // ensure the root starts and ends with a slash
-            if (!value.startsWith("/")) {
-                value = "/" + value;
+            if (!servletRoot.startsWith("/")) {
+                servletRoot = "/".concat(servletRoot);
             }
-            if (!value.endsWith("/")) {
-                value += "/";
+            if (!servletRoot.endsWith("/")) {
+                servletRoot = servletRoot.concat("/");
             }
 
-            this.servletRoot = value;
+            this.servletRoot = servletRoot;
             this.servletRootIndex = -1;
         } else {
             this.servletRoot = null;
@@ -120,9 +115,15 @@
         }
     }
 
+    /**
+     * Create a servlet resource provider for the servlet
+     * @param ref The service reference for the servlet
+     * @param servlet The servlet object itself
+     * @return A servlet resource provider
+     */
     public ServletResourceProvider create(final ServiceReference<Servlet> ref, final Servlet servlet) {
 
-        Set<String> pathSet = new HashSet<>();
+        final Set<String> pathSet = new HashSet<>();
 
         // check whether explicit paths are set
         addByPath(pathSet, ref);
@@ -185,10 +186,10 @@
                 return s;
             }
         }
-        if ( index == -1 || index >= this.searchPaths.length ) {
-            index = this.searchPaths.length - 1;
+        if ( index == -1 || index >= this.searchPath.size() ) {
+            index = this.searchPath.size() - 1;
         }
-        return this.searchPaths[index];
+        return this.searchPath.get(index);
     }
 
     /**
diff --git a/src/test/java/org/apache/sling/servlets/resolver/internal/ServletMounterTest.java b/src/test/java/org/apache/sling/servlets/resolver/internal/ServletMounterTest.java
deleted file mode 100644
index 223bf22..0000000
--- a/src/test/java/org/apache/sling/servlets/resolver/internal/ServletMounterTest.java
+++ /dev/null
@@ -1,254 +0,0 @@
-/*
- * 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.servlets.resolver.internal;
-
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertNull;
-
-import java.lang.annotation.Annotation;
-import java.lang.reflect.Field;
-import java.lang.reflect.Method;
-import java.util.ArrayList;
-import java.util.Dictionary;
-import java.util.List;
-import java.util.Map;
-
-import javax.servlet.Servlet;
-import javax.servlet.http.HttpServlet;
-
-import org.apache.sling.api.SlingHttpServletRequest;
-import org.apache.sling.api.resource.LoginException;
-import org.apache.sling.api.resource.Resource;
-import org.apache.sling.api.resource.ResourceResolver;
-import org.apache.sling.api.resource.ResourceResolverFactory;
-import org.apache.sling.api.resource.ResourceUtil;
-import org.apache.sling.api.servlets.OptingServlet;
-import org.apache.sling.api.servlets.ServletResolverConstants;
-import org.apache.sling.commons.testing.osgi.MockServiceReference;
-import org.apache.sling.commons.testing.sling.MockResource;
-import org.apache.sling.commons.testing.sling.MockResourceResolver;
-import org.apache.sling.commons.testing.sling.MockSlingHttpServletRequest;
-import org.apache.sling.servlets.resolver.internal.resource.MockServletResource;
-import org.apache.sling.servlets.resolver.internal.resource.ServletResourceProvider;
-import org.apache.sling.servlets.resolver.internal.resource.ServletResourceProviderFactory;
-import org.junit.Before;
-import org.junit.Test;
-import org.mockito.Mockito;
-import org.osgi.framework.Bundle;
-import org.osgi.framework.BundleContext;
-import org.osgi.framework.Constants;
-import org.osgi.framework.ServiceReference;
-
-public class ServletMounterTest {
-
-    private Servlet servlet;
-
-    private ServletMounter mounter;
-
-    public static final String SERVLET_PATH = "/mock";
-
-    public static final String SERVLET_NAME = "TestServlet";
-
-    private static final String SERVLET_EXTENSION = "html";
-
-    private MockResourceResolver mockResourceResolver;
-
-    @Before public void setUp() throws Exception {
-        mockResourceResolver = new MockResourceResolver() {
-            @Override
-            public void close() {
-                // nothing to do;
-            }
-
-            @Override
-            public <AdapterType> AdapterType adaptTo(Class<AdapterType> type) {
-                return null;
-            }
-
-            @Override
-            public ResourceResolver clone(Map<String, Object> authenticationInfo)
-                    throws LoginException {
-                throw new LoginException("MockResourceResolver can't be cloned - excepted for this test!");
-            }
-
-            @Override
-            public void refresh() {
-                // nothing to do
-            }
-        };
-        mockResourceResolver.setSearchPath("/");
-
-        final ResourceResolverFactory factory = new ResourceResolverFactory() {
-
-            @Override
-            public ResourceResolver getAdministrativeResourceResolver(
-                    Map<String, Object> authenticationInfo)
-                    throws LoginException {
-                return mockResourceResolver;
-            }
-
-            @Override
-            public ResourceResolver getResourceResolver(
-                    Map<String, Object> authenticationInfo)
-                    throws LoginException {
-                return mockResourceResolver;
-            }
-
-            @Override
-            public ResourceResolver getServiceResourceResolver(Map<String, Object> authenticationInfo)
-                    throws LoginException {
-                return mockResourceResolver;
-            }
-
-            @Override
-            public ResourceResolver getThreadResourceResolver() {
-                // TODO Auto-generated method stub
-                return null;
-            }
-        };
-
-        servlet = new MockSlingRequestHandlerServlet();
-        mounter = new ServletMounter();
-
-        final Class<?> mounterClass = mounter.getClass();
-
-        // set resource resolver factory
-        final Field resolverField = mounterClass.getDeclaredField("resourceResolverFactory");
-        resolverField.setAccessible(true);
-        resolverField.set(mounter, factory);
-
-        final Bundle bundle = Mockito.mock(Bundle.class);
-        Mockito.when(bundle.getBundleId()).thenReturn(1L);
-
-        final BundleContext bundleContext = Mockito.mock(BundleContext.class);
-        Mockito.when(bundle.getBundleContext()).thenReturn(bundleContext);
-
-        MockServiceReference serviceReference = new MockServiceReference(bundle);
-        serviceReference.setProperty(Constants.SERVICE_ID, 1L);
-        serviceReference.setProperty(ServletResolverConstants.SLING_SERVLET_NAME,
-            SERVLET_NAME);
-        serviceReference.setProperty(
-                ServletResolverConstants.SLING_SERVLET_PATHS, SERVLET_PATH);
-        serviceReference.setProperty(
-            ServletResolverConstants.SLING_SERVLET_EXTENSIONS,
-            SERVLET_EXTENSION);
-
-        mounter.bindServlet(ServletMounterTest.this.servlet, serviceReference);
-        mounter.activate(bundleContext, new SlingServletResolver.Config() {
-
-            @Override
-            public Class<? extends Annotation> annotationType() {
-                return SlingServletResolver.Config.class;
-            }
-
-            @Override
-            public String servletresolver_servletRoot() {
-                return "0";
-            }
-
-            @Override
-            public String[] servletresolver_paths() {
-                return new String[] {"/"};
-            }
-
-            @Override
-            public String[] servletresolver_defaultExtensions() {
-                // TODO Auto-generated method stub
-                return new String[] {"html"};
-            }
-
-            @Override
-            public int servletresolver_cacheSize() {
-                return 200;
-            }
-        });
-
-        String path = "/"
-            + MockSlingHttpServletRequest.RESOURCE_TYPE
-            + "/"
-            + ResourceUtil.getName(MockSlingHttpServletRequest.RESOURCE_TYPE)
-            + ".servlet";
-        MockServletResource res = new MockServletResource(mockResourceResolver,
-            servlet, path);
-        mockResourceResolver.addResource(res);
-
-        MockResource parent = new MockResource(mockResourceResolver,
-            ResourceUtil.getParent(res.getPath()), "nt:folder");
-        mockResourceResolver.addResource(parent);
-
-        List<Resource> childRes = new ArrayList<>();
-        childRes.add(res);
-        mockResourceResolver.addChildren(parent, childRes);
-    }
-
-
-    @Test public void testCreateServiceRegistrationProperties() throws Throwable {
-        MockServiceReference msr = new MockServiceReference(null);
-
-        msr.setProperty(ServletResolverConstants.SLING_SERVLET_RESOURCE_TYPES, "sample");
-        msr.setProperty(ServletResolverConstants.SLING_SERVLET_METHODS, "GET");
-
-        Field srpf = ServletMounter.class.getDeclaredField("servletResourceProviderFactory");
-        srpf.setAccessible(true);
-        ServletResourceProviderFactory factory = (ServletResourceProviderFactory) srpf.get(mounter);
-
-        ServletResourceProvider servlet = factory.create(msr, null);
-
-        Method createServiceProperties = ServletMounter.class.getDeclaredMethod("createServiceProperties", ServiceReference.class, ServletResourceProvider.class, String.class);
-        createServiceProperties.setAccessible(true);
-
-        // no ranking
-        assertNull(msr.getProperty(Constants.SERVICE_RANKING));
-        @SuppressWarnings("unchecked")
-        final Dictionary<String, Object> p1 = (Dictionary<String, Object>) createServiceProperties.invoke(mounter, msr, servlet, "/a");
-        assertNull(p1.get(Constants.SERVICE_RANKING));
-
-        // illegal type of ranking
-        Object nonIntValue = "Some Non Integer Value";
-        msr.setProperty(Constants.SERVICE_RANKING, nonIntValue);
-        assertEquals(nonIntValue, msr.getProperty(Constants.SERVICE_RANKING));
-        @SuppressWarnings("unchecked")
-        final Dictionary<String, Object> p2 = (Dictionary<String, Object>) createServiceProperties.invoke(mounter, msr, servlet, "/a");
-        assertNull(p2.get(Constants.SERVICE_RANKING));
-
-        // illegal type of ranking
-        Object intValue = Integer.valueOf(123);
-        msr.setProperty(Constants.SERVICE_RANKING, intValue);
-        assertEquals(intValue, msr.getProperty(Constants.SERVICE_RANKING));
-        @SuppressWarnings("unchecked")
-        final Dictionary<String, Object> p3 = (Dictionary<String, Object>) createServiceProperties.invoke(mounter, msr, servlet, "/a");
-        assertEquals(intValue, p3.get(Constants.SERVICE_RANKING));
-    }
-
-    /**
-     * This sample servlet will only handle secure requests.
-     *
-     * @see org.apache.sling.api.servlets.OptingServlet#accepts
-     */
-    @SuppressWarnings("serial")
-    private static class MockSlingRequestHandlerServlet extends HttpServlet
-            implements OptingServlet {
-
-        @Override
-        public boolean accepts(SlingHttpServletRequest request) {
-            return request.isSecure();
-        }
-    }
-
-}
diff --git a/src/test/java/org/apache/sling/servlets/resolver/internal/SlingServletResolverTest.java b/src/test/java/org/apache/sling/servlets/resolver/internal/SlingServletResolverTest.java
index 20c71b3..8d9344b 100644
--- a/src/test/java/org/apache/sling/servlets/resolver/internal/SlingServletResolverTest.java
+++ b/src/test/java/org/apache/sling/servlets/resolver/internal/SlingServletResolverTest.java
@@ -24,6 +24,7 @@
 import java.lang.annotation.Annotation;
 import java.lang.reflect.Field;
 import java.util.ArrayList;
+import java.util.Collections;
 import java.util.List;
 import java.util.Map;
 
@@ -117,6 +118,11 @@
                 // TODO Auto-generated method stub
                 return null;
             }
+
+            @Override
+            public List<String> getSearchPath() {
+                return Collections.singletonList("/");
+            }
         };
 
         servlet = new MockSlingRequestHandlerServlet();
@@ -151,11 +157,11 @@
             SERVLET_EXTENSION);
 
 //        servletResolver.bindServlet(SlingServletResolverTest.this.servlet, serviceReference);
-        servletResolver.activate(bundleContext, new SlingServletResolver.Config() {
+        servletResolver.activate(bundleContext, new ResolverConfig() {
 
             @Override
             public Class<? extends Annotation> annotationType() {
-                return SlingServletResolver.Config.class;
+                return ResolverConfig.class;
             }
 
             @Override
diff --git a/src/test/java/org/apache/sling/servlets/resolver/internal/resource/ServletMounterTest.java b/src/test/java/org/apache/sling/servlets/resolver/internal/resource/ServletMounterTest.java
new file mode 100644
index 0000000..cf90c49
--- /dev/null
+++ b/src/test/java/org/apache/sling/servlets/resolver/internal/resource/ServletMounterTest.java
@@ -0,0 +1,125 @@
+/*
+ * 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.servlets.resolver.internal.resource;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertNull;
+
+import java.lang.reflect.Field;
+import java.lang.reflect.Method;
+import java.util.Collections;
+import java.util.Dictionary;
+
+import javax.servlet.Servlet;
+
+import org.apache.sling.api.resource.ResourceResolverFactory;
+import org.apache.sling.api.servlets.ServletResolverConstants;
+import org.apache.sling.servlets.resolver.internal.ResolverConfig;
+import org.apache.sling.spi.resource.provider.ResourceProvider;
+import org.junit.Before;
+import org.junit.Test;
+import org.mockito.Mockito;
+import org.osgi.framework.Bundle;
+import org.osgi.framework.BundleContext;
+import org.osgi.framework.Constants;
+import org.osgi.framework.ServiceReference;
+
+public class ServletMounterTest {
+
+    private ServletMounter mounter;
+
+    @Before public void setUp() throws Exception {
+        final ResolverConfig config = Mockito.mock(ResolverConfig.class);
+        Mockito.when(config.servletresolver_servletRoot()).thenReturn("0");
+        Mockito.when(config.servletresolver_paths()).thenReturn(new String[] { "/"});
+        Mockito.when(config.servletresolver_defaultExtensions()).thenReturn(new String[] {"html"});
+        Mockito.when(config.servletresolver_cacheSize()).thenReturn(200);
+
+        // create mock for resource resolver factory
+        final ResourceResolverFactory factory = Mockito.mock(ResourceResolverFactory.class);
+        Mockito.when(factory.getSearchPath()).thenReturn(Collections.singletonList("/"));
+
+        // create mounter
+        this.mounter = new ServletMounter();
+
+        // set resource resolver factory
+        final Field resolverField = ServletMounter.class.getDeclaredField("resourceResolverFactory");
+        resolverField.setAccessible(true);
+        resolverField.set(mounter, factory);
+
+        // create mock bundle
+        final Bundle bundle = Mockito.mock(Bundle.class);
+        Mockito.when(bundle.getBundleId()).thenReturn(1L);
+
+        // create mock bundle context
+        final BundleContext bundleContext = Mockito.mock(BundleContext.class);
+        Mockito.when(bundle.getBundleContext()).thenReturn(bundleContext);
+
+        // activate mounter
+        this.mounter.activate(bundleContext, config);
+    }
+
+
+    @Test public void testCreateServiceProperties() throws Throwable {
+        @SuppressWarnings("unchecked")
+        final ServiceReference<Servlet> msr = Mockito.mock(ServiceReference.class);
+        Mockito.when(msr.getProperty(ServletResolverConstants.SLING_SERVLET_RESOURCE_TYPES))
+            .thenReturn("sample");
+        Mockito.when(msr.getProperty(ServletResolverConstants.SLING_SERVLET_METHODS))
+            .thenReturn("GET");
+
+        Method createServiceProperties = ServletMounter.class.getDeclaredMethod("createServiceProperties",
+                ServiceReference.class, String.class);
+        createServiceProperties.setAccessible(true);
+
+        // no ranking
+        assertNull(msr.getProperty(Constants.SERVICE_RANKING));
+        @SuppressWarnings("unchecked")
+        final Dictionary<String, Object> p1 = (Dictionary<String, Object>) createServiceProperties.invoke(mounter, msr, "/a");
+        assertEquals(2, p1.size());
+        assertNull(p1.get(Constants.SERVICE_RANKING));
+        assertEquals("/a", p1.get(ResourceProvider.PROPERTY_ROOT));
+        assertNotNull(p1.get(Constants.SERVICE_DESCRIPTION));
+
+        // illegal type of ranking
+        Object nonIntValue = "Some Non Integer Value";
+        Mockito.when(msr.getProperty(Constants.SERVICE_RANKING))
+            .thenReturn(nonIntValue);
+        assertEquals(nonIntValue, msr.getProperty(Constants.SERVICE_RANKING));
+        @SuppressWarnings("unchecked")
+        final Dictionary<String, Object> p2 = (Dictionary<String, Object>) createServiceProperties.invoke(mounter, msr, "/b");
+        assertEquals(2, p2.size());
+        assertNull(p2.get(Constants.SERVICE_RANKING));
+        assertEquals("/b", p2.get(ResourceProvider.PROPERTY_ROOT));
+        assertNotNull(p2.get(Constants.SERVICE_DESCRIPTION));
+
+        // illegal type of ranking
+        Object intValue = Integer.valueOf(123);
+        Mockito.when(msr.getProperty(Constants.SERVICE_RANKING))
+            .thenReturn(intValue);
+        assertEquals(intValue, msr.getProperty(Constants.SERVICE_RANKING));
+        @SuppressWarnings("unchecked")
+        final Dictionary<String, Object> p3 = (Dictionary<String, Object>) createServiceProperties.invoke(mounter, msr, "/c");
+        assertEquals(3, p3.size());
+        assertEquals(intValue, p3.get(Constants.SERVICE_RANKING));
+        assertEquals("/c", p3.get(ResourceProvider.PROPERTY_ROOT));
+        assertNotNull(p3.get(Constants.SERVICE_DESCRIPTION));
+    }
+}
diff --git a/src/test/java/org/apache/sling/servlets/resolver/internal/resource/ServletResourceProviderCreateTest.java b/src/test/java/org/apache/sling/servlets/resolver/internal/resource/ServletResourceProviderCreateTest.java
index cbced7b..d1e3f6e 100644
--- a/src/test/java/org/apache/sling/servlets/resolver/internal/resource/ServletResourceProviderCreateTest.java
+++ b/src/test/java/org/apache/sling/servlets/resolver/internal/resource/ServletResourceProviderCreateTest.java
@@ -18,6 +18,11 @@
  */
 package org.apache.sling.servlets.resolver.internal.resource;
 
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertTrue;
+
+import java.util.Collections;
 import java.util.HashSet;
 import java.util.Set;
 
@@ -29,13 +34,16 @@
 import org.apache.sling.api.resource.ResourceUtil;
 import org.apache.sling.api.servlets.HttpConstants;
 import org.apache.sling.api.servlets.ServletResolverConstants;
-import org.apache.sling.commons.testing.osgi.MockServiceReference;
+import org.junit.Test;
+import org.mockito.Mockito;
+import org.osgi.framework.Constants;
+import org.osgi.framework.ServiceReference;
 
-import junit.framework.TestCase;
-
-public class ServletResourceProviderCreateTest extends TestCase {
+public class ServletResourceProviderCreateTest {
 
     private static final Servlet TEST_SERVLET = new GenericServlet() {
+        private static final long serialVersionUID = 1L;
+
         @Override
         public void service(ServletRequest req, ServletResponse res) {
         }
@@ -48,20 +56,22 @@
     private static final String RES_TYPE_PATH = ResourceUtil.resourceTypeToPath(RES_TYPE);
 
     private ServletResourceProviderFactory factory = new ServletResourceProviderFactory(
-        ROOT, new String[] {"/apps/"});
+        ROOT, Collections.singletonList("/apps/"));
 
-    public void testCreateMethodsDefault() {
-        MockServiceReference msr = new MockServiceReference(null);
+    @Test public void testCreateMethodsDefault() {
+        @SuppressWarnings("unchecked")
+        final ServiceReference<Servlet> msr = Mockito.mock(ServiceReference.class);
+        Mockito.when(msr.getProperty(Constants.SERVICE_ID))
+           .thenReturn(1L);
+        Mockito.when(msr.getProperty(ServletResolverConstants.SLING_SERVLET_RESOURCE_TYPES))
+           .thenReturn(RES_TYPE);
 
-        msr.setProperty(ServletResolverConstants.SLING_SERVLET_RESOURCE_TYPES,
-            RES_TYPE);
-        // msr.setProperty(ServletResolverConstants.SLING_SERVLET_METHODS, "*");
         ServletResourceProvider srp = factory.create(msr, TEST_SERVLET);
         assertNotNull(srp);
 
-        String[] paths = srp.getServletPaths();
+        final Set<String> paths = srp.getServletPaths();
         assertNotNull(paths);
-        assertEquals(2, paths.length);
+        assertEquals(2, paths.size());
 
         Set<String> checkerSet = new HashSet<>();
         checkerSet.add(ROOT + RES_TYPE_PATH + "/" + HttpConstants.METHOD_GET
@@ -76,19 +86,22 @@
         assertTrue(checkerSet.isEmpty());
     }
 
-    public void testCreateMethodsSingle() {
-        MockServiceReference msr = new MockServiceReference(null);
-
-        msr.setProperty(ServletResolverConstants.SLING_SERVLET_RESOURCE_TYPES,
-            RES_TYPE);
-        msr.setProperty(ServletResolverConstants.SLING_SERVLET_METHODS, "GET");
+    @Test public void testCreateMethodsSingle() {
+        @SuppressWarnings("unchecked")
+        final ServiceReference<Servlet> msr = Mockito.mock(ServiceReference.class);
+        Mockito.when(msr.getProperty(Constants.SERVICE_ID))
+           .thenReturn(1L);
+        Mockito.when(msr.getProperty(ServletResolverConstants.SLING_SERVLET_RESOURCE_TYPES))
+           .thenReturn(RES_TYPE);
+        Mockito.when(msr.getProperty(ServletResolverConstants.SLING_SERVLET_METHODS))
+            .thenReturn("GET");
 
         ServletResourceProvider srp = factory.create(msr, TEST_SERVLET);
         assertNotNull(srp);
 
-        String[] paths = srp.getServletPaths();
+        final Set<String> paths = srp.getServletPaths();
         assertNotNull(paths);
-        assertEquals(1, paths.length);
+        assertEquals(1, paths.size());
 
         Set<String> checkerSet = new HashSet<>();
         checkerSet.add(ROOT + RES_TYPE_PATH + "/" + HttpConstants.METHOD_GET
@@ -101,20 +114,22 @@
         assertTrue(checkerSet.isEmpty());
     }
 
-    public void testCreateMethodsMultiple() {
-        MockServiceReference msr = new MockServiceReference(null);
-
-        msr.setProperty(ServletResolverConstants.SLING_SERVLET_RESOURCE_TYPES,
-            RES_TYPE);
-        msr.setProperty(ServletResolverConstants.SLING_SERVLET_METHODS,
-            new String[] { "GET", "POST", "PUT" });
+    @Test public void testCreateMethodsMultiple() {
+        @SuppressWarnings("unchecked")
+        final ServiceReference<Servlet> msr = Mockito.mock(ServiceReference.class);
+        Mockito.when(msr.getProperty(Constants.SERVICE_ID))
+           .thenReturn(1L);
+        Mockito.when(msr.getProperty(ServletResolverConstants.SLING_SERVLET_RESOURCE_TYPES))
+           .thenReturn(RES_TYPE);
+        Mockito.when(msr.getProperty(ServletResolverConstants.SLING_SERVLET_METHODS))
+            .thenReturn(new String[] { "GET", "POST", "PUT" });
 
         ServletResourceProvider srp = factory.create(msr, TEST_SERVLET);
         assertNotNull(srp);
 
-        String[] paths = srp.getServletPaths();
+        final Set<String> paths = srp.getServletPaths();
         assertNotNull(paths);
-        assertEquals(3, paths.length);
+        assertEquals(3, paths.size());
 
         Set<String> checkerSet = new HashSet<>();
         checkerSet.add(ROOT + RES_TYPE_PATH + "/" + HttpConstants.METHOD_GET
@@ -131,19 +146,22 @@
         assertTrue(checkerSet.isEmpty());
     }
 
-    public void testCreateMethodsAll() {
-        MockServiceReference msr = new MockServiceReference(null);
-
-        msr.setProperty(ServletResolverConstants.SLING_SERVLET_RESOURCE_TYPES,
-            RES_TYPE);
-        msr.setProperty(ServletResolverConstants.SLING_SERVLET_METHODS, "*");
+    @Test public void testCreateMethodsAll() {
+        @SuppressWarnings("unchecked")
+        final ServiceReference<Servlet> msr = Mockito.mock(ServiceReference.class);
+        Mockito.when(msr.getProperty(Constants.SERVICE_ID))
+           .thenReturn(1L);
+        Mockito.when(msr.getProperty(ServletResolverConstants.SLING_SERVLET_RESOURCE_TYPES))
+           .thenReturn(RES_TYPE);
+        Mockito.when(msr.getProperty(ServletResolverConstants.SLING_SERVLET_METHODS))
+            .thenReturn("*");
 
         ServletResourceProvider srp = factory.create(msr, TEST_SERVLET);
         assertNotNull(srp);
 
-        String[] paths = srp.getServletPaths();
+        final Set<String> paths = srp.getServletPaths();
         assertNotNull(paths);
-        assertEquals(1, paths.length);
+        assertEquals(1, paths.size());
 
         Set<String> checkerSet = new HashSet<>();
         checkerSet.add(ROOT + RES_TYPE_PATH
@@ -156,24 +174,26 @@
         assertTrue(checkerSet.isEmpty());
     }
 
-    public void testCreateSelectorsExtensions() {
-        MockServiceReference msr = new MockServiceReference(null);
-
-        msr.setProperty(ServletResolverConstants.SLING_SERVLET_RESOURCE_TYPES,
-            RES_TYPE);
-        msr.setProperty(ServletResolverConstants.SLING_SERVLET_METHODS,
-            new String[] { HttpConstants.METHOD_GET });
-        msr.setProperty(ServletResolverConstants.SLING_SERVLET_SELECTORS,
-            new String[] { "ext" });
-        msr.setProperty(ServletResolverConstants.SLING_SERVLET_EXTENSIONS,
-            new String[] { "json" });
+    @Test public void testCreateSelectorsExtensions() {
+        @SuppressWarnings("unchecked")
+        final ServiceReference<Servlet> msr = Mockito.mock(ServiceReference.class);
+        Mockito.when(msr.getProperty(Constants.SERVICE_ID))
+           .thenReturn(1L);
+        Mockito.when(msr.getProperty(ServletResolverConstants.SLING_SERVLET_RESOURCE_TYPES))
+           .thenReturn(RES_TYPE);
+        Mockito.when(msr.getProperty(ServletResolverConstants.SLING_SERVLET_METHODS))
+            .thenReturn(new String[] { HttpConstants.METHOD_GET });
+        Mockito.when(msr.getProperty(ServletResolverConstants.SLING_SERVLET_SELECTORS))
+            .thenReturn(new String[] { "ext" });
+        Mockito.when(msr.getProperty(ServletResolverConstants.SLING_SERVLET_EXTENSIONS))
+            .thenReturn(new String[] { "json" });
 
         ServletResourceProvider srp = factory.create(msr, TEST_SERVLET);
         assertNotNull(srp);
 
-        String[] paths = srp.getServletPaths();
+        final Set<String> paths = srp.getServletPaths();
         assertNotNull(paths);
-        assertEquals(1, paths.length);
+        assertEquals(1, paths.size());
 
         Set<String> checkerSet = new HashSet<>();
         checkerSet.add(ROOT + RES_TYPE_PATH + "/ext.json."
@@ -186,22 +206,25 @@
 
         assertTrue(checkerSet.isEmpty());
     }
-    public void testCreateMethodsExtensions() {
-        MockServiceReference msr = new MockServiceReference(null);
 
-        msr.setProperty(ServletResolverConstants.SLING_SERVLET_RESOURCE_TYPES,
-            RES_TYPE);
-        msr.setProperty(ServletResolverConstants.SLING_SERVLET_METHODS,
-            new String[] { HttpConstants.METHOD_GET, HttpConstants.METHOD_POST });
-        msr.setProperty(ServletResolverConstants.SLING_SERVLET_EXTENSIONS,
-            new String[] { "json", "html" });
+    @Test public void testCreateMethodsExtensions() {
+        @SuppressWarnings("unchecked")
+        final ServiceReference<Servlet> msr = Mockito.mock(ServiceReference.class);
+        Mockito.when(msr.getProperty(Constants.SERVICE_ID))
+           .thenReturn(1L);
+        Mockito.when(msr.getProperty(ServletResolverConstants.SLING_SERVLET_RESOURCE_TYPES))
+           .thenReturn(RES_TYPE);
+        Mockito.when(msr.getProperty(ServletResolverConstants.SLING_SERVLET_METHODS))
+            .thenReturn(new String[] { HttpConstants.METHOD_GET, HttpConstants.METHOD_POST });
+        Mockito.when(msr.getProperty(ServletResolverConstants.SLING_SERVLET_EXTENSIONS))
+            .thenReturn(new String[] { "json", "html" });
 
         ServletResourceProvider srp = factory.create(msr, TEST_SERVLET);
         assertNotNull(srp);
 
-        String[] paths = srp.getServletPaths();
+        final Set<String> paths = srp.getServletPaths();
         assertNotNull(paths);
-        assertEquals(4, paths.length);
+        assertEquals(4, paths.size());
 
         Set<String> checkerSet = new HashSet<>();
         checkerSet.add(ROOT + RES_TYPE_PATH + "/json."