Added support for the extends attribute
diff --git a/src/main/java/org/apache/sling/scripting/resolver/internal/BundledScriptFinder.java b/src/main/java/org/apache/sling/scripting/resolver/internal/BundledScriptFinder.java
index c52fdca..deab1bb 100644
--- a/src/main/java/org/apache/sling/scripting/resolver/internal/BundledScriptFinder.java
+++ b/src/main/java/org/apache/sling/scripting/resolver/internal/BundledScriptFinder.java
@@ -45,17 +45,17 @@
     @Reference
     private ScriptEngineManager scriptEngineManager;
 
-    private List<String> getScriptEngineExtensions() {
-        List<String> _scriptEngineExtensions = new ArrayList<>();
-        for (ScriptEngineFactory factory : scriptEngineManager.getEngineFactories()) {
-            _scriptEngineExtensions.addAll(factory.getExtensions());
-        }
-        Collections.reverse(_scriptEngineExtensions);
-        return Collections.unmodifiableList(_scriptEngineExtensions);
+    Script getScript(SlingHttpServletRequest request, Bundle bundle) {
+        return getScript(request, bundle, null);
     }
 
-    Script getScript(SlingHttpServletRequest request, Bundle bundle) {
-        List<String> scriptMatches = buildScriptMatches(request);
+    Script getScript(SlingHttpServletRequest request, Bundle bundle, String delegatedResourceType) {
+        List<String> scriptMatches;
+        if (StringUtils.isEmpty(delegatedResourceType)) {
+            scriptMatches = buildScriptMatches(request);
+        } else {
+            scriptMatches = buildScriptMatches(request, delegatedResourceType);
+        }
         for (String extension : getScriptEngineExtensions()) {
             for (String match : scriptMatches) {
                 URL bundledScriptURL = bundle.getEntry(NS_JAVAX_SCRIPT_CAPABILITY + SLASH + match + DOT + extension);
@@ -67,9 +67,13 @@
         return null;
     }
 
-    List<String> buildScriptMatches(SlingHttpServletRequest request) {
+    private List<String> buildScriptMatches(SlingHttpServletRequest request) {
+        return buildScriptMatches(request, null);
+    }
+
+    private List<String> buildScriptMatches(SlingHttpServletRequest request, String delegatedResourceType) {
         List<String> matches = new ArrayList<>();
-        String resourceType = request.getResource().getResourceType();
+        String resourceType = StringUtils.isEmpty(delegatedResourceType) ? request.getResource().getResourceType() : delegatedResourceType;
         String version = null;
         if (resourceType.contains(SLASH) && StringUtils.countMatches(resourceType, SLASH) == 1) {
             version = resourceType.substring(resourceType.indexOf(SLASH) + 1, resourceType.length());
@@ -95,4 +99,13 @@
         matches.add(script);
         return Collections.unmodifiableList(matches);
     }
+
+    private List<String> getScriptEngineExtensions() {
+        List<String> _scriptEngineExtensions = new ArrayList<>();
+        for (ScriptEngineFactory factory : scriptEngineManager.getEngineFactories()) {
+            _scriptEngineExtensions.addAll(factory.getExtensions());
+        }
+        Collections.reverse(_scriptEngineExtensions);
+        return Collections.unmodifiableList(_scriptEngineExtensions);
+    }
 }
diff --git a/src/main/java/org/apache/sling/scripting/resolver/internal/BundledScriptServlet.java b/src/main/java/org/apache/sling/scripting/resolver/internal/BundledScriptServlet.java
index f16000f..24a433a 100644
--- a/src/main/java/org/apache/sling/scripting/resolver/internal/BundledScriptServlet.java
+++ b/src/main/java/org/apache/sling/scripting/resolver/internal/BundledScriptServlet.java
@@ -49,14 +49,21 @@
     private final Bundle m_bundle;
     private final BundledScriptFinder m_bundledScriptFinder;
     private final ScriptContextProvider m_scriptContextProvider;
+    private final String m_delegatedResourceType;
 
     private Map<String, Script> scriptsMap = new HashMap<>();
     private ReadWriteLock lock = new ReentrantReadWriteLock();
 
     BundledScriptServlet(BundledScriptFinder bundledScriptFinder, Bundle bundle, ScriptContextProvider scriptContextProvider) {
+        this(bundledScriptFinder, bundle, scriptContextProvider, null);
+    }
+
+    BundledScriptServlet(BundledScriptFinder bundledScriptFinder, Bundle bundle, ScriptContextProvider scriptContextProvider, String
+            overridingResourceType) {
         m_bundle = bundle;
         m_bundledScriptFinder = bundledScriptFinder;
         m_scriptContextProvider = scriptContextProvider;
+        m_delegatedResourceType = overridingResourceType;
     }
 
     @Override
@@ -85,7 +92,11 @@
                     try {
                         script = scriptsMap.get(getScriptsMapKey(request));
                         if (script == null) {
-                            script = m_bundledScriptFinder.getScript(request, m_bundle);
+                            if (StringUtils.isEmpty(m_delegatedResourceType)) {
+                                script = m_bundledScriptFinder.getScript(request, m_bundle);
+                            } else {
+                                script = m_bundledScriptFinder.getScript(request, m_bundle, m_delegatedResourceType);
+                            }
                             if (script != null) {
                                 scriptsMap.put(scriptsMapKey, script);
                             }
@@ -107,40 +118,7 @@
                     throw new ScriptEvaluationException(script.getName(), se.getMessage(), cause);
                 }
             } else {
-                /*
-                 * The Script does not seem to belong to the capability for which this servlet has been registered. If this capability
-                 * extends another capability, the request should be dispatched to that capability.
-                 *
-                 * BIG FAT NOTE:
-                 * - we need to figure out how to map to the correct version of a wired resource type
-                 */
-                String currentResourceType = request.getResource().getResourceType();
-                if (currentResourceType.indexOf('/') > 0) {
-                    currentResourceType = currentResourceType.substring(0, currentResourceType.lastIndexOf('/'));
-                }
-                for (BundleCapability bundleCapability : m_bundle.adapt(BundleWiring.class).getCapabilities(BundledScriptTracker
-                        .NS_SLING_RESOURCE_TYPE)) {
-
-                    String capabilityRT = (String) bundleCapability.getAttributes().get(BundledScriptTracker
-                            .NS_SLING_RESOURCE_TYPE);
-                    if (currentResourceType.equals(capabilityRT)) {
-                        String extendsRT = (String) bundleCapability.getAttributes().get("extends");
-                        if (StringUtils.isNotEmpty(extendsRT)) {
-                            RequestDispatcherOptions options = new RequestDispatcherOptions();
-                            options.setForceResourceType(extendsRT + "/1.0.0");
-                            RequestDispatcher dispatcher = request.getRequestDispatcher(request.getResource(), options);
-                            if (dispatcher != null) {
-                                dispatcher.include(request, response);
-                                return;
-                            } else {
-                                response.sendError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR);
-                            }
-                        }
-                    }
-                }
                 response.sendError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR);
-
-
             }
         } else {
             throw new ServletException("Not a Sling HTTP request/response");
diff --git a/src/main/java/org/apache/sling/scripting/resolver/internal/BundledScriptTracker.java b/src/main/java/org/apache/sling/scripting/resolver/internal/BundledScriptTracker.java
index 9aac2d3..f228724 100644
--- a/src/main/java/org/apache/sling/scripting/resolver/internal/BundledScriptTracker.java
+++ b/src/main/java/org/apache/sling/scripting/resolver/internal/BundledScriptTracker.java
@@ -24,16 +24,12 @@
 import java.util.Hashtable;
 import java.util.List;
 import java.util.Map;
-import java.util.Objects;
-import java.util.Properties;
+import java.util.Optional;
 import java.util.Set;
 import java.util.stream.Collectors;
-import java.util.stream.Stream;
 
 import javax.servlet.Servlet;
 
-import aQute.bnd.annotation.headers.ProvideCapability;
-
 import org.apache.commons.lang3.StringUtils;
 import org.apache.sling.api.servlets.ServletResolverConstants;
 import org.apache.sling.commons.osgi.PropertiesUtil;
@@ -55,6 +51,8 @@
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
+import aQute.bnd.annotation.headers.ProvideCapability;
+
 @Component(
         service = {}
 )
@@ -66,6 +64,8 @@
     private static final String AT_SLING_RESOURCE_TYPE_ONLY = "sling.resourceType.standalone";
     private static final String AT_SLING_SELECTORS = "sling.resourceType.selectors";
     private static final String AT_SLING_EXTENSIONS = "sling.resourceType.extensions";
+    private static final String AT_VERSION = "version";
+    private static final String AT_EXTENDS = "extends";
 
     @Reference
     private BundledScriptFinder bundledScriptFinder;
@@ -98,7 +98,6 @@
             List<BundleCapability> capabilities = bundleWiring.getCapabilities(NS_SLING_RESOURCE_TYPE);
 
             if (!capabilities.isEmpty()) {
-                BundledScriptServlet servlet = new BundledScriptServlet(bundledScriptFinder, bundle, scriptContextProvider);
                 Hashtable<String, Object> baseProperties = new Hashtable<>();
                 baseProperties.put(ServletResolverConstants.SLING_SERVLET_METHODS,
                         new String[]{"TRACE", "OPTIONS", "GET", "HEAD", "POST", "PUT", "DELETE"});
@@ -110,10 +109,9 @@
                     List<ServiceRegistration<Servlet>> result = new ArrayList<>();
 
                     Map<String, Object> attributes = cap.getAttributes();
-
                     String resourceType = (String) attributes.get(NS_SLING_RESOURCE_TYPE);
 
-                    Version version = (Version) attributes.get("version");
+                    Version version = (Version) attributes.get(AT_VERSION);
 
                     if (version != null) {
                         resourceType += "/" + version;
@@ -132,7 +130,30 @@
                         properties.put(ServletResolverConstants.SLING_SERVLET_SELECTORS, selectors);
                     }
 
-                    result.add(m_context.registerService(Servlet.class, servlet, properties));
+                    String extendsRT = (String) attributes.get(AT_EXTENDS);
+                    if (StringUtils.isNotEmpty(extendsRT)) {
+                        LOGGER.debug("Bundle {} extends resource type {} through {}.", bundle.getSymbolicName(), extendsRT, resourceType);
+                        Optional<BundleWire> optionalWire = bundleWiring.getRequiredWires(NS_SLING_RESOURCE_TYPE).stream().filter(
+                                bundleWire -> extendsRT.equals(bundleWire.getCapability().getAttributes().get(NS_SLING_RESOURCE_TYPE))
+                        ).findFirst();
+                        if (optionalWire.isPresent()) {
+                            BundleWire extendsWire = optionalWire.get();
+                            Map<String, Object> wireCapabilityAttributes = extendsWire.getCapability().getAttributes();
+                            String wireResourceType = (String) wireCapabilityAttributes.get(NS_SLING_RESOURCE_TYPE);
+                            Version wireResourceTypeVersion = (Version) wireCapabilityAttributes.get(AT_VERSION);
+                            result.add(m_context.registerService(
+                                    Servlet.class,
+                                    new BundledScriptServlet(bundledScriptFinder, optionalWire.get().getProvider().getBundle(),
+                                            scriptContextProvider, wireResourceType + (StringUtils.isNotEmpty(wireResourceType) ? "/" +
+                                            wireResourceTypeVersion.toString() : "")),
+                                    properties
+                            ));
+                        }
+                    }
+
+                    result.add(m_context
+                            .registerService(Servlet.class, new BundledScriptServlet(bundledScriptFinder, bundle, scriptContextProvider),
+                                    properties));
                     return result.stream();
                 }).collect(Collectors.toList());
             } else {
@@ -153,4 +174,5 @@
         LOGGER.debug("Bundle {} removed", bundle.getSymbolicName());
         regs.forEach(ServiceRegistration::unregister);
     }
+
 }