diff --git a/src/main/java/org/apache/sling/servlets/resolver/internal/ServletMounter.java b/src/main/java/org/apache/sling/servlets/resolver/internal/ServletMounter.java
new file mode 100644
index 0000000..d62b3c9
--- /dev/null
+++ b/src/main/java/org/apache/sling/servlets/resolver/internal/ServletMounter.java
@@ -0,0 +1,343 @@
+/*
+ * 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.apache.sling.api.servlets.ServletResolverConstants.SLING_SERVLET_NAME;
+import static org.osgi.framework.Constants.SERVICE_ID;
+import static org.osgi.framework.Constants.SERVICE_PID;
+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;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+
+import javax.servlet.Servlet;
+import javax.servlet.ServletContext;
+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.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;
+import org.osgi.framework.Constants;
+import org.osgi.framework.ServiceReference;
+import org.osgi.framework.ServiceRegistration;
+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.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * The <code>SlingServletResolver</code> resolves a
+ * servlet for a request by implementing the {@link ServletResolver} interface.
+ *
+ * The resolver uses an own session to find the scripts.
+ *
+ */
+@Component(configurationPid = SlingServletResolver.Config.PID,
+           service = {})
+public class ServletMounter {
+
+
+    /** Logger */
+    public final Logger logger = LoggerFactory.getLogger(this.getClass());
+
+    private static final String REF_SERVLET = "Servlet";
+
+    @Reference(target="(name=org.apache.sling)")
+    private ServletContext servletContext;
+
+    private final Map<ServiceReference<Servlet>, ServletReg> servletsByReference = new HashMap<>();
+
+    private final List<PendingServlet> pendingServlets = new ArrayList<>();
+
+    /** The bundle context. */
+    private volatile BundleContext context;
+
+    private volatile ServletResourceProviderFactory servletResourceProviderFactory;
+
+    @Reference
+    private ResourceResolverFactory resourceResolverFactory;
+
+    @Reference(target="("+ServiceUserMapped.SUBSERVICENAME+"=scripts)")
+    private ServiceUserMapped scriptServiceUserMapped;
+
+    /**
+     * Activate this component.
+     */
+    @Activate
+    private void activate(final BundleContext context,
+            final SlingServletResolver.Config config)
+    throws LoginException {
+        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());
+            }
+
+            // register servlets immediately from now on
+            this.context = context;
+        }
+        createAllServlets(refs);
+    }
+
+    /**
+     * Deactivate this component.
+     */
+    @Deactivate
+    protected void deactivate() {
+        // stop registering of servlets immediately
+        this.context = null;
+
+        // Copy the list of servlets first, to minimize the need for
+        // synchronization
+        final Collection<ServiceReference<Servlet>> refs;
+        synchronized (this.servletsByReference) {
+            refs = new ArrayList<>(servletsByReference.keySet());
+        }
+        // destroy all servlets
+        destroyAllServlets(refs);
+
+        // sanity check: clear array (it should be empty now anyway)
+        synchronized ( this.servletsByReference ) {
+            this.servletsByReference.clear();
+        }
+
+        this.servletResourceProviderFactory = null;
+    }
+
+    // TODO
+    // This can be simplified once we can use DS from R7 with constructor injection
+    // as we can inject the bundle context through the constructor
+    @Reference(
+            name = REF_SERVLET,
+            service = Servlet.class,
+            cardinality = ReferenceCardinality.MULTIPLE,
+            policy = ReferencePolicy.DYNAMIC,
+            target="(|(" + ServletResolverConstants.SLING_SERVLET_PATHS + "=*)(" + ServletResolverConstants.SLING_SERVLET_RESOURCE_TYPES + "=*))")
+    protected void bindServlet(final Servlet servlet, final ServiceReference<Servlet> reference) {
+        boolean directCreate = true;
+        if (context == null) {
+            synchronized ( pendingServlets ) {
+                if (context == null) {
+                    pendingServlets.add(new PendingServlet(servlet, reference));
+                    directCreate = false;
+                }
+            }
+        }
+        if ( directCreate ) {
+            createServlet(servlet, reference);
+        }
+    }
+
+    protected void unbindServlet(final ServiceReference<Servlet> reference) {
+        synchronized ( pendingServlets ) {
+            final Iterator<PendingServlet> iter = pendingServlets.iterator();
+            while ( iter.hasNext() ) {
+                final PendingServlet ps = iter.next();
+                if ( ps.reference.compareTo(reference) == 0 ) {
+                    iter.remove();
+                    break;
+                }
+            }
+        }
+        destroyServlet(reference);
+    }
+
+    private void createAllServlets(final Collection<PendingServlet> pendingServlets) {
+        for (final PendingServlet ps : pendingServlets) {
+            createServlet(ps.servlet, ps.reference);
+        }
+    }
+
+
+    private boolean createServlet(final Servlet servlet, final ServiceReference<Servlet> reference) {
+        // check for a name, this is required
+        final String name = getName(reference);
+
+        // check for Sling properties in the service registration
+        final ServletResourceProvider provider = servletResourceProviderFactory.create(reference, servlet);
+        if (provider == null) {
+            // this is expected if the servlet is not destined for Sling
+            return false;
+        }
+
+        // initialize now
+        try {
+            servlet.init(new SlingServletConfig(servletContext, reference, name));
+            logger.debug("bindServlet: Servlet {} initialized", name);
+        } catch (final ServletException ce) {
+            logger.error("bindServlet: Servlet " + ServletResourceProviderFactory.getServiceReferenceInfo(reference) + " failed to initialize", ce);
+            return false;
+        } catch (final Throwable t) {
+            logger.error("bindServlet: Unexpected problem initializing servlet " + ServletResourceProviderFactory.getServiceReferenceInfo(reference), t);
+            return false;
+        }
+
+        boolean registered = false;
+        final Bundle bundle = reference.getBundle();
+        if ( bundle != null ) {
+            final BundleContext bundleContext = bundle.getBundleContext();
+            if ( bundleContext != null ) {
+                final List<ServiceRegistration<ResourceProvider<Object>>> regs = new ArrayList<>();
+                try {
+                    for(final String root : provider.getServletPaths()) {
+                        @SuppressWarnings("unchecked")
+                        final ServiceRegistration<ResourceProvider<Object>> reg = (ServiceRegistration<ResourceProvider<Object>>) bundleContext.registerService(
+                            ResourceProvider.class.getName(),
+                            provider,
+                            createServiceProperties(reference, provider, root));
+                        regs.add(reg);
+                    }
+                    registered = true;
+                } catch ( final IllegalStateException ise ) {
+                    // bundle context not valid anymore - ignore and continue without this
+                }
+                if ( registered ) {
+                    if ( logger.isDebugEnabled() ) {
+                        logger.debug("Registered {}", provider);
+                    }
+                    synchronized (this.servletsByReference) {
+                        servletsByReference.put(reference, new ServletReg(servlet, regs));
+                    }
+                }
+            }
+        }
+        if ( !registered ) {
+            logger.debug("bindServlet: servlet has been unregistered in the meantime. Ignoring {}", name);
+        }
+
+        return true;
+    }
+
+    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()));
+
+        // inherit service ranking
+        Object rank = reference.getProperty(Constants.SERVICE_RANKING);
+        if (rank instanceof Integer) {
+            params.put(Constants.SERVICE_RANKING, rank);
+        }
+
+        return params;
+    }
+
+    private void destroyAllServlets(final Collection<ServiceReference<Servlet>> refs) {
+        for (ServiceReference<Servlet> serviceReference : refs) {
+            destroyServlet(serviceReference);
+        }
+    }
+
+    private void destroyServlet(final ServiceReference<Servlet> reference) {
+        ServletReg registration;
+        synchronized (this.servletsByReference) {
+            registration = servletsByReference.remove(reference);
+        }
+        if (registration != null) {
+
+            for(final ServiceRegistration<ResourceProvider<Object>> reg : registration.registrations) {
+                try {
+                    reg.unregister();
+                } catch ( final IllegalStateException ise) {
+                    // this might happen on shutdown
+                }
+            }
+            final String name = RequestUtil.getServletName(registration.servlet);
+            logger.debug("unbindServlet: Servlet {} removed", name);
+
+            try {
+                registration.servlet.destroy();
+            } catch (Throwable t) {
+                logger.error("unbindServlet: Unexpected problem destroying servlet " + name, t);
+            }
+        }
+    }
+
+    /** The list of property names checked by {@link #getName(ServiceReference)} */
+    private static final String[] NAME_PROPERTIES = { SLING_SERVLET_NAME,
+        COMPONENT_NAME, SERVICE_PID, SERVICE_ID };
+
+    /**
+     * Looks for a name value in the service reference properties. See the
+     * class comment at the top for the list of properties checked by this
+     * method.
+     * @return The servlet name. This method never returns {@code null}
+     */
+    private static String getName(final ServiceReference<Servlet> reference) {
+        String servletName = null;
+        for (int i = 0; i < NAME_PROPERTIES.length
+            && (servletName == null || servletName.length() == 0); i++) {
+            Object prop = reference.getProperty(NAME_PROPERTIES[i]);
+            if (prop != null) {
+                servletName = String.valueOf(prop);
+            }
+        }
+        return servletName;
+    }
+
+    private static final class ServletReg {
+        public final Servlet servlet;
+        public final List<ServiceRegistration<ResourceProvider<Object>>> registrations;
+
+        public ServletReg(final Servlet s, final List<ServiceRegistration<ResourceProvider<Object>>> srs) {
+            this.servlet = s;
+            this.registrations = srs;
+        }
+    }
+
+    private static final class PendingServlet {
+        public final Servlet servlet;
+        public final ServiceReference<Servlet> reference;
+
+        public PendingServlet(final Servlet s, final ServiceReference<Servlet> ref) {
+            this.servlet = s;
+            this.reference = ref;
+        }
+    }
+}
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 842d144..1e381e9 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
@@ -23,24 +23,15 @@
 import static org.apache.sling.api.SlingConstants.ERROR_STATUS;
 import static org.apache.sling.api.SlingConstants.SLING_CURRENT_SERVLET_NAME;
 import static org.apache.sling.api.servlets.ServletResolverConstants.DEFAULT_ERROR_HANDLER_RESOURCE_TYPE;
