Author: bdekruijff at gmail.com
Date: Tue Feb  8 12:10:37 2011
New Revision: 765

Log:
AMDATU-284 AMDATU-285 AMDATU-84 AMDATU-282 refactorred to proactive tenant 
filter and lots of qa

Added:
   
branches/amdatu-dispatcher/amdatu-web/dispatcher/src/main/java/org/amdatu/web/dispatcher/dispatch/CustomFilterChain.java
      - copied, changed from r764, 
/branches/amdatu-dispatcher/amdatu-web/dispatcher/src/main/java/org/amdatu/web/dispatcher/dispatch/InvocationFilterChain.java
   
branches/amdatu-dispatcher/amdatu-web/dispatcher/src/main/java/org/amdatu/web/dispatcher/dispatch/CustomFilterPipeline.java
   
branches/amdatu-dispatcher/amdatu-web/dispatcher/src/main/java/org/amdatu/web/dispatcher/dispatch/CustomServletPipeline.java
      - copied, changed from r764, 
/branches/amdatu-dispatcher/amdatu-web/dispatcher/src/main/java/org/amdatu/web/dispatcher/dispatch/ServletPipeline.java
   
branches/amdatu-dispatcher/amdatu-web/dispatcher/src/main/java/org/amdatu/web/dispatcher/dispatch/ExtenderFilterChain.java
   
branches/amdatu-dispatcher/amdatu-web/dispatcher/src/main/java/org/amdatu/web/dispatcher/dispatch/ExtenderFilterPipeline.java
   branches/amdatu-dispatcher/amdatu-web/dispatcher/src/test/
   branches/amdatu-dispatcher/amdatu-web/dispatcher/src/test/java/
   branches/amdatu-dispatcher/amdatu-web/dispatcher/src/test/java/org/
   branches/amdatu-dispatcher/amdatu-web/dispatcher/src/test/java/org/amdatu/
   
branches/amdatu-dispatcher/amdatu-web/dispatcher/src/test/java/org/amdatu/web/
   
branches/amdatu-dispatcher/amdatu-web/dispatcher/src/test/java/org/amdatu/web/dispatcher/
   
branches/amdatu-dispatcher/amdatu-web/dispatcher/src/test/java/org/amdatu/web/dispatcher/handler/
   
branches/amdatu-dispatcher/amdatu-web/dispatcher/src/test/java/org/amdatu/web/dispatcher/handler/FilterHandlerTest.java
   
branches/amdatu-dispatcher/amdatu-web/dispatcher/src/test/java/org/amdatu/web/dispatcher/handler/ServletHandlerRegistryTest.java
   
branches/amdatu-dispatcher/amdatu-web/dispatcher/src/test/java/org/amdatu/web/dispatcher/handler/ServletHandlerTest.java
   
branches/amdatu-dispatcher/integration-tests/src/test/java/org/amdatu/test/integration/tests/DispatcherPerformanceTest.java
Removed:
   
branches/amdatu-dispatcher/amdatu-web/dispatcher/src/main/java/org/amdatu/web/dispatcher/DispatchFilterMatcher.java
   
branches/amdatu-dispatcher/amdatu-web/dispatcher/src/main/java/org/amdatu/web/dispatcher/DispatchServletMatcher.java
   
branches/amdatu-dispatcher/amdatu-web/dispatcher/src/main/java/org/amdatu/web/dispatcher/dispatch/FilterPipeline.java
   
branches/amdatu-dispatcher/amdatu-web/dispatcher/src/main/java/org/amdatu/web/dispatcher/dispatch/InvocationFilterChain.java
   
branches/amdatu-dispatcher/amdatu-web/dispatcher/src/main/java/org/amdatu/web/dispatcher/dispatch/NotFoundFilterChain.java
   
branches/amdatu-dispatcher/amdatu-web/dispatcher/src/main/java/org/amdatu/web/dispatcher/dispatch/ServletPipeline.java
   
branches/amdatu-dispatcher/amdatu-web/dispatcher/src/main/java/org/amdatu/web/dispatcher/matcher/
Modified:
   
branches/amdatu-dispatcher/amdatu-authentication/oauth-consumerregistry-fs/src/main/java/org/amdatu/authentication/oauth/consumerregistry/fs/service/FSConsumerRegistryImpl.java
   
branches/amdatu-dispatcher/amdatu-web/dispatcher/src/main/java/org/amdatu/web/dispatcher/DispatchExtenderFilter.java
   
branches/amdatu-dispatcher/amdatu-web/dispatcher/src/main/java/org/amdatu/web/dispatcher/DispatcherService.java
   
branches/amdatu-dispatcher/amdatu-web/dispatcher/src/main/java/org/amdatu/web/dispatcher/context/DefaultHttpContext.java
   
branches/amdatu-dispatcher/amdatu-web/dispatcher/src/main/java/org/amdatu/web/dispatcher/context/ExtServletContext.java
   
branches/amdatu-dispatcher/amdatu-web/dispatcher/src/main/java/org/amdatu/web/dispatcher/context/HttpContextManager.java
   
branches/amdatu-dispatcher/amdatu-web/dispatcher/src/main/java/org/amdatu/web/dispatcher/dispatch/HttpFilterChain.java
   
branches/amdatu-dispatcher/amdatu-web/dispatcher/src/main/java/org/amdatu/web/dispatcher/filter/DispatchInterceptFilter.java
   
branches/amdatu-dispatcher/amdatu-web/dispatcher/src/main/java/org/amdatu/web/dispatcher/handler/AbstractHandler.java
   
branches/amdatu-dispatcher/amdatu-web/dispatcher/src/main/java/org/amdatu/web/dispatcher/handler/AbstractHandlerRegistry.java
   
branches/amdatu-dispatcher/amdatu-web/dispatcher/src/main/java/org/amdatu/web/dispatcher/handler/FilterHandler.java
   
branches/amdatu-dispatcher/amdatu-web/dispatcher/src/main/java/org/amdatu/web/dispatcher/handler/FilterHandlerRegistry.java
   
branches/amdatu-dispatcher/amdatu-web/dispatcher/src/main/java/org/amdatu/web/dispatcher/handler/ServletHandler.java
   
branches/amdatu-dispatcher/amdatu-web/dispatcher/src/main/java/org/amdatu/web/dispatcher/handler/ServletHandlerRegistry.java
   
branches/amdatu-dispatcher/amdatu-web/dispatcher/src/main/java/org/amdatu/web/dispatcher/service/DispatcherServiceImpl.java
   
branches/amdatu-dispatcher/integration-tests/src/test/java/org/amdatu/test/integration/tests/OAuthSignedRequestsTest.java
   
branches/amdatu-dispatcher/integration-tests/src/test/java/org/amdatu/test/integration/tests/OAuthThreeLeggedTest.java

Modified: 
branches/amdatu-dispatcher/amdatu-authentication/oauth-consumerregistry-fs/src/main/java/org/amdatu/authentication/oauth/consumerregistry/fs/service/FSConsumerRegistryImpl.java
==============================================================================
--- 
branches/amdatu-dispatcher/amdatu-authentication/oauth-consumerregistry-fs/src/main/java/org/amdatu/authentication/oauth/consumerregistry/fs/service/FSConsumerRegistryImpl.java
    (original)
+++ 
branches/amdatu-dispatcher/amdatu-authentication/oauth-consumerregistry-fs/src/main/java/org/amdatu/authentication/oauth/consumerregistry/fs/service/FSConsumerRegistryImpl.java
    Tue Feb  8 12:10:37 2011
@@ -96,7 +96,7 @@
     }
 
     public synchronized void addConsumer(OAuthServiceConsumer consumer) throws 
