FELIX-4860 : Revisit HandlerRegistry implementation

git-svn-id: https://svn.apache.org/repos/asf/felix/trunk@1680899 13f79535-47bb-0310-9956-ffa450edef68
diff --git a/http/base/src/main/java/org/apache/felix/http/base/internal/registry/FilterRegistry.java b/http/base/src/main/java/org/apache/felix/http/base/internal/registry/FilterRegistry.java
index d402343..a3cde22 100644
--- a/http/base/src/main/java/org/apache/felix/http/base/internal/registry/FilterRegistry.java
+++ b/http/base/src/main/java/org/apache/felix/http/base/internal/registry/FilterRegistry.java
@@ -19,12 +19,8 @@
 import java.util.ArrayList;
 import java.util.Collection;
 import java.util.Collections;
+import java.util.Iterator;
 import java.util.List;
-import java.util.Map;
-import java.util.Set;
-import java.util.TreeMap;
-import java.util.TreeSet;
-import java.util.concurrent.ConcurrentHashMap;
 
 import javax.annotation.CheckForNull;
 import javax.annotation.Nonnull;
@@ -41,27 +37,67 @@
 /**
  * The filter registry keeps track of all filter mappings for a single servlet context.
  *
- * TODO - we should sort the statusMapping by result and ranking, keeping the active filters first,
- *        highest ranking first. This would allow to stop iterating and avoid sorting the result.
  */
 public final class FilterRegistry
 {
-    /** Map of all filter registrations. */
-    private final Map<FilterInfo, FilterRegistrationStatus> statusMapping = new ConcurrentHashMap<FilterInfo, FilterRegistrationStatus>();
+    /** List of all filter registrations. These are sorted by the status objects. */
+    private volatile List<FilterRegistrationStatus> filters = Collections.emptyList();
 
-    private static final class FilterRegistrationStatus
+    /**
+     * The status object keeps track of the registration status of a filter and holds
+     * the resolvers to match against a uri.
+     * The status objects are sorted by result first, followed by ranking. The active
+     * filters ( result == -1) are first, followed by the inactive ones. This sorting
+     * allows to only traverse over the active ones and also avoids any sorting
+     * as the filters are processed in the correct order already.
+     */
+    private static final class FilterRegistrationStatus implements Comparable<FilterRegistrationStatus>
     {
-        public int result;
-        public FilterHandler handler;
-        public PathResolver[] resolvers;
+        private final int result;
+        private final FilterHandler handler;
+        private final PathResolver[] resolvers;
+
+        public FilterRegistrationStatus(@Nonnull final FilterHandler handler, @CheckForNull final PathResolver[] resolvers, final int result)
+        {
+            this.handler = handler;
+            this.resolvers = resolvers;
+            this.result = result;
+        }
+
+        public int getResult()
+        {
+            return this.result;
+        }
+
+        public @Nonnull FilterHandler getHandler()
+        {
+            return this.handler;
+        }
+
+        public @CheckForNull PathResolver[] getResolvers()
+        {
+            return this.resolvers;
+        }
+
+        @Override
+        public int compareTo(final FilterRegistrationStatus o) {
+            int result = this.result - o.result;
+            if ( result == 0 )
+            {
+                result = this.handler.compareTo(o.handler);
+            }
+            return result;
+        }
     }
 
+    /**
+     * Add a filter.
+     * @param handler The handler for the filter
+     */
     public synchronized void addFilter(@Nonnull final FilterHandler handler)
     {
         final int result = handler.init();
-        final FilterRegistrationStatus status = new FilterRegistrationStatus();
-        status.result = result;
-        status.handler = handler;
+        PathResolver[] prs = null;
 
         if ( result == -1 )
         {
@@ -80,23 +116,45 @@
             }
             Collections.sort(resolvers);
 
-            status.resolvers = resolvers.toArray(new PathResolver[resolvers.size()]);
+            prs = resolvers.toArray(new PathResolver[resolvers.size()]);
         }
 
-        statusMapping.put(handler.getFilterInfo(), status);
+        final FilterRegistrationStatus status = new FilterRegistrationStatus(handler, prs, result);
+
+        final List<FilterRegistrationStatus> newList = new ArrayList<FilterRegistry.FilterRegistrationStatus>(this.filters);
+        newList.add(status);
+        Collections.sort(newList);
+
+        this.filters = newList;
     }
 