-import static org.apache.sling.api.servlets.ServletResolverConstants.SLING_SERVLET_NAME;
-import static org.osgi.framework.Constants.SERVICE_ID;
-import static org.osgi.framework.Constants.SERVICE_PID;
-import static org.osgi.service.component.ComponentConstants.COMPONENT_NAME;
 
 import java.io.IOException;
 import java.io.PrintWriter;
 import java.net.URL;
-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;
 import java.util.Iterator;
-import java.util.List;
-import java.util.Map;
 
 import javax.servlet.Servlet;
 import javax.servlet.ServletContext;
@@ -78,20 +69,13 @@
 import org.apache.sling.servlets.resolver.internal.helper.ResourceCollector;
 import org.apache.sling.servlets.resolver.internal.helper.SlingServletConfig;
 import org.apache.sling.servlets.resolver.internal.resolution.ResolutionCache;
-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;
 import org.osgi.framework.Constants;
-import org.osgi.framework.ServiceReference;
 import org.osgi.framework.ServiceRegistration;
 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.metatype.annotations.AttributeDefinition;
 import org.osgi.service.metatype.annotations.Designate;
 import org.osgi.service.metatype.annotations.ObjectClassDefinition;
@@ -163,11 +147,6 @@
     /** Servlet resolver logger */
     public static final Logger LOGGER = LoggerFactory.getLogger(SlingServletResolver.class);
 