ConsumerAlreadyExistsException,
-    ConsumerRegistryStorageException {
+        ConsumerRegistryStorageException {
         try {
             if (m_storage.getEntity(consumer.getConsumerKey()) != null) {
                 throw new ConsumerAlreadyExistsException("Consumer with key '" 
+ consumer.getConsumerKey()
@@ -114,7 +114,7 @@
     }
 
     public synchronized void updateConsumer(OAuthServiceConsumer consumer) 
throws ConsumerNotFoundException,
-    ConsumerRegistryStorageException {
+        ConsumerRegistryStorageException {
         try {
             if (m_storage.getEntity(consumer.getConsumerKey()) == null) {
                 throw new ConsumerNotFoundException("Consumer with key '" + 
consumer.getConsumerKey()
@@ -132,7 +132,7 @@
     }
 
     public synchronized void removeConsumer(OAuthServiceConsumer consumer) 
throws ConsumerNotFoundException,
-    ConsumerRegistryStorageException {
+        ConsumerRegistryStorageException {
         try {
             if (m_storage.getEntity(consumer.getConsumerKey()) == null) {
                 throw new ConsumerNotFoundException("Consumer with key '" + 
consumer.getConsumerKey()
@@ -150,7 +150,7 @@
     }
 
     public synchronized void grantResourceAccess(OAuthServiceConsumer 
consumer, String userId)
-    throws ConsumerRegistryStorageException {
+        throws ConsumerRegistryStorageException {
         try {
             FSConsumerEntity fsConsumer = 
m_storage.getEntity(consumer.getConsumerKey());
             List<String> allowedUserIds = fsConsumer.getAllowedUserIds();
@@ -168,7 +168,7 @@
     }
 
     public synchronized void withdrawResourceAccess(OAuthServiceConsumer 
consumer, String userId)
-    throws ConsumerNotFoundException, ConsumerRegistryStorageException {
+        throws ConsumerNotFoundException, ConsumerRegistryStorageException {
         try {
             FSConsumerEntity entity = 
m_storage.getEntity(consumer.getConsumerKey());
             if (entity == null) {
@@ -187,7 +187,7 @@
     }
 
     public boolean hasResourceAccess(OAuthServiceConsumer consumer, String 
userId)
-    throws ConsumerNotFoundException, ConsumerRegistryStorageException {
+        throws ConsumerNotFoundException, ConsumerRegistryStorageException {
         try {
             FSConsumerEntity entity = 
m_storage.getEntity(consumer.getConsumerKey());
             if (entity == null) {

Modified: 
branches/amdatu-dispatcher/amdatu-web/dispatcher/src/main/java/org/amdatu/web/dispatcher/DispatchExtenderFilter.java
==============================================================================
--- 
branches/amdatu-dispatcher/amdatu-web/dispatcher/src/main/java/org/amdatu/web/dispatcher/DispatchExtenderFilter.java
        (original)
+++ 
branches/amdatu-dispatcher/amdatu-web/dispatcher/src/main/java/org/amdatu/web/dispatcher/DispatchExtenderFilter.java
        Tue Feb  8 12:10:37 2011
@@ -18,6 +18,17 @@
 
 import javax.servlet.Filter;
 
+/**
+ * Service registration interface for <code>Filter</code> components that
+ * are intended to extend the functionality of the <code>DispatcherService
+ * </code> handling cross-cutting concerns such as Tenant resolving.
+ * <p/>
+ * Extender filters are handled just like any <code>Filter</code> within
+ * a <code>FilterChain</code> but are not considered to be tenant aware
+ * and are by definition invoked in an extender chain before any regular
+ * filters and servlets are considered. Inside the extender chain ordering
+ * is based on standard service ranking.
+ * 
+ */
 public interface DispatchExtenderFilter extends Filter {
-
 }

Modified: 
branches/amdatu-dispatcher/amdatu-web/dispatcher/src/main/java/org/amdatu/web/dispatcher/DispatcherService.java
==============================================================================
--- 
branches/amdatu-dispatcher/amdatu-web/dispatcher/src/main/java/org/amdatu/web/dispatcher/DispatcherService.java
     (original)
+++ 
branches/amdatu-dispatcher/amdatu-web/dispatcher/src/main/java/org/amdatu/web/dispatcher/DispatcherService.java
     Tue Feb  8 12:10:37 2011
@@ -16,11 +16,80 @@
  */
 package org.amdatu.web.dispatcher;
 
-
+/**
+ * Amdatu Web Dipatcher service registration interface. First this service 
component
+ * tracks and manages lifecycle of general as well as tenant aware web 
component
+ * service registrations of types <code>Filter</code>, <code>Servlet</code>,
+ * <code>Extenderfilter</code> and <code>HttpContext</code>. Second, it 
intercepts
+ * and dispatches incomming HTTP requests from the <code>HttpService</code> to 
an
+ * invocation chain of available components that match the optionally resolved
+ * <code>Tenant</code>. The execution chain is determined and invoked based on
+ * the following strategy:
+ * <ul>
+ * <li>All registered components of type <code>Extenderfilter</code> are added 
and
+ * ordered in an extender chain that is invoked before anything else happens. 
This
+ * is where extenders may resolve to a tenant or handle any other cross-cutting
+ * platform concern.
+ * </li>
+ * <li>If a <code>Tenant</code> was successfully resolved ny an extender both
+ * available tenant unaware filters and servlets as well as the ones specific
+ * for that tenant are added and ordered in the tenant invocation chain which
+ * is subsequently invoked.
+ * </li>
+ * <li>If no <code>Tenant</code> was resolved ny any extender only tenant 
unaware
+ * filters and servlets are added to the tenant invocation chain which is 
subsequently
+ * invoked.</li>
+ * <li>If no filter has blocked the chain and no servlet has handled the 
request
+ * at the end of the invocation chain the request is returned to the original
+ * invocation chain to support legacy code that has registered component with
+ * the <code>HttpService</code> directly.</li>
+ * </ul>
+ * <p/>
+ * To support a range of tenant resolving strategies the actual resolving is 
left
+ * to optionally available services that implement the 
<code>DispatchExtenderFilter</code>
+ * service interface. Any extender that implements tenant resolving is 
expected to
+ * store the resolved tenant object in the request context under the <code>
+ * TENANT_REQUESTCONTEXT_KEY</code>.
+ * <p/>
+ * Note: all providers must make sure that their component can deal with 
service
+ * dynamics. This can be achieved by making sure the component implementation 
can
+ * handle multiple subsequent invocations or its init/destroy lifecycle 
methods.
+ * Alternatively track the <code>DispatcherService</code> service lifecycle and
+ * handle the component accordingly.
+ */
 public interface DispatcherService {
 
-    public final static String CONTEXT_ID_KEY = "contextId";
-    public final static String PATTERN_KEY = "pattern";
-    public final static String ALIAS_KEY = "alias";
-    public final static String INIT_KEY_PREFIX = "init.";
+    /**
+     * <code>HttpServletRequest</code> attribute key where tenant resolving 
extenders
+     * must store the <code>Tenant</code> instance.
+     */
+    String TENANT_REQUESTCONTEXT_KEY = "org.amdatu.web.dispatcher.TENANT";
+
+    /**
+     * <code>Servlet</code> and <code>Filter</code> service registration 
property
+     * considered for reusing or creating a specific named 
<code>HttpContext</code>.
+     */
+    String CONTEXT_ID_KEY = "contextId";
+
+    /**
+     * <code>Filter</code> service registration property indicating for which 
requested
+     * paths it should be invoked using a regular expression format. Filters 
are
+     * ordered based on service ranking.
+     */
+    String PATTERN_KEY = "pattern";
+
+    /**
+     * <code>Servlet</code> service registration property indicating for which 
requested
+     * paths this servlet should be considered. Servlets are matched according 
to most
+     * specific path followed by standard service ranking.
+     */
+    String ALIAS_KEY = "alias";
+
+    /**
+     * Generic service registration property prefix for properties that should
+     * be passed through <code>ServletConfig</code> or 
<code>FilterConfig</code> to
+     * the components init method. The prefix will be stripped before from the 
key
+     * and the value must be of type <code>String</code>.
+     */
+    String INIT_KEY_PREFIX = "init.";
 }

Modified: 
branches/amdatu-dispatcher/amdatu-web/dispatcher/src/main/java/org/amdatu/web/dispatcher/context/DefaultHttpContext.java
==============================================================================
--- 
branches/amdatu-dispatcher/amdatu-web/dispatcher/src/main/java/org/amdatu/web/dispatcher/context/DefaultHttpContext.java
    (original)
+++ 
branches/amdatu-dispatcher/amdatu-web/dispatcher/src/main/java/org/amdatu/web/dispatcher/context/DefaultHttpContext.java
    Tue Feb  8 12:10:37 2011
@@ -22,9 +22,13 @@
 import javax.servlet.http.HttpServletResponse;
 import java.net.URL;
 
+/**
+ * Temporary default implementation of <code>HttpContext</code>.
+ * TODO transfer responsibility to httpcontext (AMDATU-283)
+ */
 public final class DefaultHttpContext implements HttpContext {
 
-    private Bundle m_bundle;
+    private final Bundle m_bundle;
 
     public DefaultHttpContext(Bundle bundle) {
         m_bundle = bundle;

Modified: 
branches/amdatu-dispatcher/amdatu-web/dispatcher/src/main/java/org/amdatu/web/dispatcher/context/ExtServletContext.java
==============================================================================
--- 
branches/amdatu-dispatcher/amdatu-web/dispatcher/src/main/java/org/amdatu/web/dispatcher/context/ExtServletContext.java
     (original)
+++ 
branches/amdatu-dispatcher/amdatu-web/dispatcher/src/main/java/org/amdatu/web/dispatcher/context/ExtServletContext.java
     Tue Feb  8 12:10:37 2011
@@ -22,6 +22,10 @@
 import javax.servlet.http.HttpServletRequest;
 import javax.servlet.http.HttpServletResponse;
 
+/**
+ * Extension of the standard <code>ServletContext</code> interface to support
+ * <code>HttpContext</code> handleSecurity delegation.
+ */
 public interface ExtServletContext extends ServletContext {
     public boolean handleSecurity(HttpServletRequest req, HttpServletResponse 
res)
         throws IOException;

Modified: 
branches/amdatu-dispatcher/amdatu-web/dispatcher/src/main/java/org/amdatu/web/dispatcher/context/HttpContextManager.java
==============================================================================
--- 
branches/amdatu-dispatcher/amdatu-web/dispatcher/src/main/java/org/amdatu/web/dispatcher/context/HttpContextManager.java
    (original)
+++ 
branches/amdatu-dispatcher/amdatu-web/dispatcher/src/main/java/org/amdatu/web/dispatcher/context/HttpContextManager.java
    Tue Feb  8 12:10:37 2011
@@ -21,11 +21,11 @@
 
 import org.osgi.framework.Bundle;
 import org.osgi.service.http.HttpContext;
+import org.osgi.service.log.LogService;
 
 /**
  * Registry for registered and/or local <code>HttpContext</code> instances 
supporting
  * reuse based on id.
- * 
  * TODO transfer responsibility to httpcontext (AMDATU-283)
  */
 public final class HttpContextManager {
@@ -33,30 +33,38 @@
     private final Map<String, HttpContext> m_idHttpContexts = new 
HashMap<String, HttpContext>();
     private final Map<HttpContext, String> m_httpContextIds = new 
HashMap<HttpContext, String>();
 
+    private LogService m_logService;
+
     public HttpContextManager() {
     }
 
+    public void setLogService(LogService logService) {
+        m_logService = logService;
+    }
+
+    public LogService getLogService() {
+        return m_logService;
+    }
+
     public synchronized HttpContext getHttpContext(Bundle bundle, String 
contextId) {
-        String id = contextId;
-        HttpContext context = m_idHttpContexts.get(id);
+        HttpContext context = m_idHttpContexts.get(contextId);
         if (context == null) {
             context = new DefaultHttpContext(bundle);
-            m_idHttpContexts.put(id, context);
-            m_httpContextIds.put(context, id);
+            m_idHttpContexts.put(contextId, context);
+            m_httpContextIds.put(context, contextId);
         }
         return context;
     }
 
     public synchronized void removeHttpContext(HttpContext context) {
-        String id = m_httpContextIds.remove(context);
-        if (id != null) {
-            m_idHttpContexts.remove(id);
+        String contextId = m_httpContextIds.remove(context);
+        if (contextId != null) {
+            m_idHttpContexts.remove(contextId);
         }
     }
 
     public synchronized void addHttpContext(Bundle bundle, String contextId, 
HttpContext context) {
-        String id = contextId;
-        m_idHttpContexts.put(id, context);
-        m_httpContextIds.put(context, id);
+        m_idHttpContexts.put(contextId, context);
+        m_httpContextIds.put(context, contextId);
     }
 }

Copied: 
branches/amdatu-dispatcher/amdatu-web/dispatcher/src/main/java/org/amdatu/web/dispatcher/dispatch/CustomFilterChain.java
 (from r764, 
/branches/amdatu-dispatcher/amdatu-web/dispatcher/src/main/java/org/amdatu/web/dispatcher/dispatch/InvocationFilterChain.java)
==============================================================================
--- 
/branches/amdatu-dispatcher/amdatu-web/dispatcher/src/main/java/org/amdatu/web/dispatcher/dispatch/InvocationFilterChain.java
       (original)
+++ 
branches/amdatu-dispatcher/amdatu-web/dispatcher/src/main/java/org/amdatu/web/dispatcher/dispatch/CustomFilterChain.java
    Tue Feb  8 12:10:37 2011
@@ -25,15 +25,21 @@
 
 import org.amdatu.web.dispatcher.handler.FilterHandler;
 
-public final class InvocationFilterChain extends HttpFilterChain {
-    
+/**
+ * Custom <code>FilterChain</code> implementation that invokes an array of 
<code>FilterHandler</code>
+ * instances wrapping <code>Filter</code> objects and subsequently invokes the 
specified <code>
+ * CustomServletPipeline</code>. If a servlet in the 
<code>CustomServletPipeline</code> handles
+ * the request we are done. If not we return to the specified proceeding chain.
+ */
+public final class CustomFilterChain extends HttpFilterChain {
+
     private final FilterHandler[] m_filterHandlers;
-    private final ServletPipeline m_servletPipeline;
+    private final CustomServletPipeline m_servletPipeline;
     private final FilterChain m_proceedingChain;
-    
     private int m_index = -1;
 
-    public InvocationFilterChain(FilterHandler[] handlers, ServletPipeline 
servletPipeline, FilterChain proceedingChain) {
+    public CustomFilterChain(FilterHandler[] handlers, CustomServletPipeline 
servletPipeline,
+        FilterChain proceedingChain) {
         m_filterHandlers = handlers;
         m_servletPipeline = servletPipeline;
         m_proceedingChain = proceedingChain;
@@ -43,13 +49,12 @@
         throws IOException, ServletException {
         this.m_index++;
 
-        if (this.m_index < this.m_filterHandlers.length) {
-            this.m_filterHandlers[this.m_index].handle(req, res, this);
+        if (m_index < m_filterHandlers.length) {
+            m_filterHandlers[m_index].handle(req, res, this);
         }
         else {
-            if (!this.m_servletPipeline.handle(req, res)) {
-                System.err.println("Request not handled. Returning to parent 
chain... ");
-                this.m_proceedingChain.doFilter(req, res);
+            if (!m_servletPipeline.handle(req, res)) {
+                m_proceedingChain.doFilter(req, res);
             }
         }
     }

Added: 
branches/amdatu-dispatcher/amdatu-web/dispatcher/src/main/java/org/amdatu/web/dispatcher/dispatch/CustomFilterPipeline.java
==============================================================================
--- (empty file)
+++ 
branches/amdatu-dispatcher/amdatu-web/dispatcher/src/main/java/org/amdatu/web/dispatcher/dispatch/CustomFilterPipeline.java
 Tue Feb  8 12:10:37 2011
@@ -0,0 +1,72 @@
+/*
+    Copyright (C) 2010 Amdatu.org
+
+    This program is free software: you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation, either version 3 of the License, or
+    (at your option) any later version.
+
+    This program is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU General Public License for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+package org.amdatu.web.dispatcher.dispatch;
+
+import java.io.IOException;
+
+import javax.servlet.FilterChain;
+import javax.servlet.RequestDispatcher;
+import javax.servlet.ServletException;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletRequestWrapper;
+import javax.servlet.http.HttpServletResponse;
+
+import org.amdatu.web.dispatcher.handler.FilterHandler;
+import org.amdatu.web.dispatcher.handler.FilterHandlerRegistry;
+import org.amdatu.web.dispatcher.handler.ServletHandler;
+import org.amdatu.web.dispatcher.handler.ServletHandlerRegistry;
+
+/**
+ * Pipeline implementation responsible for building the custom filterchain in 
collaboration
+ * with the specified handler registries, invoking it and wrapping the request 
to support
+ * dispatchers.
+ */
+public final class CustomFilterPipeline {
+
+    private final FilterHandlerRegistry m_filterHandlerRegistry;
+    private final ServletHandlerRegistry m_servletHandlerRegistry;
+    private CustomServletPipeline m_servletPipeline;
+
+    public CustomFilterPipeline(FilterHandlerRegistry filterHandlerRegistry,
+        ServletHandlerRegistry servletHandlerRegistry) {
+        m_filterHandlerRegistry = filterHandlerRegistry;
+        m_servletHandlerRegistry = servletHandlerRegistry;
+    }
+
+    public void dispatch(HttpServletRequest httpServletRequest, 
HttpServletResponse httpServletResponse,
+        FilterChain proceedingChain) throws ServletException, IOException {
+
+        FilterHandler[] filterHandlers = 
m_filterHandlerRegistry.getFilterHandlers(httpServletRequest);
+        ServletHandler[] servletHandlers = 
m_servletHandlerRegistry.getServletHandlers(httpServletRequest);
+        m_servletPipeline = new CustomServletPipeline(servletHandlers);
+
+        FilterChain chain = new CustomFilterChain(filterHandlers, 
m_servletPipeline, proceedingChain);
+        chain.doFilter(new RequestWrapper(httpServletRequest), 
httpServletResponse);
+    }
+
+    private final class RequestWrapper extends HttpServletRequestWrapper {
+        public RequestWrapper(HttpServletRequest httpServletRequest) {
+            super(httpServletRequest);
+        }
+
+        @Override
+        public RequestDispatcher getRequestDispatcher(String path) {
+            final RequestDispatcher dispatcher = 
m_servletPipeline.getRequestDispatcher(this, path);
+            return (null != dispatcher) ? dispatcher : 
super.getRequestDispatcher(path);
+        }
+    }
+}

Copied: 
branches/amdatu-dispatcher/amdatu-web/dispatcher/src/main/java/org/amdatu/web/dispatcher/dispatch/CustomServletPipeline.java
 (from r764, 
/branches/amdatu-dispatcher/amdatu-web/dispatcher/src/main/java/org/amdatu/web/dispatcher/dispatch/ServletPipeline.java)
==============================================================================
--- 
/branches/amdatu-dispatcher/amdatu-web/dispatcher/src/main/java/org/amdatu/web/dispatcher/dispatch/ServletPipeline.java
     (original)
+++ 
branches/amdatu-dispatcher/amdatu-web/dispatcher/src/main/java/org/amdatu/web/dispatcher/dispatch/CustomServletPipeline.java
        Tue Feb  8 12:10:37 2011
@@ -28,11 +28,15 @@
 
 import org.amdatu.web.dispatcher.handler.ServletHandler;
 
-public final class ServletPipeline {
+/**
+ * Pipeline implementation responsible for invoking the first matching servlet 
for a specific request
+ * and creating dispatchers.
+ */
+public final class CustomServletPipeline {
 
     private final ServletHandler[] m_servletHandlers;
 
-    public ServletPipeline(ServletHandler[] handlers) {
+    public CustomServletPipeline(ServletHandler[] handlers) {
         m_servletHandlers = handlers;
     }
 
@@ -51,7 +55,7 @@
 
     public RequestDispatcher getRequestDispatcher(HttpServletRequest 
httpServletRequest, String path) {
         for (ServletHandler handler : m_servletHandlers) {
-            if (handler.matches(httpServletRequest, path)) {
+            if (handler.matches(path)) {
                 return new Dispatcher(path, handler);
             }
         }
@@ -59,9 +63,8 @@
     }
 
     private final class Dispatcher implements RequestDispatcher {
-
-        private final String m_path;
         private final ServletHandler m_servletHandler;
+        private final String m_path;
 
         public Dispatcher(String path, ServletHandler handler) {
             m_path = path;
@@ -81,7 +84,6 @@
     }
 
     private final class RequestWrapper extends HttpServletRequestWrapper {
-
         private final String m_requestUri;
 
         public RequestWrapper(HttpServletRequest req, String requestUri) {

Added: 
branches/amdatu-dispatcher/amdatu-web/dispatcher/src/main/java/org/amdatu/web/dispatcher/dispatch/ExtenderFilterChain.java
==============================================================================
--- (empty file)
+++ 
branches/amdatu-dispatcher/amdatu-web/dispatcher/src/main/java/org/amdatu/web/dispatcher/dispatch/ExtenderFilterChain.java
  Tue Feb  8 12:10:37 2011
@@ -0,0 +1,57 @@
+/*
+    Copyright (C) 2010 Amdatu.org
+
+    This program is free software: you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation, either version 3 of the License, or
+    (at your option) any later version.
+
+    This program is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU General Public License for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+package org.amdatu.web.dispatcher.dispatch;
+
+import java.io.IOException;
+
+import javax.servlet.FilterChain;
+import javax.servlet.ServletException;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+
+import org.amdatu.web.dispatcher.handler.FilterHandler;
+
+/**
+ * Custom <code>FilterChain</code> implementation that invokes an array of 
<code>FilterHandler</code>
+ * instances wrapping <code>ExternderFilter</code> objects and continues on to 
the specified <code>
+ * TenantFilterPipeline</code>.
+ */
+public final class ExtenderFilterChain extends HttpFilterChain {
+
+    private final FilterHandler[] m_filterHandlers;
+    private final CustomFilterPipeline m_tenantFilterPipeline;
+    private final FilterChain m_proceedingChain;
+    private int m_index = -1;
+
+    public ExtenderFilterChain(FilterHandler[] filterHandlers, 
CustomFilterPipeline tenantFilterPipeline,
+        FilterChain proceedingChain) {
+        m_filterHandlers = filterHandlers;
+        m_tenantFilterPipeline = tenantFilterPipeline;
+        m_proceedingChain = proceedingChain;
+    }
+
+    protected void doFilter(HttpServletRequest httpServletRequest, 
HttpServletResponse httpServletResponse)
+        throws IOException, ServletException {
+        m_index++;
+        if (m_index < m_filterHandlers.length) {
+            m_filterHandlers[m_index].handle(httpServletRequest, 
httpServletResponse, this);
+        }
+        else {
+            m_tenantFilterPipeline.dispatch(httpServletRequest, 
httpServletResponse, m_proceedingChain);
+        }
+    }
+}

Added: 
branches/amdatu-dispatcher/amdatu-web/dispatcher/src/main/java/org/amdatu/web/dispatcher/dispatch/ExtenderFilterPipeline.java
==============================================================================
--- (empty file)
+++ 
branches/amdatu-dispatcher/amdatu-web/dispatcher/src/main/java/org/amdatu/web/dispatcher/dispatch/ExtenderFilterPipeline.java
       Tue Feb  8 12:10:37 2011
@@ -0,0 +1,60 @@
+/*
+    Copyright (C) 2010 Amdatu.org
+
+    This program is free software: you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation, either version 3 of the License, or
+    (at your option) any later version.
+
+    This program is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU General Public License for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+package org.amdatu.web.dispatcher.dispatch;
+
+import java.io.IOException;
+
+import javax.servlet.FilterChain;
+import javax.servlet.RequestDispatcher;
+import javax.servlet.ServletException;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletRequestWrapper;
+import javax.servlet.http.HttpServletResponse;
+
+import org.amdatu.web.dispatcher.handler.FilterHandler;
+
+/**
+ * Pipeline implementation responsible for building the extender filterchain, 
invoking it and wrapping
+ * the request to support dispatchers.
+ */
+public final class ExtenderFilterPipeline {
+
+    private final FilterHandler[] m_filterHandlers;
+    private final CustomFilterPipeline m_tenantFilterPipeline;
+
+    public ExtenderFilterPipeline(FilterHandler[] handlers, 
CustomFilterPipeline tenantFilterPipeline) {
+        m_filterHandlers = handlers;
+        m_tenantFilterPipeline = tenantFilterPipeline;
+    }
+
+    public void dispatch(HttpServletRequest httpServletRequest, 
HttpServletResponse httpServletResponse,
+        FilterChain proceedingChain) throws ServletException, IOException {
+        FilterChain chain = new ExtenderFilterChain(m_filterHandlers, 
m_tenantFilterPipeline, proceedingChain);
+        chain.doFilter(new RequestWrapper(httpServletRequest), 
httpServletResponse);
+    }
+
+    private final class RequestWrapper extends HttpServletRequestWrapper {
+        public RequestWrapper(HttpServletRequest req) {
+            super(req);
+        }
+
+        @Override
+        public RequestDispatcher getRequestDispatcher(String path) {
+            return null;
+        }
+    }
+}
\ No newline at end of file

Modified: 
branches/amdatu-dispatcher/amdatu-web/dispatcher/src/main/java/org/amdatu/web/dispatcher/dispatch/HttpFilterChain.java
==============================================================================
--- 
branches/amdatu-dispatcher/amdatu-web/dispatcher/src/main/java/org/amdatu/web/dispatcher/dispatch/HttpFilterChain.java
      (original)
+++ 
branches/amdatu-dispatcher/amdatu-web/dispatcher/src/main/java/org/amdatu/web/dispatcher/dispatch/HttpFilterChain.java
      Tue Feb  8 12:10:37 2011
@@ -25,12 +25,17 @@
 import javax.servlet.http.HttpServletRequest;
 import javax.servlet.http.HttpServletResponse;
 
+/**
+ * Simple utility <code>FilterChain</code> baseclass that downcasts the 
inteface method parameters
+ * to the http specific classes.
+ */
 public abstract class HttpFilterChain implements FilterChain {
 
-    public final void doFilter(ServletRequest req, ServletResponse res) throws 
IOException, ServletException {
-        doFilter((HttpServletRequest) req, (HttpServletResponse) res);
+    public final void doFilter(ServletRequest servletRequest, ServletResponse 
servletResponse) throws IOException,
+        ServletException {
+        doFilter((HttpServletRequest) servletRequest, (HttpServletResponse) 
servletResponse);
     }
 
     protected abstract void doFilter(HttpServletRequest req, 
HttpServletResponse res) throws IOException,
         ServletException;
-}
+}
\ No newline at end of file

Modified: 
branches/amdatu-dispatcher/amdatu-web/dispatcher/src/main/java/org/amdatu/web/dispatcher/filter/DispatchInterceptFilter.java
==============================================================================
--- 
branches/amdatu-dispatcher/amdatu-web/dispatcher/src/main/java/org/amdatu/web/dispatcher/filter/DispatchInterceptFilter.java
        (original)
+++ 
branches/amdatu-dispatcher/amdatu-web/dispatcher/src/main/java/org/amdatu/web/dispatcher/filter/DispatchInterceptFilter.java
        Tue Feb  8 12:10:37 2011
@@ -28,8 +28,6 @@
 import javax.servlet.http.HttpServletRequest;
 import javax.servlet.http.HttpServletResponse;
 
-import org.amdatu.web.dispatcher.DispatcherService;
-import org.amdatu.web.dispatcher.dispatch.FilterPipeline;
 import org.amdatu.web.dispatcher.service.DispatcherServiceImpl;
 import org.osgi.service.log.LogService;
 
@@ -79,24 +77,17 @@
         HttpServletRequest httpServletRequest = (HttpServletRequest) 
servletRequest;
         HttpServletResponse httpServletResponse = (HttpServletResponse) 
servletResponse;
 
-        // FIXME: no excessive logging in request path
-        if (m_logService != null)
-            m_logService.log(LogService.LOG_WARNING, 
getLogMessage(httpServletRequest));
-
-        FilterPipeline filterPipeline = 
m_dispatcherService.getFilterPipeline(httpServletRequest);
-        if (filterPipeline != null) {
-
-            // Standard behavior: invoke the custom chain that falls
-            // back to the normal http service chain when no servlet
-            // handles the request.
-            filterPipeline.dispatch(httpServletRequest, httpServletResponse,
-                filterChain);
-            return;
-        }
-
-        // Fallback behavior: if we have no custom chain we just
-        // continue the normal http service chain.
-        filterChain.doFilter(servletRequest, servletResponse);
+        try {
+            m_dispatcherService.dispatchRequest(httpServletRequest, 
httpServletResponse, filterChain);
+        }
+        catch (IOException e) {
+            m_logService.log(LogService.LOG_ERROR, "DispatcherService threw an 
IOException", e);
+            
httpServletResponse.sendError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR);
+        }
+        catch (ServletException e) {
+            m_logService.log(LogService.LOG_ERROR, "DispatcherService threw a 
ServletException", e);
+            
httpServletResponse.sendError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR);
+        }
     }
 
     private String getLogMessage(HttpServletRequest httpServletRequest) {

Modified: 
branches/amdatu-dispatcher/amdatu-web/dispatcher/src/main/java/org/amdatu/web/dispatcher/handler/AbstractHandler.java
==============================================================================
--- 
branches/amdatu-dispatcher/amdatu-web/dispatcher/src/main/java/org/amdatu/web/dispatcher/handler/AbstractHandler.java
       (original)
+++ 
branches/amdatu-dispatcher/amdatu-web/dispatcher/src/main/java/org/amdatu/web/dispatcher/handler/AbstractHandler.java
       Tue Feb  8 12:10:37 2011
@@ -20,7 +20,6 @@
 import java.util.Enumeration;
 import java.util.HashMap;
 import java.util.Map;
-import java.util.concurrent.atomic.AtomicInteger;
 
 import javax.servlet.ServletException;
 
@@ -28,25 +27,27 @@
 
 public abstract class AbstractHandler {
 
-    private final static AtomicInteger ID =
-        new AtomicInteger();
-
-    private final String m_handlerId;
+    private final Map<String, String> m_initParams = new HashMap<String, 
String>();
     private final ExtServletContext m_servletContext;
-    private final Map<String, String> m_initParams;
-    private final String m_tenantid;
-
-    public AbstractHandler(ExtServletContext context, String tenantid) {
-        m_handlerId = "" + ID.incrementAndGet();
+    protected final String m_tenantid;
+    protected final int m_handlerId;
+    protected final int m_ranking;
+
+    public AbstractHandler(int handlerId, int ranking, ExtServletContext 
context, String tenantid) {
+        m_handlerId = handlerId;
+        m_ranking = ranking;
         m_servletContext = context;
-        m_initParams = new HashMap<String, String>();
         m_tenantid = tenantid;
     }
 
-    public final String getId() {
+    public final int getId() {
         return m_handlerId;
     }
 
+    public final int getRanking() {
+        return m_ranking;
+    }
+
     public final String getTenantId() {
         return m_tenantid;
     }

Modified: 
branches/amdatu-dispatcher/amdatu-web/dispatcher/src/main/java/org/amdatu/web/dispatcher/handler/AbstractHandlerRegistry.java
==============================================================================
--- 
branches/amdatu-dispatcher/amdatu-web/dispatcher/src/main/java/org/amdatu/web/dispatcher/handler/AbstractHandlerRegistry.java
       (original)
+++ 
branches/amdatu-dispatcher/amdatu-web/dispatcher/src/main/java/org/amdatu/web/dispatcher/handler/AbstractHandlerRegistry.java
       Tue Feb  8 12:10:37 2011
@@ -21,8 +21,8 @@
 
 import javax.servlet.ServletContext;
 
-import org.amdatu.web.dispatcher.DispatcherService;
 import org.amdatu.web.dispatcher.context.DefaultHttpContext;
+import org.amdatu.web.dispatcher.context.HttpContextManager;
 import org.amdatu.web.dispatcher.service.DispatcherServiceImpl;
 import org.osgi.framework.Bundle;
 import org.osgi.framework.ServiceReference;
@@ -31,22 +31,35 @@
 
 public abstract class AbstractHandlerRegistry {
 
-    private DispatcherServiceImpl m_dispatcherService;
+    private LogService m_logService;
+    private ServletContext m_servletContext;
+    private HttpContextManager m_httpContextManager;
 
-    public AbstractHandlerRegistry(DispatcherServiceImpl dispatcherService) {
-        m_dispatcherService = dispatcherService;
+    public AbstractHandlerRegistry() {
     }
 
-    protected DispatcherService getDispatcherService() {
-        return m_dispatcherService;
+    public void setLogService(LogService logService) {
+        m_logService = logService;
     }
 
-    protected LogService getLogService() {
-        return m_dispatcherService.getLogService();
+    public LogService getLogService() {
+        return m_logService;
     }
 
-    protected ServletContext getServletContext() {
-        return m_dispatcherService.getServletContext();
+    public void setServletContext(ServletContext servletContext) {
+        m_servletContext = servletContext;
+    }
+
+    public ServletContext getServletContext() {
+        return m_servletContext;
+    }
+
+    public void setHttpContextManager(HttpContextManager httpContextManager) {
+        m_httpContextManager = httpContextManager;
+    }
+
+    public HttpContextManager getHttpContextManager() {
+        return m_httpContextManager;
     }
 
     protected String getStringProperty(ServiceReference ref, String key) {
@@ -85,7 +98,7 @@
         Bundle bundle = serviceReference.getBundle();
         String contextId = getStringProperty(serviceReference, 
DispatcherServiceImpl.CONTEXT_ID_KEY);
         if (contextId != null) {
-            return 
m_dispatcherService.getHttpContextManager().getHttpContext(bundle, contextId);
+            return m_httpContextManager.getHttpContext(bundle, contextId);
         }
         else {
             return new DefaultHttpContext(bundle);

Modified: 
branches/amdatu-dispatcher/amdatu-web/dispatcher/src/main/java/org/amdatu/web/dispatcher/handler/FilterHandler.java
==============================================================================
--- 
branches/amdatu-dispatcher/amdatu-web/dispatcher/src/main/java/org/amdatu/web/dispatcher/handler/FilterHandler.java
 (original)
+++ 
branches/amdatu-dispatcher/amdatu-web/dispatcher/src/main/java/org/amdatu/web/dispatcher/handler/FilterHandler.java
 Tue Feb  8 12:10:37 2011
@@ -30,24 +30,31 @@
 
 public final class FilterHandler extends AbstractHandler implements 
Comparable<FilterHandler> {
 
-    private final FilterHandlerRegistry m_filterHandlerRegistry;
     private final Filter m_filter;
-    private final Pattern m_pattern;
-    private final int m_ranking;
+    private final String m_pattern;
+    private final Pattern m_compiledPattern;
 
-    public FilterHandler(FilterHandlerRegistry filterHandlerRegistry, 
ExtServletContext context, Filter filter,
-        String pattern, int ranking, String tenantid) {
-        super(context, tenantid);
-        m_filterHandlerRegistry = filterHandlerRegistry;
+    public FilterHandler(int handlerId, ExtServletContext context, Filter 
filter, String pattern, int ranking,
+        String tenantid) {
+        super(handlerId, ranking, context, tenantid);
         m_filter = filter;
-        m_ranking = ranking;
-        m_pattern = Pattern.compile(pattern);
+        if (pattern == null || pattern.equals("")) {
+            m_pattern = ".*";
+        }
+        else {
+            m_pattern = pattern;
+        }
+        m_compiledPattern = Pattern.compile(m_pattern);
     }
 
     public Filter getFilter() {
         return m_filter;
     }
 
+    public String getPattern() {
+        return m_pattern;
+    }
+
     public void init() throws ServletException {
         String name = "filter_" + getId();
         FilterConfig config = new FilterConfigImpl(name, getContext(), 
getInitParams());
@@ -60,25 +67,25 @@
 
     public void handle(HttpServletRequest httpServletRequest, 
HttpServletResponse httpServletResponse,
         FilterChain filterChain) throws ServletException, IOException {
-        boolean matches = matchesPath(httpServletRequest.getPathInfo());
-        if (matches) {
-            matches = m_filterHandlerRegistry.filterHandlerMatches(this, 
httpServletRequest);
-            if (matches) {
-                doHandle(httpServletRequest, httpServletResponse, filterChain);
-                return;
-            }
+        if (matches(httpServletRequest.getPathInfo())) {
+            doHandle(httpServletRequest, httpServletResponse, filterChain);
+            return;
         }
         filterChain.doFilter(httpServletRequest, httpServletResponse);
     }
 
-    public boolean matchesPath(String uri) {
+    public boolean matches(String uri) {
         if (uri == null) {
             uri = "/";
         }
-        return m_pattern.matcher(uri).matches();
+        return m_compiledPattern.matcher(uri).matches();
     }
 
     public int compareTo(FilterHandler other) {
+        // service.id rules when service.ranking equals
+        if (m_ranking == other.m_ranking) {
+            return m_handlerId - other.m_handlerId;
+        }
         return other.m_ranking - m_ranking;
     }
 

Modified: 
branches/amdatu-dispatcher/amdatu-web/dispatcher/src/main/java/org/amdatu/web/dispatcher/handler/FilterHandlerRegistry.java
==============================================================================
--- 
branches/amdatu-dispatcher/amdatu-web/dispatcher/src/main/java/org/amdatu/web/dispatcher/handler/FilterHandlerRegistry.java
 (original)
+++ 
branches/amdatu-dispatcher/amdatu-web/dispatcher/src/main/java/org/amdatu/web/dispatcher/handler/FilterHandlerRegistry.java
 Tue Feb  8 12:10:37 2011
@@ -18,9 +18,10 @@
 
 import java.util.Arrays;
 import java.util.HashMap;
-import java.util.HashSet;
+import java.util.LinkedList;
+import java.util.List;
 import java.util.Map;
-import java.util.Set;
+import java.util.concurrent.locks.ReentrantReadWriteLock;
 
 import javax.servlet.Filter;
 import javax.servlet.ServletException;
@@ -28,32 +29,37 @@
 
 import org.amdatu.core.tenant.Tenant;
 import org.amdatu.web.dispatcher.DispatchExtenderFilter;
-import org.amdatu.web.dispatcher.DispatchFilterMatcher;
 import org.amdatu.web.dispatcher.DispatcherService;
 import org.amdatu.web.dispatcher.context.HandlerServletContext;
 import org.amdatu.web.dispatcher.service.DispatcherServiceImpl;
 import org.osgi.framework.Constants;
 import org.osgi.framework.ServiceReference;
+import org.osgi.service.log.LogService;
 
 public final class FilterHandlerRegistry extends AbstractHandlerRegistry {
 
+    private final ReentrantReadWriteLock m_extenderFilterHandlersLock = new 
ReentrantReadWriteLock();
+    private final ReentrantReadWriteLock m_filterHandlersLock = new 
ReentrantReadWriteLock();
+
     private final Map<ServiceReference, FilterHandler> m_filterHandlers =
         new HashMap<ServiceReference, FilterHandler>();
 
+    private final Map<String, FilterHandler[]> m_tenantFilterHandlerArrays =
+        new HashMap<String, FilterHandler[]>();
+
     private final Map<ServiceReference, FilterHandler> 
m_extenderFilterHandlers =
         new HashMap<ServiceReference, FilterHandler>();
-    private Set<DispatchFilterMatcher> m_matchers = new 
HashSet<DispatchFilterMatcher>();
 
-    public FilterHandlerRegistry(DispatcherServiceImpl dispatcherService) {
-        super(dispatcherService);
+    private FilterHandler[] m_extenderFilterHandlerArray = new FilterHandler[] 
{};
+
+    public FilterHandlerRegistry() {
+        super();
     }
 
     public void addDispatchExtenderFilter(ServiceReference serviceReference, 
DispatchExtenderFilter extenderFilter) {
-        if (m_extenderFilterHandlers.containsKey(serviceReference)) {
-            throw new IllegalStateException("Unexpected.... ");
-        }
 
-        int ranking = getIntProperty(serviceReference, 
Constants.SERVICE_RANKING, 0);
+        int serviceId = getIntProperty(serviceReference, Constants.SERVICE_ID, 
0);
+        int serviceRanking = getIntProperty(serviceReference, 
Constants.SERVICE_RANKING, 0);
         String pattern = getStringProperty(serviceReference, 
DispatcherService.PATTERN_KEY);
         if (pattern == null) {
             return;
@@ -62,104 +68,166 @@
         HandlerServletContext extServletContextWrapper =
             new HandlerServletContext(getServletContext(), 
getHttpContext(serviceReference));
         FilterHandler filterHandler =
-            new FilterHandler(this, extServletContextWrapper, extenderFilter, 
pattern, ranking, null);
+            new FilterHandler(serviceId, extServletContextWrapper, 
extenderFilter, pattern, serviceRanking, null);
         filterHandler.setInitParams(getInitParams(serviceReference));
 
-        if (m_extenderFilterHandlers.containsKey(serviceReference)) {
-            throw new IllegalStateException("unforseen duplicate 
extender....");
-        }
-
+        m_extenderFilterHandlersLock.writeLock().lock();
         try {
-            filterHandler.init();
-            m_extenderFilterHandlers.put(serviceReference, filterHandler);
+            if (m_extenderFilterHandlers.containsKey(serviceReference)) {
+                throw new IllegalStateException("unforseen duplicate 
extender....");
+            }
+
+            try {
+                filterHandler.init();
+                m_extenderFilterHandlers.put(serviceReference, filterHandler);
+                m_extenderFilterHandlerArray =
+                    m_extenderFilterHandlers.values().toArray(new 
FilterHandler[m_extenderFilterHandlers.size()]);
+                Arrays.sort(m_extenderFilterHandlerArray);
+            }
+            catch (ServletException e) {
+                e.printStackTrace();
+            }
         }
-        catch (ServletException e) {
-            e.printStackTrace();
+        finally {
+            m_extenderFilterHandlersLock.writeLock().unlock();
         }
     }
 
     public void removeDispatchExtenderFilter(ServiceReference 
serviceReference, DispatchExtenderFilter extenderFilter) {
-        if (!m_extenderFilterHandlers.containsKey(serviceReference)) {
-            throw new IllegalStateException("unforseen unknown extender....");
-        }
-        FilterHandler handler = 
m_extenderFilterHandlers.remove(serviceReference);
-        if (handler != null) {
-            handler.destroy();
+        m_extenderFilterHandlersLock.writeLock().lock();
+        try {
+            if (!m_extenderFilterHandlers.containsKey(serviceReference)) {
+                throw new IllegalStateException("unforseen unknown 
extender....");
+            }
+            FilterHandler handler = 
m_extenderFilterHandlers.remove(serviceReference);
+            m_extenderFilterHandlerArray =
+                m_extenderFilterHandlers.values().toArray(new 
FilterHandler[m_extenderFilterHandlers.size()]);
+            Arrays.sort(m_extenderFilterHandlerArray);
+            if (handler != null) {
+                handler.destroy();
+            }
         }
-    }
-
-    public void addDispatchFilterMatcher(DispatchFilterMatcher 
dispatchFilterMatcher) {
-        if (m_matchers.contains(dispatchFilterMatcher)) {
-            throw new IllegalStateException("unforseen duplicate matcher....");
+        finally {
+            m_extenderFilterHandlersLock.writeLock().unlock();
         }
-        m_matchers.add(dispatchFilterMatcher);
     }
 
-    public void removeDispatchFilterMatcher(DispatchFilterMatcher 
dispatchFilterMatcher) {
-        if (!m_matchers.contains(dispatchFilterMatcher)) {
-            throw new IllegalStateException("unforseen unknown matcher....");
-        }
-        m_matchers.remove(dispatchFilterMatcher);
+    public FilterHandler[] getExtenderFilterHandlers() {
+        return m_extenderFilterHandlerArray;
     }
 
     public void addFilterHandler(ServiceReference serviceReference, Filter 
filter) {
-        if (m_filterHandlers.containsKey(serviceReference)) {
-            throw new IllegalStateException("Unexpected.... ");
-        }
-        int ranking = getIntProperty(serviceReference, 
Constants.SERVICE_RANKING, 0);
+
+        int serviceId = getIntProperty(serviceReference, Constants.SERVICE_ID, 
0);
+        int serviceRanking = getIntProperty(serviceReference, 
Constants.SERVICE_RANKING, 0);
         String pattern = getStringProperty(serviceReference, 
DispatcherService.PATTERN_KEY);
         if (pattern == null) {
+            if (getLogService() != null)
+                getLogService().log(LogService.LOG_WARNING, "Cannot register a 
filter without pattern");
             return;
         }
-
-        String tenant = getStringProperty(serviceReference, 
Tenant.TENANT_ID_SERVICEPROPERTY);
+        String tenantId = getStringProperty(serviceReference, 
Tenant.TENANT_ID_SERVICEPROPERTY);
 
         HandlerServletContext extServletContextWrapper =
             new HandlerServletContext(getServletContext(), 
getHttpContext(serviceReference));
+
         FilterHandler filterHandler =
-            new FilterHandler(this, extServletContextWrapper, filter, pattern, 
ranking, tenant);
+            new FilterHandler(serviceId, extServletContextWrapper, filter, 
pattern, serviceRanking, tenantId);
         filterHandler.setInitParams(getInitParams(serviceReference));
 
+        m_filterHandlersLock.writeLock().lock();
         try {
-            filterHandler.init();
-            m_filterHandlers.put(serviceReference, filterHandler);
+            if (m_filterHandlers.containsKey(serviceReference)) {
+                throw new IllegalStateException("Unexpected.... ");
+            }
+            try {
+                filterHandler.init();
+                m_filterHandlers.put(serviceReference, filterHandler);
+                m_tenantFilterHandlerArrays.clear();
+            }
+            catch (ServletException e) {
+                e.printStackTrace();
+            }
         }
-        catch (ServletException e) {
-            e.printStackTrace();
+        finally {
+            m_filterHandlersLock.writeLock().unlock();
         }
     }
 
     public void removeFilterHandler(ServiceReference serviceReference, Filter 
filter) {
-        if (!m_filterHandlers.containsKey(serviceReference)) {
-            throw new IllegalStateException("Unexpected.... ");
+        m_filterHandlersLock.writeLock().lock();
+        try {
+            if (!m_filterHandlers.containsKey(serviceReference)) {
+                throw new IllegalStateException("Unexpected.... ");
+            }
+            FilterHandler filterHandler = 
m_filterHandlers.remove(serviceReference);
+            m_tenantFilterHandlerArrays.clear();
+            if (filterHandler != null) {
+                filterHandler.destroy();
+            }
         }
-        FilterHandler filterHandler = 
m_filterHandlers.remove(serviceReference);
-        if (filterHandler != null) {
-            filterHandler.destroy();
+        finally {
+            m_filterHandlersLock.writeLock().unlock();
         }
     }
 
     public FilterHandler[] getFilterHandlers(HttpServletRequest 
httpServletRequest) {
-        // FIXME optimize
-        FilterHandler[] filterHandlers = m_filterHandlers.values().toArray(new 
FilterHandler[m_filterHandlers.size()]);
-        Arrays.sort(filterHandlers);
-        FilterHandler[] extenderFilterHandlers =
-            m_extenderFilterHandlers.values().toArray(new 
FilterHandler[m_extenderFilterHandlers.size()]);
-        Arrays.sort(filterHandlers);
-        FilterHandler[] finalFilterHandlers = new 
FilterHandler[filterHandlers.length + extenderFilterHandlers.length];
-        System.arraycopy(extenderFilterHandlers, 0, finalFilterHandlers, 0, 
extenderFilterHandlers.length);
-        System.arraycopy(filterHandlers, 0, finalFilterHandlers, 
extenderFilterHandlers.length, filterHandlers.length);
-
-        System.err.println("Number of matching filters: " + 
filterHandlers.length);
-        return finalFilterHandlers;
-    }
-
-    public boolean filterHandlerMatches(FilterHandler filterHandler, 
HttpServletRequest httpServletRequest) {
-        for (DispatchFilterMatcher matcher : m_matchers) {
-            if (!matcher.matches(filterHandler, httpServletRequest)) {
-                return false;
+
+        Tenant tenant =
+            (Tenant) 
httpServletRequest.getAttribute(DispatcherService.TENANT_REQUESTCONTEXT_KEY);
+
+        String tenantId = "";
+        if (tenant != null) {
+            tenantId = tenant.getId();
+
+        }
+
+        m_filterHandlersLock.readLock().lock();
+        try {
+            FilterHandler[] handlerArray = 
m_tenantFilterHandlerArrays.get(tenantId);
+            if (handlerArray != null) {
+                return handlerArray;
             }
         }
-        return true;
+        finally {
+            m_filterHandlersLock.readLock().unlock();
+        }
+
+        m_filterHandlersLock.writeLock().lock();
+        try {
+            // retry
+            FilterHandler[] handlerArray = 
m_tenantFilterHandlerArrays.get(tenantId);
+            if (handlerArray != null) {
+                return handlerArray;
+            }
+
+            // build
+            if (tenant == null) {
+                List<FilterHandler> filterHandlers = new 
LinkedList<FilterHandler>();
+                for (FilterHandler filterHandler : m_filterHandlers.values()) {
+                    if (filterHandler.getTenantId() == null || 
filterHandler.getTenantId() == "") {
+                        filterHandlers.add(filterHandler);
+                    }
+                }
+                handlerArray = filterHandlers.toArray(new 
FilterHandler[filterHandlers.size()]);
+            }
+            else {
+                List<FilterHandler> filterHandlers = new 
LinkedList<FilterHandler>();
+                for (FilterHandler filterHandler : m_filterHandlers.values()) {
+                    if (filterHandler.getTenantId() == null || 
filterHandler.getTenantId() == ""
+                            || 
filterHandler.getTenantId().equals(tenant.getId())) {
+                        filterHandlers.add(filterHandler);
+                    }
+                }
+                handlerArray = filterHandlers.toArray(new 
FilterHandler[filterHandlers.size()]);
+            }
+
+            Arrays.sort(handlerArray);
+            m_tenantFilterHandlerArrays.put(tenantId, handlerArray);
+            return handlerArray;
+        }
+        finally {
+            m_filterHandlersLock.writeLock().unlock();
+        }
     }
 }

Modified: 
branches/amdatu-dispatcher/amdatu-web/dispatcher/src/main/java/org/amdatu/web/dispatcher/handler/ServletHandler.java
==============================================================================
--- 
branches/amdatu-dispatcher/amdatu-web/dispatcher/src/main/java/org/amdatu/web/dispatcher/handler/ServletHandler.java
        (original)
+++ 
branches/amdatu-dispatcher/amdatu-web/dispatcher/src/main/java/org/amdatu/web/dispatcher/handler/ServletHandler.java
        Tue Feb  8 12:10:37 2011
@@ -28,15 +28,18 @@
 
 public final class ServletHandler extends AbstractHandler implements 
Comparable<ServletHandler> {
 
-    private final ServletHandlerRegistry m_servletHandlerRegistry;
     private final String m_alias;
     private final Servlet m_servlet;
 
-    public ServletHandler(ServletHandlerRegistry servletHandlerRegistry, 
ExtServletContext context, Servlet servlet,
+    public ServletHandler(int handlerId, int ranking, ExtServletContext 
context, Servlet servlet,
         String alias, String tenantid) {
-        super(context, tenantid);
-        m_servletHandlerRegistry = servletHandlerRegistry;
-        m_alias = alias;
+        super(handlerId, ranking, context, tenantid);
+        if (alias == null || alias.equals("")) {
+            m_alias = "/";
+        }
+        else {
+            m_alias = alias;
+        }
         m_servlet = servlet;
     }
 
@@ -60,36 +63,34 @@
 
     public boolean handle(HttpServletRequest httpServletRequest, 
HttpServletResponse httpServletResponse)
         throws ServletException, IOException {
-        if (matches(httpServletRequest)) {
+        if (matches(httpServletRequest.getPathInfo())) {
             doHandle(httpServletRequest, httpServletResponse);
             return true;
         }
         return false;
     }
 
-    public boolean matches(HttpServletRequest httpServletRequest) {
-        return matches(httpServletRequest, httpServletRequest.getPathInfo());
-    }
-
-    public boolean matches(HttpServletRequest httpServletRequest, String path) 
{
-        return matchesPath(path)
-                && m_servletHandlerRegistry.servletHandlerMatches(this,
-                        httpServletRequest);
-    }
-
-    public boolean matchesPath(String uri) {
-        if (uri == null) {
+    public boolean matches(String path) {
+        if (path == null) {
             return m_alias.equals("/");
         }
         else if (m_alias.equals("/")) {
-            return uri.startsWith(m_alias);
+            return path.startsWith(m_alias);
         }
         else {
-            return uri.equals(m_alias) || uri.startsWith(m_alias + "/");
+            return path.equals(m_alias) || path.startsWith(m_alias + "/");
         }
     }
 
     public int compareTo(ServletHandler other) {
+        if (other.m_alias.length() == m_alias.length()) {
+            if (m_ranking == other.m_ranking) {
+                return m_handlerId - other.m_handlerId;
+            }
+            else {
+                return other.m_ranking - m_ranking;
+            }
+        }
         return other.m_alias.length() - m_alias.length();
     }
 

Modified: 
branches/amdatu-dispatcher/amdatu-web/dispatcher/src/main/java/org/amdatu/web/dispatcher/handler/ServletHandlerRegistry.java
==============================================================================
--- 
branches/amdatu-dispatcher/amdatu-web/dispatcher/src/main/java/org/amdatu/web/dispatcher/handler/ServletHandlerRegistry.java
        (original)
+++ 
branches/amdatu-dispatcher/amdatu-web/dispatcher/src/main/java/org/amdatu/web/dispatcher/handler/ServletHandlerRegistry.java
        Tue Feb  8 12:10:37 2011
@@ -18,53 +18,41 @@
 
 import java.util.Arrays;
 import java.util.HashMap;
-import java.util.HashSet;
+import java.util.LinkedList;
+import java.util.List;
 import java.util.Map;
-import java.util.Set;
+import java.util.concurrent.locks.ReentrantReadWriteLock;
 
 import javax.servlet.Servlet;
 import javax.servlet.ServletException;
 import javax.servlet.http.HttpServletRequest;
 
 import org.amdatu.core.tenant.Tenant;
-import org.amdatu.web.dispatcher.DispatchServletMatcher;
 import org.amdatu.web.dispatcher.DispatcherService;
 import org.amdatu.web.dispatcher.context.HandlerServletContext;
 import org.amdatu.web.dispatcher.service.DispatcherServiceImpl;
+import org.osgi.framework.Constants;
 import org.osgi.framework.ServiceReference;
 import org.osgi.service.log.LogService;
 
-//FIXME synchronization
 public final class ServletHandlerRegistry extends AbstractHandlerRegistry {
 
+    private final ReentrantReadWriteLock m_servletHandlersLock = new 
ReentrantReadWriteLock();
+
     private final Map<ServiceReference, ServletHandler> m_servletHandlers =
         new HashMap<ServiceReference, ServletHandler>();
 
-    private Set<DispatchServletMatcher> m_matchers = new 
HashSet<DispatchServletMatcher>();
-
-    public ServletHandlerRegistry(DispatcherServiceImpl dispatcherService) {
-        super(dispatcherService);
-    }
-
-    public void addDispatchServletMatcher(DispatchServletMatcher 
dispatchServletMatcher) {
-        if (m_matchers.contains(dispatchServletMatcher)) {
-            throw new IllegalStateException("unforseen duplicate matcher....");
-        }
-        m_matchers.add(dispatchServletMatcher);
-    }
+    private final Map<String, ServletHandler[]> m_tenantServletHandlerArrays =
+        new HashMap<String, ServletHandler[]>();
 
-    public void removeDispatchServletMatcher(DispatchServletMatcher 
dispatchServletMatcher) {
-        if (!m_matchers.contains(dispatchServletMatcher)) {
-            throw new IllegalStateException("unforseen unknown matcher....");
-        }
-        m_matchers.remove(dispatchServletMatcher);
+    public ServletHandlerRegistry() {
+        super();
     }
 
     public void addServletHandler(ServiceReference serviceReference, Servlet 
servlet) {
-        if (m_servletHandlers.containsKey(serviceReference)) {
-            throw new IllegalStateException("Unexpected.... ");
-        }
 
+        int serviceId = getIntProperty(serviceReference, Constants.SERVICE_ID, 
0);
+        int serviceRanking = getIntProperty(serviceReference, 
Constants.SERVICE_RANKING, 0);
         String alias = getStringProperty(serviceReference, 
DispatcherServiceImpl.ALIAS_KEY);
         if (alias == null) {
             if (getLogService() != null)
@@ -73,47 +61,106 @@
         }
 
         String tenant = getStringProperty(serviceReference, 
Tenant.TENANT_ID_SERVICEPROPERTY);
-
         HandlerServletContext servletContextWrapper =
             new HandlerServletContext(getServletContext(), 
getHttpContext(serviceReference));
 
-        ServletHandler handler = new ServletHandler(this, 
servletContextWrapper, servlet, alias, tenant);
+        ServletHandler handler =
+            new ServletHandler(serviceId, serviceRanking, 
servletContextWrapper, servlet, alias, tenant);
         handler.setInitParams(getInitParams(serviceReference));
 
+        m_servletHandlersLock.writeLock().lock();
         try {
-            handler.init();
-            m_servletHandlers.put(serviceReference, handler);
+            if (m_servletHandlers.containsKey(serviceReference)) {
+                throw new IllegalStateException("Unexpected.... ");
+            }
+            try {
+                handler.init();
+                m_servletHandlers.put(serviceReference, handler);
+                m_tenantServletHandlerArrays.clear();
+            }
+            catch (ServletException e) {
+                e.printStackTrace();
+            }
         }
-        catch (ServletException e) {
-            e.printStackTrace();
+        finally {
+            m_servletHandlersLock.writeLock().unlock();
         }
     }
 
     public void removeServletHandler(ServiceReference serviceReference, 
Servlet servlet) {
-        if (!m_servletHandlers.containsKey(serviceReference)) {
-            return;
+
+        m_servletHandlersLock.writeLock().lock();
+        try {
+            if (!m_servletHandlers.containsKey(serviceReference)) {
+                return;
+            }
+            ServletHandler servletHandler = 
m_servletHandlers.remove(serviceReference);
+            m_tenantServletHandlerArrays.clear();
+            if (servletHandler != null) {
+                servletHandler.destroy();
+            }
         }
-        ServletHandler servletHandler = 
m_servletHandlers.remove(serviceReference);
-        if (servletHandler != null) {
-            servletHandler.destroy();
+        finally {
+            m_servletHandlersLock.writeLock().unlock();
         }
     }
 
     public ServletHandler[] getServletHandlers(HttpServletRequest 
httpServletRequest) {
-        ServletHandler[] servletHandlers =
-            m_servletHandlers.values().toArray(new 
ServletHandler[m_servletHandlers.size()]);
-        Arrays.sort(servletHandlers);
 
-        System.err.println("Number of matching servlets: " + 
servletHandlers.length);
-        return servletHandlers;
-    }
+        Tenant tenant =
+            (Tenant) 
httpServletRequest.getAttribute(DispatcherService.TENANT_REQUESTCONTEXT_KEY);
+
+        String tenantId = "";
+        if (tenant != null) {
+            tenantId = tenant.getId();
+
+        }
 
-    public boolean servletHandlerMatches(ServletHandler servletHandler, 
HttpServletRequest httpServletRequest) {
-        for (DispatchServletMatcher matcher : m_matchers) {
-            if (!matcher.matches(servletHandler, httpServletRequest)) {
-                return false;
+        m_servletHandlersLock.readLock().lock();
+        try {
+            ServletHandler[] handlerArray = 
m_tenantServletHandlerArrays.get(tenantId);
+            if (handlerArray != null) {
+                return handlerArray;
             }
         }
-        return true;
+        finally {
+            m_servletHandlersLock.readLock().unlock();
+        }
+
+        m_servletHandlersLock.writeLock().lock();
+        try {
+            // retry
+            ServletHandler[] handlerArray = 
m_tenantServletHandlerArrays.get(tenantId);
+            if (handlerArray != null) {
+                return handlerArray;
+            }
+
+            // build
+            if (tenant == null) {
+                List<ServletHandler> filterHandlers = new 
LinkedList<ServletHandler>();
+                for (ServletHandler filterHandler : 
m_servletHandlers.values()) {
+                    if (filterHandler.getTenantId() == null || 
filterHandler.getTenantId() == "") {
+                        filterHandlers.add(filterHandler);
+                    }
+                }
+                handlerArray = filterHandlers.toArray(new 
ServletHandler[filterHandlers.size()]);
+            }
+            else {
+                List<ServletHandler> filterHandlers = new 
LinkedList<ServletHandler>();
+                for (ServletHandler filterHandler : 
m_servletHandlers.values()) {
+                    if (filterHandler.getTenantId() == null || 
filterHandler.getTenantId() == ""
+                        || filterHandler.getTenantId().equals(tenant.getId())) 
{
+                        filterHandlers.add(filterHandler);
+                    }
+                }
+                handlerArray = filterHandlers.toArray(new 
ServletHandler[filterHandlers.size()]);
+            }
+            Arrays.sort(handlerArray);
+            m_tenantServletHandlerArrays.put(tenantId, handlerArray);
+            return handlerArray;
+        }
+        finally {
+            m_servletHandlersLock.writeLock().unlock();
+        }
     }
 }

Modified: 
branches/amdatu-dispatcher/amdatu-web/dispatcher/src/main/java/org/amdatu/web/dispatcher/service/DispatcherServiceImpl.java
==============================================================================
--- 
branches/amdatu-dispatcher/amdatu-web/dispatcher/src/main/java/org/amdatu/web/dispatcher/service/DispatcherServiceImpl.java
 (original)
+++ 
branches/amdatu-dispatcher/amdatu-web/dispatcher/src/main/java/org/amdatu/web/dispatcher/service/DispatcherServiceImpl.java
 Tue Feb  8 12:10:37 2011
@@ -16,25 +16,26 @@
  */
 package org.amdatu.web.dispatcher.service;
 
+import java.io.IOException;
 import java.util.Hashtable;
 
 import javax.servlet.Filter;
+import javax.servlet.FilterChain;
 import javax.servlet.Servlet;
 import javax.servlet.ServletContext;
 import javax.servlet.ServletException;
 import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
 
 import org.amdatu.web.dispatcher.DispatchExtenderFilter;
 import org.amdatu.web.dispatcher.DispatcherService;
 import org.amdatu.web.dispatcher.context.DefaultHttpContext;
-import org.amdatu.web.dispatcher.context.HandlerServletContext;
 import org.amdatu.web.dispatcher.context.HttpContextManager;
-import org.amdatu.web.dispatcher.dispatch.FilterPipeline;
-import org.amdatu.web.dispatcher.dispatch.ServletPipeline;
+import org.amdatu.web.dispatcher.dispatch.ExtenderFilterPipeline;
+import org.amdatu.web.dispatcher.dispatch.CustomFilterPipeline;
 import org.amdatu.web.dispatcher.filter.DispatchInterceptFilter;
 import org.amdatu.web.dispatcher.handler.FilterHandlerRegistry;
 import org.amdatu.web.dispatcher.handler.ServletHandlerRegistry;
-import org.amdatu.web.dispatcher.matcher.TenantAwareServletMatcher;
 import org.apache.felix.http.api.ExtHttpService;
 import org.osgi.framework.Bundle;
 import org.osgi.framework.BundleContext;
@@ -52,7 +53,6 @@
     private HttpContextManager m_httpContextManager;
     private ServletHandlerRegistry m_servletHandlerRegistry;
     private FilterHandlerRegistry m_filterHandlerRegistry;
-
     private ServletContext m_extServletContext;
 
     public void init() {
@@ -67,16 +67,8 @@
 
     public void start() throws Exception {
 
-        // tmp should be service regs
-        m_servletHandlerRegistry = new ServletHandlerRegistry(this);
-        m_servletHandlerRegistry.addDispatchServletMatcher(new 
TenantAwareServletMatcher());
-
-        // tmp should be service regs
-        m_filterHandlerRegistry = new FilterHandlerRegistry(this);
-        HandlerServletContext extServletContextWrapper =
-            new HandlerServletContext(m_extServletContext, new 
DefaultHttpContext(m_bundleContext.getBundle()));
-
         m_httpContextManager = new HttpContextManager();
+        m_httpContextManager.setLogService(m_logService);
 
         m_interceptorFilter = new DispatchInterceptFilter();
         m_interceptorFilter.setLogService(m_logService);
@@ -85,6 +77,16 @@
             m_httpService.registerFilter(m_interceptorFilter, ".*", new 
Hashtable<String, Object>(), 0,
                 new DefaultHttpContext(m_bundleContext.getBundle()));
             m_extServletContext = m_interceptorFilter.getServletContext();
+
+            m_servletHandlerRegistry = new ServletHandlerRegistry();
+            m_servletHandlerRegistry.setLogService(m_logService);
+            m_servletHandlerRegistry.setServletContext(m_extServletContext);
+            
m_servletHandlerRegistry.setHttpContextManager(m_httpContextManager);
+
+            m_filterHandlerRegistry = new FilterHandlerRegistry();
+            m_filterHandlerRegistry.setLogService(m_logService);
+            m_filterHandlerRegistry.setServletContext(m_extServletContext);
+            
m_filterHandlerRegistry.setHttpContextManager(m_httpContextManager);
         }
         catch (ServletException e) {
             throw new Exception(DispatcherServiceImpl.class.getSimpleName() + 
" failed to start", e);
@@ -93,11 +95,11 @@
     }
 
     public void stop() {
-        m_logService.log(LogService.LOG_ERROR, "stop");
-
+        m_servletHandlerRegistry = null;
+        m_filterHandlerRegistry = null;
         m_httpContextManager = null;
 
-        m_httpService.unregister(".*");
+        m_httpService.unregisterFilter(m_interceptorFilter);
         m_interceptorFilter.setDispatcherService(null);
         m_interceptorFilter.setLogService(null);
         m_interceptorFilter = null;
@@ -149,13 +151,13 @@
         m_filterHandlerRegistry.removeFilterHandler(serviceReference, filter);
     }
 
-    public FilterPipeline getFilterPipeline(HttpServletRequest 
httpServletRequest) {
-        ServletPipeline servletPipeline =
-            new 
ServletPipeline(m_servletHandlerRegistry.getServletHandlers(httpServletRequest));
-        FilterPipeline filterPipeline =
-            new 
FilterPipeline(m_filterHandlerRegistry.getFilterHandlers(httpServletRequest),
-                servletPipeline);
-        return filterPipeline;
+    public void dispatchRequest(HttpServletRequest httpServletRequest, 
HttpServletResponse httpServletResponse,
+        FilterChain filterChain) throws IOException, ServletException {
+
+        ExtenderFilterPipeline pipeline =
+            new 
ExtenderFilterPipeline(m_filterHandlerRegistry.getExtenderFilterHandlers(), new 
CustomFilterPipeline(
+                m_filterHandlerRegistry, m_servletHandlerRegistry));
+        pipeline.dispatch(httpServletRequest, httpServletResponse, 
filterChain);
     }
 
     private String getStringProperty(ServiceReference ref, String key) {

Added: 
branches/amdatu-dispatcher/amdatu-web/dispatcher/src/test/java/org/amdatu/web/dispatcher/handler/FilterHandlerTest.java
==============================================================================
--- (empty file)
+++ 
branches/amdatu-dispatcher/amdatu-web/dispatcher/src/test/java/org/amdatu/web/dispatcher/handler/FilterHandlerTest.java
     Tue Feb  8 12:10:37 2011
@@ -0,0 +1,101 @@
+/*
+    Copyright (C) 2010 Amdatu.org
+
+    This program is free software: you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation, either version 3 of the License, or
+    (at your option) any later version.
+
+    This program is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU General Public License for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+package org.amdatu.web.dispatcher.handler;
+
+import java.util.Arrays;
+
+import javax.servlet.Filter;
+
+import junit.framework.Assert;
+
+import org.amdatu.web.dispatcher.context.ExtServletContext;
+import org.jmock.Mockery;
+import org.junit.Before;
+import org.junit.Test;
+
+public class FilterHandlerTest {
+
+    private Mockery m_context;
+
+    @Before
+    public void setUp() {
+        m_context = new Mockery();
+    }
+
+    @Test
+    public void testFilterHandlerCreate() {
+
+        ExtServletContext context = m_context.mock(ExtServletContext.class);
+        Filter filter = m_context.mock(Filter.class);
+
+        FilterHandler fh1 = new FilterHandler(1, context, filter, "aaa", 2, 
"t1");
+        Assert.assertEquals(1, fh1.getId());
+        Assert.assertEquals(fh1.getTenantId(), "t1");
+        Assert.assertEquals(fh1.getContext(), context);
+        Assert.assertEquals(fh1.getRanking(), 2);
+        Assert.assertEquals(fh1.getPattern(), "aaa");
+        Assert.assertEquals(fh1.getFilter(), filter);
+    }
+
+    @Test
+    public void testFilterHandlerMatching() {
+
+        ExtServletContext context = m_context.mock(ExtServletContext.class);
+        Filter filter = m_context.mock(Filter.class);
+
+        FilterHandler fh1 = new FilterHandler(1, context, filter, ".*", 0, "");
+        Assert.assertTrue(fh1.matches(null));
+        Assert.assertTrue(fh1.matches(""));
+        Assert.assertTrue(fh1.matches("/"));
+        Assert.assertTrue(fh1.matches("/whatever"));
+
+        FilterHandler fh2 = new FilterHandler(2, context, filter, "/.*", 2, 
"");
+        Assert.assertTrue(fh2.matches(null));
+        Assert.assertTrue(fh2.matches("/"));
+        Assert.assertTrue(fh2.matches("/whatever"));
+
+        FilterHandler fh3 = new FilterHandler(3, context, filter, "/hello.*", 
2, "");
+        Assert.assertFalse(fh3.matches(null));
+        Assert.assertFalse(fh3.matches("/"));
+        Assert.assertTrue(fh3.matches("/hello"));
+        Assert.assertTrue(fh3.matches("/hellowww"));
+        Assert.assertTrue(fh3.matches("/hello/"));
+        Assert.assertTrue(fh3.matches("/hello/world"));
+        Assert.assertFalse(fh3.matches("/hell0"));
+        Assert.assertFalse(fh3.matches("/hell0/"));
+        Assert.assertFalse(fh3.matches("/hell0/world"));
+    }
+
+    @Test
+    public void testFilterHandlerSorting() {
+
+        ExtServletContext context = m_context.mock(ExtServletContext.class);
+        Filter filter = m_context.mock(Filter.class);
+
+        FilterHandler fh1 = new FilterHandler(1, context, filter, ".*", 0, "");
+        FilterHandler fh2 = new FilterHandler(2, context, filter, ".*", 2, "");
+        FilterHandler fh3 = new FilterHandler(3, context, filter, ".*", 1, "");
+        FilterHandler fh4 = new FilterHandler(4, context, filter, ".*", 1, "");
+
+        // higher service.ranking rules
+        // lower service.id rules when service.ranking equals
+        FilterHandler[] expectedArray = new FilterHandler[] { fh2, fh3, fh4, 
fh1 };
+        FilterHandler[] sortedArray = new FilterHandler[] { fh1, fh2, fh3, fh4 
};
+        Arrays.sort(sortedArray);
+        Assert.assertTrue(Arrays.equals(expectedArray, sortedArray));
+    }
+}

Added: 
branches/amdatu-dispatcher/amdatu-web/dispatcher/src/test/java/org/amdatu/web/dispatcher/handler/ServletHandlerRegistryTest.java
==============================================================================
--- (empty file)
+++ 
branches/amdatu-dispatcher/amdatu-web/dispatcher/src/test/java/org/amdatu/web/dispatcher/handler/ServletHandlerRegistryTest.java
    Tue Feb  8 12:10:37 2011
@@ -0,0 +1,49 @@
+/*
+    Copyright (C) 2010 Amdatu.org
+
+    This program is free software: you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation, either version 3 of the License, or
+    (at your option) any later version.
+
+    This program is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU General Public License for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+package org.amdatu.web.dispatcher.handler;
+
+import javax.servlet.ServletContext;
+
+import junit.framework.Assert;
+
+import org.jmock.Mockery;
+import org.junit.Before;
+import org.junit.Test;
+import org.osgi.service.log.LogService;
+
+public class ServletHandlerRegistryTest {
+
+    private Mockery m_context;
+
+    @Before
+    public void setUp() {
+        m_context = new Mockery();
+    }
+
+    @Test
+    public void testFilterReg() {
+        LogService logService = m_context.mock(LogService.class);
+        ServletContext servletContext = m_context.mock(ServletContext.class);
+
+        ServletHandlerRegistry sr = new ServletHandlerRegistry();
+        sr.setLogService(logService);
+        sr.setServletContext(servletContext);
+
+        // FIXME to be done
+        Assert.assertTrue(true);
+    }
+}

Added: 
branches/amdatu-dispatcher/amdatu-web/dispatcher/src/test/java/org/amdatu/web/dispatcher/handler/ServletHandlerTest.java
==============================================================================
--- (empty file)
+++ 
branches/amdatu-dispatcher/amdatu-web/dispatcher/src/test/java/org/amdatu/web/dispatcher/handler/ServletHandlerTest.java
    Tue Feb  8 12:10:37 2011
@@ -0,0 +1,98 @@
+/*
+    Copyright (C) 2010 Amdatu.org
+
+    This program is free software: you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation, either version 3 of the License, or
+    (at your option) any later version.
+
+    This program is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU General Public License for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+package org.amdatu.web.dispatcher.handler;
+
+import java.util.Arrays;
+
+import javax.servlet.Servlet;
+
+import junit.framework.Assert;
+
+import org.amdatu.web.dispatcher.context.ExtServletContext;
+import org.jmock.Mockery;
+import org.junit.Before;
+import org.junit.Test;
+
+public class ServletHandlerTest {
+
+    private Mockery m_context;
+
+    @Before
+    public void setUp() {
+        m_context = new Mockery();
+    }
+
+    @Test
+    public void testServletHandlerCreate() {
+
+        ExtServletContext context = m_context.mock(ExtServletContext.class);
+        Servlet servlet = m_context.mock(Servlet.class);
+
+        ServletHandler sh1 = new ServletHandler(1, 2, context, servlet, 
"/helloworld", "t1");
+        Assert.assertEquals(1, sh1.getId());
+        Assert.assertEquals(sh1.getTenantId(), "t1");
+        Assert.assertEquals(sh1.getContext(), context);
+        Assert.assertEquals(sh1.getRanking(), 2);
+        Assert.assertEquals(sh1.getAlias(), "/helloworld");
+        Assert.assertEquals(sh1.getServlet(), servlet);
+    }
+
+    @Test
+    public void testServletHandlerMatching() {
+
+        ExtServletContext context = m_context.mock(ExtServletContext.class);
+        Servlet servlet = m_context.mock(Servlet.class);
+
+        ServletHandler sh1 = new ServletHandler(1, 0, context, servlet, "", 
"");
+        Assert.assertTrue(sh1.matches(null));
+        Assert.assertTrue(sh1.matches("/"));
+        Assert.assertTrue(sh1.matches("/whatever"));
+
+        ServletHandler sh2 = new ServletHandler(1, 0, context, servlet, "/", 
"");
+        Assert.assertTrue(sh2.matches(null));
+        Assert.assertTrue(sh2.matches("/"));
+        Assert.assertTrue(sh2.matches("/whatever"));
+
+        ServletHandler sh3 = new ServletHandler(1, 0, context, servlet, 
"/hello", "");
+        Assert.assertTrue(sh3.matches("/hello"));
+        Assert.assertTrue(sh3.matches("/hello/"));
+        Assert.assertTrue(sh3.matches("/hello/whatever"));
+        Assert.assertFalse(sh3.matches("/hell0"));
+        Assert.assertFalse(sh3.matches("/hell0/"));
+    }
+
+    @Test
+    public void testServletHandlerSorting() {
+
+        ExtServletContext context = m_context.mock(ExtServletContext.class);
+        Servlet servlet = m_context.mock(Servlet.class);
+
+        ServletHandler sh1 = new ServletHandler(1, 0, context, servlet, 
"/hello", "");
+        ServletHandler sh2 = new ServletHandler(2, 8, context, servlet, 
"/hello", "");
+        ServletHandler sh3 = new ServletHandler(3, 0, context, servlet, 
"/hello/world", "");
+        ServletHandler sh4 = new ServletHandler(4, 0, context, servlet, 
"/hello/world", "");
+        ServletHandler sh5 = new ServletHandler(5, 2, context, servlet, 
"/hello/world", "");
+
+        // specific path rules
+        // higher service.ranking rules when path equals
+        // lower service.id rules when service.ranking equals
+        ServletHandler[] expectedArray = new ServletHandler[] { sh5, sh3, sh4, 
sh2, sh1 };
+        ServletHandler[] sortedArray = new ServletHandler[] { sh1, sh2, sh3, 
sh4, sh5 };
+        Arrays.sort(sortedArray);
+        Assert.assertTrue(Arrays.equals(expectedArray, sortedArray));
+    }
+}

Added: 
branches/amdatu-dispatcher/integration-tests/src/test/java/org/amdatu/test/integration/tests/DispatcherPerformanceTest.java
==============================================================================
--- (empty file)
+++ 
branches/amdatu-dispatcher/integration-tests/src/test/java/org/amdatu/test/integration/tests/DispatcherPerformanceTest.java
 Tue Feb  8 12:10:37 2011
@@ -0,0 +1,344 @@
+package org.amdatu.test.integration.tests;
+
+import static org.ops4j.pax.exam.CoreOptions.provision;
+
+import java.io.IOException;
+import java.net.URL;
+import java.util.ArrayList;
+import java.util.Dictionary;
+import java.util.HashMap;
+import java.util.Hashtable;
+import java.util.List;
+import java.util.Map;
+
+import javax.servlet.Filter;
+import javax.servlet.FilterChain;
+import javax.servlet.FilterConfig;
+import javax.servlet.Servlet;
+import javax.servlet.ServletConfig;
+import javax.servlet.ServletException;
+import javax.servlet.ServletRequest;
+import javax.servlet.ServletResponse;
+import javax.servlet.http.HttpServletResponse;
+
+import org.amdatu.core.tenant.Tenant;
+import org.amdatu.core.tenant.TenantException;
+import org.amdatu.core.tenant.TenantManagementService;
+import org.amdatu.test.integration.base.ConfigProvider;
+import org.amdatu.test.integration.base.IntegrationTestBase;
+import org.apache.commons.httpclient.HttpClient;
+import org.apache.commons.httpclient.HttpException;
+import org.apache.commons.httpclient.HttpMethod;
+import org.apache.commons.httpclient.HttpStatus;
+import org.apache.commons.httpclient.methods.GetMethod;
+import org.apache.felix.dm.Component;
+import org.apache.felix.dm.DependencyManager;
+import org.junit.Assert;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.ops4j.pax.exam.Option;
+import org.ops4j.pax.exam.junit.Configuration;
+import org.ops4j.pax.exam.junit.JUnit4TestRunner;
+import org.osgi.service.cm.ConfigurationAdmin;
+import org.osgi.service.http.HttpService;
+import org.osgi.service.log.LogService;
+
+/**
+ * This test tests the performance of the dispatcher/http service. In a single 
test run we 
+ * perform an amount of [REQUESTS] GET requests to a single Test servlet we 
registered. 
+ * Doing this we vary the amount of Servlet filters and Tenants. This results 
in a matrix
+ * of #Servlet filters against #tenants where each cell holds the results of 
running the 
+ * single performance test.
+ */
+ at RunWith(JUnit4TestRunner.class)
+public class DispatcherPerformanceTest extends IntegrationTestBase {
+
+    private final static String RESOURCE_ID = "test";
+    private final static String TEST_TEXT = "Integration test successfull!";
+    private final static String TEST_HEADER_BEFORE = "testFilterBefore";
+    private final static String TEST_HEADER_BEFORE_VALUE = "before";
+    private final static String TEST_HEADER_AFTER = "testFilterAfter";
+    private final static String TEST_HEADER_AFTER_VALUE = "after";
+
+    private final static String SERVLET_ALIAS_BASE = "/test/servlet";
+    private final static int REQUESTS = 2000;
+    private final static String EOL = System.getProperty("line.separator");
+
+    private int[] FILTER_AMOUNT = new int[] { 50 };
+    private int[] TENANT_AMOUNT = new int[] { 50 };
+    private PerformanceResults[][] m_resultMatrix = new 
PerformanceResults[FILTER_AMOUNT.length][TENANT_AMOUNT.length];
+
+    private volatile LogService m_logService;
+    private volatile TenantManagementService m_tenantService;
+    private volatile ConfigurationAdmin m_configAdmin;
+    private DependencyManager m_manager;
+
+    private String m_servletBaseUrl;
+    private List<Long> m_results = new ArrayList<Long>();
+
+    class PerformanceResults {
+        int size;
+        int filterCount;
+        int tenantCount;
+        double sum;
+        double average;
+        double sd;
+    }
+
+    @Configuration
+    public Option[] configure() {
+        return super.configure();
+    }
+
+    protected Option provisionBundles() {
+        return provision(
+                amdatuTenantStoreFSService(),
+                amdatuTenantService(),
+                felixHttpServiceJetty(),
+                amdatuDispatcher(),
+                amdatuHostnameTenantResolver(),
+                slingCommons(),
+                slingMime(),
+                commonsHttpClient(),
+                paxSwissbox(),
+                ops4jBaseLang(),
+                commonsLogging(),
+                commonsCodec(),
+                amdatuHttpContext(),
+                amdatuJspSupport());
+    }
+
+    @Override
+    protected Component[] getDependencies(DependencyManager manager) {
+        // Now we register a test servlet, also whiteboard-style
+        m_manager = manager;
+
+        Component testComponent = manager.createComponent()
+            .setImplementation(this)
+            
.add(manager.createServiceDependency().setService(LogService.class).setRequired(true))
+            
.add(manager.createServiceDependency().setService(ConfigurationAdmin.class))
+            
.add(manager.createServiceDependency().setService(TenantManagementService.class).setRequired(true))
+            
.add(manager.createServiceDependency().setService(HttpService.class).setRequired(true));
+
+        return new Component[] { testComponent };
+    }
+
+    protected void initConfiguration() throws IOException {
+        m_configAdmin = getService(ConfigurationAdmin.class);
+        m_logService = getService(LogService.class);
+
+        // Add cassandra and templates configs
+        ConfigProvider configProvider = new ConfigProvider();
+        configProvider.addTenantConfig(m_configAdmin);
+        configProvider.addFSTenantStoreConfig(m_configAdmin);
+        configProvider.addFelixHttpServiceConfig(m_configAdmin);
+        m_logService.log(LogService.LOG_DEBUG, "HttpService config set to " + 
ConfigProvider.HOSTNAME + ":"
+            + ConfigProvider.PORTNR);
+    }
+
+    @Test
+    public void testPerformance() throws Exception {
+        // Remove the default tenant
+        deleteAllTenants();
+
+        int lastFilter = 0;
+        int currentFilterCount = 0;
+        int lastTenant = 0;
+        int currentTenantCount = 0;
+
+        addTestServlet(SERVLET_ALIAS_BASE);
+
+        for (int filterIndex = 0; filterIndex < FILTER_AMOUNT.length; 
filterIndex++) {
+            // Register test filters
+            int requiredFilterCount = FILTER_AMOUNT[filterIndex];
+            while (currentFilterCount < requiredFilterCount) {
+                lastFilter++;
+                currentFilterCount++;
+                addTestFilter();
+                m_logService.log(LogService.LOG_INFO, "Added filter " + 
lastFilter);
+            }
+
+            for (int tenantIndex = 0; tenantIndex < TENANT_AMOUNT.length; 
tenantIndex++) {
+                // Create tenants
+                int requiredTenantCount = TENANT_AMOUNT[tenantIndex];
+                while (currentTenantCount < requiredTenantCount) {
+                    lastTenant++;
+                    currentTenantCount++;
+                    Map<String, String> properties = new HashMap<String, 
String>();
+                    properties.put(Tenant.HOSTNAME_PROPERTY, "127.0.0." + 
lastTenant);
+                    long before = System.currentTimeMillis();
+                    m_tenantService.createTenant("tenant_" + lastTenant, 
"tenant_" + lastTenant, properties);
+                    long diff = System.currentTimeMillis() - before;
+                    m_logService.log(LogService.LOG_INFO, "Added tenant " + 
"tenant_" + lastTenant + " in " + diff
+                        + " ms");
+                }
+
+                // Give time to register/unregister all filters, servlets, 
tenants, etc.
+                m_logService.log(LogService.LOG_INFO, "Waiting for all 
services to be registered/unregistered..");
+                Thread.sleep(3000);
+
+                m_logService.log(LogService.LOG_INFO, "Running single 
performance test with " + requiredFilterCount
+                        + " filters and " + requiredTenantCount + " tenants.");
+                PerformanceResults results = runSingleTest(currentFilterCount, 
currentTenantCount);
+                m_resultMatrix[filterIndex][tenantIndex] = results;
+                m_logService.log(LogService.LOG_INFO, "Intermediate result:" + 
toString(results));
+            }
+
+            // Delete all tenants
+            deleteAllTenants();
+            currentTenantCount = 0;
+            lastTenant = 0;
+        }
+
+        StringBuffer msg = new StringBuffer();
+        msg.append("***********************************" + EOL + EOL);
+        for (int filterIndex = 0; filterIndex < m_resultMatrix.length; 
filterIndex++) {
+            PerformanceResults[] results = m_resultMatrix[filterIndex];
+            for (int tenantIndex = 0; tenantIndex < results.length; 
tenantIndex++) {
+                msg.append(toString(results[tenantIndex]));
+                msg.append(EOL);
+            }
+        }
+        msg.append("***********************************" + EOL);
+        Thread.sleep(3000);
+        m_logService.log(LogService.LOG_INFO, "Performance test results: " + 
EOL + msg);
+    }
+
+    private void deleteAllTenants() throws TenantException {
+        long before = System.currentTimeMillis();
+        int size = m_tenantService.getTenants() != null ? 
m_tenantService.getTenants().size() : 0;
+        m_logService.log(LogService.LOG_INFO, "Removing " + size + " tenants");
+        while (m_tenantService.getTenants() != null && 
m_tenantService.getTenants().size() > 0) {
+            m_tenantService.deleteTenant(m_tenantService.getTenants().get(0));
+        }
+        long diff = System.currentTimeMillis() - before;
+        m_logService.log(LogService.LOG_INFO, "Removed " + size + " tenants in 
" + diff + " ms");
+    }
+
+    private String toString(PerformanceResults results) {
+        String msg = "";
+        msg += "  #Filters: " + results.filterCount + ", #Tenants: " + 
results.tenantCount + EOL;
+        msg +=
+            "  size=" + results.size + ", sum=" + results.sum + ", mean=" + 
results.average + ", sd=" + results.sd
+                + EOL;
+        return msg;
+    }
+
+    private PerformanceResults runSingleTest(int filterCount, int tenantCount) 
throws HttpException, IOException {
+        HttpClient httpClient = new HttpClient();
+        m_results = new ArrayList<Long>();
+        m_servletBaseUrl = "http://127.0.0.1:"; + ConfigProvider.PORTNR + 
SERVLET_ALIAS_BASE;
+
+        // Warming up request
+        HttpMethod warmingUpMethod = new GetMethod(m_servletBaseUrl);
+        try {
+            // Execute the method, this should return a 200
+            httpClient.executeMethod(warmingUpMethod);
+        }
+        finally {
+            // Release the connection.
+            warmingUpMethod.releaseConnection();
+        }
+
+        for (int i = 0; i < REQUESTS; i++) {
+            long before = System.currentTimeMillis();
+            String url = m_servletBaseUrl + "?test" + i; // Unique URL to 
prevent HTTP caching, as we do not want to test performance of the HTTP cache
+            HttpMethod method = new GetMethod(url);
+            try {
+                // Execute the method, this should return a 200
+                int statusCode = httpClient.executeMethod(method);
+                Assert.assertTrue("HTTP GET to '" + url + "' returned " + 
statusCode, statusCode == HttpStatus.SC_OK);
+            }
+            finally {
+                // Release the connection.
+                method.releaseConnection();
+            }
+            long after = System.currentTimeMillis();
+            ;
+            m_results.add(after - before);
+        }
+
+        double sum = 0;
+        double sd = 0;
+        for (long result : m_results) {
+            sum += result;
+        }
+        double mean = sum / m_results.size();
+        for (long result : m_results) {
+            sd += Math.pow(result - mean, 2);
+        }
+        sd = Math.sqrt(sd / m_results.size());
+
+        PerformanceResults results = new PerformanceResults();
+        results.size = m_results.size();
+        results.filterCount = filterCount;
+        results.tenantCount = tenantCount;
+        results.sum = sum;
+        results.average = mean;
+        results.sd = sd;
+        return results;
+    }
+
+    private void addTestServlet(String alias) {
+        Dictionary<String, String> servletProperties = new Hashtable<String, 
String>();
+        servletProperties.put("alias", alias);
+        m_manager.add(m_manager.createAdapterService(Tenant.class, null)
+            .setImplementation(MyTestServlet.class)
+            .setInterface(new String[] { Servlet.class.getName() }, 
servletProperties)
+            .setCallbacks("_init", "_start", "_stop", "_destroy"));
+    }
+
+    private void addTestFilter() {
+        Dictionary<String, String> properties = new Hashtable<String, 
String>();
+        properties.put("pattern", ".*");
+        m_manager.add(m_manager.createAdapterService(Tenant.class, null)
+            .setImplementation(MyTestFilter.class)
+            .setInterface(new String[] { Filter.class.getName() }, properties)
+            .setCallbacks("_init", "_start", "_stop", "_destroy"));
+    }
+
+    public static class MyTestFilter implements Filter {
+
+        public void init(FilterConfig filterconfig) throws ServletException {
+        }
+
+        public void destroy() {
+        }
+
+        public void doFilter(ServletRequest req, ServletResponse res, 
FilterChain chain) throws IOException,
+            ServletException {
+            ((HttpServletResponse) res).setHeader(TEST_HEADER_BEFORE, 
TEST_HEADER_BEFORE_VALUE);
+            chain.doFilter(req, res);
+            ((HttpServletResponse) res).setHeader(TEST_HEADER_AFTER, 
TEST_HEADER_AFTER_VALUE);
+        }
+    }
+
+    public static class MyTestServlet implements Servlet {
+
+        public void destroy() {
+        }
+
+        public ServletConfig getServletConfig() {
+            return null;
+        }
+
+        public String getServletInfo() {
+            return null;
+        }
+
+        public void init(ServletConfig arg0) throws ServletException {
+        }
+
+        public void service(ServletRequest req, ServletResponse res) throws 
ServletException, IOException {
+            res.getWriter().append(TEST_TEXT);
+        }
+
+        public URL getResource(String name) {
+            return null;
+        }
+
+        public String getResourceId() {
+            return RESOURCE_ID;
+        }
+    }
+}
\ No newline at end of file

Modified: 
branches/amdatu-dispatcher/integration-tests/src/test/java/org/amdatu/test/integration/tests/OAuthSignedRequestsTest.java
==============================================================================
--- 
branches/amdatu-dispatcher/integration-tests/src/test/java/org/amdatu/test/integration/tests/OAuthSignedRequestsTest.java
   (original)
+++ 
branches/amdatu-dispatcher/integration-tests/src/test/java/org/amdatu/test/integration/tests/OAuthSignedRequestsTest.java
   Tue Feb  8 12:10:37 2011
@@ -26,6 +26,8 @@
 
 import net.oauth.OAuthMessage;
 
+import org.amdatu.authentication.oauth.api.ConsumerNotFoundException;
+import org.amdatu.authentication.oauth.api.ConsumerRegistryStorageException;
 import org.amdatu.authentication.oauth.api.OAuthServiceConsumer;
 import org.amdatu.authentication.oauth.client.OAuthServiceConsumerClient;
 import org.amdatu.test.integration.base.ConfigProvider;
@@ -52,6 +54,15 @@
         // Step 1: Register a service consumer
         m_logService.log(LogService.LOG_DEBUG, "*** Step 1: Register service 
consumer ***");
         OAuthServiceConsumer consumer = new OAuthTestConsumer();
+
+        // FIXME ad-hoc fix. Handle fixture properly (AMDATU-284)
+        try {
+            m_consumerRegistry.removeConsumer(consumer);
+        }
+        catch (ConsumerNotFoundException e) {
+        }
+        catch (ConsumerRegistryStorageException e) {
+        }
         m_consumerRegistry.addConsumer(consumer);
 
         // Step 2: Create an OAuthClient for our Amdatu OAuth server

Modified: 
branches/amdatu-dispatcher/integration-tests/src/test/java/org/amdatu/test/integration/tests/OAuthThreeLeggedTest.java
==============================================================================
--- 
branches/amdatu-dispatcher/integration-tests/src/test/java/org/amdatu/test/integration/tests/OAuthThreeLeggedTest.java
      (original)
+++ 
branches/amdatu-dispatcher/integration-tests/src/test/java/org/amdatu/test/integration/tests/OAuthThreeLeggedTest.java
      Tue Feb  8 12:10:37 2011
@@ -22,6 +22,8 @@
 import net.oauth.OAuthAccessor;
 import net.oauth.OAuthMessage;
 
+import org.amdatu.authentication.oauth.api.ConsumerNotFoundException;
+import org.amdatu.authentication.oauth.api.ConsumerRegistryStorageException;
 import org.amdatu.authentication.oauth.api.OAuthServiceConsumer;
 import org.amdatu.authentication.oauth.client.OAuthResourceOwnerClient;
 import org.amdatu.authentication.oauth.client.OAuthServiceConsumerClient;
@@ -49,6 +51,15 @@
         // Step 1: Register a service consumer
         m_logService.log(LogService.LOG_DEBUG, "*** Step 1: Register service 
consumer ***");
         OAuthServiceConsumer consumer = new OAuthTestConsumer();
+
+        // FIXME ad-hoc fix. Handle fixture properly (AMDATU-284)
+        try {
+            m_consumerRegistry.removeConsumer(consumer);
+        }
+        catch (ConsumerNotFoundException e) {
+        }
+        catch (ConsumerRegistryStorageException e) {
+        }
         m_consumerRegistry.addConsumer(consumer);
 
         // Step 2: Create an OAuthClient for our Amdatu OAuth server

Reply via email to