+    /**
+     * Remove a filter
+     * @param filterInfo The filter info
+     * @param destroy boolean flag indicating whether to call destroy on the filter.
+     */
     public synchronized void removeFilter(@Nonnull final FilterInfo filterInfo, final boolean destroy)
     {
-        final FilterRegistrationStatus status = statusMapping.remove(filterInfo);
-        if ( status != null )
+        FilterRegistrationStatus found = null;
+        final List<FilterRegistrationStatus> newList = new ArrayList<FilterRegistry.FilterRegistrationStatus>(this.filters);
+        final Iterator<FilterRegistrationStatus> i = newList.iterator();
+        while ( i.hasNext() )
         {
-            if ( status.result == -1 )
+            final FilterRegistrationStatus status = i.next();
+            if ( status.getHandler().getFilterInfo().compareTo(filterInfo) == 0 )
             {
-                if (destroy)
-                {
-                    status.handler.dispose();
-                }
+                found = status;
+                i.remove();
+                break;
+            }
+        }
+        if ( found != null )
+        {
+            this.filters = newList;
+
+            if ( found.getResult() == -1 && destroy )
+            {
+                found.getHandler().dispose();
             }
         }
     }
@@ -113,31 +171,37 @@
             @Nonnull final DispatcherType dispatcherType,
             @Nonnull final String requestURI)
     {
-        final Set<FilterHandler> result = new TreeSet<FilterHandler>();
+        final List<FilterHandler> result = new ArrayList<FilterHandler>();
+        final List<FilterRegistrationStatus> allFilters = this.filters;
 
-        for(final FilterRegistrationStatus status : this.statusMapping.values())
+        for(final FilterRegistrationStatus status : allFilters)
         {
-            if (referencesDispatcherType(status.handler, dispatcherType) )
+            // as soon as we encounter a failing filter, we can stop
+            if ( status.getResult() != -1 )
+            {
+                break;
+            }
+            if (referencesDispatcherType(status.getHandler(), dispatcherType) )
             {
                 boolean added = false;
-                for(final PathResolver resolver : status.resolvers)
+                for(final PathResolver resolver : status.getResolvers())
                 {
                     if ( resolver.resolve(requestURI) != null )
                     {
-                        result.add(status.handler);
+                        result.add(status.getHandler());
                         added = true;
                         break;
                     }
                 }
                 // check for servlet name
                 final String servletName = (handler != null) ? handler.getName() : null;
-                if ( !added && servletName != null && status.handler.getFilterInfo().getServletNames() != null )
+                if ( !added && servletName != null && status.getHandler().getFilterInfo().getServletNames() != null )
                 {
-                    for(final String name : status.handler.getFilterInfo().getServletNames())
+                    for(final String name : status.getHandler().getFilterInfo().getServletNames())
                     {
                         if ( servletName.equals(name) )
                         {
-                            result.add(status.handler);
+                            result.add(status.getHandler());
                             added = true;
                             break;
                         }
@@ -168,30 +232,32 @@
         return false;
     }
 
+    /**
+     * Get the runtime information about filters
+     * @param servletContextDTO The servlet context DTO
+     * @param failedFilterDTOs The collection holding the failed filters.
+     */
     public void getRuntimeInfo(final ServletContextDTO servletContextDTO,
                                final Collection<FailedFilterDTO> failedFilterDTOs)
     {
-        // we create a map to sort filter DTOs by ranking/service id
-        final Map<FilterInfo, FilterDTO> filterDTOs = new TreeMap<FilterInfo, FilterDTO>();
-        final Map<FilterInfo, FailedFilterDTO> failureFilterDTOs = new TreeMap<FilterInfo, FailedFilterDTO>();
+        final List<FilterDTO> filterDTOs = new ArrayList<FilterDTO>();
 
-        for(final Map.Entry<FilterInfo, FilterRegistrationStatus> entry : this.statusMapping.entrySet())
+        final List<FilterRegistrationStatus> allFilters = this.filters;
+        for(final FilterRegistrationStatus status : allFilters)
         {
-            if ( entry.getValue().result != -1 )
+            if ( status.getResult() != -1 )
             {
-                failureFilterDTOs.put(entry.getKey(), FilterDTOBuilder.buildFailed(entry.getValue().handler, entry.getValue().result));
+                failedFilterDTOs.add((FailedFilterDTO)FilterDTOBuilder.build(status.getHandler(), status.getResult()));
             }
             else
             {
-                filterDTOs.put(entry.getKey(), FilterDTOBuilder.build(entry.getValue().handler));
+                filterDTOs.add(FilterDTOBuilder.build(status.getHandler(), status.getResult()));
             }
         }
 
-        final Collection<FilterDTO> filterDTOArray = filterDTOs.values();
-        if ( !filterDTOArray.isEmpty() )
+        if ( !filterDTOs.isEmpty() )
         {
-            servletContextDTO.filterDTOs = filterDTOArray.toArray(new FilterDTO[filterDTOArray.size()]);
+            servletContextDTO.filterDTOs = filterDTOs.toArray(new FilterDTO[filterDTOs.size()]);
         }
-        failedFilterDTOs.addAll(failureFilterDTOs.values());
     }
 }
diff --git a/http/base/src/main/java/org/apache/felix/http/base/internal/runtime/FilterInfo.java b/http/base/src/main/java/org/apache/felix/http/base/internal/runtime/FilterInfo.java
index 07722c9..4e35a69 100644
--- a/http/base/src/main/java/org/apache/felix/http/base/internal/runtime/FilterInfo.java
+++ b/http/base/src/main/java/org/apache/felix/http/base/internal/runtime/FilterInfo.java
@@ -138,26 +138,6 @@
         this.dispatcher = new DispatcherType[] {DispatcherType.REQUEST};
     }
 
-    FilterInfo(int serviceRanking,
-            long serviceId,
-            String name,
-            String[] patterns,
-            String[] servletNames,
-            String[] regexs,
-            boolean asyncSupported,
-            DispatcherType[] dispatcher,
-            Map<String, String> initParams)
-    {
-        super(serviceRanking, serviceId);
-        this.name = name;
-        this.patterns = patterns;
-        this.servletNames = servletNames;
-        this.regexs = regexs;
-        this.asyncSupported = asyncSupported;
-        this.dispatcher = dispatcher;
-        this.initParams = Collections.unmodifiableMap(initParams);
-    }
-
     @Override
     public boolean isValid()
     {
diff --git a/http/base/src/main/java/org/apache/felix/http/base/internal/runtime/ServletContextHelperInfo.java b/http/base/src/main/java/org/apache/felix/http/base/internal/runtime/ServletContextHelperInfo.java
index 05d468d..2766c61 100644
--- a/http/base/src/main/java/org/apache/felix/http/base/internal/runtime/ServletContextHelperInfo.java
+++ b/http/base/src/main/java/org/apache/felix/http/base/internal/runtime/ServletContextHelperInfo.java
@@ -54,11 +54,11 @@
         this.initParams = getInitParams(ref, CONTEXT_INIT_PREFIX);
     }
 
-    public ServletContextHelperInfo(int serviceRanking,
-            long serviceId,
-            String name,
-            String path,
-            Map<String, String> initParams)
+    public ServletContextHelperInfo(final int serviceRanking,
+            final long serviceId,
+            final String name,
+            final String path,
+            final Map<String, String> initParams)
     {
         super(serviceRanking, serviceId);
         this.name = name;
diff --git a/http/base/src/main/java/org/apache/felix/http/base/internal/runtime/dto/FailedDTOHolder.java b/http/base/src/main/java/org/apache/felix/http/base/internal/runtime/dto/FailedDTOHolder.java
index c538b69..023aec0 100644
--- a/http/base/src/main/java/org/apache/felix/http/base/internal/runtime/dto/FailedDTOHolder.java
+++ b/http/base/src/main/java/org/apache/felix/http/base/internal/runtime/dto/FailedDTOHolder.java
@@ -97,8 +97,7 @@
 
             if ( ((ServletInfo) info).getPatterns() != null || !isError )
             {
-                final FailedServletDTO dto = (FailedServletDTO)ServletDTOBuilder.build((ServletInfo) info, true);
-                dto.failureReason = failureCode;
+                final FailedServletDTO dto = (FailedServletDTO)ServletDTOBuilder.build((ServletInfo) info, failureCode);
                 if ( ((ServletInfo) info).getPatterns() != null )
                 {
                     dto.patterns = ((ServletInfo) info).getPatterns();
@@ -108,7 +107,7 @@
         }
         else if (info instanceof FilterInfo)
         {
-            final FailedFilterDTO dto = (FailedFilterDTO)FilterDTOBuilder.build((FilterInfo) info, true);
+            final FailedFilterDTO dto = (FailedFilterDTO)FilterDTOBuilder.build((FilterInfo) info, failureCode);
             dto.failureReason = failureCode;
 
             this.failedFilterDTOs.add(dto);
diff --git a/http/base/src/main/java/org/apache/felix/http/base/internal/runtime/dto/FilterDTOBuilder.java b/http/base/src/main/java/org/apache/felix/http/base/internal/runtime/dto/FilterDTOBuilder.java
index ae743e8..13d1bb6 100644
--- a/http/base/src/main/java/org/apache/felix/http/base/internal/runtime/dto/FilterDTOBuilder.java
+++ b/http/base/src/main/java/org/apache/felix/http/base/internal/runtime/dto/FilterDTOBuilder.java
@@ -18,6 +18,7 @@
  */
 package org.apache.felix.http.base.internal.runtime.dto;
 
+import javax.annotation.Nonnull;
 import javax.servlet.DispatcherType;
 
 import org.apache.felix.http.base.internal.handler.FilterHandler;
@@ -28,11 +29,11 @@
 public final class FilterDTOBuilder
 {
     /**
-     * Build an array of filter DTO from a filter handler array
+     * Build an array of filter DTOs from a filter handler array
      * @param handlers The filter handler array
      * @return The filter DTO array
      */
-    public static FilterDTO[] build(final FilterHandler[] handlers)
+    public static @Nonnull FilterDTO[] build(@Nonnull final FilterHandler[] handlers)
     {
         if ( handlers.length == 0 )
         {
@@ -41,7 +42,7 @@
         final FilterDTO[] array = new FilterDTO[handlers.length];
         for(int i=0; i<handlers.length; i++)
         {
-            array[i] = build(handlers[i]);
+            array[i] = build(handlers[i], -1);
         }
 
         return array;
@@ -52,9 +53,9 @@
      * @param handler The filter handler
      * @return A filter DTO
      */
-    public static FilterDTO build(final FilterHandler handler)
+    public static @Nonnull FilterDTO build(@Nonnull final FilterHandler handler, final int reason)
     {
-        final FilterDTO filterDTO = build(handler.getFilterInfo(), false);
+        final FilterDTO filterDTO = build(handler.getFilterInfo(), reason);
 
         filterDTO.name = handler.getName();
         filterDTO.servletContextId = handler.getContextServiceId();
@@ -67,9 +68,9 @@
      * @param info The filter info
      * @return A filter DTO
      */
-    public static FilterDTO build(final FilterInfo info, final boolean failed)
+    public static @Nonnull FilterDTO build(@Nonnull final FilterInfo info, final int reason)
     {
-        final FilterDTO filterDTO = (failed ? new FailedFilterDTO() : new FilterDTO());
+        final FilterDTO filterDTO = (reason != -1 ? new FailedFilterDTO() : new FilterDTO());
 
         filterDTO.asyncSupported = info.isAsyncSupported();
         filterDTO.dispatcher = getNames(info.getDispatcher());
@@ -80,33 +81,17 @@
         filterDTO.serviceId = info.getServiceId();
         filterDTO.servletNames = BuilderConstants.copyWithDefault(info.getServletNames(), BuilderConstants.EMPTY_STRING_ARRAY);
 
-        return filterDTO;
-    }
-
-    /**
-     * Build a filter failed DTO from a filter handler
-     * @param handler The filter handler
-     * @return A filter DTO
-     */
-    public static FailedFilterDTO buildFailed(final FilterHandler handler, final int reason)
-    {
-        final FailedFilterDTO filterDTO = (FailedFilterDTO)build(handler.getFilterInfo(), true);
-
-        filterDTO.name = handler.getName();
-        filterDTO.servletContextId = handler.getContextServiceId();
-        filterDTO.failureReason = reason;
-
-        return filterDTO;
-    }
-
-    private static String[] getNames(final DispatcherType[] dispatcher)
-    {
-        if (dispatcher == null)
+        if ( reason != -1 )
         {
-            return BuilderConstants.EMPTY_STRING_ARRAY;
+            ((FailedFilterDTO)filterDTO).failureReason = reason;
         }
 
-        String[] names = new String[dispatcher.length];
+        return filterDTO;
+    }
+
+    private static @Nonnull String[] getNames(@Nonnull final DispatcherType[] dispatcher)
+    {
+        final String[] names = new String[dispatcher.length];
         for (int i = 0; i < dispatcher.length; i++)
         {
             names[i] = dispatcher[i].name();
diff --git a/http/base/src/main/java/org/apache/felix/http/base/internal/runtime/dto/ServletDTOBuilder.java b/http/base/src/main/java/org/apache/felix/http/base/internal/runtime/dto/ServletDTOBuilder.java
index 0cc28af..23564d5 100644
--- a/http/base/src/main/java/org/apache/felix/http/base/internal/runtime/dto/ServletDTOBuilder.java
+++ b/http/base/src/main/java/org/apache/felix/http/base/internal/runtime/dto/ServletDTOBuilder.java
@@ -33,15 +33,10 @@
      */
     public static ServletDTO build(final ServletHandler handler, final int reason)
     {
-        final ServletDTO dto = build(handler.getServletInfo(), reason != -1);
+        final ServletDTO dto = build(handler.getServletInfo(), reason);
 
         BaseServletDTOBuilder.fill(dto, handler);
 
-        if ( reason != -1 )
-        {
-            ((FailedServletDTO)dto).failureReason = reason;
-        }
-
         return dto;
     }
 
@@ -50,12 +45,17 @@
      * @param info The servlet info
      * @return A servlet DTO
      */
-    public static ServletDTO build(final ServletInfo info, final boolean failed)
+    public static ServletDTO build(final ServletInfo info, final int reason)
     {
-        final ServletDTO dto = (failed ? new FailedServletDTO() : new ServletDTO());
+        final ServletDTO dto = (reason != -1 ? new FailedServletDTO() : new ServletDTO());
 
         BaseServletDTOBuilder.fill(dto, info);
 
+        if ( reason != -1 )
+        {
+            ((FailedServletDTO)dto).failureReason = reason;
+        }
+
         dto.patterns = BuilderConstants.EMPTY_STRING_ARRAY;
 
         return dto;
diff --git a/http/base/src/test/java/org/apache/felix/http/base/internal/registry/PerContextHandlerRegistryTest.java b/http/base/src/test/java/org/apache/felix/http/base/internal/registry/PerContextHandlerRegistryTest.java
index 7be52a0..23df916 100644
--- a/http/base/src/test/java/org/apache/felix/http/base/internal/registry/PerContextHandlerRegistryTest.java
+++ b/http/base/src/test/java/org/apache/felix/http/base/internal/registry/PerContextHandlerRegistryTest.java
@@ -24,7 +24,6 @@
 import java.util.List;
 
 import org.apache.felix.http.base.internal.runtime.ServletContextHelperInfo;
-import org.apache.felix.http.base.internal.runtime.WhiteboardServiceHelper;
 import org.junit.Test;
 
 /**
@@ -111,6 +110,6 @@
 
     private ServletContextHelperInfo createServletContextHelperInfo(final String path, final long serviceId, final int ranking)
     {
-        return WhiteboardServiceHelper.createContextInfo(ranking, serviceId, "", path, null);
+        return new ServletContextHelperInfo(ranking, serviceId, "", path, null);
     }
 }
diff --git a/http/base/src/test/java/org/apache/felix/http/base/internal/runtime/WhiteboardServiceHelper.java b/http/base/src/test/java/org/apache/felix/http/base/internal/runtime/WhiteboardServiceHelper.java
deleted file mode 100644
index 220bc32..0000000
--- a/http/base/src/test/java/org/apache/felix/http/base/internal/runtime/WhiteboardServiceHelper.java
+++ /dev/null
@@ -1,208 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *   http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-package org.apache.felix.http.base.internal.runtime;
-
-import static org.mockito.Mockito.mock;
-import static org.mockito.Mockito.when;
-
-import java.util.HashMap;
-import java.util.Map;
-import java.util.concurrent.atomic.AtomicLong;
-
-import javax.servlet.DispatcherType;
-import javax.servlet.Filter;
-import javax.servlet.Servlet;
-
-import org.apache.felix.http.base.internal.context.ExtServletContext;
-import org.apache.felix.http.base.internal.handler.FilterHandler;
-import org.apache.felix.http.base.internal.handler.HttpServiceFilterHandler;
-import org.apache.felix.http.base.internal.handler.HttpServiceServletHandler;
-import org.apache.felix.http.base.internal.handler.ServletHandler;
-import org.osgi.framework.ServiceReference;
-
-public final class WhiteboardServiceHelper
-{
-    public static final AtomicLong ID_COUNTER = new AtomicLong();
-
-    public static FilterHandler createTestFilterWithServiceId(String identifier,
-            ExtServletContext context)
-    {
-        return createTestFilter(identifier, context, ID_COUNTER.incrementAndGet());
-    }
-
-    public static FilterHandler createTestFilter(String identifier,
-            ExtServletContext context)
-    {
-        return createTestFilter(identifier, context, -ID_COUNTER.incrementAndGet());
-    }
-
-    private static FilterHandler createTestFilter(String identifier,
-            ExtServletContext context,
-            Long serviceId)
-    {
-        FilterInfo filterInfo = createFilterInfo(identifier, serviceId);
-        return new HttpServiceFilterHandler(context, filterInfo, mock(Filter.class));
-    }
-
-    private static FilterInfo createFilterInfo(String identifier,
-            Long serviceId)
-    {
-        boolean asyncSupported = true;
-        String name = identifier;
-        Map<String, String> initParams = createInitParameterMap(identifier);
-        String[] patterns = new String[]{ "/" + identifier };
-        String[] regexs = new String[]{ "." + identifier };
-        DispatcherType[] dispatcher = new DispatcherType[] { DispatcherType.ASYNC, DispatcherType.REQUEST };
-        return createFilterInfo(0, serviceId, name, patterns, null, regexs, asyncSupported, dispatcher, initParams);
-    }
-
-    public static FilterInfo createFilterInfo(int serviceRanking,
-            Long serviceId,
-            String name,
-            String[] patterns,
-            String[] servletNames,
-            String[] regexs,
-            boolean asyncSupported,
-            DispatcherType[] dispatcher,
-            Map<String, String> initParams)
-    {
-        FilterInfo info = new FilterInfo(0,
-                serviceId,
-                name,
-                patterns,
-                servletNames,
-                regexs,
-                asyncSupported,
-                dispatcher,
-                initParams);
-        return info;
-    }
-
-    public static ServletHandler createTestServletWithServiceId(String identifier,
-            ExtServletContext context,
-            long contextServiceId)
-    {
-        return createTestServlet(identifier, context, ID_COUNTER.incrementAndGet(), contextServiceId);
-    }
-
-    public static ServletHandler createTestServlet(String identifier, ExtServletContext context, long contextServiceId)
-    {
-        return createTestServlet(identifier, context, -ID_COUNTER.incrementAndGet(), contextServiceId);
-    }
-
-    private static ServletHandler createTestServlet(String identifier,
-            ExtServletContext context,
-            Long serviceId,
-            Long contextServiceId)
-    {
-        ServletInfo servletInfo = createServletInfo(identifier, serviceId);
-        Servlet servlet = mock(Servlet.class);
-        when(servlet.getServletInfo()).thenReturn("info_" + identifier);
-        final ServletHandler h = new HttpServiceServletHandler(context, servletInfo, servlet);
-
-        return h;
-    }
-
-    private static ServletInfo createServletInfo(String identifier, Long serviceId)
-    {
-        boolean asyncSupported = true;
-        String name = identifier;
-        Map<String, String> initParams = createInitParameterMap(identifier);
-        String[] patterns = new String[]{ "/" + identifier };
-        return createServletInfo(0, serviceId, name, patterns, null, asyncSupported, initParams);
-    }
-
-    public static ServletInfo createServletInfo(int serviceRanking,
-            Long serviceId,
-            String name,
-            String[] patterns,
-            String[] errorPages,
-            boolean asyncSupported,
-            Map<String, String> initParams)
-    {
-        return new ServletInfo(0,
-                serviceId,
-                name,
-                patterns,
-                errorPages,
-                asyncSupported,
-                initParams);
-    }
-
-    @SuppressWarnings("serial")
-    private static HashMap<String, String> createInitParameterMap(final String identifier)
-    {
-        return new HashMap<String, String>()
-                {
-                    {
-                        put("paramOne_" + identifier, "valOne_" + identifier);
-                        put("paramTwo_" + identifier, "valTwo_" + identifier);
-                    }
-                };
-    }
-/*
-    public static ServletState createErrorPageWithServiceId(String identifier, ExtServletContext context, long contextServiceId)
-    {
-        return createErrorPage(identifier, context, ID_COUNTER.incrementAndGet(), contextServiceId);
-    }
-
-    public static ServletState createErrorPage(String identifier, ExtServletContext context, long contextServiceId)
-    {
-        return createErrorPage(identifier, context, -ID_COUNTER.incrementAndGet(), contextServiceId);
-    }
-
-    private static ServletState createErrorPage(String identifier,
-            ExtServletContext context,
-            Long serviceId,
-            long contextServiceId)
-    {
-        final ServletHandler servletHandler = createTestServlet(identifier, context, serviceId, contextServiceId);
-        final Collection<Long> errorCodes = Arrays.asList(400L, 500L);
-        final Collection<String> exceptions = Arrays.asList("Bad request", "Error");
-
-        final ServletState state = new ServletState(servletHandler);
-        final long[] codes = new long[errorCodes.size()];
-        final Iterator<Long> iter = errorCodes.iterator();
-        for(int i=0; i<codes.length; i++)
-        {
-            codes[i] = iter.next();
-        }
-        state.setErrorCodes(codes);
-        state.setErrorExceptions(exceptions.toArray(new String[exceptions.size()]));
-        return state;
-    }
-*/
-    public static ServletContextHelperInfo createContextInfo(int serviceRanking,
-            long serviceId,
-            String name,
-            String path,
-            Map<String, String> initParams)
-    {
-        return new ServletContextHelperInfo(serviceRanking,
-                serviceId,
-                name,
-                path,
-                initParams);
-    }
-
-    public static ResourceInfo createContextInfo(ServiceReference<Object> ref)
-    {
-        return new ResourceInfo(ref);
-    }
-}