-    private static final String REF_SERVLET = "Servlet";
-
-    @Reference(target="(name=org.apache.sling)")
-    private ServletContext servletContext;
-
     @Reference
     private ResourceResolverFactory resourceResolverFactory;
 
@@ -180,18 +159,10 @@
     @Reference
     private ResolutionCache resolutionCache;
 
-    private List<String> scriptEnginesExtensions = new ArrayList<>();
-
     private ResourceResolver sharedScriptResolver;
 
-    private final Map<ServiceReference<Servlet>, ServletReg> servletsByReference = new HashMap<>();
-
-    private final List<PendingServlet> pendingServlets = new ArrayList<>();
-
-    /** The bundle context. */
-    private volatile BundleContext context;
-
-    private ServletResourceProviderFactory servletResourceProviderFactory;
+    @Reference(target="(name=org.apache.sling)")
+    private ServletContext servletContext;
 
     // the default servlet if no other servlet applies for a request. This
     // field is set on demand by getDefaultServlet()
@@ -207,11 +178,6 @@
     private String[] executionPaths;
 
     /**
-     * The search paths
-     */
-    private String[] searchPaths;
-
-    /**
      * The default extensions
      */
     private String[] defaultExtensions;
@@ -345,8 +311,6 @@
         return new ScriptResource(scriptResource, perThreadScriptResolver, this.sharedScriptResolver).adaptTo(Servlet.class);
     }
 
-    // ---------- ScriptResolver interface ------------------------------------
-
     // ---------- ErrorHandler interface --------------------------------------
 
     /**
@@ -591,7 +555,7 @@
             return scriptServlet;
         }
 
-        final Collection<Resource> candidates = locationUtil.getServlets(resolver, scriptEnginesExtensions);
+        final Collection<Resource> candidates = locationUtil.getServlets(resolver, localCache.getScriptEngineExtensions());
 
         if (LOGGER.isDebugEnabled()) {
             if (candidates.isEmpty()) {
@@ -734,21 +698,8 @@
      */
     @Activate
     protected void activate(final BundleContext context, final Config config) throws LoginException {
-        final Collection<PendingServlet> refs;
-        synchronized (this.pendingServlets) {
-
-            refs = new ArrayList<>(pendingServlets);
-            pendingServlets.clear();
-
-            this.sharedScriptResolver =
-                    resourceResolverFactory.getServiceResourceResolver(Collections.singletonMap(ResourceResolverFactory.SUBSERVICE, (Object)"scripts"));
-            this.searchPaths = this.sharedScriptResolver.getSearchPath();
-            servletResourceProviderFactory = new ServletResourceProviderFactory(config.servletresolver_servletRoot(), this.searchPaths);
-
-            // register servlets immediately from now on
-            this.context = context;
-        }
-        createAllServlets(refs);
+        this.sharedScriptResolver =
+                resourceResolverFactory.getServiceResourceResolver(Collections.singletonMap(ResourceResolverFactory.SUBSERVICE, (Object)"scripts"));
 
         this.executionPaths = AbstractResourceCollector.getExecutionPaths(config.servletresolver_paths());
         this.defaultExtensions = config.servletresolver_defaultExtensions();
@@ -764,27 +715,10 @@
      */
     @Deactivate
     protected void deactivate() {
-        // stop registering of servlets immediately
-        this.context = null;
-
         if (this.plugin != null) {
             this.plugin.dispose();
         }
 
-        // Copy the list of servlets first, to minimize the need for
-        // synchronization
-        final Collection<ServiceReference<Servlet>> refs;
-        synchronized (this.servletsByReference) {
-            refs = new ArrayList<>(servletsByReference.keySet());
-        }
-        // destroy all servlets
-        destroyAllServlets(refs);
-
-        // sanity check: clear array (it should be empty now anyway)
-        synchronized ( this.servletsByReference ) {
-            this.servletsByReference.clear();
-        }
-
         // destroy the fallback error handler servlet
         if (fallbackErrorServlet != null) {
             try {
@@ -800,211 +734,12 @@
             this.sharedScriptResolver.close();
             this.sharedScriptResolver = null;
         }
-
-        this.servletResourceProviderFactory = null;
-    }
-
-    // TODO
-    // This can be simplified once we can use DS from R7 with constructor injection
-    // as we can inject the bundle context through the constructor
-    @Reference(
-            name = REF_SERVLET,
-            service = Servlet.class,
-            cardinality = ReferenceCardinality.MULTIPLE,
-            policy = ReferencePolicy.DYNAMIC,
-            target="(|(" + ServletResolverConstants.SLING_SERVLET_PATHS + "=*)(" + ServletResolverConstants.SLING_SERVLET_RESOURCE_TYPES + "=*))")
-    protected void bindServlet(final Servlet servlet, final ServiceReference<Servlet> reference) {
-        boolean directCreate = true;
-        if (context == null) {
-            synchronized ( pendingServlets ) {
-                if (context == null) {
-                    pendingServlets.add(new PendingServlet(servlet, reference));
-                    directCreate = false;
-                }
-            }
-        }
-        if ( directCreate ) {
-            createServlet(servlet, reference);
-        }
-    }
-
-    protected void unbindServlet(final ServiceReference<Servlet> reference) {
-        synchronized ( pendingServlets ) {
-            final Iterator<PendingServlet> iter = pendingServlets.iterator();
-            while ( iter.hasNext() ) {
-                final PendingServlet ps = iter.next();
-                if ( ps.reference.compareTo(reference) == 0 ) {
-                    iter.remove();
-                    break;
-                }
-            }
-        }
-        destroyServlet(reference);
-    }
-
-    // ---------- Servlet Management -------------------------------------------
-
-    private void createAllServlets(final Collection<PendingServlet> pendingServlets) {
-        for (final PendingServlet ps : pendingServlets) {
-            createServlet(ps.servlet, ps.reference);
-        }
-    }
-
-
-    private boolean createServlet(final Servlet servlet, final ServiceReference<Servlet> reference) {
-        // check for a name, this is required
-        final String name = getName(reference);
-
-        // check for Sling properties in the service registration
-        final ServletResourceProvider provider = servletResourceProviderFactory.create(reference, servlet);
-        if (provider == null) {
-            // this is expected if the servlet is not destined for Sling
-            return false;
-        }
-
-        // initialize now
-        try {
-            servlet.init(new SlingServletConfig(servletContext, reference, name));
-            LOGGER.debug("bindServlet: Servlet {} initialized", name);
-        } catch (final ServletException ce) {
-            LOGGER.error("bindServlet: Servlet " + ServletResourceProviderFactory.getServiceReferenceInfo(reference) + " failed to initialize", ce);
-            return false;
-        } catch (final Throwable t) {
-            LOGGER.error("bindServlet: Unexpected problem initializing servlet " + ServletResourceProviderFactory.getServiceReferenceInfo(reference), t);
-            return false;
-        }
-
-        boolean registered = false;
-        final Bundle bundle = reference.getBundle();
-        if ( bundle != null ) {
-            final BundleContext bundleContext = bundle.getBundleContext();
-            if ( bundleContext != null ) {
-                final List<ServiceRegistration<ResourceProvider<Object>>> regs = new ArrayList<>();
-                try {
-                    for(final String root : provider.getServletPaths()) {
-                        @SuppressWarnings("unchecked")
-                        final ServiceRegistration<ResourceProvider<Object>> reg = (ServiceRegistration<ResourceProvider<Object>>) bundleContext.registerService(
-                            ResourceProvider.class.getName(),
-                            provider,
-                            createServiceProperties(reference, provider, root));
-                        regs.add(reg);
-                    }
-                    registered = true;
-                } catch ( final IllegalStateException ise ) {
-                    // bundle context not valid anymore - ignore and continue without this
-                }
-                if ( registered ) {
-                    if ( LOGGER.isDebugEnabled() ) {
-                        LOGGER.debug("Registered {}", provider);
-                    }
-                    synchronized (this.servletsByReference) {
-                        servletsByReference.put(reference, new ServletReg(servlet, regs));
-                    }
-                }
-            }
-        }
-        if ( !registered ) {
-            LOGGER.debug("bindServlet: servlet has been unregistered in the meantime. Ignoring {}", name);
-        }
-
-        return true;
-    }
-
-    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()));
-
-        // inherit service ranking
-        Object rank = reference.getProperty(Constants.SERVICE_RANKING);
-        if (rank instanceof Integer) {
-            params.put(Constants.SERVICE_RANKING, rank);
-        }
-
-        return params;
-    }
-
-    private void destroyAllServlets(final Collection<ServiceReference<Servlet>> refs) {
-        for (ServiceReference<Servlet> serviceReference : refs) {
-            destroyServlet(serviceReference);
-        }
-    }
-
-    private void destroyServlet(final ServiceReference<Servlet> reference) {
-        ServletReg registration;
-        synchronized (this.servletsByReference) {
-            registration = servletsByReference.remove(reference);
-        }
-        if (registration != null) {
-
-            for(final ServiceRegistration<ResourceProvider<Object>> reg : registration.registrations) {
-                try {
-                    reg.unregister();
-                } catch ( final IllegalStateException ise) {
-                    // this might happen on shutdown
-                }
-            }
-            final String name = RequestUtil.getServletName(registration.servlet);
-            LOGGER.debug("unbindServlet: Servlet {} removed", name);
-
-            try {
-                registration.servlet.destroy();
-            } catch (Throwable t) {
-                LOGGER.error("unbindServlet: Unexpected problem destroying servlet " + name, t);
-            }
-        }
-    }
-
-    /** The list of property names checked by {@link #getName(ServiceReference)} */
-    private static final String[] NAME_PROPERTIES = { SLING_SERVLET_NAME,
-        COMPONENT_NAME, SERVICE_PID, SERVICE_ID };
-
-    /**
-     * Looks for a name value in the service reference properties. See the
-     * class comment at the top for the list of properties checked by this
-     * method.
-     * @return The servlet name. This method never returns {@code null}
-     */
-    private static String getName(final ServiceReference<Servlet> reference) {
-        String servletName = null;
-        for (int i = 0; i < NAME_PROPERTIES.length
-            && (servletName == null || servletName.length() == 0); i++) {
-            Object prop = reference.getProperty(NAME_PROPERTIES[i]);
-            if (prop != null) {
-                servletName = String.valueOf(prop);
-            }
-        }
-        return servletName;
     }
 
     private boolean isPathAllowed(final String path) {
         return AbstractResourceCollector.isPathAllowed(path, this.executionPaths);
     }
 
-    private static final class ServletReg {
-        public final Servlet servlet;
-        public final List<ServiceRegistration<ResourceProvider<Object>>> registrations;
-
-        public ServletReg(final Servlet s, final List<ServiceRegistration<ResourceProvider<Object>>> srs) {
-            this.servlet = s;
-            this.registrations = srs;
-        }
-    }
-
-    private static final class PendingServlet {
-        public final Servlet servlet;
-        public final ServiceReference<Servlet> reference;
-
-        public PendingServlet(final Servlet s, final ServiceReference<Servlet> ref) {
-            this.servlet = s;
-            this.reference = ref;
-        }
-    }
-
     @SuppressWarnings("serial")
     class ServletResolverWebConsolePlugin extends HttpServlet {
         private static final String PARAMETER_URL = "url";
@@ -1144,7 +879,7 @@
                                 defaultExtensions,
                                 method,
                                 requestPathInfo.getSelectors());
-                        servlets = locationUtil.getServlets(resourceResolver, scriptEnginesExtensions);
+                        servlets = locationUtil.getServlets(resourceResolver, resolutionCache.getScriptEngineExtensions());
                     }
                     tr(pw);
                     tdLabel(pw, "Candidates");
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 48b3732..b83d7f7 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
@@ -18,15 +18,12 @@
  */
 package org.apache.sling.servlets.resolver.internal;
 
-import static junit.framework.TestCase.assertNull;
 import static junit.framework.TestCase.assertTrue;
 import static org.junit.Assert.assertEquals;
 
 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;
 
@@ -47,15 +44,12 @@
 import org.apache.sling.commons.testing.sling.MockSlingHttpServletRequest;
 import org.apache.sling.servlets.resolver.internal.resolution.ResolutionCache;
 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 SlingServletResolverTest {
 
@@ -156,7 +150,7 @@
             ServletResolverConstants.SLING_SERVLET_EXTENSIONS,
             SERVLET_EXTENSION);
 
-        servletResolver.bindServlet(SlingServletResolverTest.this.servlet, serviceReference);
+//        servletResolver.bindServlet(SlingServletResolverTest.this.servlet, serviceReference);
         servletResolver.activate(bundleContext, new SlingServletResolver.Config() {
 
             @Override
@@ -226,7 +220,7 @@
         assertTrue("Did not ignore unwanted request",
             result.getClass() != MockSlingRequestHandlerServlet.class);
     }
-
+/*
     @Test public void testCreateServiceRegistrationProperties() throws Throwable {
         MockServiceReference msr = new MockServiceReference(null);
 
@@ -264,7 +258,7 @@
         final Dictionary<String, Object> p3 = (Dictionary<String, Object>) createServiceProperties.invoke(servletResolver, msr, servlet, "/a");
         assertEquals(intValue, p3.get(Constants.SERVICE_RANKING));
     }
-
+*/
     /**
      * This sample servlet will only handle secure requests.
      *
