[maven-release-plugin] copy for tag no

git-svn-id: https://svn.apache.org/repos/asf/sling/tags/no@1759311 13f79535-47bb-0310-9956-ffa450edef68
diff --git a/README.txt b/README.txt
deleted file mode 100644
index be32065..0000000
--- a/README.txt
+++ /dev/null
@@ -1,27 +0,0 @@
-Apache Sling Resource Resolver
-
-This bundle provides the Resource Resolver and Resource Resolver Factory
-
-Getting Started
-===============
-
-This component uses a Maven 3 (http://maven.apache.org/) build
-environment. It requires a Java 6 JDK (or higher) and Maven (http://maven.apache.org/)
-3.0.3 or later. We recommend to use the latest Maven version.
-
-If you have Maven installed, you can compile and
-package the jar using the following command:
-
-    mvn package
-
-See the Maven documentation for other build features.
-
-The latest source code for this component is available in the
-Subversion (http://subversion.apache.org/) source repository of
-the Apache Software Foundation. If you have Subversion installed,
-you can checkout the latest source using the following command:
-
-    svn checkout http://svn.apache.org/repos/asf/sling/trunk/resourceresolver
-
-See the Subversion documentation for other source control features.
-
diff --git a/pom.xml b/pom.xml
index 1dd01c4..4de43c2 100644
--- a/pom.xml
+++ b/pom.xml
@@ -1,207 +1,174 @@
-<?xml version="1.0" encoding="ISO-8859-1"?>
-<!--
-    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.
--->
-<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
+<!--~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+  ~ 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.
+  ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~-->
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
     <modelVersion>4.0.0</modelVersion>
+
     <parent>
         <groupId>org.apache.sling</groupId>
         <artifactId>sling</artifactId>
-        <version>26</version>
+        <version>28</version>
         <relativePath />
     </parent>
 
-    <artifactId>org.apache.sling.resourceresolver</artifactId>
-    <version>1.4.14</version>
-    <packaging>bundle</packaging>
+    <artifactId>htl-maven-plugin</artifactId>
+    <version>1.0.0</version>
+    <packaging>maven-plugin</packaging>
 
-    <name>Apache Sling Resource Resolver</name>
-    <description>
-        This bundle provides the Resource Resolver and the Resource Resolver Factory.
-    </description>
+    <name>Apache Sling HTL Maven Plugin</name>
+    <description>The Apache Sling HTL Maven Plugin provides support for validating HTML Template Language scripts from projects.</description>
 
     <scm>
-        <connection>
-            scm:svn:http://svn.apache.org/repos/asf/sling/tags/no
-        </connection>
-        <developerConnection>
-            scm:svn:https://svn.apache.org/repos/asf/sling/tags/no
-        </developerConnection>
-        <url>
-            http://svn.apache.org/viewvc/sling/tags/no
-        </url>
+        <connection>scm:svn:http://svn.apache.org/repos/asf/sling/tags/no</connection>
+        <developerConnection>scm:svn:https://svn.apache.org/repos/asf/sling/tags/no</developerConnection>
+        <url>http://svn.apache.org/viewvc/sling/tags/no</url>
     </scm>
 
     <properties>
-        <site.jira.version.id>12314286</site.jira.version.id>
-        <site.javadoc.exclude>**.internal.**</site.javadoc.exclude>
+        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
+        <maven.version>3.3.3</maven.version>
     </properties>
 
+    <dependencies>
+        <dependency>
+            <groupId>org.apache.sling</groupId>
+            <artifactId>org.apache.sling.scripting.sightly.compiler</artifactId>
+            <version>1.0.0</version>
+        </dependency>
+        <dependency>
+            <groupId>commons-io</groupId>
+            <artifactId>commons-io</artifactId>
+            <version>2.5</version>
+        </dependency>
+        <dependency>
+            <groupId>commons-lang</groupId>
+            <artifactId>commons-lang</artifactId>
+            <version>2.5</version>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.maven</groupId>
+            <artifactId>maven-plugin-api</artifactId>
+            <version>${maven.version}</version>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.maven</groupId>
+            <artifactId>maven-artifact</artifactId>
+            <version>${maven.version}</version>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.maven</groupId>
+            <artifactId>maven-core</artifactId>
+            <version>${maven.version}</version>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.maven.plugin-tools</groupId>
+            <artifactId>maven-plugin-annotations</artifactId>
+            <version>3.4</version>
+            <scope>provided</scope>
+        </dependency>
+        <dependency>
+            <groupId>org.codehaus.plexus</groupId>
+            <artifactId>plexus-utils</artifactId>
+            <version>3.0.24</version>
+        </dependency>
+        <dependency>
+            <groupId>org.sonatype.plexus</groupId>
+            <artifactId>plexus-build-api</artifactId>
+            <version>0.0.7</version>
+        </dependency>
+
+
+        <!-- Testing Dependencies -->
+        <dependency>
+            <groupId>org.codehaus.plexus</groupId>
+            <artifactId>plexus-container-default</artifactId>
+            <version>1.6</version>
+            <scope>test</scope>
+        </dependency>
+        <dependency>
+            <groupId>junit</groupId>
+            <artifactId>junit</artifactId>
+            <scope>test</scope>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.maven.plugin-testing</groupId>
+            <artifactId>maven-plugin-testing-harness</artifactId>
+            <version>3.3.0</version>
+            <scope>test</scope>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.maven</groupId>
+            <artifactId>maven-compat</artifactId>
+            <scope>test</scope>
+            <version>${maven.version}</version>
+        </dependency>
+        <dependency>
+            <groupId>org.slf4j</groupId>
+            <artifactId>slf4j-simple</artifactId>
+            <scope>test</scope>
+        </dependency>
+    </dependencies>
+
     <build>
         <plugins>
             <plugin>
-                <groupId>org.apache.felix</groupId>
-                <artifactId>maven-scr-plugin</artifactId>
-            </plugin>
-            <plugin>
-                <groupId>org.apache.sling</groupId>
-                <artifactId>maven-sling-plugin</artifactId>
+                <groupId>org.apache.maven.plugins</groupId>
+                <artifactId>maven-plugin-plugin</artifactId>
+                <version>3.4</version>
                 <executions>
                     <execution>
-                        <id>generate-adapter-metadata</id>
+                        <id>mojo-descriptor</id>
                         <phase>process-classes</phase>
                         <goals>
-                            <goal>generate-adapter-metadata</goal>
+                            <goal>descriptor</goal>
+                        </goals>
+                    </execution>
+                    <execution>
+                        <id>generated-helpmojo</id>
+                        <goals>
+                            <goal>helpmojo</goal>
+                        </goals>
+                    </execution>
+                </executions>
+                <configuration>
+                    <skipErrorNoDescriptorsFound>true</skipErrorNoDescriptorsFound>
+                </configuration>
+            </plugin>
+            <plugin>
+                <groupId>org.codehaus.plexus</groupId>
+                <artifactId>plexus-component-metadata</artifactId>
+                <version>1.6</version>
+                <executions>
+                    <execution>
+                        <goals>
+                            <goal>generate-metadata</goal>
                         </goals>
                     </execution>
                 </executions>
             </plugin>
             <plugin>
-                <groupId>org.apache.felix</groupId>
-                <artifactId>maven-bundle-plugin</artifactId>
-                <extensions>true</extensions>
+                <groupId>org.apache.rat</groupId>
+                <artifactId>apache-rat-plugin</artifactId>
                 <configuration>
-                    <instructions>
-                        <Import-Package>
-                            javax.annotation;resolution:=optional,
-                            org.apache.sling.api.resource;provide:=true,
-                            org.apache.sling.commons.osgi;version="$(@)",
-                            *
-                        </Import-Package>
-                    </instructions>
-                </configuration>
-            </plugin>
-            <plugin>
-                <groupId>org.apache.maven.plugins</groupId>
-                <artifactId>maven-javadoc-plugin</artifactId>
-                <configuration>
-                    <excludePackageNames>
-                        org.apache.sling.resourceresolver.impl
-                    </excludePackageNames>
+                    <excludes>
+                        <exclude>**/*.iml</exclude>
+                        <exclude>**/target/**/*</exclude>
+                    </excludes>
                 </configuration>
             </plugin>
         </plugins>
     </build>
-    
-    <dependencies>
-        <dependency>
-            <groupId>org.apache.felix</groupId>
-            <artifactId>org.apache.felix.scr.annotations</artifactId>
-        </dependency>
-        <dependency>
-            <groupId>javax.jcr</groupId>
-            <artifactId>jcr</artifactId>
-            <version>2.0</version>
-        </dependency>
-        <dependency>
-            <groupId>org.osgi</groupId>
-            <artifactId>org.osgi.core</artifactId>
-        </dependency>
-        <dependency>
-            <groupId>org.osgi</groupId>
-            <artifactId>org.osgi.compendium</artifactId>
-        </dependency>
-        <dependency>
-            <groupId>org.apache.sling</groupId>
-            <artifactId>org.apache.sling.api</artifactId>
-            <version>2.11.0</version>
-            <scope>provided</scope>
-        </dependency>
-        <dependency>
-            <groupId>org.apache.sling</groupId>
-            <artifactId>org.apache.sling.serviceusermapper</artifactId>
-            <version>1.0.0</version>
-        </dependency>
-        <dependency>
-            <groupId>org.slf4j</groupId>
-            <artifactId>slf4j-api</artifactId>
-        </dependency>
-        <dependency>
-            <groupId>org.apache.sling</groupId>
-            <artifactId>org.apache.sling.commons.osgi</artifactId>
-            <version>2.2.0</version>
-            <scope>provided</scope>
-        </dependency>
-        <dependency>
-           <groupId>commons-collections</groupId>
-           <artifactId>commons-collections</artifactId>
-           <version>3.2.1</version>
-            <scope>provided</scope>
-        </dependency>
-        <dependency>
-           <groupId>commons-lang</groupId>
-           <artifactId>commons-lang</artifactId>
-           <version>2.4</version>
-           <scope>provided</scope>
-        </dependency>
-        <dependency>
-            <groupId>org.apache.sling</groupId>
-            <artifactId>adapter-annotations</artifactId>
-            <version>1.0.0</version>
-            <scope>provided</scope>
-        </dependency>
-        <dependency>
-            <groupId>com.google.code.findbugs</groupId>
-            <artifactId>jsr305</artifactId>
-            <version>3.0.0</version>
-            <scope>provided</scope>
-        </dependency>
-
-        <!-- For the Console Plugin of the ResourceResolverFactoryImpl -->
-        <dependency>
-            <groupId>javax.servlet</groupId>
-            <artifactId>servlet-api</artifactId>
-        </dependency>
-
-        <!-- Testing -->
-        <dependency>
-            <groupId>org.hamcrest</groupId>
-            <artifactId>hamcrest-library</artifactId>
-            <version>1.3</version>
-            <scope>test</scope>
-        </dependency>
-        <dependency>
-            <groupId>org.slf4j</groupId>
-            <artifactId>slf4j-simple</artifactId>
-        </dependency>
-        <dependency>
-            <groupId>junit-addons</groupId>
-            <artifactId>junit-addons</artifactId>
-            <version>1.4</version>
-            <scope>test</scope>
-        </dependency>
-        <dependency>
-            <groupId>org.apache.felix</groupId>
-            <artifactId>org.apache.felix.framework</artifactId>
-            <version>3.0.8</version>
-            <scope>test</scope>
-        </dependency>
-        <dependency>
-        	<groupId>org.mockito</groupId>
-        	<artifactId>mockito-all</artifactId>
-        	<version>1.9.5</version>
-        	<scope>test</scope>
-        </dependency>
-        <dependency>
-        	<groupId>org.apache.sling</groupId>
-        	<artifactId>org.apache.sling.testing.osgi-mock</artifactId>
-        	<version>1.4.0</version>
-        	<scope>test</scope>
-        </dependency>
-    </dependencies>
 </project>
diff --git a/src/main/java/org/apache/sling/maven/htl/ValidateMojo.java b/src/main/java/org/apache/sling/maven/htl/ValidateMojo.java
new file mode 100644
index 0000000..826b2a4
--- /dev/null
+++ b/src/main/java/org/apache/sling/maven/htl/ValidateMojo.java
@@ -0,0 +1,250 @@
+/*******************************************************************************
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ ******************************************************************************/
+package org.apache.sling.maven.htl;
+
+import java.io.File;
+import java.io.FileNotFoundException;
+import java.io.FileReader;
+import java.io.IOException;
+import java.io.Reader;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import org.apache.maven.plugin.AbstractMojo;
+import org.apache.maven.plugin.MojoExecutionException;
+import org.apache.maven.plugin.MojoFailureException;
+import org.apache.maven.plugins.annotations.Component;
+import org.apache.maven.plugins.annotations.LifecyclePhase;
+import org.apache.maven.plugins.annotations.Mojo;
+import org.apache.maven.plugins.annotations.Parameter;
+import org.apache.maven.project.MavenProject;
+import org.apache.sling.scripting.sightly.compiler.CompilationResult;
+import org.apache.sling.scripting.sightly.compiler.CompilationUnit;
+import org.apache.sling.scripting.sightly.compiler.CompilerMessage;
+import org.apache.sling.scripting.sightly.compiler.SightlyCompiler;
+import org.codehaus.plexus.util.Scanner;
+import org.codehaus.plexus.util.StringUtils;
+import org.sonatype.plexus.build.incremental.BuildContext;
+
+/**
+ * This goal validates Sightly scripts syntax.
+ */
+@Mojo(
+        name = "validate",
+        defaultPhase = LifecyclePhase.COMPILE,
+        threadSafe = true
+)
+public class ValidateMojo extends AbstractMojo {
+
+    private static final String DEFAULT_INCLUDES = "**/*.html";
+    private static final String DEFAULT_EXCLUDES = "";
+
+    @Component
+    private BuildContext buildContext;
+
+    @Parameter(defaultValue = "${project}", readonly = true, required = true)
+    protected MavenProject project;
+
+    /**
+     * Defines the root folder where this Mojo expects to find Sightly scripts to validate.
+     */
+    @Parameter(property = "sourceDirectory", defaultValue = "${project.build.sourceDirectory}")
+    private File sourceDirectory;
+
+    /**
+     * List of files to include. Specified as fileset patterns which are relative to the input directory whose contents will be scanned
+     * (see the sourceDirectory configuration option).
+     */
+    @Parameter
+    private String[] includes;
+
+    /**
+     * List of files to exclude. Specified as fileset patterns which are relative to the input directory whose contents will be scanned
+     * (see the sourceDirectory configuration option).
+     */
+    @Parameter
+    private String[] excludes;
+
+    /**
+     * If set to "true" it will fail the build on compiler warnings.
+     */
+    @Parameter(property = "failOnWarnings", defaultValue = "false")
+    private boolean failOnWarnings;
+
+    private boolean hasWarnings = false;
+    private boolean hasErrors = false;
+    private String processedIncludes = null;
+    private String processedExcludes = null;
+    private List<File> processedFiles = Collections.emptyList();
+
+    private int sourceDirectoryLength = 0;
+
+    public void execute() throws MojoExecutionException, MojoFailureException {
+
+        long start = System.currentTimeMillis();
+
+        if (!sourceDirectory.isAbsolute()) {
+            sourceDirectory = new File(project.getBasedir(), sourceDirectory.getPath());
+        }
+        if (!sourceDirectory.exists()) {
+            throw new MojoExecutionException(
+                    String.format("Configured sourceDirectory={%s} does not exist.", sourceDirectory.getAbsolutePath()));
+        }
+        if (!sourceDirectory.isDirectory()) {
+            throw new MojoExecutionException(
+                    String.format("Configured sourceDirectory={%s} is not a directory.", sourceDirectory.getAbsolutePath()));
+        }
+
+        if ( !buildContext.hasDelta(sourceDirectory )) {
+            getLog().info("No files found to validate, skipping");
+            return;
+        }
+
+        // don't fail execution in Eclipse as it generates an error marker in the POM file, which is not desired
+        boolean mayFailExecution = !buildContext.getClass().getName().startsWith("org.eclipse.m2e");
+
+        sourceDirectoryLength = sourceDirectory.getAbsolutePath().length();
+        processedIncludes = processIncludes();
+        processedExcludes = processExcludes();
+        try {
+            SightlyCompiler compiler = new SightlyCompiler();
+
+            Scanner scanner = buildContext.newScanner(sourceDirectory);
+            scanner.setExcludes(new String[] { processedExcludes } );
+            scanner.setIncludes(new String[] { processedIncludes } );
+            scanner.scan();
+
+            String[] includedFiles = scanner.getIncludedFiles();
+
+            processedFiles = new ArrayList<>(includedFiles.length);
+            for ( String includedFile : includedFiles ) {
+                processedFiles.add(new File(sourceDirectory, includedFile));
+            }
+            Map<File, CompilationResult> compilationResults = new HashMap<>();
+            for (File script : processedFiles) {
+                compilationResults.put(script, compiler.compile(getCompilationUnit(script)));
+            }
+            for (Map.Entry<File, CompilationResult> entry : compilationResults.entrySet()) {
+                File script = entry.getKey();
+                CompilationResult result = entry.getValue();
+                buildContext.removeMessages(script);
+
+                if (result.getWarnings().size() > 0) {
+                    for (CompilerMessage message : result.getWarnings()) {
+                        buildContext.addMessage(script, message.getLine(), message.getColumn(), message.getMessage(), BuildContext.SEVERITY_WARNING, null);
+                    }
+                    hasWarnings = true;
+                }
+                if (result.getErrors().size() > 0) {
+                    for (CompilerMessage message : result.getErrors()) {
+                        String messageString = message.getMessage().replaceAll(System.lineSeparator(), "");
+                        buildContext.addMessage(script, message.getLine(), message.getColumn(), messageString, BuildContext.SEVERITY_ERROR, null);
+                    }
+                    hasErrors = true;
+                }
+            }
+
+            getLog().info("Processed " + processedFiles.size() + " files in " + ( System.currentTimeMillis() - start ) + " milliseconds");
+
+            if (mayFailExecution && hasWarnings && failOnWarnings) {
+                throw new MojoFailureException("Compilation warnings were configured to fail the build.");
+            }
+            if (mayFailExecution && hasErrors) {
+                throw new MojoFailureException("Please check the reported syntax errors.");
+            }
+        } catch (IOException e) {
+            throw new MojoExecutionException(String.format("Cannot filter files from {%s} with includes {%s} and excludes {%s}.",
+                    sourceDirectory.getAbsolutePath(), processedIncludes, processedExcludes), e);
+        }
+
+    }
+
+    public File getSourceDirectory() {
+        return sourceDirectory;
+    }
+
+    public boolean shouldFailOnWarnings() {
+        return failOnWarnings;
+    }
+
+    public boolean hasWarnings() {
+        return hasWarnings;
+    }
+
+    public boolean hasErrors() {
+        return hasErrors;
+    }
+
+    public String getIncludes() {
+        return processedIncludes;
+    }
+
+    public String getExcludes() {
+        return processedExcludes;
+    }
+
+    public List<File> getProcessedFiles() {
+        return processedFiles;
+    }
+
+    private String processIncludes() {
+        if (includes == null) {
+            return DEFAULT_INCLUDES;
+        }
+        return join(includes, ',');
+    }
+
+    private String processExcludes() {
+        if (excludes == null) {
+            return DEFAULT_EXCLUDES;
+        }
+        return join(excludes, ',');
+    }
+
+    private String join(String[] array, char joinChar) {
+        StringBuilder stringBuilder = new StringBuilder();
+        for (int index = 0; index < array.length; index++) {
+            stringBuilder.append(StringUtils.trim(array[index]));
+            if (index < array.length - 1) {
+                stringBuilder.append(joinChar);
+            }
+        }
+        return stringBuilder.toString();
+    }
+
+    private CompilationUnit getCompilationUnit(final File file) throws FileNotFoundException {
+        final Reader reader = new FileReader(file);
+        return new CompilationUnit() {
+            public String getScriptName() {
+                return file.getAbsolutePath().substring(sourceDirectoryLength);
+            }
+
+            public Reader getScriptReader() {
+                return reader;
+            }
+        };
+    }
+
+    // visible for testing only
+    void setBuildContext(BuildContext buildContext) {
+
+        this.buildContext = buildContext;
+    }
+}
diff --git a/src/main/java/org/apache/sling/resourceresolver/impl/CommonResourceResolverFactoryImpl.java b/src/main/java/org/apache/sling/resourceresolver/impl/CommonResourceResolverFactoryImpl.java
deleted file mode 100644
index b15038a..0000000
--- a/src/main/java/org/apache/sling/resourceresolver/impl/CommonResourceResolverFactoryImpl.java
+++ /dev/null
@@ -1,431 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *   http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-package org.apache.sling.resourceresolver.impl;
-
-import java.lang.ref.ReferenceQueue;
-import java.lang.ref.WeakReference;
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.HashMap;
-import java.util.Iterator;
-import java.util.List;
-import java.util.Map;
-import java.util.Stack;
-import java.util.concurrent.ConcurrentHashMap;
-import java.util.concurrent.atomic.AtomicBoolean;
-
-import org.apache.commons.collections.BidiMap;
-import org.apache.sling.api.resource.LoginException;
-import org.apache.sling.api.resource.ResourceResolver;
-import org.apache.sling.api.resource.ResourceResolverFactory;
-import org.apache.sling.resourceresolver.impl.console.ResourceResolverWebConsolePlugin;
-import org.apache.sling.resourceresolver.impl.helper.ResourceDecoratorTracker;
-import org.apache.sling.resourceresolver.impl.helper.ResourceResolverControl;
-import org.apache.sling.resourceresolver.impl.mapping.MapConfigurationProvider;
-import org.apache.sling.resourceresolver.impl.mapping.MapEntries;
-import org.apache.sling.resourceresolver.impl.mapping.Mapping;
-import org.apache.sling.resourceresolver.impl.providers.ResourceProviderTracker;
-import org.apache.sling.spi.resource.provider.ResourceProvider;
-import org.osgi.framework.BundleContext;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-/**
- * The <code>CommonResourceResolverFactoryImpl</code> is a singleton
- * implementing the shared/common functionality of all resource
- * resolver factories.
- */
-public class CommonResourceResolverFactoryImpl implements ResourceResolverFactory, MapConfigurationProvider {
-
-    /** Helper for the resource resolver. */
-    private MapEntries mapEntries = MapEntries.EMPTY;
-
-    /** The web console plugin. */
-    private ResourceResolverWebConsolePlugin plugin;
-
-    /** The activator */
-    private final ResourceResolverFactoryActivator activator;
-
-    /**
-     * Thread local holding the resource resolver stack
-     */
-    private ThreadLocal<Stack<WeakReference<ResourceResolver>>> resolverStackHolder = new ThreadLocal<Stack<WeakReference<ResourceResolver>>>();
-
-    /** Flag indicating whether this factory is still active. */
-    private final AtomicBoolean isActive = new AtomicBoolean(true);
-
-    /** The reference queue to handle disposing of resource resolver instances. */
-    private final ReferenceQueue<ResourceResolver> resolverReferenceQueue = new ReferenceQueue<ResourceResolver>();
-
-    /** All weak references for the resource resolver instances. */
-    private final Map<Integer, ResolverWeakReference> refs = new ConcurrentHashMap<Integer, CommonResourceResolverFactoryImpl.ResolverWeakReference>();
-
-    /** Background thread handling disposing of resource resolver instances. */
-    private final Thread refQueueThread;
-
-    private boolean logResourceResolverClosing = false;
-
-    /**
-     * Create a new common resource resolver factory.
-     */
-    public CommonResourceResolverFactoryImpl(final ResourceResolverFactoryActivator activator) {
-        this.activator = activator;
-        this.logResourceResolverClosing = activator.shouldLogResourceResolverClosing();
-        this.refQueueThread = new Thread("Apache Sling Resource Resolver Finalizer Thread") {
-
-            @Override
-            public void run() {
-                while ( isActive.get() ) {
-                    try {
-                        final ResolverWeakReference ref = (ResolverWeakReference) resolverReferenceQueue.remove();
-                        try {
-                            ref.close();
-                        } catch ( final Throwable t ) {
-                            // we ignore everything from there to not stop this thread
-                        }
-                        refs.remove(ref.control.hashCode());
-                    } catch ( final InterruptedException ie) {
-                        Thread.currentThread().interrupt();
-                    }
-                }
-                for(final ResolverWeakReference ref : refs.values()) {
-                    ref.close();
-                }
-                refs.clear();
-            }
-
-        };
-        this.refQueueThread.setDaemon(true);
-        this.refQueueThread.start();
-    }
-
-    // ---------- Resource Resolver Factory ------------------------------------
-
-    /**
-     * @see org.apache.sling.api.resource.ResourceResolverFactory#getAdministrativeResourceResolver(java.util.Map)
-     */
-    @Override
-    public ResourceResolver getAdministrativeResourceResolver(final Map<String, Object> passedAuthenticationInfo)
-    throws LoginException {
-        if ( !isActive.get() ) {
-            throw new LoginException("ResourceResolverFactory is deactivated.");
-        }
-
-        // create a copy of the passed authentication info as we modify the map
-        final Map<String, Object> authenticationInfo = new HashMap<String, Object>();
-        authenticationInfo.put(ResourceProvider.AUTH_ADMIN, Boolean.TRUE);
-        if ( passedAuthenticationInfo != null ) {
-            authenticationInfo.putAll(passedAuthenticationInfo);
-            // make sure there is no leaking of service bundle and info props
-            authenticationInfo.remove(ResourceProvider.AUTH_SERVICE_BUNDLE);
-            authenticationInfo.remove(SUBSERVICE);
-        }
-
-        return getResourceResolverInternal(authenticationInfo, true);
-    }
-
-    /**
-     * @see org.apache.sling.api.resource.ResourceResolverFactory#getResourceResolver(java.util.Map)
-     */
-    @Override
-    public ResourceResolver getResourceResolver(final Map<String, Object> passedAuthenticationInfo)
-    throws LoginException {
-        if ( !isActive.get() ) {
-            throw new LoginException("ResourceResolverFactory is deactivated.");
-        }
-
-        // create a copy of the passed authentication info as we modify the map
-        final Map<String, Object> authenticationInfo = new HashMap<String, Object>();
-        if ( passedAuthenticationInfo != null ) {
-            authenticationInfo.putAll(passedAuthenticationInfo);
-            // make sure there is no leaking of service bundle and info props
-            authenticationInfo.remove(ResourceProvider.AUTH_SERVICE_BUNDLE);
-            authenticationInfo.remove(SUBSERVICE);
-        }
-
-        final ResourceResolver result = getResourceResolverInternal(authenticationInfo, false);
-        Stack<WeakReference<ResourceResolver>> resolverStack = resolverStackHolder.get();
-        if ( resolverStack == null ) {
-            resolverStack = new Stack<WeakReference<ResourceResolver>>();
-            resolverStackHolder.set(resolverStack);
-        }
-        resolverStack.push(new WeakReference<ResourceResolver>(result));
-        return result;
-    }
-
-
-    /**
-     * @see org.apache.sling.api.resource.ResourceResolverFactory#getThreadResourceResolver()
-     */
-    @Override
-    public ResourceResolver getThreadResourceResolver() {
-        if ( !isActive.get() ) {
-            return null;
-        }
-
-        ResourceResolver result = null;
-        final Stack<WeakReference<ResourceResolver>> resolverStack = resolverStackHolder.get();
-        if ( resolverStack != null) {
-            while ( result == null && !resolverStack.isEmpty() ) {
-                result = resolverStack.peek().get();
-                if ( result == null ) {
-                    resolverStack.pop();
-                }
-            }
-        }
-        return result;
-    }
-
-    // ---------- Implementation helpers --------------------------------------
-
-    /**
-     * Inform about a new resource resolver instance.
-     * We create a weak reference to be able to close the resolver if close on the
-     * resource resolver is never called.
-     * @param resolver The resource resolver
-     * @param ctrl The resource resolver control
-     */
-    public void register(final ResourceResolver resolver,
-            final ResourceResolverControl ctrl) {
-        // create new weak reference
-        refs.put(ctrl.hashCode(), new ResolverWeakReference(resolver, this.resolverReferenceQueue, ctrl));
-    }
-
-    /**
-     * Inform about a closed resource resolver.
-     * Make sure to remove it from the current thread context.
-     * @param resourceResolverImpl The resource resolver
-     * @param ctrl The resource resolver control
-     */
-    public void unregister(final ResourceResolver resourceResolverImpl,
-            final ResourceResolverControl ctrl) {
-        // close the context
-        ctrl.close();
-        // remove it from the set of weak references.
-        refs.remove(ctrl.hashCode());
-
-        // on shutdown, the factory might already be closed before the resolvers close
-        // therefore we have to check for null
-        final ThreadLocal<Stack<WeakReference<ResourceResolver>>> tl = resolverStackHolder;
-        if ( tl != null ) {
-            final Stack<WeakReference<ResourceResolver>> resolverStack = tl.get();
-            if ( resolverStack != null ) {
-                final Iterator<WeakReference<ResourceResolver>> i = resolverStack.iterator();
-                while ( i.hasNext() ) {
-                    final WeakReference<ResourceResolver> ref = i.next();
-                    if ( ref.get() == null || ref.get() == resourceResolverImpl ) {
-                        i.remove();
-                    }
-                }
-                if ( resolverStack.isEmpty() ) {
-                    tl.remove();
-                }
-            }
-        }
-    }
-
-    /**
-     * Create a new ResourceResolver
-     * @param authenticationInfo The authentication map
-     * @param isAdmin is an administrative resolver requested?
-     * @return A resource resolver
-     * @throws LoginException if login to any of the required resource providers fails.
-     */
-    public ResourceResolver getResourceResolverInternal(final Map<String, Object> authenticationInfo,
-                    final boolean isAdmin)
-    throws LoginException {
-        if ( !isActive.get() ) {
-            throw new LoginException("ResourceResolverFactory is deactivated.");
-        }
-
-        return new ResourceResolverImpl(this, isAdmin, authenticationInfo);
-    }
-
-    public MapEntries getMapEntries() {
-        return mapEntries;
-    }
-
-    /** Activates this component */
-    protected void activate(final BundleContext bundleContext) {
-        final Logger logger = LoggerFactory.getLogger(getClass());
-        try {
-            plugin = new ResourceResolverWebConsolePlugin(bundleContext, this, this.activator.getRuntimeService());
-        } catch (final Throwable ignore) {
-            // an exception here probably means the web console plugin is not
-            // available
-            logger.debug("activate: unable to setup web console plugin.", ignore);
-        }
-        // set up the map entries from configuration
-        try {
-            mapEntries = new MapEntries(this, bundleContext, this.activator.getEventAdmin());
-        } catch (final Exception e) {
-            logger.error("activate: Cannot access repository, failed setting up Mapping Support", e);
-        }
-    }
-
-    /**
-     * Deactivates this component
-     */
-    protected void deactivate() {
-        isActive.set(false);
-        this.refQueueThread.interrupt();
-        if (plugin != null) {
-            plugin.dispose();
-            plugin = null;
-        }
-
-        if (mapEntries != null) {
-            mapEntries.dispose();
-            mapEntries = MapEntries.EMPTY;
-        }
-        resolverStackHolder = null;
-    }
-
-    public ResourceDecoratorTracker getResourceDecoratorTracker() {
-        return this.activator.getResourceDecoratorTracker();
-    }
-
-    public String[] getSearchPath() {
-        return this.activator.getSearchPath();
-    }
-
-    public boolean isMangleNamespacePrefixes() {
-        return this.activator.isMangleNamespacePrefixes();
-    }
-
-    @Override
-    public String getMapRoot() {
-        return this.activator.getMapRoot();
-    }
-
-    @Override
-    public Mapping[] getMappings() {
-        return this.activator.getMappings();
-    }
-
-    @Override
-    public BidiMap getVirtualURLMap() {
-        return this.activator.getVirtualURLMap();
-    }
-
-    @Override
-    public int getDefaultVanityPathRedirectStatus() {
-        return this.activator.getDefaultVanityPathRedirectStatus();
-    }
-
-    /**
-     * get's the ServiceTracker of the ResourceAccessSecurity service
-     */
-    public ResourceAccessSecurityTracker getResourceAccessSecurityTracker () {
-        return this.activator.getResourceAccessSecurityTracker();
-    }
-
-    @Override
-    public ResourceResolver getServiceResourceResolver(
-            final Map<String, Object> authenticationInfo) throws LoginException {
-        throw new IllegalStateException("This method is not implemented.");
-    }
-
-    @Override
-    public boolean isVanityPathEnabled() {
-        return this.activator.isVanityPathEnabled();
-    }
-
-    @Override
-    public long getMaxCachedVanityPathEntries() {
-        return this.activator.getMaxCachedVanityPathEntries();
-    }
-
-    @Override
-    public boolean isMaxCachedVanityPathEntriesStartup() {
-        return this.activator.isMaxCachedVanityPathEntriesStartup();
-    }
-
-    @Override
-    public int getVanityBloomFilterMaxBytes() {
-        return this.activator.getVanityBloomFilterMaxBytes();
-    }
-
-    @Override
-    public boolean isOptimizeAliasResolutionEnabled() {
-        return this.activator.isOptimizeAliasResolutionEnabled();
-    }
-
-    @Override
-    public boolean hasVanityPathPrecedence() {
-        return this.activator.hasVanityPathPrecedence();
-    }
-
-    @Override
-    public List<VanityPathConfig> getVanityPathConfig() {
-        final String[] includes = this.activator.getVanityPathWhiteList();
-        final String[] excludes = this.activator.getVanityPathBlackList();
-        if ( includes == null && excludes == null ) {
-            return null;
-        }
-        final List<VanityPathConfig> configs = new ArrayList<VanityPathConfig>();
-        if ( includes != null ) {
-            for(final String val : includes) {
-                configs.add(new VanityPathConfig(val, false));
-            }
-        }
-        if ( excludes != null ) {
-            for(final String val : excludes) {
-                configs.add(new VanityPathConfig(val, true));
-            }
-        }
-        Collections.sort(configs);
-        return configs;
-    }
-
-    /**
-     * Is this factory still alive?
-     */
-    public boolean isLive() {
-        return this.isActive.get();
-    }
-
-    public boolean shouldLogResourceResolverClosing() {
-        return logResourceResolverClosing;
-    }
-
-    public ResourceProviderTracker getResourceProviderTracker() {
-        return activator.getResourceProviderTracker();
-    }
-
-    /**
-     * Extension of a weak reference to be able to get the control object
-     * that is used for cleaning up.
-     */
-    private static final class ResolverWeakReference extends WeakReference<ResourceResolver> {
-
-        private final ResourceResolverControl control;
-
-        public ResolverWeakReference(final ResourceResolver referent,
-                final ReferenceQueue<? super ResourceResolver> q,
-                final ResourceResolverControl ctrl) {
-            super(referent, q);
-            this.control = ctrl;
-        }
-
-        public void close() {
-            this.control.close();
-        }
-    }
-}
\ No newline at end of file
diff --git a/src/main/java/org/apache/sling/resourceresolver/impl/FactoryPreconditions.java b/src/main/java/org/apache/sling/resourceresolver/impl/FactoryPreconditions.java
deleted file mode 100644
index 24cad65..0000000
--- a/src/main/java/org/apache/sling/resourceresolver/impl/FactoryPreconditions.java
+++ /dev/null
@@ -1,143 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *   http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-package org.apache.sling.resourceresolver.impl;
-
-import java.util.ArrayList;
-import java.util.List;
-
-import org.apache.sling.resourceresolver.impl.legacy.LegacyResourceProviderWhiteboard;
-import org.apache.sling.resourceresolver.impl.providers.ResourceProviderHandler;
-import org.apache.sling.resourceresolver.impl.providers.ResourceProviderTracker;
-import org.osgi.framework.BundleContext;
-import org.osgi.framework.Constants;
-import org.osgi.framework.Filter;
-import org.osgi.framework.InvalidSyntaxException;
-import org.osgi.framework.ServiceReference;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-/**
- * Helper class which checks whether all conditions for registering
- * the resource resolver factory are fulfilled.
- */
-public class FactoryPreconditions {
-
-    private static final class RequiredProvider {
-        public String name;
-        public String pid;
-        public Filter filter;
-    };
-
-    private volatile ResourceProviderTracker tracker;
-
-    private volatile List<RequiredProvider> requiredProviders;
-
-    public void activate(final BundleContext bc,
-            final String[] legycyConfiguration,
-            final String[] namesConfiguration,
-            final ResourceProviderTracker tracker) {
-        synchronized ( this ) {
-            this.tracker = tracker;
-
-            final List<RequiredProvider> rps = new ArrayList<RequiredProvider>();
-            if ( legycyConfiguration != null ) {
-                final Logger logger = LoggerFactory.getLogger(getClass());
-                for(final String r : legycyConfiguration) {
-                    if ( r != null && r.trim().length() > 0 ) {
-                        final String value = r.trim();
-                        RequiredProvider rp = new RequiredProvider();
-                        if ( value.startsWith("(") ) {
-                            try {
-                                rp.filter = bc.createFilter(value);
-                            } catch (final InvalidSyntaxException e) {
-                                logger.warn("Ignoring invalid filter syntax for required provider: " + value, e);
-                                rp = null;
-                            }
-                        } else {
-                            rp.pid = value;
-                        }
-                        if ( rp != null ) {
-                            rps.add(rp);
-                        }
-                    }
-                }
-            }
-            if ( namesConfiguration != null ) {
-                for(final String r : namesConfiguration) {
-                    final String value = r.trim();
-                    if ( !value.isEmpty() ) {
-                        final RequiredProvider rp = new RequiredProvider();
-                        rp.name = value;
-                        rps.add(rp);
-                    }
-                }
-            }
-            this.requiredProviders = rps;
-        }
-    }
-
-    public void deactivate() {
-        synchronized ( this ) {
-            this.requiredProviders = null;
-            this.tracker = null;
-        }
-    }
-
-    public boolean checkPreconditions(final String unavailableName, final String unavailableServicePid) {
-        synchronized ( this ) {
-            final List<RequiredProvider> localRequiredProviders = this.requiredProviders;
-            final ResourceProviderTracker localTracker = this.tracker;
-            boolean canRegister = localTracker != null;
-            if (localRequiredProviders != null && localTracker != null ) {
-                for (final RequiredProvider rp : localRequiredProviders) {
-                    canRegister = false;
-                    for (final ResourceProviderHandler h : localTracker.getResourceProviderStorage().getAllHandlers()) {
-                        final ServiceReference ref = h.getInfo().getServiceReference();
-                        final Object servicePid = ref.getProperty(Constants.SERVICE_PID);
-                        if ( unavailableServicePid != null && unavailableServicePid.equals(servicePid) ) {
-                            // ignore this service
-                            continue;
-                        }
-                        if ( unavailableName != null && unavailableName.equals(h.getInfo().getName()) ) {
-                            // ignore this service
-                            continue;
-                        }
-                        if ( rp.name != null && rp.name.equals(h.getInfo().getName()) ) {
-                            canRegister = true;
-                            break;
-                        } else if (rp.filter != null && rp.filter.match(ref)) {
-                            canRegister = true;
-                            break;
-                        } else if (rp.pid != null && rp.pid.equals(servicePid)){
-                            canRegister = true;
-                            break;
-                        } else if (rp.pid != null && rp.pid.equals(ref.getProperty(LegacyResourceProviderWhiteboard.ORIGINAL_SERVICE_PID))) {
-                            canRegister = true;
-                            break;
-                        }
-                    }
-                    if ( !canRegister ) {
-                        break;
-                    }
-                }
-            }
-            return canRegister;
-        }
-    }
-}
diff --git a/src/main/java/org/apache/sling/resourceresolver/impl/ResourceAccessSecurityTracker.java b/src/main/java/org/apache/sling/resourceresolver/impl/ResourceAccessSecurityTracker.java
deleted file mode 100644
index 0e12d42..0000000
--- a/src/main/java/org/apache/sling/resourceresolver/impl/ResourceAccessSecurityTracker.java
+++ /dev/null
@@ -1,56 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *   http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-package org.apache.sling.resourceresolver.impl;
-
-import org.apache.felix.scr.annotations.Component;
-import org.apache.felix.scr.annotations.Reference;
-import org.apache.felix.scr.annotations.ReferenceCardinality;
-import org.apache.felix.scr.annotations.ReferencePolicy;
-import org.apache.felix.scr.annotations.ReferencePolicyOption;
-import org.apache.felix.scr.annotations.Service;
-import org.apache.sling.api.security.ResourceAccessSecurity;
-
-/**
- * This internal helper class keeps track of the resource access security services
- * and always returns the one with the highest service ranking.
- */
-@Component
-@Service(value=ResourceAccessSecurityTracker.class)
-public class ResourceAccessSecurityTracker {
-
-    @Reference(policyOption=ReferencePolicyOption.GREEDY,
-               cardinality=ReferenceCardinality.OPTIONAL_UNARY,
-               policy=ReferencePolicy.DYNAMIC,
-               target="(" + ResourceAccessSecurity.CONTEXT + "=" + ResourceAccessSecurity.APPLICATION_CONTEXT + ")")
-    private volatile ResourceAccessSecurity applicationResourceAccessSecurity;
-
-    @Reference(policyOption=ReferencePolicyOption.GREEDY,
-            cardinality=ReferenceCardinality.OPTIONAL_UNARY,
-            policy=ReferencePolicy.DYNAMIC,
-            target="(" + ResourceAccessSecurity.CONTEXT + "=" + ResourceAccessSecurity.PROVIDER_CONTEXT + ")")
-    private volatile ResourceAccessSecurity providerResourceAccessSecurity;
-
-    public ResourceAccessSecurity getApplicationResourceAccessSecurity() {
-        return this.applicationResourceAccessSecurity;
-    }
-
-    public ResourceAccessSecurity getProviderResourceAccessSecurity() {
-        return this.providerResourceAccessSecurity;
-    }
-}
diff --git a/src/main/java/org/apache/sling/resourceresolver/impl/ResourceResolverFactoryActivator.java b/src/main/java/org/apache/sling/resourceresolver/impl/ResourceResolverFactoryActivator.java
deleted file mode 100644
index abb7a56..0000000
--- a/src/main/java/org/apache/sling/resourceresolver/impl/ResourceResolverFactoryActivator.java
+++ /dev/null
@@ -1,717 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *   http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-package org.apache.sling.resourceresolver.impl;
-
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.Dictionary;
-import java.util.Hashtable;
-import java.util.List;
-import java.util.Map;
-
-import org.apache.commons.collections.BidiMap;
-import org.apache.commons.collections.bidimap.TreeBidiMap;
-import org.apache.felix.scr.annotations.Activate;
-import org.apache.felix.scr.annotations.Component;
-import org.apache.felix.scr.annotations.Deactivate;
-import org.apache.felix.scr.annotations.Properties;
-import org.apache.felix.scr.annotations.Property;
-import org.apache.felix.scr.annotations.PropertyUnbounded;
-import org.apache.felix.scr.annotations.Reference;
-import org.apache.felix.scr.annotations.ReferenceCardinality;
-import org.apache.felix.scr.annotations.ReferencePolicy;
-import org.apache.felix.scr.annotations.References;
-import org.apache.sling.api.resource.ResourceDecorator;
-import org.apache.sling.api.resource.ResourceResolverFactory;
-import org.apache.sling.api.resource.runtime.RuntimeService;
-import org.apache.sling.commons.osgi.PropertiesUtil;
-import org.apache.sling.resourceresolver.impl.helper.ResourceDecoratorTracker;
-import org.apache.sling.resourceresolver.impl.mapping.MapEntries;
-import org.apache.sling.resourceresolver.impl.mapping.Mapping;
-import org.apache.sling.resourceresolver.impl.observation.ResourceChangeListenerWhiteboard;
-import org.apache.sling.resourceresolver.impl.providers.ResourceProviderTracker;
-import org.apache.sling.resourceresolver.impl.providers.ResourceProviderTracker.ChangeListener;
-import org.apache.sling.resourceresolver.impl.providers.RuntimeServiceImpl;
-import org.apache.sling.serviceusermapping.ServiceUserMapper;
-import org.osgi.framework.Bundle;
-import org.osgi.framework.BundleContext;
-import org.osgi.framework.Constants;
-import org.osgi.framework.ServiceFactory;
-import org.osgi.framework.ServiceRegistration;
-import org.osgi.service.component.ComponentContext;
-import org.osgi.service.event.EventAdmin;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-/**
- * The <code>ResourceResolverFactoryActivator/code> keeps track of required services for the
- * resource resolver factory.
- * One all required providers and provider factories are available a resource resolver factory
- * is registered.
- *
- */
-@Component(
-     name = "org.apache.sling.jcr.resource.internal.JcrResourceResolverFactoryImpl",
-     label = "Apache Sling Resource Resolver Factory",
-     description = "Configures the Resource Resolver for request URL and resource path rewriting.",
-     specVersion = "1.1",
-     metatype = true)
-@Properties({
-    @Property(name = Constants.SERVICE_DESCRIPTION, value = "Apache Sling Resource Resolver Factory"),
-    @Property(name = Constants.SERVICE_VENDOR, value = "The Apache Software Foundation")
-})
-@References({
-    @Reference(name = "ResourceDecorator", referenceInterface = ResourceDecorator.class, cardinality = ReferenceCardinality.OPTIONAL_MULTIPLE, policy = ReferencePolicy.DYNAMIC)
-})
-public class ResourceResolverFactoryActivator {
-
-    private static final class FactoryRegistration {
-        /** Registration .*/
-        public volatile ServiceRegistration factoryRegistration;
-
-        /** Runtime registration. */
-        public volatile ServiceRegistration runtimeRegistration;
-
-        public volatile CommonResourceResolverFactoryImpl commonFactory;
-    }
-
-    @Property(value = { "/apps", "/libs" },
-              label = "Resource Search Path",
-              description = "The list of absolute path prefixes " +
-                            "applied to find resources whose path is just specified with a relative path. " +
-                            "The default value is [ \"/apps\", \"/libs\" ]. If an empty path is specified a " +
-                            "single entry path of [ \"/\" ] is assumed.")
-    public static final String PROP_PATH = "resource.resolver.searchpath";
-
-    /**
-     * Defines whether namespace prefixes of resource names inside the path
-     * (e.g. <code>jcr:</code> in <code>/home/path/jcr:content</code>) are
-     * mangled or not.
-     * <p>
-     * Mangling means that any namespace prefix contained in the path is replaced as per the generic
-     * substitution pattern <code>/([^:]+):/_$1_/</code> when calling the <code>map</code> method of
-     * the resource resolver. Likewise the <code>resolve</code> methods will unmangle such namespace
-     * prefixes according to the substitution pattern <code>/_([^_]+)_/$1:/</code>.
-     * <p>
-     * This feature is provided since there may be systems out there in the wild which cannot cope
-     * with URLs containing colons, even though they are perfectly valid characters in the path part
-     * of URI references with a scheme.
-     * <p>
-     * The default value of this property if no configuration is provided is <code>true</code>.
-     *
-     */
-    @Property(boolValue = true,
-              label = "Namespace Mangling",
-              description = "Defines whether namespace " +
-                            "prefixes of resource names inside the path (e.g. \"jcr:\" in \"/home/path/jcr:content\") " +
-                            "are mangled or not. Mangling means that any namespace prefix contained in the " +
-                            "path is replaced as per the generic substitution pattern \"/([^:]+):/_$1_/\" " +
-                            "when calling the \"map\" method of the resource resolver. Likewise the " +
-                            "\"resolve\" methods will unmangle such namespace prefixes according to the " +
-                            "substituation pattern \"/_([^_]+)_/$1:/\". This feature is provided since " +
-                            "there may be systems out there in the wild which cannot cope with URLs " +
-                            "containing colons, even though they are perfectly valid characters in the " +
-                            "path part of URI references with a scheme. The default value of this property " +
-                            "if no configuration is provided is \"true\".")
-    private static final String PROP_MANGLE_NAMESPACES = "resource.resolver.manglenamespaces";
-
-    @Property(boolValue = true,
-              label = "Allow Direct Mapping",
-              description = "Whether to add a direct URL mapping to the front of the mapping list.")
-    private static final String PROP_ALLOW_DIRECT = "resource.resolver.allowDirect";
-
-    @Property(unbounded=PropertyUnbounded.ARRAY,
-              label = "Required Providers (Deprecated)",
-              description = "A resource resolver factory is only " +
-                             "available (registered) if all resource providers mentioned in this configuration " +
-                             "are available. Each entry is either a service PID or a filter expression.  " +
-                             "Invalid filters are ignored.")
-    private static final String PROP_REQUIRED_PROVIDERS_LEGACY = "resource.resolver.required.providers";
-
-    @Property(unbounded=PropertyUnbounded.ARRAY,
-            value = "JCR",
-            label = "Required Providers ",
-            description = "A resource resolver factory is only " +
-                           "available (registered) if all resource providers mentioned in this configuration " +
-                           "are available. Each entry is refers to the name of a registered provider.")
-    private static final String PROP_REQUIRED_PROVIDERS = "resource.resolver.required.providernames";
-
-    /**
-     * The resolver.virtual property has no default configuration. But the Sling
-     * maven plugin and the sling management console cannot handle empty
-     * multivalue properties at the moment. So we just add a dummy direct
-     * mapping.
-     */
-    @Property(value = "/:/", unbounded = PropertyUnbounded.ARRAY,
-              label = "Virtual URLs",
-              description = "List of virtual URLs and there mappings to real URLs. " +
-                            "Format is <externalURL>:<internalURL>. Mappings are " +
-                            "applied on the complete request URL only.")
-    private static final String PROP_VIRTUAL = "resource.resolver.virtual";
-
-    @Property(value = { "/:/", "/content/:/", "/system/docroot/:/" },
-              label = "URL Mappings",
-              description = "List of mappings to apply to paths. Incoming mappings are " +
-                            "applied to request paths to map to resource paths, " +
-                            "outgoing mappings are applied to map resource paths to paths used on subsequent " +
-                            "requests. Form is <internalPathPrefix><op><externalPathPrefix> where <op> is " +
-                            "\">\" for incoming mappings, \"<\" for outgoing mappings and \":\" for mappings " +
-                            "applied in both directions. Mappings are applied in configuration order by " +
-                            "comparing and replacing URL prefixes. Note: The use of \"-\" as the <op> value " +
-                            "indicating a mapping in both directions is deprecated.")
-    private static final String PROP_MAPPING = "resource.resolver.mapping";
-
-    @Property(value = MapEntries.DEFAULT_MAP_ROOT,
-              label = "Mapping Location",
-              description = "The path to the root of the configuration to setup and configure " +
-                            "the ResourceResolver mapping. The default value is /etc/map.")
-    private static final String PROP_MAP_LOCATION = "resource.resolver.map.location";
-
-    @Property(intValue = MapEntries.DEFAULT_DEFAULT_VANITY_PATH_REDIRECT_STATUS,
-              label = "Default Vanity Path Redirect Status",
-              description = "The default status code used when a sling:vanityPath is configured to redirect " +
-                            "and does not have a specific status code associated with it " +
-                            "(via a sling:redirectStatus property)")
-    private static final String PROP_DEFAULT_VANITY_PATH_REDIRECT_STATUS = "resource.resolver.default.vanity.redirect.status";
-
-    private static final boolean DEFAULT_ENABLE_VANITY_PATH = true;
-    @Property(boolValue = DEFAULT_ENABLE_VANITY_PATH,
-              label = "Enable Vanity Paths",
-              description = "This flag controls whether all resources with a sling:vanityPath property " +
-                            "are processed and added to the mappoing table.")
-    private static final String PROP_ENABLE_VANITY_PATH = "resource.resolver.enable.vanitypath";
-
-    private static final long DEFAULT_MAX_CACHED_VANITY_PATHS = -1;
-    @Property(longValue = DEFAULT_MAX_CACHED_VANITY_PATHS,
-              label = "Maximum number of cached vanity path entries",
-              description = "The maximum number of cached vanity path entries. " +
-                            "Default is -1 (no limit)")
-    private static final String PROP_MAX_CACHED_VANITY_PATHS = "resource.resolver.vanitypath.maxEntries";
-
-    private static final boolean DEFAULT_MAX_CACHED_VANITY_PATHS_STARTUP = true;
-    @Property(boolValue = DEFAULT_MAX_CACHED_VANITY_PATHS_STARTUP,
-              label = "Limit the maximum number of cached vanity path entries only at startup",
-              description = "Limit the maximum number of cached vanity path entries only at startup. " +
-                            "Default is true")
-    private static final String PROP_MAX_CACHED_VANITY_PATHS_STARTUP = "resource.resolver.vanitypath.maxEntries.startup";
-
-    private static final int DEFAULT_VANITY_BLOOM_FILTER_MAX_BYTES = 1024000;
-    @Property(longValue = DEFAULT_VANITY_BLOOM_FILTER_MAX_BYTES,
-              label = "Maximum number of vanity bloom filter bytes",
-              description = "The maximum number of vanity bloom filter bytes. " +
-                            "Changing this value is subject to vanity bloom filter rebuild")
-    private static final String PROP_VANITY_BLOOM_FILTER_MAX_BYTES = " resource.resolver.vanitypath.bloomfilter.maxBytes";
-
-    private static final boolean DEFAULT_ENABLE_OPTIMIZE_ALIAS_RESOLUTION = true;
-    @Property(boolValue = DEFAULT_ENABLE_OPTIMIZE_ALIAS_RESOLUTION ,
-              label = "Optimize alias resolution",
-              description ="This flag controls whether to optimize" +
-                      " the alias resolution by creating an internal cache of aliases. This might have an impact on the startup time"+
-                      " and on the alias update time if the number of aliases is huge (over 10000).")
-    private static final String PROP_ENABLE_OPTIMIZE_ALIAS_RESOLUTION = "resource.resolver.optimize.alias.resolution";
-
-    @Property(unbounded=PropertyUnbounded.ARRAY,
-            label = "Allowed Vanity Path Location",
-            description ="This setting can contain a list of path prefixes, e.g. /libs/, /content/. If " +
-                    "such a list is configured, only vanity paths from resources starting with this prefix " +
-                    " are considered. If the list is empty, all vanity paths are used.")
-    private static final String PROP_ALLOWED_VANITY_PATH_PREFIX = "resource.resolver.vanitypath.whitelist";
-
-    @Property(unbounded=PropertyUnbounded.ARRAY,
-            label = "Denied Vanity Path Location",
-            description ="This setting can contain a list of path prefixes, e.g. /misc/. If " +
-                    "such a list is configured,vanity paths from resources starting with this prefix " +
-                    " are not considered. If the list is empty, all vanity paths are used.")
-    private static final String PROP_DENIED_VANITY_PATH_PREFIX = "resource.resolver.vanitypath.blacklist";
-
-    private static final boolean DEFAULT_VANITY_PATH_PRECEDENCE = false;
-    @Property(boolValue = DEFAULT_VANITY_PATH_PRECEDENCE ,
-              label = "Vanity Path Precedence",
-              description ="This flag controls whether vanity paths" +
-                      " will have precedence over existing /etc/map mapping")
-    private static final String PROP_VANITY_PATH_PRECEDENCE = "resource.resolver.vanity.precedence";
-
-    private static final boolean DEFAULT_PARANOID_PROVIDER_HANDLING = false;
-    @Property(boolValue = DEFAULT_PARANOID_PROVIDER_HANDLING,
-              label = "Paranoid Provider Handling",
-              description = "If this flag is enabled, an unregistration of a resource provider (not factory), "
-                          + "is causing the resource resolver factory to restart, potentially cleaning up "
-                          + "for memory leaks caused by objects hold from that resource provider.")
-    private static final String PROP_PARANOID_PROVIDER_HANDLING = "resource.resolver.providerhandling.paranoid";
-
-    private static final boolean DEFAULT_LOG_RESOURCE_RESOLVER_CLOSING = false;
-    @Property(boolValue = DEFAULT_LOG_RESOURCE_RESOLVER_CLOSING,
-              label = "Log resource resolver closing",
-              description = "When enabled CRUD operations with a closed resource resolver will log a stack trace " +
-                  "with the point where the used resolver was closed. It's advisable to not enable this feature on " +
-                  "production systems.")
-    private static final String PROP_LOG_RESOURCE_RESOLVER_CLOSING = "resource.resolver.log.closing";
-
-    /** Logger. */
-    private final Logger logger = LoggerFactory.getLogger(this.getClass());
-
-    /** Tracker for the resource decorators. */
-    private final ResourceDecoratorTracker resourceDecoratorTracker = new ResourceDecoratorTracker();
-
-    /** all mappings */
-    private volatile Mapping[] mappings;
-
-    /** The fake URLs */
-    private volatile BidiMap virtualURLMap;
-
-    /** <code>true</code>, if direct mappings from URI to handle are allowed */
-    private volatile boolean allowDirect = false;
-
-    /** the search path for ResourceResolver.getResource(String) */
-    private volatile String[] searchPath;
-
-    /** the root location of the /etc/map entries */
-    private volatile String mapRoot;
-
-    /** whether to mangle paths with namespaces or not */
-    private volatile boolean mangleNamespacePrefixes;
-
-    /** paranoid provider handling. */
-    private volatile boolean paranoidProviderHandling;
-
-    /** Event admin. */
-    @Reference
-    EventAdmin eventAdmin;
-
-    /** Service User Mapper */
-    @Reference
-    private ServiceUserMapper serviceUserMapper;
-
-    @Reference
-    ResourceAccessSecurityTracker resourceAccessSecurityTracker;
-
-    volatile ResourceProviderTracker resourceProviderTracker;
-
-    volatile ResourceChangeListenerWhiteboard changeListenerWhiteboard;
-
-    /** ComponentContext */
-    private volatile ComponentContext componentContext;
-
-    private volatile int defaultVanityPathRedirectStatus;
-
-    /** vanityPath enabled? */
-    private volatile boolean enableVanityPath = DEFAULT_ENABLE_VANITY_PATH;
-
-    /** alias resource resolution optimization enabled? */
-    private volatile boolean enableOptimizeAliasResolution = DEFAULT_ENABLE_OPTIMIZE_ALIAS_RESOLUTION;
-
-    /** max number of cache vanity path entries */
-    private volatile long maxCachedVanityPathEntries = DEFAULT_MAX_CACHED_VANITY_PATHS;
-
-    /** limit max number of cache vanity path entries only at startup*/
-    private volatile boolean maxCachedVanityPathEntriesStartup = DEFAULT_MAX_CACHED_VANITY_PATHS_STARTUP;
-
-    /** Maximum number of vanity bloom filter bytes */
-    private volatile int vanityBloomFilterMaxBytes = DEFAULT_VANITY_BLOOM_FILTER_MAX_BYTES;
-
-    /** vanity paths will have precedence over existing /etc/map mapping? */
-    private volatile boolean vanityPathPrecedence = DEFAULT_VANITY_PATH_PRECEDENCE;
-
-    /** log the place where a resource resolver is closed */
-    private volatile boolean logResourceResolverClosing = DEFAULT_LOG_RESOURCE_RESOLVER_CLOSING;
-
-    /** Vanity path whitelist */
-    private volatile String[] vanityPathWhiteList;
-
-    /** Vanity path blacklist */
-    private volatile String[] vanityPathBlackList;
-
-    private final FactoryPreconditions preconds = new FactoryPreconditions();
-
-    /** Factory registration. */
-    private volatile FactoryRegistration factoryRegistration;
-
-    /**
-     * Get the resource decorator tracker.
-     */
-    public ResourceDecoratorTracker getResourceDecoratorTracker() {
-        return this.resourceDecoratorTracker;
-    }
-
-    public ResourceAccessSecurityTracker getResourceAccessSecurityTracker() {
-        return this.resourceAccessSecurityTracker;
-    }
-
-    public EventAdmin getEventAdmin() {
-        return this.eventAdmin;
-    }
-
-    /**
-     * This method is called from {@link MapEntries}
-     */
-    public BidiMap getVirtualURLMap() {
-        return virtualURLMap;
-    }
-
-    /**
-     * This method is called from {@link MapEntries}
-     */
-    public Mapping[] getMappings() {
-        return mappings;
-    }
-
-    public String[] getSearchPath() {
-        return searchPath;
-    }
-
-    public boolean isMangleNamespacePrefixes() {
-        return mangleNamespacePrefixes;
-
-    }
-
-    public String getMapRoot() {
-        return mapRoot;
-    }
-
-    public int getDefaultVanityPathRedirectStatus() {
-        return defaultVanityPathRedirectStatus;
-    }
-
-    public boolean isVanityPathEnabled() {
-        return this.enableVanityPath;
-    }
-
-    public boolean isOptimizeAliasResolutionEnabled() {
-        return this.enableOptimizeAliasResolution;
-    }
-
-    public String[] getVanityPathWhiteList() {
-        return this.vanityPathWhiteList;
-    }
-
-    public String[] getVanityPathBlackList() {
-        return this.vanityPathBlackList;
-    }
-
-    public boolean hasVanityPathPrecedence() {
-        return this.vanityPathPrecedence;
-    }
-
-    public long getMaxCachedVanityPathEntries() {
-        return this.maxCachedVanityPathEntries;
-    }
-
-    public boolean isMaxCachedVanityPathEntriesStartup() {
-        return this.maxCachedVanityPathEntriesStartup;
-    }
-
-    public int getVanityBloomFilterMaxBytes() {
-        return this.vanityBloomFilterMaxBytes;
-    }
-
-    public boolean shouldLogResourceResolverClosing() {
-        return logResourceResolverClosing;
-    }
-
-    // ---------- SCR Integration ---------------------------------------------
-
-    /**
-     * Activates this component, called by SCR before registering as a service
-     */
-    @Activate
-    protected void activate(final ComponentContext componentContext) {
-        this.componentContext = componentContext;
-        final Dictionary<?, ?> properties = componentContext.getProperties();
-
-        final BidiMap virtuals = new TreeBidiMap();
-        final String[] virtualList = PropertiesUtil.toStringArray(properties.get(PROP_VIRTUAL));
-        for (int i = 0; virtualList != null && i < virtualList.length; i++) {
-            final String[] parts = Mapping.split(virtualList[i]);
-            virtuals.put(parts[0], parts[2]);
-        }
-        virtualURLMap = virtuals;
-
-        final List<Mapping> maps = new ArrayList<Mapping>();
-        final String[] mappingList = (String[]) properties.get(PROP_MAPPING);
-        for (int i = 0; mappingList != null && i < mappingList.length; i++) {
-            maps.add(new Mapping(mappingList[i]));
-        }
-        final Mapping[] tmp = maps.toArray(new Mapping[maps.size()]);
-
-        // check whether direct mappings are allowed
-        final Boolean directProp = (Boolean) properties.get(PROP_ALLOW_DIRECT);
-        allowDirect = (directProp != null) ? directProp.booleanValue() : true;
-        if (allowDirect) {
-            final Mapping[] tmp2 = new Mapping[tmp.length + 1];
-            tmp2[0] = Mapping.DIRECT;
-            System.arraycopy(tmp, 0, tmp2, 1, tmp.length);
-            mappings = tmp2;
-        } else {
-            mappings = tmp;
-        }
-
-        // from configuration if available
-        searchPath = PropertiesUtil.toStringArray(properties.get(PROP_PATH));
-        if (searchPath != null && searchPath.length > 0) {
-            for (int i = 0; i < searchPath.length; i++) {
-                // ensure leading slash
-                if (!searchPath[i].startsWith("/")) {
-                    searchPath[i] = "/" + searchPath[i];
-                }
-                // ensure trailing slash
-                if (!searchPath[i].endsWith("/")) {
-                    searchPath[i] += "/";
-                }
-            }
-        }
-        if (searchPath == null) {
-            searchPath = new String[] { "/" };
-        }
-        // namespace mangling
-        mangleNamespacePrefixes = PropertiesUtil.toBoolean(properties.get(PROP_MANGLE_NAMESPACES), false);
-
-        // the root of the resolver mappings
-        mapRoot = PropertiesUtil.toString(properties.get(PROP_MAP_LOCATION), MapEntries.DEFAULT_MAP_ROOT);
-
-        defaultVanityPathRedirectStatus = PropertiesUtil.toInteger(properties.get(PROP_DEFAULT_VANITY_PATH_REDIRECT_STATUS),
-                                                                   MapEntries.DEFAULT_DEFAULT_VANITY_PATH_REDIRECT_STATUS);
-        this.enableVanityPath = PropertiesUtil.toBoolean(properties.get(PROP_ENABLE_VANITY_PATH), DEFAULT_ENABLE_VANITY_PATH);
-        // vanity path white list
-        this.vanityPathWhiteList = null;
-        String[] vanityPathPrefixes = PropertiesUtil.toStringArray(properties.get(PROP_ALLOWED_VANITY_PATH_PREFIX));
-        if ( vanityPathPrefixes != null ) {
-            final List<String> prefixList = new ArrayList<String>();
-            for(final String value : vanityPathPrefixes) {
-                if ( value.trim().length() > 0 ) {
-                    if ( value.trim().endsWith("/") ) {
-                        prefixList.add(value.trim());
-                    } else {
-                        prefixList.add(value.trim() + "/");
-                    }
-                }
-            }
-            if ( prefixList.size() > 0 ) {
-                this.vanityPathWhiteList = prefixList.toArray(new String[prefixList.size()]);
-            }
-        }
-        // vanity path black list
-        this.vanityPathBlackList = null;
-        vanityPathPrefixes = PropertiesUtil.toStringArray(properties.get(PROP_DENIED_VANITY_PATH_PREFIX));
-        if ( vanityPathPrefixes != null ) {
-            final List<String> prefixList = new ArrayList<String>();
-            for(final String value : vanityPathPrefixes) {
-                if ( value.trim().length() > 0 ) {
-                    if ( value.trim().endsWith("/") ) {
-                        prefixList.add(value.trim());
-                    } else {
-                        prefixList.add(value.trim() + "/");
-                    }
-                }
-            }
-            if ( prefixList.size() > 0 ) {
-                this.vanityPathBlackList = prefixList.toArray(new String[prefixList.size()]);
-            }
-        }
-
-        this.enableOptimizeAliasResolution = PropertiesUtil.toBoolean(properties.get(PROP_ENABLE_OPTIMIZE_ALIAS_RESOLUTION), DEFAULT_ENABLE_OPTIMIZE_ALIAS_RESOLUTION);
-        this.maxCachedVanityPathEntries = PropertiesUtil.toLong(properties.get(PROP_MAX_CACHED_VANITY_PATHS), DEFAULT_MAX_CACHED_VANITY_PATHS);
-        this.maxCachedVanityPathEntriesStartup = PropertiesUtil.toBoolean(properties.get(PROP_MAX_CACHED_VANITY_PATHS_STARTUP), DEFAULT_MAX_CACHED_VANITY_PATHS_STARTUP);
-        this.vanityBloomFilterMaxBytes = PropertiesUtil.toInteger(properties.get(PROP_VANITY_BLOOM_FILTER_MAX_BYTES), DEFAULT_VANITY_BLOOM_FILTER_MAX_BYTES);
-
-        this.vanityPathPrecedence = PropertiesUtil.toBoolean(properties.get(PROP_VANITY_PATH_PRECEDENCE), DEFAULT_VANITY_PATH_PRECEDENCE);
-        this.logResourceResolverClosing = PropertiesUtil.toBoolean(properties.get(PROP_LOG_RESOURCE_RESOLVER_CLOSING),
-            DEFAULT_LOG_RESOURCE_RESOLVER_CLOSING);
-        this.paranoidProviderHandling = PropertiesUtil.toBoolean(properties.get(PROP_PARANOID_PROVIDER_HANDLING), DEFAULT_PARANOID_PROVIDER_HANDLING);
-
-        final BundleContext bc = componentContext.getBundleContext();
-
-        // check for required property
-        final String[] requiredResourceProvidersLegacy = PropertiesUtil.toStringArray(properties.get(PROP_REQUIRED_PROVIDERS_LEGACY));
-        final String[] requiredResourceProviderNames = PropertiesUtil.toStringArray(properties.get(PROP_REQUIRED_PROVIDERS));
-
-        if ( requiredResourceProvidersLegacy != null && requiredResourceProvidersLegacy.length > 0 ) {
-            logger.error("ResourceResolverFactory is using deprecated required providers configuration (" + PROP_REQUIRED_PROVIDERS_LEGACY +
-                    "). Please change to use the property " + PROP_REQUIRED_PROVIDERS + " for values: " + Arrays.toString(requiredResourceProvidersLegacy));
-        }
-        // for testing: if we run unit test, both trackers are set from the outside
-        if ( this.resourceProviderTracker == null ) {
-            this.resourceProviderTracker = new ResourceProviderTracker();
-            this.changeListenerWhiteboard = new ResourceChangeListenerWhiteboard();
-            this.preconds.activate(bc, requiredResourceProvidersLegacy, requiredResourceProviderNames, resourceProviderTracker);
-            this.changeListenerWhiteboard.activate(this.componentContext.getBundleContext(),
-                this.resourceProviderTracker, searchPath);
-            this.resourceProviderTracker.activate(this.componentContext.getBundleContext(),
-                    this.eventAdmin,
-                    new ChangeListener() {
-
-                        @Override
-                        public void providerAdded() {
-                            if ( factoryRegistration == null ) {
-                                checkFactoryPreconditions(null, null);
-                            }
-
-                        }
-
-                        @Override
-                        public void providerRemoved(final String name, final String pid, final boolean stateful, final boolean isUsed) {
-                            if ( factoryRegistration != null ) {
-                                if ( isUsed && (stateful || paranoidProviderHandling) ) {
-                                    unregisterFactory();
-                                }
-                                checkFactoryPreconditions(name, pid);
-                            }
-                        }
-                    });
-        } else {
-            this.preconds.activate(bc, requiredResourceProvidersLegacy, requiredResourceProviderNames, resourceProviderTracker);
-            this.checkFactoryPreconditions(null, null);
-         }
-    }
-
-    /**
-     * Deactivates this component (called by SCR to take out of service)
-     */
-    @Deactivate
-    protected void deactivate() {
-        this.unregisterFactory();
-
-        this.componentContext = null;
-
-        this.changeListenerWhiteboard.deactivate();
-        this.resourceProviderTracker.deactivate();
-        this.preconds.deactivate();
-        this.resourceDecoratorTracker.close();
-    }
-
-    /**
-     * Unregister the factory (if registered)
-     * This method might be called concurrently from deactivate and the
-     * background thread, therefore we need to synchronize.
-     */
-    private void unregisterFactory() {
-        FactoryRegistration local = null;
-        synchronized ( this ) {
-            if ( this.factoryRegistration != null ) {
-                local = this.factoryRegistration;
-                this.factoryRegistration = null;
-            }
-        }
-        this.unregisterFactory(local);
-    }
-
-    /**
-     * Unregister the provided factory
-     */
-    private void unregisterFactory(final FactoryRegistration local) {
-        if ( local != null ) {
-            if ( local.factoryRegistration != null ) {
-                local.factoryRegistration.unregister();
-            }
-            if ( local.runtimeRegistration != null ) {
-                local.runtimeRegistration.unregister();
-            }
-            if ( local.commonFactory != null ) {
-                local.commonFactory.deactivate();
-            }
-        }
-    }
-
-    /**
-     * Try to register the factory.
-     */
-    private void registerFactory(final ComponentContext localContext) {
-        final FactoryRegistration local = new FactoryRegistration();
-
-        if ( localContext != null ) {
-            // activate and register factory
-            final Dictionary<String, Object> serviceProps = new Hashtable<String, Object>();
-            serviceProps.put(Constants.SERVICE_VENDOR, localContext.getProperties().get(Constants.SERVICE_VENDOR));
-            serviceProps.put(Constants.SERVICE_DESCRIPTION, localContext.getProperties().get(Constants.SERVICE_DESCRIPTION));
-
-            local.commonFactory = new CommonResourceResolverFactoryImpl(this);
-            local.commonFactory.activate(localContext.getBundleContext());
-            local.factoryRegistration = localContext.getBundleContext().registerService(
-                ResourceResolverFactory.class.getName(), new ServiceFactory() {
-
-                    @Override
-                    public Object getService(final Bundle bundle, final ServiceRegistration registration) {
-                        if ( ResourceResolverFactoryActivator.this.componentContext == null ) {
-                            return null;
-                        }
-                        final ResourceResolverFactoryImpl r = new ResourceResolverFactoryImpl(
-                                local.commonFactory, bundle,
-                            ResourceResolverFactoryActivator.this.serviceUserMapper);
-                        return r;
-                    }
-
-                    @Override
-                    public void ungetService(final Bundle bundle, final ServiceRegistration registration, final Object service) {
-                        // nothing to do
-                    }
-                }, serviceProps);
-
-            local.runtimeRegistration = localContext.getBundleContext().registerService(RuntimeService.class.getName(),
-                    this.getRuntimeService(), null);
-
-            this.factoryRegistration = local;
-        }
-    }
-
-    public RuntimeService getRuntimeService() {
-        return new RuntimeServiceImpl(this.resourceProviderTracker);
-    }
-
-    /**
-     * Check the preconditions and if it changed, either register factory or unregister
-     */
-    private void checkFactoryPreconditions(final String unavailableName, final String unavailableServicePid) {
-        final ComponentContext localContext = this.componentContext;
-        if ( localContext != null ) {
-            final boolean result = this.preconds.checkPreconditions(unavailableName, unavailableServicePid);
-            if ( result && this.factoryRegistration == null ) {
-                boolean create = true;
-                synchronized ( this ) {
-                    if ( this.factoryRegistration == null ) {
-                        this.factoryRegistration = new FactoryRegistration();
-                    } else {
-                        create = false;
-                    }
-                }
-                if ( create ) {
-                    this.registerFactory(localContext);
-                }
-            } else if ( !result && this.factoryRegistration != null ) {
-                this.unregisterFactory();
-            }
-        }
-    }
-
-    /**
-     * Bind a resource decorator.
-     */
-    protected void bindResourceDecorator(final ResourceDecorator decorator, final Map<String, Object> props) {
-        this.resourceDecoratorTracker.bindResourceDecorator(decorator, props);
-    }
-
-    /**
-     * Unbind a resource decorator.
-     */
-    protected void unbindResourceDecorator(final ResourceDecorator decorator, final Map<String, Object> props) {
-        this.resourceDecoratorTracker.unbindResourceDecorator(decorator, props);
-    }
-
-    public ResourceProviderTracker getResourceProviderTracker() {
-        return resourceProviderTracker;
-    }
-}
diff --git a/src/main/java/org/apache/sling/resourceresolver/impl/ResourceResolverFactoryImpl.java b/src/main/java/org/apache/sling/resourceresolver/impl/ResourceResolverFactoryImpl.java
deleted file mode 100644
index e0e882b..0000000
--- a/src/main/java/org/apache/sling/resourceresolver/impl/ResourceResolverFactoryImpl.java
+++ /dev/null
@@ -1,116 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *   http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-package org.apache.sling.resourceresolver.impl;
-
-import java.util.HashMap;
-import java.util.Map;
-
-import org.apache.sling.api.resource.LoginException;
-import org.apache.sling.api.resource.ResourceResolver;
-import org.apache.sling.api.resource.ResourceResolverFactory;
-import org.apache.sling.serviceusermapping.ServiceUserMapper;
-import org.apache.sling.spi.resource.provider.ResourceProvider;
-import org.osgi.framework.Bundle;
-
-/**
- * The <code>ResourceResolverFactoryImpl</code> is the {@link ResourceResolverFactory} service
- * providing the following
- * functionality:
- * <ul>
- * <li><code>ResourceResolverFactory</code> service
- * <li>Fires OSGi EventAdmin events on behalf of internal helper objects
- * </ul>
- *
- */
-public class ResourceResolverFactoryImpl implements ResourceResolverFactory {
-
-    private final CommonResourceResolverFactoryImpl commonFactory;
-
-    private final ServiceUserMapper serviceUserMapper;
-
-    private final Bundle usingBundle;
-
-    public ResourceResolverFactoryImpl(
-            final CommonResourceResolverFactoryImpl commonFactory,
-            final Bundle usingBundle,
-            final ServiceUserMapper serviceUserMapper) {
-        this.commonFactory = commonFactory;
-        this.serviceUserMapper = serviceUserMapper;
-        this.usingBundle = usingBundle;
-    }
-
-    // ---------- Resource Resolver Factory ------------------------------------
-
-    /**
-     * @see org.apache.sling.api.resource.ResourceResolverFactory#getServiceResourceResolver(java.util.Map)
-     */
-    public ResourceResolver getServiceResourceResolver(final Map<String, Object> passedAuthenticationInfo) throws LoginException {
-        // create a copy of the passed authentication info as we modify the map
-        final Map<String, Object> authenticationInfo = new HashMap<String, Object>();
-        final String subServiceName;
-        if ( passedAuthenticationInfo != null ) {
-            authenticationInfo.putAll(passedAuthenticationInfo);
-            authenticationInfo.remove(PASSWORD);
-            final Object info = passedAuthenticationInfo.get(SUBSERVICE);
-            subServiceName = (info instanceof String) ? (String) info : null;
-        } else {
-            subServiceName = null;
-        }
-
-        // Ensure a mapped user name: If no user is defined for a bundle
-        // acting as a service, the user may be null. We can decide whether
-        // this should yield guest access or no access at all. For now
-        // no access is granted if there is no service user defined for
-        // the bundle.
-        final String userName = this.serviceUserMapper.getServiceUserID(this.usingBundle, subServiceName);
-        if (userName == null) {
-            throw new LoginException("Cannot derive user name for bundle "
-                + this.usingBundle + " and sub service " + subServiceName);
-        }
-
-        // ensure proper user name and service bundle
-        authenticationInfo.put(ResourceResolverFactory.USER, userName);
-        authenticationInfo.put(ResourceProvider.AUTH_SERVICE_BUNDLE, this.usingBundle);
-
-        return commonFactory.getResourceResolverInternal(authenticationInfo, false);
-    }
-
-    /**
-     * @see org.apache.sling.api.resource.ResourceResolverFactory#getResourceResolver(java.util.Map)
-     */
-    public ResourceResolver getResourceResolver(
-            final Map<String, Object> authenticationInfo) throws LoginException {
-        return commonFactory.getResourceResolver(authenticationInfo);
-    }
-
-    /**
-     * @see org.apache.sling.api.resource.ResourceResolverFactory#getAdministrativeResourceResolver(java.util.Map)
-     */
-    public ResourceResolver getAdministrativeResourceResolver(
-            final Map<String, Object> authenticationInfo) throws LoginException {
-        return commonFactory.getAdministrativeResourceResolver(authenticationInfo);
-    }
-
-    /**
-     * @see org.apache.sling.api.resource.ResourceResolverFactory#getThreadResourceResolver()
-     */
-    public ResourceResolver getThreadResourceResolver() {
-        return commonFactory.getThreadResourceResolver();
-    }
-}
\ No newline at end of file
diff --git a/src/main/java/org/apache/sling/resourceresolver/impl/ResourceResolverImpl.java b/src/main/java/org/apache/sling/resourceresolver/impl/ResourceResolverImpl.java
deleted file mode 100644
index 3210a45..0000000
--- a/src/main/java/org/apache/sling/resourceresolver/impl/ResourceResolverImpl.java
+++ /dev/null
@@ -1,1382 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *   http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-package org.apache.sling.resourceresolver.impl;
-
-import static org.apache.commons.lang.StringUtils.defaultString;
-
-import java.util.Arrays;
-import java.util.Collections;
-import java.util.HashMap;
-import java.util.HashSet;
-import java.util.Iterator;
-import java.util.LinkedList;
-import java.util.Map;
-import java.util.Set;
-import java.util.StringTokenizer;
-import java.util.regex.Matcher;
-import java.util.regex.Pattern;
-
-import javax.annotation.CheckForNull;
-import javax.jcr.NamespaceException;
-import javax.jcr.RepositoryException;
-import javax.jcr.Session;
-import javax.servlet.http.HttpServletRequest;
-
-import org.apache.sling.adapter.annotations.Adaptable;
-import org.apache.sling.adapter.annotations.Adapter;
-import org.apache.sling.api.SlingException;
-import org.apache.sling.api.adapter.SlingAdaptable;
-import org.apache.sling.api.resource.LoginException;
-import org.apache.sling.api.resource.NonExistingResource;
-import org.apache.sling.api.resource.PersistenceException;
-import org.apache.sling.api.resource.Resource;
-import org.apache.sling.api.resource.ResourceNotFoundException;
-import org.apache.sling.api.resource.ResourceResolver;
-import org.apache.sling.api.resource.ResourceResolverFactory;
-import org.apache.sling.api.resource.ResourceUtil;
-import org.apache.sling.api.resource.ResourceWrapper;
-import org.apache.sling.resourceresolver.impl.helper.RedirectResource;
-import org.apache.sling.resourceresolver.impl.helper.ResourceIteratorDecorator;
-import org.apache.sling.resourceresolver.impl.helper.ResourcePathIterator;
-import org.apache.sling.resourceresolver.impl.helper.ResourceResolverContext;
-import org.apache.sling.resourceresolver.impl.helper.ResourceResolverControl;
-import org.apache.sling.resourceresolver.impl.helper.StarResource;
-import org.apache.sling.resourceresolver.impl.helper.URI;
-import org.apache.sling.resourceresolver.impl.helper.URIException;
-import org.apache.sling.resourceresolver.impl.mapping.MapEntry;
-import org.apache.sling.resourceresolver.impl.params.ParsedParameters;
-import org.apache.sling.resourceresolver.impl.providers.ResourceProviderStorageProvider;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-@Adaptable(adaptableClass = ResourceResolver.class, adapters = { @Adapter(Session.class) })
-public class ResourceResolverImpl extends SlingAdaptable implements ResourceResolver {
-
-    /** Default logger */
-    private static final Logger logger = LoggerFactory.getLogger(ResourceResolverImpl.class);
-
-    private static final Map<String, String> EMPTY_PARAMETERS = Collections.emptyMap();
-
-    private static final String MANGLE_NAMESPACE_IN_SUFFIX = "_";
-
-    private static final String MANGLE_NAMESPACE_IN_PREFIX = "/_";
-
-    private static final Pattern MANGLE_NAMESPACE_IN_PATTERN = Pattern.compile("/_([^_/]+)_");
-
-    private static final String MANGLE_NAMESPACE_OUT_SUFFIX = ":";
-
-    private static final String MANGLE_NAMESPACE_OUT_PREFIX = "/";
-
-    private static final Pattern MANLE_NAMESPACE_OUT_PATTERN = Pattern.compile("/([^:/]+):");
-
-    public static final String PROP_REDIRECT_INTERNAL = "sling:internalRedirect";
-
-    public static final String PROP_ALIAS = "sling:alias";
-
-    // The suffix of a resource being a content node of some parent
-    // such as nt:file. The slash is included to prevent false
-    // positives for the String.endsWith check for names like
-    // "xyzjcr:content"
-    private static final String JCR_CONTENT_LEAF = "/jcr:content";
-
-    /** The factory which created this resource resolver. */
-    private final CommonResourceResolverFactoryImpl factory;
-
-    /** Resource resolver control. */
-    private final ResourceResolverControl control;
-
-    /** Resource resolver context. */
-    private final ResourceResolverContext context;
-
-    private volatile Exception closedResolverException;
-
-    public ResourceResolverImpl(final CommonResourceResolverFactoryImpl factory, final boolean isAdmin, final Map<String, Object> authenticationInfo) throws LoginException {
-        this(factory, isAdmin, authenticationInfo, factory.getResourceProviderTracker());
-    }
-
-    ResourceResolverImpl(final CommonResourceResolverFactoryImpl factory, final boolean isAdmin, final Map<String, Object> authenticationInfo, final ResourceProviderStorageProvider resourceProviderTracker) throws LoginException {
-        this.factory = factory;
-        this.context = new ResourceResolverContext(this, factory.getResourceAccessSecurityTracker());
-        this.control = createControl(resourceProviderTracker, authenticationInfo, isAdmin);
-        this.factory.register(this, control);
-    }
-
-    /**
-     * Constructor for cloning the resource resolver
-     * @param resolver The resolver to clone
-     * @param authenticationInfo The auth info
-     * @throws LoginException if auth to a required provider fails
-     */
-    private ResourceResolverImpl(final ResourceResolverImpl resolver, final Map<String, Object> authenticationInfo) throws LoginException {
-        this.factory = resolver.factory;
-        Map<String, Object> authInfo = new HashMap<String, Object>();
-        if (resolver.control.getAuthenticationInfo() != null) {
-            authInfo.putAll(resolver.control.getAuthenticationInfo());
-        }
-        if (authenticationInfo != null) {
-            authInfo.putAll(authenticationInfo);
-        }
-        this.context = new ResourceResolverContext(this, factory.getResourceAccessSecurityTracker());
-        this.control = createControl(factory.getResourceProviderTracker(), authInfo, resolver.control.isAdmin());
-        this.factory.register(this, control);
-    }
-
-    /**
-     * Create the resource resolver control
-     * @param storage The provider storage
-     * @param authenticationInfo Current auth info
-     * @param isAdmin Is this admin?
-     * @return A control
-     * @throws LoginException If auth to the required providers fails.
-     */
-    private ResourceResolverControl createControl(final ResourceProviderStorageProvider resourceProviderTracker,
-            final Map<String, Object> authenticationInfo,
-            final boolean isAdmin)
-    throws LoginException {
-        final ResourceResolverControl control = new ResourceResolverControl(isAdmin, authenticationInfo, resourceProviderTracker);
-
-        this.context.getProviderManager().authenticateAll(resourceProviderTracker.getResourceProviderStorage().getAuthRequiredHandlers(), control);
-
-        return control;
-    }
-
-    /**
-     * @see org.apache.sling.api.resource.ResourceResolver#clone(Map)
-     */
-    @Override
-    public ResourceResolver clone(final Map<String, Object> authenticationInfo)
-            throws LoginException {
-        // ensure resolver is still live
-        checkClosed();
-
-        // create a regular resource resolver
-        return new ResourceResolverImpl(this, authenticationInfo);
-    }
-
-    /**
-     * @see org.apache.sling.api.resource.ResourceResolver#isLive()
-     */
-    @Override
-    public boolean isLive() {
-        return !this.control.isClosed() && this.control.isLive(this.context) && this.factory.isLive();
-    }
-
-    /**
-     * @see org.apache.sling.api.resource.ResourceResolver#close()
-     */
-    @Override
-    public void close() {
-        if (factory.shouldLogResourceResolverClosing()) {
-            closedResolverException = new Exception("Stack Trace");
-        }
-        this.factory.unregister(this, this.control);
-    }
-
-    /**
-     * Check if the resource resolver is already closed or the factory which created this resolver is no longer live.
-     *
-     * @throws IllegalStateException
-     *             If the resolver is already closed or the factory is no longer live.
-     */
-    private void checkClosed() {
-        if (this.control.isClosed()) {
-            if (closedResolverException != null) {
-                logger.error("The ResourceResolver has already been closed.", closedResolverException);
-            }
-            throw new IllegalStateException("Resource resolver is already closed.");
-        }
-        if (!this.factory.isLive()) {
-            throw new IllegalStateException("Resource resolver factory which created this resolver is no longer active.");
-        }
-    }
-
-    // ---------- attributes
-
-    /**
-     * @see org.apache.sling.api.resource.ResourceResolver#getAttributeNames()
-     */
-    @Override
-    public Iterator<String> getAttributeNames() {
-        checkClosed();
-        return this.control.getAttributeNames(this.context).iterator();
-    }
-
-    /**
-     * @see org.apache.sling.api.resource.ResourceResolver#getAttribute(String)
-     */
-    @Override
-    public Object getAttribute(final String name) {
-        checkClosed();
-        if (name == null) {
-            throw new NullPointerException("name");
-        }
-
-        return this.control.getAttribute(this.context, name);
-    }
-
-    // ---------- resolving resources
-
-    /**
-     * @see org.apache.sling.api.resource.ResourceResolver#resolve(java.lang.String)
-     */
-    @Override
-    public Resource resolve(final String path) {
-        checkClosed();
-
-        final Resource rsrc = this.resolveInternal(null, path);
-        return rsrc;
-    }
-
-    /**
-     * @see org.apache.sling.api.resource.ResourceResolver#resolve(javax.servlet.http.HttpServletRequest)
-     */
-    @SuppressWarnings("deprecation")
-    @Override
-    public Resource resolve(final HttpServletRequest request) {
-        checkClosed();
-
-        // throws NPE if request is null as required
-        final Resource rsrc = this.resolveInternal(request, request.getPathInfo());
-        return rsrc;
-    }
-
-    /**
-     * @see org.apache.sling.api.resource.ResourceResolver#resolve(javax.servlet.http.HttpServletRequest,
-     *      java.lang.String)
-     */
-    @Override
-    public Resource resolve(final HttpServletRequest request, String path) {
-        checkClosed();
-
-        final Resource rsrc = this.resolveInternal(request, path);
-        return rsrc;
-    }
-
-    private Resource resolveInternal(final HttpServletRequest request, String absPath) {
-        // make sure abspath is not null and is absolute
-        if (absPath == null) {
-            absPath = "/";
-        } else if (!absPath.startsWith("/")) {
-            absPath = "/" + absPath;
-        }
-
-        // check for special namespace prefix treatment
-        absPath = unmangleNamespaces(absPath);
-
-        // Assume http://localhost:80 if request is null
-        String[] realPathList = { absPath };
-        String requestPath;
-        if (request != null) {
-            requestPath = getMapPath(request.getScheme(), request.getServerName(), request.getServerPort(), absPath);
-        } else {
-            requestPath = getMapPath("http", "localhost", 80, absPath);
-        }
-
-        logger.debug("resolve: Resolving request path {}", requestPath);
-
-        // loop while finding internal or external redirect into the
-        // content out of the virtual host mapping tree
-        // the counter is to ensure we are not caught in an endless loop here
-        // TODO: might do better to be able to log the loop and help the user
-        for (int i = 0; i < 100; i++) {
-
-            String[] mappedPath = null;
-
-            final Iterator<MapEntry> mapEntriesIterator = this.factory.getMapEntries().getResolveMapsIterator(requestPath);
-            while (mapEntriesIterator.hasNext()) {
-                final MapEntry mapEntry = mapEntriesIterator.next();
-                mappedPath = mapEntry.replace(requestPath);
-                if (mappedPath != null) {
-                    if (logger.isDebugEnabled()) {
-                        logger.debug("resolve: MapEntry {} matches, mapped path is {}", mapEntry, Arrays.toString(mappedPath));
-                    }
-                    if (mapEntry.isInternal()) {
-                        // internal redirect
-                        logger.debug("resolve: Redirecting internally");
-                        break;
-                    }
-
-                    // external redirect
-                    logger.debug("resolve: Returning external redirect");
-                    return this.factory.getResourceDecoratorTracker().decorate(
-                            new RedirectResource(this, absPath, mappedPath[0], mapEntry.getStatus()));
-                }
-            }
-
-            // if there is no virtual host based path mapping, abort
-            // and use the original realPath
-            if (mappedPath == null) {
-                logger.debug("resolve: Request path {} does not match any MapEntry", requestPath);
-                break;
-            }
-
-            // if the mapped path is not an URL, use this path to continue
-            if (!mappedPath[0].contains("://")) {
-                logger.debug("resolve: Mapped path is for resource tree");
-                realPathList = mappedPath;
-                break;
-            }
-
-            // otherwise the mapped path is an URI and we have to try to
-            // resolve that URI now, using the URI's path as the real path
-            try {
-                final URI uri = new URI(mappedPath[0], false);
-                requestPath = getMapPath(uri.getScheme(), uri.getHost(), uri.getPort(), uri.getPath());
-                realPathList = new String[] { uri.getPath() };
-
-                logger.debug("resolve: Mapped path is an URL, using new request path {}", requestPath);
-            } catch (final URIException use) {
-                // TODO: log and fail
-                throw new ResourceNotFoundException(absPath);
-            }
-        }
-
-        // now we have the real path resolved from virtual host mapping
-        // this path may be absolute or relative, in which case we try
-        // to resolve it against the search path
-
-        Resource res = null;
-        for (int i = 0; res == null && i < realPathList.length; i++) {
-            final ParsedParameters parsedPath = new ParsedParameters(realPathList[i]);
-            final String realPath = parsedPath.getRawPath();
-
-
-            // first check whether the requested resource is a StarResource
-            if (StarResource.appliesTo(realPath)) {
-                logger.debug("resolve: Mapped path {} is a Star Resource", realPath);
-                res = new StarResource(this, ensureAbsPath(realPath));
-
-            } else {
-
-                if (realPath.startsWith("/")) {
-
-                    // let's check it with a direct access first
-                    logger.debug("resolve: Try absolute mapped path {}", realPath);
-                    res = resolveInternal(realPath, parsedPath.getParameters());
-
-                } else {
-
-                    final String[] searchPath = getSearchPath();
-                    for (int spi = 0; res == null && spi < searchPath.length; spi++) {
-                        logger.debug("resolve: Try relative mapped path with search path entry {}", searchPath[spi]);
-                        res = resolveInternal(searchPath[spi] + realPath, parsedPath.getParameters());
-                    }
-
-                }
-            }
-        }
-
-        // if no resource has been found, use a NonExistingResource
-        if (res == null) {
-            final ParsedParameters parsedPath = new ParsedParameters(realPathList[0]);
-            final String resourcePath = ensureAbsPath(parsedPath.getRawPath());
-            logger.debug("resolve: Path {} does not resolve, returning NonExistingResource at {}", absPath, resourcePath);
-
-            res = new NonExistingResource(this, resourcePath);
-            // SLING-864: if the path contains a dot we assume this to be
-            // the start for any selectors, extension, suffix, which may be
-            // used for further request processing.
-            // the resolution path must be the full path and is already set within
-            // the non existing resource
-            final int index = resourcePath.indexOf('.');
-            if (index != -1) {
-                res.getResourceMetadata().setResolutionPathInfo(resourcePath.substring(index));
-            }
-            res.getResourceMetadata().setParameterMap(parsedPath.getParameters());
-        } else {
-            logger.debug("resolve: Path {} resolves to Resource {}", absPath, res);
-        }
-
-        return this.factory.getResourceDecoratorTracker().decorate(res);
-    }
-
-    /**
-     * calls map(HttpServletRequest, String) as map(null, resourcePath)
-     *
-     * @see org.apache.sling.api.resource.ResourceResolver#map(java.lang.String)
-     */
-    @Override
-    public String map(final String resourcePath) {
-        checkClosed();
-        return map(null, resourcePath);
-    }
-
-    /**
-     * full implementation - apply sling:alias from the resource path - apply
-     * /etc/map mappings (inkl. config backwards compat) - return absolute uri
-     * if possible
-     *
-     * @see org.apache.sling.api.resource.ResourceResolver#map(javax.servlet.http.HttpServletRequest,
-     *      java.lang.String)
-     */
-    @Override
-    public String map(final HttpServletRequest request, final String resourcePath) {
-        checkClosed();
-
-        // find a fragment or query
-        int fragmentQueryMark = resourcePath.indexOf('#');
-        if (fragmentQueryMark < 0) {
-            fragmentQueryMark = resourcePath.indexOf('?');
-        }
-
-        // cut fragment or query off the resource path
-        String mappedPath;
-        final String fragmentQuery;
-        if (fragmentQueryMark >= 0) {
-            fragmentQuery = resourcePath.substring(fragmentQueryMark);
-            mappedPath = resourcePath.substring(0, fragmentQueryMark);
-            logger.debug("map: Splitting resource path '{}' into '{}' and '{}'", new Object[] { resourcePath, mappedPath,
-                    fragmentQuery });
-        } else {
-            fragmentQuery = null;
-            mappedPath = resourcePath;
-        }
-
-        // cut off scheme and host, if the same as requested
-        final String schemehostport;
-        final String schemePrefix;
-        if (request != null) {
-            schemehostport = MapEntry.getURI(request.getScheme(), request.getServerName(), request.getServerPort(), "/");
-            schemePrefix = request.getScheme().concat("://");
-            logger.debug("map: Mapping path {} for {} (at least with scheme prefix {})", new Object[] { resourcePath,
-                    schemehostport, schemePrefix });
-
-        } else {
-
-            schemehostport = null;
-            schemePrefix = null;
-            logger.debug("map: Mapping path {} for default", resourcePath);
-
-        }
-
-        ParsedParameters parsed = new ParsedParameters(mappedPath);
-        final Resource res = resolveInternal(parsed.getRawPath(), parsed.getParameters());
-
-        if (res != null) {
-
-            // keep, what we might have cut off in internal resolution
-            final String resolutionPathInfo = res.getResourceMetadata().getResolutionPathInfo();
-
-            logger.debug("map: Path maps to resource {} with path info {}", res, resolutionPathInfo);
-
-            // find aliases for segments. we can't walk the parent chain
-            // since the request session might not have permissions to
-            // read all parents SLING-2093
-            final LinkedList<String> names = new LinkedList<String>();
-
-            Resource current = res;
-            String path = res.getPath();
-            while (path != null) {
-                String alias = null;
-                if (current != null && !path.endsWith(JCR_CONTENT_LEAF)) {
-                    if (factory.getMapEntries().isOptimizeAliasResolutionEnabled()) {
-                        logger.debug("map: Optimize Alias Resolution is Enabled");
-                        String parentPath = ResourceUtil.getParent(path);
-                        if (parentPath != null) {
-                            final Map<String, String> aliases = factory.getMapEntries().getAliasMap(parentPath);
-                            if (aliases!= null && aliases.containsValue(current.getName())) {
-                                for (String key:aliases.keySet()) {
-                                    if (current.getName().equals(aliases.get(key))) {
-                                        alias = key;
-                                        break;
-                                    }
-                                }
-                            }
-                        }
-                    } else {
-                        logger.debug("map: Optimize Alias Resolution is Disabled");
-                        alias = ResourceResolverControl.getProperty(current, PROP_ALIAS);
-                    }
-                }
-                if (alias == null || alias.length() == 0) {
-                    alias = ResourceUtil.getName(path);
-                }
-                names.add(alias);
-                path = ResourceUtil.getParent(path);
-                if ("/".equals(path)) {
-                    path = null;
-                } else if (path != null) {
-                    current = res.getResourceResolver().resolve(path);
-                }
-            }
-
-            // build path from segment names
-            final StringBuilder buf = new StringBuilder();
-
-            // construct the path from the segments (or root if none)
-            if (names.isEmpty()) {
-                buf.append('/');
-            } else {
-                while (!names.isEmpty()) {
-                    buf.append('/');
-                    buf.append(names.removeLast());
-                }
-            }
-
-            // reappend the resolutionPathInfo
-            if (resolutionPathInfo != null) {
-                buf.append(resolutionPathInfo);
-            }
-
-            // and then we have the mapped path to work on
-            mappedPath = buf.toString();
-
-            logger.debug("map: Alias mapping resolves to path {}", mappedPath);
-
-        }
-
-        boolean mappedPathIsUrl = false;
-        for (final MapEntry mapEntry : this.factory.getMapEntries().getMapMaps()) {
-            final String[] mappedPaths = mapEntry.replace(mappedPath);
-            if (mappedPaths != null) {
-
-                logger.debug("map: Match for Entry {}", mapEntry);
-
-                mappedPathIsUrl = !mapEntry.isInternal();
-
-                if (mappedPathIsUrl && schemehostport != null) {
-
-                    mappedPath = null;
-
-                    for (final String candidate : mappedPaths) {
-                        if (candidate.startsWith(schemehostport)) {
-                            mappedPath = candidate.substring(schemehostport.length() - 1);
-                            mappedPathIsUrl = false;
-                            logger.debug("map: Found host specific mapping {} resolving to {}", candidate, mappedPath);
-                            break;
-                        } else if (candidate.startsWith(schemePrefix) && mappedPath == null) {
-                            mappedPath = candidate;
-                        }
-                    }
-
-                    if (mappedPath == null) {
-                        mappedPath = mappedPaths[0];
-                    }
-
-                } else {
-
-                    // we can only go with assumptions selecting the first entry
-                    mappedPath = mappedPaths[0];
-
-                }
-
-                logger.debug("resolve: MapEntry {} matches, mapped path is {}", mapEntry, mappedPath);
-
-                break;
-            }
-        }
-
-        // this should not be the case, since mappedPath is primed
-        if (mappedPath == null) {
-            mappedPath = resourcePath;
-        }
-
-        // [scheme:][//authority][path][?query][#fragment]
-        try {
-            // use commons-httpclient's URI instead of java.net.URI, as it can
-            // actually accept *unescaped* URIs, such as the "mappedPath" and
-            // return them in proper escaped form, including the path, via
-            // toString()
-            final URI uri = new URI(mappedPath, false);
-
-            // 1. mangle the namespaces in the path
-            String path = mangleNamespaces(uri.getPath());
-
-            // 2. prepend servlet context path if we have a request
-            if (request != null && request.getContextPath() != null && request.getContextPath().length() > 0) {
-                path = request.getContextPath().concat(path);
-            }
-            // update the path part of the URI
-            uri.setPath(path);
-
-            mappedPath = uri.toString();
-        } catch (final URIException e) {
-            logger.warn("map: Unable to mangle namespaces for " + mappedPath + " returning unmangled", e);
-        }
-
-        logger.debug("map: Returning URL {} as mapping for path {}", mappedPath, resourcePath);
-
-        // reappend fragment and/or query
-        if (fragmentQuery != null) {
-            mappedPath = mappedPath.concat(fragmentQuery);
-        }
-
-        return mappedPath;
-    }
-
-    // ---------- search path for relative resoures
-
-    /**
-     * @see org.apache.sling.api.resource.ResourceResolver#getSearchPath()
-     */
-    @Override
-    public String[] getSearchPath() {
-        checkClosed();
-        return factory.getSearchPath().clone();
-    }
-
-    // ---------- direct resource access without resolution
-
-    /**
-     * @see org.apache.sling.api.resource.ResourceResolver#getResource(java.lang.String)
-     */
-    @Override
-    public Resource getResource(String path) {
-        checkClosed();
-        final Resource result = this.getResourceInternal(null, path);
-        return result;
-    }
-
-    /**
-     * @see org.apache.sling.api.resource.ResourceResolver#getResource(org.apache.sling.api.resource.Resource,
-     *      java.lang.String)
-     */
-    @Override
-    public Resource getResource(final Resource base, final String path) {
-        checkClosed();
-
-        String absolutePath = path;
-        if (absolutePath != null && !absolutePath.startsWith("/") && base != null && base.getPath() != null ) {
-            absolutePath = appendToPath(base.getPath(), absolutePath);
-        }
-
-        final Resource result = getResourceInternal(base, absolutePath);
-        return result;
-    }
-
-    /**
-     * Methods concatenates two paths. If the first path contains parameters separated semicolon, they are
-     * moved at the end of the result.
-     *
-     * @param pathWithParameters
-     * @param segmentToAppend
-     * @return
-     */
-    private static String appendToPath(final String pathWithParameters, final String segmentToAppend) {
-        final ParsedParameters parsed = new ParsedParameters(pathWithParameters);
-        if (parsed.getParametersString() == null) {
-            return new StringBuilder(parsed.getRawPath()).append('/').append(segmentToAppend).toString();
-        } else {
-            return new StringBuilder(parsed.getRawPath()).append('/').append(segmentToAppend).append(parsed.getParametersString()).toString();
-        }
-    }
-
-    private Resource getResourceInternal(Resource parent, String path) {
-
-        Resource result = null;
-        if ( path != null ) {
-            // if the path is absolute, normalize . and .. segments and get res
-            if (path.startsWith("/")) {
-                ParsedParameters parsedPath = new ParsedParameters(path);
-                path = ResourceUtil.normalize(parsedPath.getRawPath());
-                result = (path != null) ? getAbsoluteResourceInternal(parent, path, parsedPath.getParameters(), false) : null;
-                if (result != null) {
-                    result = this.factory.getResourceDecoratorTracker().decorate(result);
-                }
-            } else {
-
-                // otherwise we have to apply the search path
-                // (don't use this.getSearchPath() to save a few cycle for not cloning)
-                final String[] paths = factory.getSearchPath();
-                if (paths != null) {
-                    for (final String prefix : factory.getSearchPath()) {
-                        result = getResource(prefix + path);
-                        if (result != null) {
-                            break;
-                        }
-                    }
-                }
-            }
-        }
-
-        return result;
-    }
-
-    /**
-     * @see org.apache.sling.api.resource.ResourceResolver#listChildren(org.apache.sling.api.resource.Resource)
-     */
-    @Override
-    public Iterator<Resource> listChildren(final Resource parent) {
-        checkClosed();
-
-        if (parent instanceof ResourceWrapper) {
-            return listChildren(((ResourceWrapper) parent).getResource());
-        }
-        return new ResourceIteratorDecorator(this.factory.getResourceDecoratorTracker(), this.control.listChildren(this.context, parent));
-    }
-
-    /**
-     * @see org.apache.sling.api.resource.Resource#getChildren()
-     */
-    @Override
-    public Iterable<Resource> getChildren(final Resource parent) {
-        return new Iterable<Resource>() {
-
-            @Override
-            public Iterator<Resource> iterator() {
-                return listChildren(parent);
-            }
-        };
-    }
-
-    // ---------- Querying resources
-
-    private static final String DEFAULT_QUERY_LANGUAGE = "xpath";
-
-    /**
-     * @see org.apache.sling.api.resource.ResourceResolver#findResources(java.lang.String,
-     *      java.lang.String)
-     */
-    @Override
-    public Iterator<Resource> findResources(final String query, final String language) throws SlingException {
-        checkClosed();
-
-        return new ResourceIteratorDecorator(this.factory.getResourceDecoratorTracker(),
-                control.findResources(this.context, query, defaultString(language, DEFAULT_QUERY_LANGUAGE)));
-    }
-
-    /**
-     * @see org.apache.sling.api.resource.ResourceResolver#queryResources(java.lang.String,
-     *      java.lang.String)
-     */
-    @Override
-    public Iterator<Map<String, Object>> queryResources(final String query, final String language)
-            throws SlingException {
-        checkClosed();
-
-        return control.queryResources(this.context, query, defaultString(language, DEFAULT_QUERY_LANGUAGE));
-    }
-
-    /**
-     * @see org.apache.sling.api.resource.ResourceResolver#getUserID()
-     */
-    @Override
-    public String getUserID() {
-        checkClosed();
-
-        // Try auth info first
-        if ( this.control.getAuthenticationInfo() != null ) {
-            final Object impUser = this.control.getAuthenticationInfo().get(ResourceResolverFactory.USER_IMPERSONATION);
-            if ( impUser != null ) {
-                return impUser.toString();
-            }
-            final Object user = this.control.getAuthenticationInfo().get(ResourceResolverFactory.USER);
-            if ( user != null ) {
-                return user.toString();
-            }
-        }
-        // Try session
-        final Session session = this.getSession();
-        if ( session != null ) {
-            return session.getUserID();
-        }
-        // Try attributes
-        final Object impUser = this.getAttribute(ResourceResolverFactory.USER_IMPERSONATION);
-        if ( impUser != null ) {
-            return impUser.toString();
-        }
-        final Object user = this.getAttribute(ResourceResolverFactory.USER);
-        if ( user != null ) {
-            return user.toString();
-        }
-
-        return null;
-    }
-
-    /** Cached session object, fetched on demand. */
-    private Session cachedSession;
-    /** Flag indicating if a searching has already been searched. */
-    private boolean searchedSession = false;
-
-    /**
-     * Try to get a session from one of the resource providers.
-     */
-    private Session getSession() {
-        if ( !this.searchedSession ) {
-            this.searchedSession = true;
-            this.cachedSession = this.control.adaptTo(this.context, Session.class);
-        }
-        return this.cachedSession;
-    }
-
-    // ---------- Adaptable interface
-
-    /**
-     * @see org.apache.sling.api.adapter.SlingAdaptable#adaptTo(java.lang.Class)
-     */
-    @Override
-    @SuppressWarnings("unchecked")
-    public <AdapterType> AdapterType adaptTo(final Class<AdapterType> type) {
-        checkClosed();
-
-        if (type == Session.class) {
-            return (AdapterType) getSession();
-        }
-        final AdapterType result = this.control.adaptTo(this.context, type);
-        if ( result != null ) {
-            return result;
-        }
-
-        // fall back to default behaviour
-        return super.adaptTo(type);
-    }
-
-    // ---------- internal
-
-    /**
-     * Returns a string used for matching map entries against the given request
-     * or URI parts.
-     *
-     * @param scheme
-     *            The URI scheme
-     * @param host
-     *            The host name
-     * @param port
-     *            The port number. If this is negative, the default value used
-     *            is 80 unless the scheme is "https" in which case the default
-     *            value is 443.
-     * @param path
-     *            The (absolute) path
-     * @return The request path string {scheme}/{host}.{port}{path}.
-     */
-    private static String getMapPath(final String scheme, final String host, int port, final String path) {
-        if (port < 0) {
-            port = ("https".equals(scheme)) ? 443 : 80;
-        }
-
-        return scheme + "/" + host + "." + port + path;
-    }
-
-    /**
-     * Internally resolves the absolute path. The will almost always contain
-     * request selectors and an extension. Therefore this method uses the
-     * {@link ResourcePathIterator} to cut off parts of the path to find the
-     * actual resource.
-     * <p>
-     * This method operates in two steps:
-     * <ol>
-     * <li>Check the path directly
-     * <li>Drill down the resource tree from the root down to the resource trying to get the child
-     * as per the respective path segment or finding a child whose <code>sling:alias</code> property
-     * is set to the respective name.
-     * </ol>
-     * <p>
-     * If neither mechanism (direct access and drill down) resolves to a resource this method
-     * returns <code>null</code>.
-     *
-     * @param absPath
-     *            The absolute path of the resource to return.
-     * @return The resource found or <code>null</code> if the resource could not
-     *         be found. The
-     *         {@link org.apache.sling.api.resource.ResourceMetadata#getResolutionPathInfo()
-     *         resolution path info} field of the resource returned is set to
-     *         the part of the <code>absPath</code> which has been cut off by
-     *         the {@link ResourcePathIterator} to resolve the resource.
-     */
-    private Resource resolveInternal(final String absPath, final Map<String, String> parameters) {
-        Resource resource = null;
-        String curPath = absPath;
-        try {
-            final ResourcePathIterator it = new ResourcePathIterator(absPath);
-            while (it.hasNext() && resource == null) {
-                curPath = it.next();
-                resource = getAbsoluteResourceInternal(null, curPath, parameters, true);
-            }
-        } catch (final Exception ex) {
-            throw new SlingException("Problem trying " + curPath + " for request path " + absPath, ex);
-        }
-
-        // SLING-627: set the part cut off from the uriPath as
-        // sling.resolutionPathInfo property such that
-        // uriPath = curPath + sling.resolutionPathInfo
-        if (resource != null) {
-
-            final String rpi = absPath.substring(curPath.length());
-            resource.getResourceMetadata().setResolutionPath(absPath.substring(0, curPath.length()));
-            resource.getResourceMetadata().setResolutionPathInfo(rpi);
-            resource.getResourceMetadata().setParameterMap(parameters);
-
-            logger.debug("resolveInternal: Found resource {} with path info {} for {}", new Object[] { resource, rpi, absPath });
-
-        } else {
-
-            String tokenizedPath = absPath;
-            
-            // no direct resource found, so we have to drill down into the
-            // resource tree to find a match
-            resource = getAbsoluteResourceInternal(null, "/", parameters, true);
-            
-            //no read access on / drilling further down
-            //SLING-5638
-            if (resource == null) {
-                resource = getAbsoluteResourceInternal(absPath, parameters, true);
-                if (resource != null) {
-                    tokenizedPath = tokenizedPath.substring(resource.getPath().length());
-                }
-            }
-            
-            final StringBuilder resolutionPath = new StringBuilder();
-            final StringTokenizer tokener = new StringTokenizer(tokenizedPath, "/");
-            while (resource != null && tokener.hasMoreTokens()) {
-                final String childNameRaw = tokener.nextToken();
-
-                Resource nextResource = getChildInternal(resource, childNameRaw);
-                if (nextResource != null) {
-
-                    resource = nextResource;
-                    resolutionPath.append("/").append(childNameRaw);
-                    
-                } else {
-
-                    String childName = null;
-                    final ResourcePathIterator rpi = new ResourcePathIterator(childNameRaw);
-                    while (rpi.hasNext() && nextResource == null) {
-                        childName = rpi.next();
-                        nextResource = getChildInternal(resource, childName);
-                    }
-
-                    // switch the currentResource to the nextResource (may be
-                    // null)
-                    resource = nextResource;
-                    resolutionPath.append("/").append(childName);
-
-                    // terminate the search if a resource has been found
-                    // with the extension cut off
-                    if (nextResource != null) {
-                        break;
-                    }
-                }
-            }
-
-            // SLING-627: set the part cut off from the uriPath as
-            // sling.resolutionPathInfo property such that
-            // uriPath = curPath + sling.resolutionPathInfo
-            if (resource != null) {
-                final String path = resolutionPath.toString();
-                final String pathInfo = absPath.substring(path.length());
-
-                resource.getResourceMetadata().setResolutionPath(path);
-                resource.getResourceMetadata().setResolutionPathInfo(pathInfo);
-                resource.getResourceMetadata().setParameterMap(parameters);
-
-                logger.debug("resolveInternal: Found resource {} with path info {} for {}", new Object[] { resource, pathInfo,
-                        absPath });
-            }
-        }
-
-        return resource;
-    }
-
-    private Resource getChildInternal(final Resource parent, final String childName) {
-        final String path;
-        if ( childName.startsWith("/") ) {
-            path = childName;
-        } else {
-            path = parent.getPath() + '/' + childName;
-        }
-        Resource child = getAbsoluteResourceInternal(parent, ResourceUtil.normalize(path), EMPTY_PARAMETERS, true );
-        if (child != null) {
-            final String alias = ResourceResolverControl.getProperty(child, PROP_REDIRECT_INTERNAL);
-            if (alias != null) {
-                // TODO: might be a redirect ??
-                logger.warn("getChildInternal: Internal redirect to {} for Resource {} is not supported yet, ignoring", alias,
-                        child);
-            }
-
-            // we have the resource name, continue with the next level
-            return child;
-        }
-
-        // we do not have a child with the exact name, so we look for
-        // a child, whose alias matches the childName
-        if (factory.getMapEntries().isOptimizeAliasResolutionEnabled()){
-            logger.debug("getChildInternal: Optimize Alias Resolution is Enabled");
-            //optimization made in SLING-2521
-            final Map<String, String> aliases = factory.getMapEntries().getAliasMap(parent.getPath());
-            if (aliases != null) {
-                final String aliasName = aliases.get(childName);
-                if (aliasName != null ) {
-                    final String aliasPath;
-                    if ( aliasName.startsWith("/") ) {
-                        aliasPath = aliasName;
-                    } else {
-                        aliasPath = parent.getPath() + '/' + aliasName;
-                    }
-                    final Resource aliasedChild = getAbsoluteResourceInternal(parent, ResourceUtil.normalize(aliasPath), EMPTY_PARAMETERS, true );
-                    logger.debug("getChildInternal: Found Resource {} with alias {} to use", aliasedChild, childName);
-                    return aliasedChild;
-                }
-            }
-        } else {
-            logger.debug("getChildInternal: Optimize Alias Resolution is Disabled");
-            final Iterator<Resource> children = listChildren(parent);
-            while (children.hasNext()) {
-                child = children.next();
-                if (!child.getPath().endsWith(JCR_CONTENT_LEAF)) {
-                    final String[] aliases = ResourceResolverControl.getProperty(child, PROP_ALIAS, String[].class);
-                    if (aliases != null) {
-                        for (final String alias : aliases) {
-                            if (childName.equals(alias)) {
-                                logger.debug("getChildInternal: Found Resource {} with alias {} to use", child, childName);
-                                final Resource aliasedChild = getAbsoluteResourceInternal(parent, ResourceUtil.normalize(child.getPath()) , EMPTY_PARAMETERS, true);
-                                return aliasedChild;
-                            }
-                        }
-                    }
-                }
-            }
-        }
-
-        // no match for the childName found
-        logger.debug("getChildInternal: Resource {} has no child {}", parent, childName);
-        return null;
-    }
-
-    /**
-     * Creates a resource with the given path if existing
-     */
-    private Resource getAbsoluteResourceInternal(@CheckForNull final Resource parent, @CheckForNull final String path, final Map<String, String> parameters, final boolean isResolve) {
-        if (path == null || path.length() == 0 || path.charAt(0) != '/') {
-            logger.debug("getResourceInternal: Path must be absolute {}", path);
-            return null; // path must be absolute
-        }
-
-        final Resource parentToUse;
-        if (parent != null && path.startsWith(parent.getPath())) {
-            parentToUse = parent;
-        } else {
-            parentToUse = null;
-        }
-
-        final Resource resource = this.control.getResource(this.context, path, parentToUse, parameters, isResolve);
-        if (resource != null) {
-            resource.getResourceMetadata().setResolutionPath(path);
-            resource.getResourceMetadata().setParameterMap(parameters);
-            return resource;
-        }
-
-        logger.debug("getResourceInternal: Cannot resolve path '{}' to a resource", path);
-        return null;
-    }
-    
-    /**
-     * Creates a resource, traversing bottom up, to the highest readable resource.
-     * 
-     */
-    private Resource getAbsoluteResourceInternal(String absPath, final Map<String, String> parameters, final boolean isResolved) {
-         
-        if (!absPath.contains("/") || "/".equals(absPath)) {
-            return null;
-        }
-        
-        absPath = absPath.substring(absPath.indexOf("/"));
-        Resource resource = getAbsoluteResourceInternal(null, absPath, parameters, isResolved);
-        
-        absPath = absPath.substring(0, absPath.lastIndexOf("/"));
-
-        while (!absPath.equals("")) {
-            Resource r = getAbsoluteResourceInternal(null, absPath, parameters, true);
-            
-            if (r != null) {
-                resource = r;
-            }            
-            absPath = absPath.substring(0, absPath.lastIndexOf("/"));
-        }        
-        return resource;
-    }
-
-    /**
-     * Returns the <code>path</code> as an absolute path. If the path is already
-     * absolute it is returned unmodified (the same instance actually). If the
-     * path is relative it is made absolute by prepending the first entry of the
-     * {@link #getSearchPath() search path}.
-     *
-     * @param path
-     *            The path to ensure absolute
-     * @return The absolute path as explained above
-     */
-    private String ensureAbsPath(String path) {
-        if (!path.startsWith("/")) {
-            path = getSearchPath()[0] + path;
-        }
-        return path;
-    }
-
-    private String mangleNamespaces(String absPath) {
-        if (factory.isMangleNamespacePrefixes() && absPath != null && absPath.contains(MANGLE_NAMESPACE_OUT_SUFFIX)) {
-            final Matcher m = MANLE_NAMESPACE_OUT_PATTERN.matcher(absPath);
-
-            final StringBuffer buf = new StringBuffer();
-            while (m.find()) {
-                final String namespace = m.group(1);
-                try {
-
-                    // throws if "namespace" is not a registered
-                    // namespace prefix
-                    final Session session = getSession();
-                    if ( session != null ) {
-                        session.getNamespaceURI(namespace);
-                        final String replacement = MANGLE_NAMESPACE_IN_PREFIX + namespace + MANGLE_NAMESPACE_IN_SUFFIX;
-                        m.appendReplacement(buf, replacement);
-                    } else {
-                        logger.debug("mangleNamespaces: '{}' is not a prefix, not mangling", namespace);
-                    }
-
-
-                } catch (final NamespaceException ne) {
-
-                    // not a valid prefix
-                    logger.debug("mangleNamespaces: '{}' is not a prefix, not mangling", namespace);
-
-                } catch (final RepositoryException re) {
-
-                    logger.warn("mangleNamespaces: Problem checking namespace '{}'", namespace, re);
-
-                }
-            }
-
-            m.appendTail(buf);
-
-            absPath = buf.toString();
-        }
-
-        return absPath;
-    }
-
-    private String unmangleNamespaces(String absPath) {
-        if (factory.isMangleNamespacePrefixes() && absPath.contains(MANGLE_NAMESPACE_IN_PREFIX)) {
-            final Matcher m = MANGLE_NAMESPACE_IN_PATTERN.matcher(absPath);
-            final StringBuffer buf = new StringBuffer();
-            while (m.find()) {
-                final String namespace = m.group(1);
-                try {
-
-                    // throws if "namespace" is not a registered
-                    // namespace prefix
-                    final Session session = getSession();
-                    if ( session != null ) {
-                        session.getNamespaceURI(namespace);
-                        final String replacement = MANGLE_NAMESPACE_OUT_PREFIX + namespace + MANGLE_NAMESPACE_OUT_SUFFIX;
-                        m.appendReplacement(buf, replacement);
-                    } else {
-                        logger.debug("unmangleNamespaces: '{}' is not a prefix, not unmangling", namespace);
-                    }
-
-
-                } catch (final NamespaceException ne) {
-
-                    // not a valid prefix
-                    logger.debug("unmangleNamespaces: '{}' is not a prefix, not unmangling", namespace);
-
-                } catch (final RepositoryException re) {
-
-                    logger.warn("unmangleNamespaces: Problem checking namespace '{}'", namespace, re);
-
-                }
-            }
-            m.appendTail(buf);
-            absPath = buf.toString();
-        }
-
-        return absPath;
-    }
-
-    /**
-     * @see org.apache.sling.api.resource.ResourceResolver#delete(org.apache.sling.api.resource.Resource)
-     */
-    @Override
-    public void delete(final Resource resource)
-            throws PersistenceException {
-        // check if the resource is non existing - throws NPE if resource is null as stated in the API
-        if ( ResourceUtil.isNonExistingResource(resource) ) {
-            // nothing to do
-            return;
-        }
-        // if resource is null, we get an NPE as stated in the API
-        this.control.delete(this.context, resource);
-    }
-
-    /**
-     * @see org.apache.sling.api.resource.ResourceResolver#create(org.apache.sling.api.resource.Resource, java.lang.String, Map)
-     */
-    @Override
-    public Resource create(final Resource parent, final String name, final Map<String, Object> properties)
-            throws PersistenceException {
-        // if parent or name is null, we get an NPE as stated in the API
-        if ( name == null ) {
-            throw new NullPointerException("name");
-        }
-        // name should be a name not a path
-        if ( name.indexOf("/") != -1 ) {
-            throw new IllegalArgumentException("Name should not contain a slash: " + name);
-        }
-        final String path;
-        if ( parent.getPath().equals("/") ) {
-            path = parent.getPath() + name;
-        } else {
-            path = parent.getPath() + "/" + name;
-        }
-        // experimental code for handling synthetic resources
-        if ( ResourceUtil.isSyntheticResource(parent) ) {
-            Resource grandParent = parent.getParent();
-            if (grandParent != null) {
-                this.create(grandParent, parent.getName(), null);
-            } else {
-                throw new IllegalArgumentException("Can't create child on a synthetic root");
-            }
-        }
-        final Resource rsrc = this.control.create(this.context, path, properties);
-        rsrc.getResourceMetadata().setResolutionPath(rsrc.getPath());
-        return this.factory.getResourceDecoratorTracker().decorate(rsrc);
-    }
-
-    /**
-     * @see org.apache.sling.api.resource.ResourceResolver#revert()
-     */
-    @Override
-    public void revert() {
-        this.control.revert(this.context);
-    }
-
-    /**
-     * @see org.apache.sling.api.resource.ResourceResolver#commit()
-     */
-    @Override
-    public void commit() throws PersistenceException {
-        this.control.commit(this.context);
-    }
-
-    /**
-     * @see org.apache.sling.api.resource.ResourceResolver#hasChanges()
-     */
-    @Override
-    public boolean hasChanges() {
-        return this.control.hasChanges(this.context);
-    }
-
-    /**
-     * @see org.apache.sling.api.resource.ResourceResolver#hasChildren()
-     */
-	@Override
-    public boolean hasChildren(Resource resource) {
-		return listChildren(resource).hasNext();
-	}
-
-    /**
-     * @see org.apache.sling.api.resource.ResourceResolver#getParentResourceType(org.apache.sling.api.resource.Resource)
-     */
-    @Override
-    public String getParentResourceType(final Resource resource) {
-        String resourceSuperType = null;
-        if ( resource != null ) {
-            resourceSuperType = resource.getResourceSuperType();
-            if (resourceSuperType == null) {
-                resourceSuperType = this.getParentResourceType(resource.getResourceType());
-            }
-        }
-        return resourceSuperType;
-    }
-
-    /**
-     * @see org.apache.sling.api.resource.ResourceResolver#getParentResourceType(java.lang.String)
-     */
-    @Override
-    public String getParentResourceType(final String resourceType) {
-        return this.control.getParentResourceType(this.factory, this, resourceType);
-    }
-
-    /**
-     * @see org.apache.sling.api.resource.ResourceResolver#isResourceType(org.apache.sling.api.resource.Resource, java.lang.String)
-     */
-    @Override
-    public boolean isResourceType(final Resource resource, final String resourceType) {
-        boolean result = false;
-        if ( resource != null && resourceType != null ) {
-             // Check if the resource is of the given type. This method first checks the
-             // resource type of the resource, then its super resource type and continues
-             //  to go up the resource super type hierarchy.
-             if (resourceType.equals(resource.getResourceType())) {
-                 result = true;
-             } else {
-                 Set<String> superTypesChecked = new HashSet<String>();
-                 String superType = this.getParentResourceType(resource);
-                 while (!result && superType != null) {
-                     if (resourceType.equals(superType)) {
-                         result = true;
-                     } else {
-                         superTypesChecked.add(superType);
-                         superType = this.getParentResourceType(superType);
-                         if (superType != null && superTypesChecked.contains(superType)) {
-                             throw new SlingException("Cyclic dependency for resourceSuperType hierarchy detected on resource " + resource.getPath(), null);
-                         }
-                     }
-                 }
-             }
-
-        }
-        return result;
-    }
-
-    /**
-     * @see org.apache.sling.api.resource.ResourceResolver#refresh()
-     */
-    @Override
-    public void refresh() {
-        this.control.refresh(this.context);
-    }
-
-    @Override
-    public Resource getParent(final Resource child) {
-        Resource rsrc = null;
-        final String parentPath = ResourceUtil.getParent(child.getPath());
-        if ( parentPath != null ) {
-            // if the parent path is relative, resolve using search paths.
-            if ( !parentPath.startsWith("/") ) {
-                rsrc = context.getResourceResolver().getResource(parentPath);
-            } else {
-                rsrc = this.control.getParent(this.context, parentPath, child);
-                if (rsrc != null ) {
-                    rsrc.getResourceMetadata().setResolutionPath(rsrc.getPath());
-                    rsrc = this.factory.getResourceDecoratorTracker().decorate(rsrc);
-                }
-            }
-        }
-        return rsrc;
-    }
-
-    @Override
-    public Resource copy(final String srcAbsPath, final String destAbsPath) throws PersistenceException {
-        Resource rsrc = this.control.copy(this.context, srcAbsPath, destAbsPath);
-        if (rsrc != null ) {
-            rsrc.getResourceMetadata().setResolutionPath(rsrc.getPath());
-            rsrc = this.factory.getResourceDecoratorTracker().decorate(rsrc);
-        }
-        return rsrc;
-    }
-
-    @Override
-    public Resource move(final String srcAbsPath, final String destAbsPath) throws PersistenceException {
-        Resource rsrc = this.control.move(this.context, srcAbsPath, destAbsPath);
-        if (rsrc != null ) {
-            rsrc.getResourceMetadata().setResolutionPath(rsrc.getPath());
-            rsrc = this.factory.getResourceDecoratorTracker().decorate(rsrc);
-        }
-        return rsrc;
-    }
-}
diff --git a/src/main/java/org/apache/sling/resourceresolver/impl/console/ResourceResolverWebConsolePlugin.java b/src/main/java/org/apache/sling/resourceresolver/impl/console/ResourceResolverWebConsolePlugin.java
deleted file mode 100644
index 5d6beaa..0000000
--- a/src/main/java/org/apache/sling/resourceresolver/impl/console/ResourceResolverWebConsolePlugin.java
+++ /dev/null
@@ -1,612 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *   http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-package org.apache.sling.resourceresolver.impl.console;
-
-import java.io.IOException;
-import java.io.PrintWriter;
-import java.io.UnsupportedEncodingException;
-import java.net.URL;
-import java.net.URLEncoder;
-import java.util.Arrays;
-import java.util.Collection;
-import java.util.Dictionary;
-import java.util.HashSet;
-import java.util.Hashtable;
-import java.util.List;
-import java.util.Set;
-
-import javax.servlet.ServletException;
-import javax.servlet.http.HttpServlet;
-import javax.servlet.http.HttpServletRequest;
-import javax.servlet.http.HttpServletRequestWrapper;
-import javax.servlet.http.HttpServletResponse;
-
-import org.apache.sling.api.request.ResponseUtil;
-import org.apache.sling.api.resource.ResourceResolver;
-import org.apache.sling.api.resource.runtime.RuntimeService;
-import org.apache.sling.api.resource.runtime.dto.ResourceProviderDTO;
-import org.apache.sling.api.resource.runtime.dto.ResourceProviderFailureDTO;
-import org.apache.sling.api.resource.runtime.dto.RuntimeDTO;
-import org.apache.sling.resourceresolver.impl.CommonResourceResolverFactoryImpl;
-import org.apache.sling.resourceresolver.impl.helper.URI;
-import org.apache.sling.resourceresolver.impl.helper.URIException;
-import org.apache.sling.resourceresolver.impl.mapping.MapEntries;
-import org.apache.sling.resourceresolver.impl.mapping.MapEntry;
-import org.apache.sling.spi.resource.provider.ResourceProvider;
-import org.osgi.framework.BundleContext;
-import org.osgi.framework.Constants;
-import org.osgi.framework.InvalidSyntaxException;
-import org.osgi.framework.ServiceReference;
-import org.osgi.framework.ServiceRegistration;
-
-public class ResourceResolverWebConsolePlugin extends HttpServlet {
-
-    private static final long serialVersionUID = 0;
-
-    private static final String ATTR_TEST = "plugin.test";
-
-    private static final String ATTR_SUBMIT = "plugin.submit";
-
-    private static final String PAR_MSG = "msg";
-    private static final String PAR_TEST = "test";
-
-    private final transient CommonResourceResolverFactoryImpl resolverFactory;
-
-    private transient ServiceRegistration service;
-
-    private final transient RuntimeService runtimeService;
-
-    private final transient BundleContext bundleContext;
-
-    public ResourceResolverWebConsolePlugin(final BundleContext context,
-            final CommonResourceResolverFactoryImpl resolverFactory,
-            final RuntimeService runtimeService) {
-        this.resolverFactory = resolverFactory;
-        this.runtimeService = runtimeService;
-        this.bundleContext = context;
-
-        Dictionary<String, Object> props = new Hashtable<String, Object>();
-        props.put(Constants.SERVICE_DESCRIPTION,
-                "Apache Sling Resource Resolver Web Console Plugin");
-        props.put(Constants.SERVICE_VENDOR, "The Apache Software Foundation");
-        props.put(Constants.SERVICE_PID, getClass().getName());
-        props.put("felix.webconsole.label", "jcrresolver");
-        props.put("felix.webconsole.title", "Resource Resolver");
-        props.put("felix.webconsole.css", "/jcrresolver/res/ui/resourceresolver.css");
-        props.put("felix.webconsole.category", "Sling");
-        props.put("felix.webconsole.configprinter.modes", "always");
-
-        service = context.registerService(
-                new String[] { "javax.servlet.Servlet" }, this, props);
-    }
-
-    public void dispose() {
-        if (service != null) {
-            service.unregister();
-            service = null;
-        }
-    }
-
-    @Override
-    protected void doGet(final HttpServletRequest request,
-            final HttpServletResponse response) throws ServletException,
-            IOException {
-        final String msg = request.getParameter(PAR_MSG);
-        final String test;
-        if (msg != null) {
-            test = request.getParameter(PAR_TEST);
-        } else {
-            test = null;
-        }
-
-        final PrintWriter pw = response.getWriter();
-
-        pw.println("<table class='content' cellpadding='0' cellspacing='0' width='100%'>");
-
-        final MapEntries mapEntries = resolverFactory.getMapEntries();
-
-        titleHtml(pw, "Configuration", null);
-        pw.println("<tr class='content'>");
-        pw.println("<td class='content'>Resource Search Path</td>");
-        pw.print("<td class='content' colspan='2'>");
-        pw.print(Arrays.asList(resolverFactory.getSearchPath()).toString());
-        pw.print("</td>");
-        pw.println("</tr>");
-        pw.println("<tr class='content'>");
-        pw.println("<td class='content'>Namespace Mangling</td>");
-        pw.print("<td class='content' colspan='2'>");
-        pw.print(resolverFactory.isMangleNamespacePrefixes() ? "Enabled"
-                : "Disabled");
-        pw.print("</td>");
-        pw.println("</tr>");
-        pw.println("<tr class='content'>");
-        pw.println("<td class='content'>Mapping Location</td>");
-        pw.print("<td class='content' colspan='2'>");
-        pw.print(resolverFactory.getMapRoot());
-        pw.print("</td>");
-        pw.println("</tr>");
-
-        separatorHtml(pw);
-
-        titleHtml(
-                pw,
-                "Configuration Test",
-                "To test the configuration, enter an URL or a resource path into "
-                        + "the field and click 'Resolve' to resolve the URL or click 'Map' "
-                        + "to map the resource path. To simulate a map call that takes the "
-                        + "current request into account, provide a full URL whose "
-                        + "scheme/host/port prefix will then be used as the request "
-                        + "information. The path passed to map will always be the path part "
-                        + "of the URL.");
-
-        pw.println("<tr class='content'>");
-        pw.println("<td class='content'>Test</td>");
-        pw.print("<td class='content' colspan='2'>");
-        pw.print("<form method='post'>");
-        pw.print("<input type='text' name='" + ATTR_TEST + "' value='");
-        if (test != null) {
-            pw.print(ResponseUtil.escapeXml(test));
-        }
-        pw.println("' class='input' size='50'>");
-        pw.println("&nbsp;&nbsp;<input type='submit' name='" + ATTR_SUBMIT
-                + "' value='Resolve' class='submit'>");
-        pw.println("&nbsp;&nbsp;<input type='submit' name='" + ATTR_SUBMIT
-                + "' value='Map' class='submit'>");
-        pw.print("</form>");
-        pw.print("</td>");
-        pw.println("</tr>");
-
-        if (msg != null) {
-            pw.println("<tr class='content'>");
-            pw.println("<td class='content'>&nbsp;</td>");
-            pw.print("<td class='content' colspan='2'>");
-            pw.print(ResponseUtil.escapeXml(msg));
-            pw.println("</td>");
-            pw.println("</tr>");
-        }
-
-        separatorHtml(pw);
-
-        dumpDTOsHtml(pw);
-
-        separatorHtml(pw);
-        dumpMapHtml(
-                pw,
-                "Resolver Map Entries",
-                "Lists the entries used by the ResourceResolver.resolve methods to map URLs to Resources",
-                mapEntries.getResolveMaps());
-
-        separatorHtml(pw);
-
-        dumpMapHtml(
-                pw,
-                "Mapping Map Entries",
-                "Lists the entries used by the ResourceResolver.map methods to map Resource Paths to URLs",
-                mapEntries.getMapMaps());
-
-        pw.println("</table>");
-
-    }
-
-    @Override
-    protected void doPost(HttpServletRequest request,
-            HttpServletResponse response) throws ServletException, IOException {
-
-        final String test = request.getParameter(ATTR_TEST);
-        String msg = null;
-        if (test != null && test.length() > 0) {
-
-            ResourceResolver resolver = null;
-            try {
-                // prepare the request for the resource resolver
-                HttpServletRequest helper = new ResolverRequest(request, test);
-
-                // get an administrative resource resolver
-                resolver = resolverFactory
-                        .getAdministrativeResourceResolver(null);
-
-                // map or resolve as instructed
-                Object result;
-                if ("Map".equals(request.getParameter(ATTR_SUBMIT))) {
-                    if (helper.getServerName() == null) {
-                        result = resolver.map(helper.getPathInfo());
-                    } else {
-                        result = resolver.map(helper, helper.getPathInfo());
-                    }
-                } else {
-                    result = resolver.resolve(helper, helper.getPathInfo());
-                }
-
-                // set the result to render the result
-                msg = result.toString();
-
-            } catch (final Throwable t) {
-
-                // some error occurred, report it as a result
-                msg = "Test Failure: " + t;
-
-            } finally {
-                if (resolver != null) {
-                    resolver.close();
-                }
-            }
-
-        }
-
-        // finally redirect
-        final String path = request.getContextPath() + request.getServletPath()
-                + request.getPathInfo();
-        final String redirectTo;
-        if (msg == null) {
-            redirectTo = path;
-        } else {
-            redirectTo = path + '?' + PAR_MSG + '=' + encodeParam(msg) + '&'
-                    + PAR_TEST + '=' + encodeParam(test);
-        }
-        response.sendRedirect(redirectTo);
-    }
-
-    private String encodeParam(final String value) {
-        try {
-            return URLEncoder.encode(value, "UTF-8");
-        } catch (UnsupportedEncodingException e) {
-            // should never happen
-            return value;
-        }
-    }
-
-    // ---------- ConfigurationPrinter
-
-    public void printConfiguration(final PrintWriter pw) {
-        dumpDTOsText(pw);
-
-        separatorText(pw);
-
-        final MapEntries mapEntries = resolverFactory.getMapEntries();
-
-        dumpMapText(pw, "Resolver Map Entries", mapEntries.getResolveMaps());
-
-        separatorText(pw);
-
-        dumpMapText(pw, "Mapping Map Entries", mapEntries.getMapMaps());
-    }
-
-    // ---------- internal
-
-    private void dumpMapHtml(PrintWriter pw, String title, String description,
-            Collection<MapEntry> list) {
-
-        titleHtml(pw, title, description);
-
-        pw.println("<tr class='content'>");
-        pw.println("<th class='content'>Pattern</th>");
-        pw.println("<th class='content'>Replacement</th>");
-        pw.println("<th class='content'>Redirect</th>");
-        pw.println("</tr>");
-
-        final Set<String> usedPatterns = new HashSet<String>();
-
-        for (final MapEntry entry : list) {
-            final String pattern = entry.getPattern();
-            pw.print("<tr class='content");
-            if (!usedPatterns.add(pattern)) {
-                pw.print(" duplicate");
-            }
-            pw.println("'>");
-            pw.println("<td class='content' style='vertical-align: top'>");
-            pw.print(ResponseUtil.escapeXml(pattern));
-            pw.print("</td>");
-
-            pw.print("<td class='content' style='vertical-align: top'>");
-            final String[] repls = entry.getRedirect();
-            for (final String repl : repls) {
-                pw.print(ResponseUtil.escapeXml(repl));
-                pw.print("<br/>");
-            }
-            pw.print("</td>");
-
-            pw.print("<td class='content' style='vertical-align: top'>");
-            if (entry.isInternal()) {
-                pw.print("internal");
-            } else {
-                pw.print("external: ");
-                pw.print(String.valueOf(entry.getStatus()));
-            }
-            pw.println("</td></tr>");
-
-        }
-    }
-
-    private void titleHtml(PrintWriter pw, String title, String description) {
-        pw.print("<tr class='content'>");
-        pw.print("<th colspan='3'class='content container'>");
-        pw.print(ResponseUtil.escapeXml(title));
-        pw.println("</th></tr>");
-
-        if (description != null) {
-            pw.print("<tr class='content'>");
-            pw.print("<td colspan='3'class='content'>");
-            pw.print(ResponseUtil.escapeXml(description));
-            pw.println("</th></tr>");
-        }
-    }
-
-    private void separatorHtml(PrintWriter pw) {
-        pw.print("<tr class='content'>");
-        pw.println("<td class='content' colspan='3'>&nbsp;</td>");
-        pw.println("</tr>");
-    }
-
-    private void dumpMapText(PrintWriter pw, String title,
-            Collection<MapEntry> list) {
-
-        pw.println(title);
-
-        final String format = "%25s%25s%15s\r\n";
-        pw.printf(format, "Pattern", "Replacement", "Redirect");
-
-        for (MapEntry entry : list) {
-            final List<String> redir = Arrays.asList(entry.getRedirect());
-            final String status = entry.isInternal() ? "internal"
-                    : "external: " + entry.getStatus();
-            pw.printf(format, entry.getPattern(), redir, status);
-        }
-    }
-
-    private ServiceReference getServiceReference(final long id) {
-        try {
-            final ServiceReference[] refs = this.bundleContext.getServiceReferences(ResourceProvider.class.getName(),
-                    "(" + Constants.SERVICE_ID + "=" + String.valueOf(id) + ")");
-            if ( refs != null && refs.length > 0 ) {
-                return refs[0];
-            }
-        } catch ( final InvalidSyntaxException ise) {
-            // ignore
-        }
-        return null;
-    }
-
-    private void dumpDTOsHtml(final PrintWriter pw) {
-
-        titleHtml(pw, "Resource Providers", "Lists all available and activate resource prodivers.");
-
-        pw.println("<tr class='content'>");
-        pw.println("<th class='content'>Provider</th>");
-        pw.println("<th class='content'>Path</th>");
-        pw.println("<th class='content'>Configuration</th>");
-        pw.println("</tr>");
-
-        final RuntimeDTO runtimeDTO = this.runtimeService.getRuntimeDTO();
-        for(final ResourceProviderDTO dto : runtimeDTO.providers) {
-            // get service reference
-            final ServiceReference ref = this.getServiceReference(dto.serviceId);
-            final StringBuilder sb = new StringBuilder();
-            if ( dto.name != null ) {
-                sb.append(dto.name);
-                sb.append(' ');
-            } else {
-                sb.append("<unnamed> ");
-            }
-            if ( ref != null ) {
-                sb.append("(serviceId = ");
-                sb.append(dto.serviceId);
-                sb.append(", bundleId = ");
-                sb.append(ref.getBundle().getBundleId());
-                sb.append(")");
-            }
-            pw.print("<tr class='content'>");
-            pw.print("<td class='content' style='vertical-align: top'>");
-            pw.print(ResponseUtil.escapeXml(sb.toString()));
-            pw.print("</td>");
-
-            pw.print("<td class='content' style='vertical-align: top'>");
-            pw.print(ResponseUtil.escapeXml(dto.path));
-            pw.print("</td>");
-
-            pw.print("<td class='content' style='vertical-align: top'>");
-            pw.print("auth=");
-            pw.print(dto.authType.name());
-            pw.print("<br/>");
-            pw.print("adaptable=");
-            pw.print(dto.adaptable);
-            pw.print("<br/>");
-            pw.print("attributable=");
-            pw.print(dto.attributable);
-            pw.print("<br/>");
-            pw.print("modifiable=");
-            pw.print(dto.modifiable);
-            pw.print("<br/>");
-            pw.print("refreshable=");
-            pw.print(dto.refreshable);
-            pw.print("<br/>");
-            pw.print("supportsQueryLanguage=");
-            pw.print(dto.supportsQueryLanguage);
-            pw.print("<br/>");
-            pw.print("useResourceAccessSecurity=");
-            pw.print(dto.useResourceAccessSecurity);
-            pw.println("</td></tr>");
-        }
-
-        if ( runtimeDTO.failedProviders.length > 0 ) {
-            titleHtml(pw, "Failed Resource Providers", "Lists all failed providers.");
-
-            pw.println("<tr class='content'>");
-            pw.println("<th class='content'>Provider</th>");
-            pw.println("<th class='content'>Path</th>");
-            pw.println("<th class='content'>Reason</th>");
-            pw.println("</tr>");
-
-            for(final ResourceProviderFailureDTO dto : runtimeDTO.failedProviders) {
-                // get service reference
-                final ServiceReference ref = this.getServiceReference(dto.serviceId);
-                final StringBuilder sb = new StringBuilder();
-                if ( dto.name != null ) {
-                    sb.append(dto.name);
-                    sb.append(' ');
-                } else {
-                    sb.append("<unnamed> ");
-                }
-                if ( ref != null ) {
-                    sb.append("(serviceId = ");
-                    sb.append(dto.serviceId);
-                    sb.append(", bundleId = ");
-                    sb.append(ref.getBundle().getBundleId());
-                    sb.append(")");
-                }
-                pw.print("<tr class='content'>");
-                pw.print("<td class='content' style='vertical-align: top'>");
-                pw.print(ResponseUtil.escapeXml(sb.toString()));
-                pw.print("</td>");
-
-                pw.print("<td class='content' style='vertical-align: top'>");
-                pw.print(ResponseUtil.escapeXml(dto.path));
-                pw.print("</td>");
-
-                pw.print("<td class='content' style='vertical-align: top'>");
-                pw.print(dto.reason.name());
-                pw.println("</td></tr>");
-            }
-        }
-    }
-
-    private void dumpDTOsText(final PrintWriter pw) {
-
-        pw.println("Resource Providers");
-
-        final String format = "%35s %25s %15s\r\n";
-        pw.printf(format, "Provider", "Path", "Configuration");
-
-        final RuntimeDTO runtimeDTO = this.runtimeService.getRuntimeDTO();
-        for(final ResourceProviderDTO dto : runtimeDTO.providers) {
-            // get service reference
-            final ServiceReference ref = this.getServiceReference(dto.serviceId);
-            final StringBuilder sb = new StringBuilder();
-            if ( dto.name != null ) {
-                sb.append(dto.name);
-                sb.append(' ');
-            } else {
-                sb.append("<unnamed> ");
-            }
-            if ( ref != null ) {
-                sb.append("(serviceId = ");
-                sb.append(dto.serviceId);
-                sb.append(", bundleId = ");
-                sb.append(ref.getBundle().getBundleId());
-                sb.append(")");
-            }
-            final StringBuilder config = new StringBuilder();
-            config.append("auth=");
-            config.append(dto.authType.name());
-            config.append(", adaptable=");
-            config.append(dto.adaptable);
-            config.append(", attributable=");
-            config.append(dto.attributable);
-            config.append(", modifiable=");
-            config.append(dto.modifiable);
-            config.append(", refreshable=");
-            config.append(dto.refreshable);
-            config.append(", supportsQueryLanguage=");
-            config.append(dto.supportsQueryLanguage);
-            config.append(", useResourceAccessSecurity=");
-            config.append(dto.useResourceAccessSecurity);
-            pw.printf(format, sb.toString(), dto.path, config.toString());
-        }
-        pw.println();
-        if ( runtimeDTO.failedProviders.length > 0 ) {
-            pw.println("Failed Resource Providers");
-            pw.printf(format, "Provider", "Path", "Reason");
-
-            for(final ResourceProviderFailureDTO dto : runtimeDTO.failedProviders) {
-                // get service reference
-                final ServiceReference ref = this.getServiceReference(dto.serviceId);
-                final StringBuilder sb = new StringBuilder();
-                if ( dto.name != null ) {
-                    sb.append(dto.name);
-                    sb.append(' ');
-                } else {
-                    sb.append("<unnamed> ");
-                }
-                if ( ref != null ) {
-                    sb.append("(serviceId = ");
-                    sb.append(dto.serviceId);
-                    sb.append(", bundleId = ");
-                    sb.append(ref.getBundle().getBundleId());
-                    sb.append(")");
-                }
-                pw.printf(format, sb.toString(), dto.path, dto.reason.name());
-            }
-            pw.println();
-        }
-    }
-
-    private void separatorText(PrintWriter pw) {
-        pw.println();
-    }
-
-    /**
-     * Method to retrieve static resources from this bundle.
-     */
-    @SuppressWarnings("unused")
-    private URL getResource(final String path) {
-        if (path.startsWith("/jcrresolver/res/ui/")) {
-            return this.getClass().getResource(path.substring(12));
-        }
-        return null;
-    }
-
-    private static class ResolverRequest extends HttpServletRequestWrapper {
-
-        private final URI uri;
-
-        public ResolverRequest(HttpServletRequest request, String uriString)
-                throws URIException {
-            super(request);
-            uri = new URI(uriString, false);
-        }
-
-        @Override
-        public String getScheme() {
-            return uri.getScheme();
-        }
-
-        @Override
-        public String getServerName() {
-            try {
-                return uri.getHost();
-            } catch (URIException ue) {
-                return null;
-            }
-        }
-
-        @Override
-        public int getServerPort() {
-            return uri.getPort();
-        }
-
-        @Override
-        public String getPathInfo() {
-            try {
-                return uri.getPath();
-            } catch (URIException ue) {
-                return "";
-            }
-        }
-    }
-
-}
diff --git a/src/main/java/org/apache/sling/resourceresolver/impl/helper/AbstractIterator.java b/src/main/java/org/apache/sling/resourceresolver/impl/helper/AbstractIterator.java
deleted file mode 100644
index 86253a9..0000000
--- a/src/main/java/org/apache/sling/resourceresolver/impl/helper/AbstractIterator.java
+++ /dev/null
@@ -1,53 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *   http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-package org.apache.sling.resourceresolver.impl.helper;
-
-import java.util.Iterator;
-import java.util.NoSuchElementException;
-
-public abstract class AbstractIterator<T> implements Iterator<T> {
-
-    private T nextElement;
-
-    protected abstract T seek();
-
-    @Override
-    public boolean hasNext() {
-        if (nextElement == null) {
-            nextElement = seek();
-        }
-        return nextElement != null;
-    }
-
-    @Override
-    public T next() {
-        if (nextElement == null && !hasNext()) {
-            throw new NoSuchElementException();
-        }
-        final T result = nextElement;
-        nextElement = null;
-        return result;
-    }
-
-    @Override
-    public void remove() {
-        throw new UnsupportedOperationException();
-    }
-
-}
diff --git a/src/main/java/org/apache/sling/resourceresolver/impl/helper/ChainedIterator.java b/src/main/java/org/apache/sling/resourceresolver/impl/helper/ChainedIterator.java
deleted file mode 100644
index 5dfda1f..0000000
--- a/src/main/java/org/apache/sling/resourceresolver/impl/helper/ChainedIterator.java
+++ /dev/null
@@ -1,50 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *   http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-package org.apache.sling.resourceresolver.impl.helper;
-
-import java.util.Iterator;
-
-public class ChainedIterator<T> extends AbstractIterator<T> {
-
-    private final Iterator<Iterator<T>> iterators;
-
-    private Iterator<T> currentIterator;
-
-    public ChainedIterator(Iterator<Iterator<T>> iterators) {
-        this.iterators = iterators;
-    }
-
-    @Override
-    protected T seek() {
-        while (true) {
-            if (currentIterator == null) {
-                if (!iterators.hasNext()) {
-                    return null;
-                }
-                currentIterator = iterators.next();
-                continue;
-            }
-            if (currentIterator.hasNext()) {
-                return currentIterator.next();
-            } else {
-                currentIterator = null;
-            }
-        }
-    }
-}
diff --git a/src/main/java/org/apache/sling/resourceresolver/impl/helper/RedirectResource.java b/src/main/java/org/apache/sling/resourceresolver/impl/helper/RedirectResource.java
deleted file mode 100644
index 43c241b..0000000
--- a/src/main/java/org/apache/sling/resourceresolver/impl/helper/RedirectResource.java
+++ /dev/null
@@ -1,72 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *   http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-package org.apache.sling.resourceresolver.impl.helper;
-
-import java.util.Collections;
-import java.util.HashMap;
-import java.util.Map;
-
-import org.apache.sling.adapter.annotations.Adaptable;
-import org.apache.sling.adapter.annotations.Adapter;
-import org.apache.sling.api.resource.Resource;
-import org.apache.sling.api.resource.ResourceResolver;
-import org.apache.sling.api.resource.SyntheticResource;
-import org.apache.sling.api.resource.ValueMap;
-import org.apache.sling.api.wrappers.ValueMapDecorator;
-
-@Adaptable(adaptableClass = Resource.class, adapters = @Adapter(value = { Map.class, ValueMap.class }))
-public final class RedirectResource extends SyntheticResource {
-
-    static final String RT_SLING_REDIRECT = "sling:redirect";
-
-    static final String PROP_SLING_TARGET = "sling:target";
-
-    static final String PROP_SLING_STATUS = "sling:status";
-
-    private final Map<String, Object> values;
-
-    public RedirectResource(final ResourceResolver resolver, final String path,
-            final String target, final int status) {
-        super(resolver, path, RT_SLING_REDIRECT);
-
-        final Map<String, Object> props = new HashMap<String, Object>();
-        props.put(PROP_SLING_TARGET, target);
-        props.put(PROP_SLING_STATUS, status);
-        this.values = Collections.unmodifiableMap(props);
-    }
-
-    /**
-     * @see org.apache.sling.api.adapter.Adaptable#adaptTo(java.lang.Class)
-     */
-    @SuppressWarnings("unchecked")
-    public <AdapterType> AdapterType adaptTo(final Class<AdapterType> type) {
-        if (type == ValueMap.class) {
-            return (AdapterType) new ValueMapDecorator(values);
-        } else if (type == Map.class) {
-            return (AdapterType) values;
-        }
-
-        return super.adaptTo(type);
-    }
-
-    @Override
-    public String toString() {
-        return super.toString() + ", values=" + values;
-    }
-}
\ No newline at end of file
diff --git a/src/main/java/org/apache/sling/resourceresolver/impl/helper/ResourceDecoratorTracker.java b/src/main/java/org/apache/sling/resourceresolver/impl/helper/ResourceDecoratorTracker.java
deleted file mode 100644
index 460f912..0000000
--- a/src/main/java/org/apache/sling/resourceresolver/impl/helper/ResourceDecoratorTracker.java
+++ /dev/null
@@ -1,149 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *   http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-package org.apache.sling.resourceresolver.impl.helper;
-
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.Iterator;
-import java.util.List;
-import java.util.Map;
-
-import org.apache.sling.api.resource.Resource;
-import org.apache.sling.api.resource.ResourceDecorator;
-import org.apache.sling.commons.osgi.ServiceUtil;
-
-/**
- * Helper class to track the resource decorators and keep them sorted by their
- * service ranking.
- */
-public class ResourceDecoratorTracker {
-
-    private static final ResourceDecorator[] EMPTY_ARRAY = new ResourceDecorator[0];
-
-    /**
-     * The (optional) resource decorators, working copy.
-     */
-    protected final List<ResourceDecoratorEntry> resourceDecorators = new ArrayList<ResourceDecoratorEntry>();
-
-    /**
-     * An array of the above, updates when changes are created.
-     */
-    private volatile ResourceDecorator[] resourceDecoratorsArray = EMPTY_ARRAY;
-
-    public void close() {
-        synchronized (this.resourceDecorators) {
-            this.resourceDecorators.clear();
-            this.resourceDecoratorsArray = EMPTY_ARRAY;
-        }
-    }
-
-    /**
-     * Decorate a resource.
-     */
-    public Resource decorate(final Resource resource) {
-        Resource result = resource;
-        final ResourceDecorator[] decorators = this.resourceDecoratorsArray;
-        for (final ResourceDecorator decorator : decorators) {
-            final Resource original = result;
-            result = decorator.decorate(original);
-            if (result == null) {
-                result = original;
-            }
-        }
-
-        // make resource metadata read-only
-        result.getResourceMetadata().lock();
-
-        return result;
-    }
-
-    /**
-     * Bind a resource decorator.
-     */
-    public void bindResourceDecorator(final ResourceDecorator decorator,
-            final Map<String, Object> props) {
-        synchronized (this.resourceDecorators) {
-            this.resourceDecorators.add(new ResourceDecoratorEntry(decorator,
-                    ServiceUtil.getComparableForServiceRanking(props)));
-            Collections.sort(this.resourceDecorators);
-            updateResourceDecoratorsArray();
-        }
-    }
-
-    /**
-     * Unbind a resouce decorator.
-     */
-    public void unbindResourceDecorator(final ResourceDecorator decorator,
-            final Map<String, Object> props) {
-        synchronized (this.resourceDecorators) {
-            final Iterator<ResourceDecoratorEntry> i = this.resourceDecorators
-                    .iterator();
-            while (i.hasNext()) {
-                final ResourceDecoratorEntry current = i.next();
-                if (current.decorator == decorator) {
-                    i.remove();
-                    break;
-                }
-            }
-            updateResourceDecoratorsArray();
-        }
-    }
-
-    /**
-     * Updates the ResourceDecorators array, this method is not thread safe and
-     * should only be called from a synchronized block.
-     */
-    private void updateResourceDecoratorsArray() {
-        final ResourceDecorator[] decorators;
-        if (this.resourceDecorators.size() > 0) {
-            decorators = new ResourceDecorator[this.resourceDecorators.size()];
-            int index = 0;
-            final Iterator<ResourceDecoratorEntry> i = this.resourceDecorators
-                    .iterator();
-            while (i.hasNext()) {
-                decorators[index] = i.next().decorator;
-                index++;
-            }
-        } else {
-            decorators = EMPTY_ARRAY;
-        }
-        this.resourceDecoratorsArray = decorators;
-    }
-
-    /**
-     * Internal class to keep track of the resource decorators.
-     */
-    private static final class ResourceDecoratorEntry implements
-            Comparable<ResourceDecoratorEntry> {
-
-        final Comparable<Object> comparable;
-
-        final ResourceDecorator decorator;
-
-        public ResourceDecoratorEntry(final ResourceDecorator d,
-                final Comparable<Object> comparable) {
-            this.comparable = comparable;
-            this.decorator = d;
-        }
-
-        public int compareTo(final ResourceDecoratorEntry o) {
-            return comparable.compareTo(o.comparable);
-        }
-    }
-}
diff --git a/src/main/java/org/apache/sling/resourceresolver/impl/helper/ResourceIteratorDecorator.java b/src/main/java/org/apache/sling/resourceresolver/impl/helper/ResourceIteratorDecorator.java
deleted file mode 100644
index 2611c94..0000000
--- a/src/main/java/org/apache/sling/resourceresolver/impl/helper/ResourceIteratorDecorator.java
+++ /dev/null
@@ -1,66 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *   http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-package org.apache.sling.resourceresolver.impl.helper;
-
-import java.util.Iterator;
-
-import org.apache.sling.api.resource.Resource;
-
-/**
- * Resource iterator handling the decoration of resources.
- */
-public class ResourceIteratorDecorator implements Iterator<Resource> {
-
-    private final ResourceDecoratorTracker tracker;
-
-    private final Iterator<Resource> iterator;
-
-    public ResourceIteratorDecorator(final ResourceDecoratorTracker tracker,
-            final Iterator<Resource> iterator) {
-        this.tracker = tracker;
-        this.iterator = iterator;
-    }
-
-    /**
-     * @see java.util.Iterator#hasNext()
-     */
-    @Override
-    public boolean hasNext() {
-        return this.iterator.hasNext();
-    }
-
-    /**
-     * @see java.util.Iterator#next()
-     */
-    @Override
-    public Resource next() {
-        final Resource rsrc = this.iterator.next();
-        rsrc.getResourceMetadata().setResolutionPath(rsrc.getPath());
-
-        return this.tracker.decorate(rsrc);
-    }
-
-    /**
-     * @see java.util.Iterator#remove()
-     */
-    @Override
-    public void remove() {
-        this.iterator.remove();
-    }
-}
diff --git a/src/main/java/org/apache/sling/resourceresolver/impl/helper/ResourcePathIterator.java b/src/main/java/org/apache/sling/resourceresolver/impl/helper/ResourcePathIterator.java
deleted file mode 100644
index 17482eb..0000000
--- a/src/main/java/org/apache/sling/resourceresolver/impl/helper/ResourcePathIterator.java
+++ /dev/null
@@ -1,99 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements.  See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License.  You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.apache.sling.resourceresolver.impl.helper;
-
-import java.util.Iterator;
-import java.util.NoSuchElementException;
-
-/**
- * Iterate over the the HTTP request path by creating shorter segments of that
- * path using "." as a separator.
- * <p>
- * For example, if path = /some/stuff.a4.html/xyz.ext the sequence is:
- * <ol>
- * <li> /some/stuff.a4.html/xyz.ext </li>
- * <li> /some/stuff.a4.html/xyz </li>
- * <li> /some/stuff.a4</li>
- * <li> /some/stuff </li>
- * </ol>
- * <p>
- * The root path (/) is never returned.
- */
-public class ResourcePathIterator implements Iterator<String> {
-
-    // the next path to return, null if nothing more to return
-    private String nextPath;
-
-    /**
-     * Creates a new instance iterating over the given path
-     *
-     * @param path The path to iterate over. If this is empty or
-     *            <code>null</code> this iterator will not return anything.
-     */
-    public ResourcePathIterator(String path) {
-
-        if (path == null || path.length() == 0) {
-
-            // null or empty path, there is nothing to return
-            nextPath = null;
-
-        } else {
-
-            // find last non-slash character
-            int i = path.length() - 1;
-            while (i >= 0 && path.charAt(i) == '/') {
-                i--;
-            }
-
-            if (i < 0) {
-                // only slashes, assume root node
-                nextPath = "/";
-
-            } else if (i < path.length() - 1) {
-                // cut off slash
-                nextPath = path.substring(0, i + 1);
-
-            } else {
-                // no trailing slash
-                nextPath = path;
-            }
-        }
-    }
-
-    public boolean hasNext() {
-        return nextPath != null;
-    }
-
-    public String next() {
-        if (!hasNext()) {
-            throw new NoSuchElementException();
-        }
-
-        final String result = nextPath;
-
-        // find next path
-        int lastDot = nextPath.lastIndexOf('.');
-        nextPath = (lastDot > 0) ? nextPath.substring(0, lastDot) : null;
-
-        return result;
-    }
-
-    public void remove() {
-        throw new UnsupportedOperationException("remove");
-    }
-
-}
diff --git a/src/main/java/org/apache/sling/resourceresolver/impl/helper/ResourceResolverContext.java b/src/main/java/org/apache/sling/resourceresolver/impl/helper/ResourceResolverContext.java
deleted file mode 100644
index e9a004b..0000000
--- a/src/main/java/org/apache/sling/resourceresolver/impl/helper/ResourceResolverContext.java
+++ /dev/null
@@ -1,49 +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 SF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations under the License.
- */
-package org.apache.sling.resourceresolver.impl.helper;
-
-import javax.annotation.Nonnull;
-
-import org.apache.sling.api.resource.ResourceResolver;
-import org.apache.sling.resourceresolver.impl.ResourceAccessSecurityTracker;
-import org.apache.sling.resourceresolver.impl.providers.stateful.ProviderManager;
-
-/**
- * The resource resolver context.
- *
- * This class is not thread safe (same as the resource resolver).
- */
-public class ResourceResolverContext {
-
-    private final ResourceResolver resolver;
-
-    private final ProviderManager providerManager;
-
-    public ResourceResolverContext(@Nonnull final ResourceResolver resolver, @Nonnull final ResourceAccessSecurityTracker tracker) {
-        this.resolver = resolver;
-        this.providerManager = new ProviderManager(resolver, tracker);
-    }
-
-    public ResourceResolver getResourceResolver() {
-        return this.resolver;
-    }
-
-    public ProviderManager getProviderManager() {
-        return this.providerManager;
-    }
-}
diff --git a/src/main/java/org/apache/sling/resourceresolver/impl/helper/ResourceResolverControl.java b/src/main/java/org/apache/sling/resourceresolver/impl/helper/ResourceResolverControl.java
deleted file mode 100644
index 1e6f046..0000000
--- a/src/main/java/org/apache/sling/resourceresolver/impl/helper/ResourceResolverControl.java
+++ /dev/null
@@ -1,786 +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 SF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations under the License.
- */
-package org.apache.sling.resourceresolver.impl.helper;
-
-import java.io.Closeable;
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.Collection;
-import java.util.Collections;
-import java.util.HashSet;
-import java.util.IdentityHashMap;
-import java.util.Iterator;
-import java.util.LinkedHashSet;
-import java.util.List;
-import java.util.Map;
-import java.util.Map.Entry;
-import java.util.Set;
-import java.util.concurrent.atomic.AtomicBoolean;
-
-import javax.annotation.CheckForNull;
-import javax.annotation.Nonnull;
-
-import org.apache.commons.collections.iterators.IteratorChain;
-import org.apache.commons.lang.ArrayUtils;
-import org.apache.sling.api.resource.LoginException;
-import org.apache.sling.api.resource.PersistenceException;
-import org.apache.sling.api.resource.Resource;
-import org.apache.sling.api.resource.ResourceResolver;
-import org.apache.sling.api.resource.ResourceResolverFactory;
-import org.apache.sling.api.resource.ResourceUtil;
-import org.apache.sling.api.resource.SyntheticResource;
-import org.apache.sling.api.resource.ValueMap;
-import org.apache.sling.api.resource.path.PathBuilder;
-import org.apache.sling.resourceresolver.impl.providers.ResourceProviderHandler;
-import org.apache.sling.resourceresolver.impl.providers.ResourceProviderInfo;
-import org.apache.sling.resourceresolver.impl.providers.ResourceProviderStorage;
-import org.apache.sling.resourceresolver.impl.providers.ResourceProviderStorageProvider;
-import org.apache.sling.resourceresolver.impl.providers.stateful.AuthenticatedResourceProvider;
-import org.apache.sling.resourceresolver.impl.providers.tree.Node;
-import org.apache.sling.spi.resource.provider.ResourceProvider;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-/**
- * This class takes a number of {@link AuthenticatedResourceProvider} objects and
- * exposes it as one such object. Provider appropriate for the given operation
- * is chosen basing on its {@link ResourceProviderInfo#getPath()} (more specific
- * first) and service ranking.
- *
- * Like a resource resolver itself, this class is not thread safe.
- */
-public class ResourceResolverControl {
-
-    private static final Logger logger = LoggerFactory.getLogger(ResourceResolverControl.class);
-
-    private static final String FORBIDDEN_ATTRIBUTE = ResourceResolverFactory.PASSWORD;
-
-    /** Is this a resource resolver for an admin? */
-    private final boolean isAdmin;
-
-    /** The authentication info. */
-    private final Map<String, Object> authenticationInfo;
-
-    /** Resource type resource resolver (admin resolver) */
-    private volatile ResourceResolver resourceTypeResourceResolver;
-
-    /** Flag for handling multiple calls to close. */
-    private final AtomicBoolean isClosed = new AtomicBoolean(false);
-
-    private final ResourceProviderStorageProvider resourceProviderTracker;
-
-    private final Map<ResourceProviderHandler, Object> authenticatedProviders;
-
-    /**
-     * Create a new resource resolver context.
-     */
-    public ResourceResolverControl(final boolean isAdmin,
-            final Map<String, Object> authenticationInfo,
-            final ResourceProviderStorageProvider resourceProviderTracker) {
-        this.authenticatedProviders = new IdentityHashMap<ResourceProviderHandler, Object>();
-        this.authenticationInfo = authenticationInfo;
-        this.isAdmin = isAdmin;
-        this.resourceProviderTracker = resourceProviderTracker;
-    }
-
-    /**
-     * Is this an admin resource resolver?
-     * @return{@code true} if it is an admin resource resolver
-     */
-    public boolean isAdmin() {
-        return isAdmin;
-    }
-
-    /**
-     * The authentication info
-     * @return The map with the auth info
-     */
-    public Map<String, Object> getAuthenticationInfo() {
-        return this.authenticationInfo;
-    }
-
-    /**
-     * Is this already closed?
-     * @return {@code true} if it is closed.
-     */
-    public boolean isClosed() {
-        return this.isClosed.get();
-    }
-
-    /**
-     * Logs out from all providers.
-     */
-    private void logout() {
-        for(final Map.Entry<ResourceProviderHandler, Object> entry : this.authenticatedProviders.entrySet()) {
-            try {
-                final ResourceProvider<Object> rp = entry.getKey().getResourceProvider();
-                if ( rp != null ) {
-                    rp.logout(entry.getValue());
-                } else if ( entry.getValue() instanceof Closeable ) {
-                    ((Closeable)entry.getValue()).close();
-                }
-            } catch ( final Throwable t ) {
-                // we ignore everything from there to not stop this thread
-            }
-        }
-        this.authenticatedProviders.clear();
-    }
-
-    /**
-     * Refreshes all refreshable providers.
-     */
-    public void refresh(@Nonnull final ResourceResolverContext context) {
-        for (final AuthenticatedResourceProvider p : context.getProviderManager().getAllUsedRefreshable()) {
-            p.refresh();
-        }
-    }
-
-    /**
-     * Returns {@code true} if all providers are live.
-     */
-    public boolean isLive(@Nonnull final ResourceResolverContext context) {
-        for (final AuthenticatedResourceProvider p : context.getProviderManager().getAllAuthenticated()) {
-            if (!p.isLive()) {
-                return false;
-            }
-        }
-        return true;
-    }
-
-    /**
-     * Returns parent from the most appropriate resource provider accepting the
-     * given children.
-     *
-     * In some cases the {@link SyntheticResource} can be returned if no
-     * resource provider returns parent for this child. See
-     * {@link #getResource(String, Resource, Map, boolean)} for more details
-     */
-    public Resource getParent(@Nonnull final ResourceResolverContext context, @Nonnull final String parentPath, @Nonnull final Resource child) {
-        final AuthenticatedResourceProvider childProvider = getBestMatchingProvider(context, child.getPath());
-        final AuthenticatedResourceProvider parentProvider = getBestMatchingProvider(context, parentPath);
-        if ( parentProvider != null ) {
-            final Resource parentCandidate;
-            if ( childProvider == parentProvider ) {
-                parentCandidate = parentProvider.getParent(child);
-            } else {
-                parentCandidate = parentProvider.getResource(parentPath, null, null);
-            }
-            if (parentCandidate != null) {
-                return parentCandidate;
-            }
-        }
-
-        if (isIntermediatePath(parentPath)) {
-            return new SyntheticResource(context.getResourceResolver(), parentPath, ResourceProvider.RESOURCE_TYPE_SYNTHETIC);
-        }
-        return null;
-    }
-
-    /**
-     * Returns resource from the most appropriate resource provider.
-     * <br/><br/>
-     * If there's no such provider and the path is a part of some resource
-     * provider path, then the {@link SyntheticResource} will be returned. For
-     * instance, if we have resource provider under
-     * {@code /libs/sling/servlet/default/GET.servlet} and no resource provider
-     * returns a resource for {@code /libs/sling/servlet/default}, then the
-     * {@link SyntheticResource} will be returned to provide a consistent
-     * resource tree.
-     * <br/><br/>
-     * The same behaviour occurs in {@link #getParent(Resource)} and
-     * {@link #listChildren(Resource)}.
-     */
-    public Resource getResource(final ResourceResolverContext context,
-            String path, Resource parent, Map<String, String> parameters,
-            boolean isResolve) {
-        if (path == null || path.length() == 0 || path.charAt(0) != '/') {
-            logger.debug("Not absolute {}", path);
-            return null; // path must be absolute
-        }
-
-        final AuthenticatedResourceProvider provider = this.getBestMatchingProvider(context, path);
-        if ( provider != null ) {
-            final Resource resourceCandidate = provider.getResource(path, parent, parameters);
-            if (resourceCandidate != null) {
-                return resourceCandidate;
-            }
-        }
-
-        // query: /libs/sling/servlet/default
-        // resource Provider: libs/sling/servlet/default/GET.servlet
-        // list will match libs, sling, servlet, default
-        // and there will be no resource provider at the end
-        // SLING-3482 : this is only done for getResource but not resolve
-        //              as it is important e.g. for servlet resolution
-        //              to get the parent resource for resource traversal.
-        if (!isResolve && isIntermediatePath(path)) {
-            logger.debug("Resolved Synthetic {}", path);
-            return new SyntheticResource(context.getResourceResolver(), path, ResourceProvider.RESOURCE_TYPE_SYNTHETIC);
-        }
-        logger.debug("Resource null {} ", path);
-        return null;
-    }
-
-    private boolean isIntermediatePath(final String fullPath) {
-        return getResourceProviderStorage().getTree().getNode(fullPath) != null;
-    }
-
-    /**
-     * This method asks all matching resource providers for the children iterators,
-     * merges them, adds {@link SyntheticResource}s (see
-     * {@link #getResource(String, Resource, Map, boolean)} for more details),
-     * filters out the duplicates and returns the resulting iterator. All
-     * transformations are done lazily, during the {@link Iterator#hasNext()}
-     * invocation on the result.
-     */
-    @SuppressWarnings("unchecked")
-    public Iterator<Resource> listChildren(final ResourceResolverContext context, final Resource parent) {
-        final String parentPath = parent.getPath();
-
-        // 3 sources are combined: children of the provider which owns 'parent',
-        // providers which are directly mounted at a child path,
-        // synthetic resources for providers mounted at a lower level
-
-        // children of the 'parent' provider
-        Iterator<Resource> realChildren = null;
-        final AuthenticatedResourceProvider provider = this.getBestMatchingProvider(context, parentPath);
-        if ( provider != null ) {
-            realChildren = provider.listChildren(parent);
-        }
-
-        final Set<String> visitedNames = new HashSet<String>();
-
-        IteratorChain chain = new IteratorChain();
-        if ( realChildren != null ) {
-            chain.addIterator(realChildren);
-        }
-
-        // synthetic and providers are done in one loop
-        final Node<ResourceProviderHandler> node = getResourceProviderStorage().getTree().getNode(parent.getPath());
-        if (node != null) {
-            final List<Resource> syntheticList = new ArrayList<Resource>();
-            final List<Resource> providerList = new ArrayList<Resource>();
-
-            for (final Entry<String, Node<ResourceProviderHandler>> entry : node.getChildren().entrySet()) {
-                final String name = entry.getKey();
-                final ResourceProviderHandler handler = entry.getValue().getValue();
-                PathBuilder pathBuilder = new PathBuilder(parent.getPath());
-                pathBuilder.append(name);
-                final String childPath = pathBuilder.toString();
-                if (handler == null) {
-                    syntheticList.add(new SyntheticResource(context.getResourceResolver(), childPath, ResourceProvider.RESOURCE_TYPE_SYNTHETIC));
-                } else {
-                    Resource rsrc = null;
-                    try {
-                        final AuthenticatedResourceProvider rp = context.getProviderManager().getOrCreateProvider(handler, this);
-                        rsrc = rp == null ? null : rp.getResource(childPath, parent, null);
-                    } catch ( final LoginException ignore) {
-                        // ignore
-                    }
-                    if ( rsrc != null ) {
-                        providerList.add(rsrc);
-                    } else {
-                        // if there is a child provider underneath, we need to create a synthetic resource
-                        // otherwise we need to make sure that no one else is providing this child
-                        if ( entry.getValue().getChildren().isEmpty() ) {
-                            syntheticList.add(new SyntheticResource(context.getResourceResolver(), childPath, ResourceProvider.RESOURCE_TYPE_SYNTHETIC));
-                        } else {
-                            visitedNames.add(name);
-                        }
-                    }
-                }
-            }
-            if ( !providerList.isEmpty() ) {
-                chain.addIterator(providerList.iterator());
-            }
-            if ( !syntheticList.isEmpty() ) {
-                chain.addIterator(syntheticList.iterator());
-            }
-        }
-        if ( chain.size() == 0 ) {
-            return Collections.EMPTY_LIST.iterator();
-        }
-        return new UniqueResourceIterator(visitedNames, chain);
-    }
-
-    /**
-     * Returns the union of all attribute names.
-     */
-    public Collection<String> getAttributeNames(final ResourceResolverContext context) {
-        final Set<String> names = new LinkedHashSet<String>();
-        for (final AuthenticatedResourceProvider p : context.getProviderManager().getAllBestEffort(getResourceProviderStorage().getAttributableHandlers(), this)) {
-            p.getAttributeNames(names);
-        }
-        if ( this.authenticationInfo != null ) {
-            names.addAll(authenticationInfo.keySet());
-        }
-        names.remove(FORBIDDEN_ATTRIBUTE);
-        return names;
-    }
-
-    /**
-     * Returns the first non-null result of the
-     * {@link AuthenticatedResourceProvider#getAttribute(String)} invocation on
-     * the providers.
-     */
-    public Object getAttribute(final ResourceResolverContext context, final String name) {
-        if (FORBIDDEN_ATTRIBUTE.equals(name)) {
-            return null;
-        }
-        for (final AuthenticatedResourceProvider p : context.getProviderManager().getAllBestEffort(getResourceProviderStorage().getAttributableHandlers(), this)) {
-            final Object attribute = p.getAttribute(name);
-            if (attribute != null) {
-                return attribute;
-            }
-        }
-        return this.authenticationInfo != null ? this.authenticationInfo.get(name) :null;
-    }
-
-    /**
-     * Create a resource.
-     *
-     * @throws UnsupportedOperationException
-     *             If creation is not allowed/possible
-     * @throws PersistenceException
-     *             If creation fails
-     * @return The new resource
-     */
-    public Resource create(final ResourceResolverContext context,
-            final String path, final Map<String, Object> properties)
-    throws PersistenceException {
-        final AuthenticatedResourceProvider provider = getBestMatchingModifiableProvider(context, path);
-        if ( provider != null ) {
-            final Resource creationResultResource = provider.create(context.getResourceResolver(), path, properties);
-            if (creationResultResource != null) {
-                return creationResultResource;
-            }
-        }
-        throw new UnsupportedOperationException("create '" + ResourceUtil.getName(path) + "' at " + ResourceUtil.getParent(path));
-    }
-
-    /**
-     * Delete the resource. Iterate over all modifiable ResourceProviders
-     * giving each an opportunity to delete the resource if they are able.
-     *
-     * @throws NullPointerException
-     *             if resource is null
-     * @throws UnsupportedOperationException
-     *             If deletion is not allowed/possible
-     * @throws PersistenceException
-     *             If deletion fails
-     */
-    public void delete(final ResourceResolverContext context, final Resource resource) throws PersistenceException {
-        final String path = resource.getPath();
-        final AuthenticatedResourceProvider provider = getBestMatchingModifiableProvider(context, path);
-        if ( provider != null ) {
-            provider.delete(resource);
-            return;
-        }
-        throw new UnsupportedOperationException("delete at '" + path + "'");
-    }
-
-    /**
-     * Revert changes on all modifiable ResourceProviders.
-     */
-    public void revert(final ResourceResolverContext context) {
-        for (final AuthenticatedResourceProvider p : context.getProviderManager().getAllUsedModifiable()) {
-            p.revert();
-        }
-    }
-
-    /**
-     * Commit changes on all modifiable ResourceProviders.
-     */
-    public void commit(final ResourceResolverContext context) throws PersistenceException {
-        for (final AuthenticatedResourceProvider p : context.getProviderManager().getAllUsedModifiable()) {
-            p.commit();
-        }
-    }
-
-    /**
-     * Check if any modifiable ResourceProvider has uncommited changes.
-     */
-    public boolean hasChanges(final ResourceResolverContext context) {
-        for (final AuthenticatedResourceProvider p : context.getProviderManager().getAllUsedModifiable()) {
-            if (p.hasChanges()) {
-                return true;
-            }
-        }
-        return false;
-    }
-
-    /**
-     * Return the union of query languages supported by the providers.
-     */
-    public String[] getSupportedLanguages(final ResourceResolverContext context) {
-        final Set<String> supportedLanguages = new LinkedHashSet<String>();
-        for (AuthenticatedResourceProvider p : context.getProviderManager().getAllBestEffort(getResourceProviderStorage().getLanguageQueryableHandlers(), this)) {
-            supportedLanguages.addAll(Arrays.asList(p.getSupportedLanguages()));
-        }
-        return supportedLanguages.toArray(new String[supportedLanguages.size()]);
-    }
-
-    /**
-     * Queries all resource providers and combines the results.
-     */
-    public Iterator<Resource> findResources(final ResourceResolverContext context,
-            final String query, final String language) {
-        final List<AuthenticatedResourceProvider> queryableRP = getQueryableProviders(context, language);
-        final List<Iterator<Resource>> iterators = new ArrayList<Iterator<Resource>>(queryableRP.size());
-        for (AuthenticatedResourceProvider p : queryableRP) {
-            iterators.add(p.findResources(query, language));
-        }
-        return new ChainedIterator<Resource>(iterators.iterator());
-    }
-
-    private List<AuthenticatedResourceProvider> getQueryableProviders(
-            final ResourceResolverContext context,
-            final String language) {
-        final List<AuthenticatedResourceProvider> queryableProviders = new ArrayList<AuthenticatedResourceProvider>();
-        for (final AuthenticatedResourceProvider p : context.getProviderManager().getAllBestEffort(getResourceProviderStorage().getLanguageQueryableHandlers(), this)) {
-            if (ArrayUtils.contains(p.getSupportedLanguages(), language)) {
-                queryableProviders.add(p);
-            }
-        }
-        return queryableProviders;
-    }
-
-    /**
-     * Queries all resource providers and combines the results.
-     */
-    public Iterator<Map<String, Object>> queryResources(final ResourceResolverContext context,
-            final String query, final String language) {
-        final List<AuthenticatedResourceProvider> queryableRP = getQueryableProviders(context, language);
-        final List<Iterator<Map<String, Object>>> iterators = new ArrayList<Iterator<Map<String, Object>>>(queryableRP.size());
-        for (AuthenticatedResourceProvider p : queryableRP) {
-            iterators.add(p.queryResources(query, language));
-        }
-        return new ChainedIterator<Map<String, Object>>(iterators.iterator());
-    }
-
-    /**
-     * Returns the first non-null result of the adaptTo() method invoked on the
-     * providers.
-     */
-    @SuppressWarnings("unchecked")
-    public <AdapterType> AdapterType adaptTo(final ResourceResolverContext context, Class<AdapterType> type) {
-        for (AuthenticatedResourceProvider p : context.getProviderManager().getAllBestEffort(getResourceProviderStorage().getAdaptableHandlers(), this)) {
-            final Object adaptee = p.adaptTo(type);
-            if (adaptee != null) {
-                return (AdapterType) adaptee;
-            }
-        }
-        return null;
-    }
-
-    private AuthenticatedResourceProvider checkSourceAndDest(final ResourceResolverContext context,
-            final String srcAbsPath, final String destAbsPath) throws PersistenceException {
-        // check source
-        final Node<ResourceProviderHandler> srcNode = getResourceProviderStorage().getTree().getBestMatchingNode(srcAbsPath);
-        if ( srcNode == null ) {
-            throw new PersistenceException("Source resource does not exist.", null, srcAbsPath, null);
-        }
-        AuthenticatedResourceProvider srcProvider = null;
-        try {
-            srcProvider = context.getProviderManager().getOrCreateProvider(srcNode.getValue(), this);
-        } catch (LoginException e) {
-            // ignore
-        }
-        if ( srcProvider == null ) {
-            throw new PersistenceException("Source resource does not exist.", null, srcAbsPath, null);
-        }
-        final Resource srcResource = srcProvider.getResource(srcAbsPath, null, null);
-        if ( srcResource == null ) {
-            throw new PersistenceException("Source resource does not exist.", null, srcAbsPath, null);
-        }
-
-        // check destination
-        final Node<ResourceProviderHandler> destNode = getResourceProviderStorage().getTree().getBestMatchingNode(destAbsPath);
-        if ( destNode == null ) {
-            throw new PersistenceException("Destination resource does not exist.", null, destAbsPath, null);
-        }
-        AuthenticatedResourceProvider destProvider = null;
-        try {
-            destProvider = context.getProviderManager().getOrCreateProvider(destNode.getValue(), this);
-        } catch (LoginException e) {
-            // ignore
-        }
-        if ( destProvider == null ) {
-            throw new PersistenceException("Destination resource does not exist.", null, destAbsPath, null);
-        }
-        final Resource destResource = destProvider.getResource(destAbsPath, null, null);
-        if ( destResource == null ) {
-            throw new PersistenceException("Destination resource does not exist.", null, destAbsPath, null);
-        }
-
-        // check for sub providers of src and dest
-        if ( srcProvider == destProvider && !collectProviders(context, srcNode) && !collectProviders(context, destNode) ) {
-            return srcProvider;
-        }
-        return null;
-    }
-
-    private boolean collectProviders(final ResourceResolverContext context,
-            final Node<ResourceProviderHandler> parent) {
-        boolean hasMoreProviders = false;
-        for (final Entry<String, Node<ResourceProviderHandler>> entry : parent.getChildren().entrySet()) {
-            if ( entry.getValue().getValue() != null ) {
-                try {
-                    context.getProviderManager().getOrCreateProvider(entry.getValue().getValue(), this);
-                    hasMoreProviders = true;
-                } catch ( final LoginException ignore) {
-                    // ignore
-                }
-            }
-            if ( collectProviders(context, entry.getValue())) {
-                hasMoreProviders = true;
-            }
-        }
-
-        return hasMoreProviders;
-    }
-
-    private void copy(final ResourceResolverContext context, final Resource src, final String dstPath, final List<Resource> newNodes) throws PersistenceException {
-        final ValueMap vm = src.getValueMap();
-        final String createPath = new PathBuilder(dstPath).append(src.getName()).toString();
-        newNodes.add(this.create(context, createPath, vm));
-        for(final Resource c : src.getChildren()) {
-            copy(context, c, createPath, newNodes);
-        }
-    }
-
-    /**
-     * Tries to find a resource provider accepting both paths and invokes
-     * {@link AuthenticatedResourceProvider#copy(String, String)} method on it.
-     * Returns false if there's no such provider.
-     */
-    public Resource copy(final ResourceResolverContext context,
-            final String srcAbsPath, final String destAbsPath) throws PersistenceException {
-        final AuthenticatedResourceProvider optimizedSourceProvider = checkSourceAndDest(context, srcAbsPath, destAbsPath);
-        if ( optimizedSourceProvider != null && optimizedSourceProvider.copy(srcAbsPath, destAbsPath) ) {
-            return this.getResource(context, destAbsPath + '/' + ResourceUtil.getName(srcAbsPath), null, null, false);
-        }
-
-        final Resource srcResource = this.getResource(context, srcAbsPath, null, null, false);
-        final List<Resource> newResources = new ArrayList<Resource>();
-        boolean rollback = true;
-        try {
-            this.copy(context, srcResource, destAbsPath, newResources);
-            rollback = false;
-            return newResources.get(0);
-        } finally {
-            if ( rollback ) {
-                for(final Resource rsrc : newResources) {
-                    this.delete(context, rsrc);
-                }
-            }
-        }
-    }
-
-    /**
-     * Tries to find a resource provider accepting both paths and invokes
-     * {@link AuthenticatedResourceProvider#move(String, String)} method on it.
-     * Returns false if there's no such provider.
-     */
-    public Resource move(final ResourceResolverContext context,
-            String srcAbsPath, String destAbsPath) throws PersistenceException {
-        final AuthenticatedResourceProvider optimizedSourceProvider = checkSourceAndDest(context, srcAbsPath, destAbsPath);
-        if ( optimizedSourceProvider != null && optimizedSourceProvider.move(srcAbsPath, destAbsPath) ) {
-            return this.getResource(context, destAbsPath + '/' + ResourceUtil.getName(srcAbsPath), null, null, false);
-        }
-        final Resource srcResource = this.getResource(context, srcAbsPath, null, null, false);
-        final List<Resource> newResources = new ArrayList<Resource>();
-        boolean rollback = true;
-        try {
-            this.copy(context, srcResource, destAbsPath, newResources);
-            this.delete(context, srcResource);
-            rollback = false;
-            return newResources.get(0);
-        } finally {
-            if ( rollback ) {
-                for(final Resource rsrc : newResources) {
-                    this.delete(context, rsrc);
-                }
-            }
-        }
-    }
-
-    public ResourceProviderStorage getResourceProviderStorage() {
-        return this.resourceProviderTracker.getResourceProviderStorage();
-    }
-
-    /**
-     * @param path
-     * @return
-     */
-    private @CheckForNull AuthenticatedResourceProvider getBestMatchingProvider(final ResourceResolverContext context,
-            final String path) {
-        try {
-            final Node<ResourceProviderHandler> node = resourceProviderTracker.getResourceProviderStorage().getTree().getBestMatchingNode(path);
-            return node == null ? null : context.getProviderManager().getOrCreateProvider(node.getValue(), this);
-        } catch ( final LoginException le ) {
-            // ignore
-            return null;
-        }
-    }
-
-    /**
-     * @param path
-     * @return The modifiable provider or {@code null}
-     */
-    private @CheckForNull AuthenticatedResourceProvider getBestMatchingModifiableProvider(
-            final ResourceResolverContext context,
-            final String path)  {
-        final Node<ResourceProviderHandler> node = resourceProviderTracker.getResourceProviderStorage().getTree().getBestMatchingNode(path);
-        if ( node != null && node.getValue().getInfo().isModifiable() ) {
-            try {
-                return context.getProviderManager().getOrCreateProvider(node.getValue(), this);
-            } catch ( final LoginException le ) {
-                // ignore
-                return null;
-            }
-        }
-        return null;
-    }
-
-
-    /**
-     * Close all dynamic resource providers.
-     */
-    public void close() {
-        if (this.isClosed.compareAndSet(false, true)) {
-            this.logout();
-            if ( this.resourceTypeResourceResolver != null ) {
-                try {
-                    this.resourceTypeResourceResolver.close();
-                } catch ( final Throwable t) {
-                    // the resolver (or the underlying provider) might already be terminated (bundle stopped etc.)
-                    // so we ignore anything from here
-                }
-                this.resourceTypeResourceResolver = null;
-            }
-        }
-    }
-
-    @SuppressWarnings("deprecation")
-    private ResourceResolver getResourceTypeResourceResolver(
-            final ResourceResolverFactory factory,
-            final ResourceResolver resolver) {
-        if ( this.isAdmin ) {
-            return resolver;
-        } else {
-            if ( this.resourceTypeResourceResolver == null ) {
-                try {
-                    this.resourceTypeResourceResolver = factory.getAdministrativeResourceResolver(null);
-                } catch (final LoginException e) {
-                    // we simply ignore this and return null
-                }
-            }
-            return this.resourceTypeResourceResolver;
-        }
-    }
-
-    /**
-     * Get the parent resource type
-     *
-     * @see org.apache.sling.api.resource.ResourceResolver#getParentResourceType(java.lang.String)
-     */
-    public String getParentResourceType(
-            final ResourceResolverFactory factory,
-            final ResourceResolver resolver,
-            final String resourceType) {
-        // normalize resource type to a path string
-        final String rtPath = (resourceType == null ? null : ResourceUtil.resourceTypeToPath(resourceType));
-        // get the resource type resource and check its super type
-        String resourceSuperType = null;
-
-        if ( rtPath != null ) {
-            ResourceResolver adminResolver = this.getResourceTypeResourceResolver(factory, resolver);
-            if ( adminResolver != null ) {
-                final Resource rtResource = adminResolver.getResource(rtPath);
-                if (rtResource != null) {
-                    resourceSuperType = rtResource.getResourceSuperType();
-                }
-            }
-        }
-        return resourceSuperType;
-    }
-
-    /**
-     * Returns {@link #getProperty(Resource, String, Class) getProperty(res,
-     * propName, String.class)}
-     *
-     * @param res The resource to access the property from
-     * @param propName The name of the property to access
-     * @return The property as a {@code String} or {@code null} if the property
-     *         does not exist or cannot be converted into a {@code String}
-     */
-    public static String getProperty(final Resource res, final String propName) {
-        return getProperty(res, propName, String.class);
-    }
-
-    /**
-     * Returns the value of the name property of the resource converted to the
-     * requested {@code type}.
-     * <p>
-     * If the resource itself does not have the property, the property is looked
-     * up in the {@code jcr:content} child node. This access is done through the
-     * same {@code ValueMap} as is used to access the property directly. This
-     * generally only works for JCR based {@code ValueMap} instances which
-     * provide access to relative path property names. This may not work in non
-     * JCR {@code ValueMap}, however in non JCR envs there is usually no
-     * "jcr:content" child node anyway
-     *
-     * @param res The resource to access the property from
-     * @param propName The name of the property to access
-     * @param type The type into which to convert the property
-     * @return The property converted to the requested {@code type} or
-     *         {@code null} if the property does not exist or cannot be
-     *         converted into the requested {@code type}
-     */
-    public static <Type> Type getProperty(final Resource res, final String propName, final Class<Type> type) {
-
-        // check the property in the resource itself
-        final ValueMap props = res.adaptTo(ValueMap.class);
-        if (props != null) {
-            Type prop = props.get(propName, type);
-            if (prop != null) {
-                return prop;
-            }
-            // otherwise, check it in the jcr:content child resource
-            // This is a special case checking for JCR based resources
-            // we directly use the deep resolution of properties of the
-            // JCR value map implementation - this does not work
-            // in non JCR environments, however in non JCR envs there
-            // is usually no "jcr:content" child node anyway
-            prop = props.get("jcr:content/" + propName, type);
-            return prop;
-        }
-
-        return null;
-    }
-
-    public void registerAuthenticatedProvider(@Nonnull ResourceProviderHandler handler,
-            @CheckForNull Object providerState) {
-        this.authenticatedProviders.put(handler, providerState);
-    }
-
-    public void clearAuthenticatedProviders() {
-        this.authenticatedProviders.clear();
-    }
-}
diff --git a/src/main/java/org/apache/sling/resourceresolver/impl/helper/StarResource.java b/src/main/java/org/apache/sling/resourceresolver/impl/helper/StarResource.java
deleted file mode 100644
index 74f148d..0000000
--- a/src/main/java/org/apache/sling/resourceresolver/impl/helper/StarResource.java
+++ /dev/null
@@ -1,111 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *   http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-package org.apache.sling.resourceresolver.impl.helper;
-
-import org.apache.sling.adapter.annotations.Adaptable;
-import org.apache.sling.adapter.annotations.Adapter;
-import org.apache.sling.api.SlingException;
-import org.apache.sling.api.resource.Resource;
-import org.apache.sling.api.resource.ResourceMetadata;
-import org.apache.sling.api.resource.ResourceResolver;
-import org.apache.sling.api.resource.SyntheticResource;
-
-/**
- * Used to provide the equivalent of an empty Node for GET requests to
- * *.something (SLING-344)
- */
-@Adaptable(adaptableClass = Resource.class, adapters = @Adapter(value = { String.class }))
-public class StarResource extends SyntheticResource {
-
-    final static String SLASH_STAR = "/*";
-    public final static String DEFAULT_RESOURCE_TYPE = "sling:syntheticStarResource";
-
-    private static final String UNSET_RESOURCE_SUPER_TYPE = "<unset>";
-
-    private String resourceSuperType;
-
-    @SuppressWarnings("serial")
-    static class SyntheticStarResourceException extends SlingException {
-        SyntheticStarResourceException(String reason, Throwable cause) {
-            super(reason, cause);
-        }
-    }
-
-    /**
-     * True if a StarResource should be used for the given request, if a real
-     * Resource was not found
-     */
-    public static boolean appliesTo(String path) {
-        return path.contains(SLASH_STAR) || path.endsWith(SLASH_STAR);
-    }
-
-    /**
-     * Returns true if the path of the resource ends with the
-     * {@link #SLASH_STAR} and therefore should be considered a star resource.
-     */
-    public static boolean isStarResource(Resource res) {
-        return res.getPath().endsWith(SLASH_STAR);
-    }
-
-    public StarResource(ResourceResolver resourceResolver, String path) {
-        super(resourceResolver, getResourceMetadata(path),
-                DEFAULT_RESOURCE_TYPE);
-        resourceSuperType = UNSET_RESOURCE_SUPER_TYPE;
-    }
-
-    /**
-     * Calls {@link ResourceUtil#getResourceSuperType(ResourceResolver, String)}
-     * method to dynamically resolve the resource super type of this star
-     * resource.
-     */
-    @Override
-    public String getResourceSuperType() {
-        // Yes, this isn't how you're supposed to compare Strings, but this is
-        // intentional.
-        if (resourceSuperType == UNSET_RESOURCE_SUPER_TYPE) {
-            resourceSuperType = this.getResourceResolver().getParentResourceType(this.getResourceType());
-        }
-        return resourceSuperType;
-    }
-
-    @Override
-    @SuppressWarnings("unchecked")
-    public <Type> Type adaptTo(Class<Type> type) {
-        if (type == String.class) {
-            return (Type) "";
-        }
-        return super.adaptTo(type);
-    }
-
-    /** Get our ResourceMetadata for given path */
-    static ResourceMetadata getResourceMetadata(String path) {
-        ResourceMetadata result = new ResourceMetadata();
-
-        // The path is up to /*, what follows is pathInfo
-        final int index = path.indexOf(SLASH_STAR);
-        if (index >= 0) {
-            result.setResolutionPath(path.substring(0, index) + SLASH_STAR);
-            result.setResolutionPathInfo(path.substring(index
-                    + SLASH_STAR.length()));
-        } else {
-            result.setResolutionPath(path);
-        }
-        return result;
-    }
-}
\ No newline at end of file
diff --git a/src/main/java/org/apache/sling/resourceresolver/impl/helper/URI.java b/src/main/java/org/apache/sling/resourceresolver/impl/helper/URI.java
deleted file mode 100644
index 231c65c..0000000
--- a/src/main/java/org/apache/sling/resourceresolver/impl/helper/URI.java
+++ /dev/null
@@ -1,4200 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *   http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-package org.apache.sling.resourceresolver.impl.helper;
-
-import java.io.ByteArrayOutputStream;
-import java.io.IOException;
-import java.io.ObjectInputStream;
-import java.io.ObjectOutputStream;
-import java.io.Serializable;
-import java.io.UnsupportedEncodingException;
-import java.util.Arrays;
-import java.util.BitSet;
-import java.util.HashMap;
-import java.util.Locale;
-
-import org.apache.sling.api.SlingException;
-
-/**
- * The interface for the URI(Uniform Resource Identifiers) version of RFC 2396.
- * This class has the purpose of supportting of parsing a URI reference to
- * extend any specific protocols, the character encoding of the protocol to be
- * transported and the charset of the document.
- * 
- * A URI is always in an "escaped" form, since escaping or unescaping a
- * completed URI might change its semantics.
- * 
- * Implementers should be careful not to escape or unescape the same string more
- * than once, since unescaping an already unescaped string might lead to
- * misinterpreting a percent data character as another escaped character, or
- * vice versa in the case of escaping an already escaped string.
- * 
- * In order to avoid these problems, data types used as follows:
- * 
- * <blockquote>
- *
- * <pre>
- *   URI character sequence: char
- *   octet sequence: byte
- *   original character sequence: String
- * </pre>
- *
- * </blockquote>
- * 
- * So, a URI is a sequence of characters as an array of a char type, which is
- * not always represented as a sequence of octets as an array of byte.
- * 
- * URI Syntactic Components
- * 
- * <blockquote>
- *
- * <pre>
- * - In general, written as follows:
- *   Absolute URI = &lt;scheme&gt:&lt;scheme-specific-part&gt;
- *   Generic URI = &lt;scheme&gt;://&lt;authority&gt;&lt;path&gt;?&lt;query&gt;
- * - Syntax
- *   absoluteURI   = scheme ":" ( hier_part | opaque_part )
- *   hier_part     = ( net_path | abs_path ) [ "?" query ]
- *   net_path      = "//" authority [ abs_path ]
- *   abs_path      = "/"  path_segments
- * </pre>
- *
- * </blockquote>
- * 
- * The following examples illustrate URI that are in common use.
- *
- * <pre>
- * ftp://ftp.is.co.za/rfc/rfc1808.txt
- *    -- ftp scheme for File Transfer Protocol services
- * gopher://spinaltap.micro.umn.edu/00/Weather/California/Los%20Angeles
- *    -- gopher scheme for Gopher and Gopher+ Protocol services
- * http://www.math.uio.no/faq/compression-faq/part1.html
- *    -- http scheme for Hypertext Transfer Protocol services
- * mailto:mduerst@ifi.unizh.ch
- *    -- mailto scheme for electronic mail addresses
- * news:comp.infosystems.www.servers.unix
- *    -- news scheme for USENET news groups and articles
- * telnet://melvyl.ucop.edu/
- *    -- telnet scheme for interactive services via the TELNET Protocol
- * </pre>
- *
- * Please, notice that there are many modifications from URL(RFC 1738) and
- * relative URL(RFC 1808).
- * 
- * <b>The expressions for a URI</b>
- * 
- *
- * <pre>
- * For escaped URI forms
- *  - URI(char[]) // constructor
- *  - char[] getRawXxx() // method
- *  - String getEscapedXxx() // method
- *  - String toString() // method
- * 
- * For unescaped URI forms
- *  - URI(String) // constructor
- *  - String getXXX() // method
- * </pre>
- * 
- * This class is a slightly modified version of the URI class distributed with
- * Http Client 3.1. The changes involve removing dependencies to other Http
- * Client classes and the Commons Codec library. To this avail the following
- * methods have been added to this class:
- * <ul>
- * <li>getBytes, getAsciiString, getString, getAsciiBytes has been copied from
- * the Http Client 3.1 EncodingUtils class.</li>
- * <li>encodeUrl and decodeUrl have been copied from the Commons Codec URLCodec
- * class.</li>
- * </ul>
- * The signatures have been simplified and adapted to the use in this class.
- * Also the exception thrown has been changed to be {@link URIException}.
- */
-public class URI implements Cloneable, Comparable<URI>, Serializable {
-
-    // ----------------------------------------------------------- Constructors
-
-    /** Create an instance as an internal use */
-    protected URI() {
-    }
-
-    /**
-     * Construct a URI from a string with the given charset. The input string
-     * can be either in escaped or unescaped form.
-     *
-     * @param s URI character sequence
-     * @param escaped <tt>true</tt> if URI character sequence is in escaped
-     *            form. <tt>false</tt> otherwise.
-     * @param charset the charset string to do escape encoding, if required
-     * @throws URIException If the URI cannot be created.
-     * @throws NullPointerException if input string is <code>null</code>
-     * @see #getProtocolCharset
-     * @since 3.0
-     */
-    public URI(String s, boolean escaped, String charset) throws URIException,
-            NullPointerException {
-        protocolCharset = charset;
-        parseUriReference(s, escaped);
-    }
-
-    /**
-     * Construct a URI from a string with the given charset. The input string
-     * can be either in escaped or unescaped form.
-     *
-     * @param s URI character sequence
-     * @param escaped <tt>true</tt> if URI character sequence is in escaped
-     *            form. <tt>false</tt> otherwise.
-     * @throws URIException If the URI cannot be created.
-     * @throws NullPointerException if input string is <code>null</code>
-     * @see #getProtocolCharset
-     * @since 3.0
-     */
-    public URI(String s, boolean escaped) throws URIException,
-            NullPointerException {
-        parseUriReference(s, escaped);
-    }
-
-    /**
-     * Construct a general URI from the given components.
-     * 
-     * <blockquote>
-     *
-     * <pre>
-     *   URI-reference = [ absoluteURI | relativeURI ] [ "#" fragment ]
-     *   absoluteURI   = scheme ":" ( hier_part | opaque_part )
-     *   opaque_part   = uric_no_slash *uric
-     * </pre>
-     *
-     * </blockquote>
-     * 
-     * It's for absolute URI = &lt;scheme&gt;:&lt;scheme-specific-part&gt;#
-     * &lt;fragment&gt;.
-     *
-     * @param scheme the scheme string
-     * @param schemeSpecificPart scheme_specific_part
-     * @param fragment the fragment string
-     * @throws URIException If the URI cannot be created.
-     * @see #getDefaultProtocolCharset
-     */
-    public URI(String scheme, String schemeSpecificPart, String fragment)
-            throws URIException {
-
-        // validate and contruct the URI character sequence
-        if (scheme == null) {
-            throw new URIException(URIException.PARSING, "scheme required");
-        }
-        char[] s = scheme.toLowerCase().toCharArray();
-        if (validate(s, URI.scheme)) {
-            _scheme = s; // is_absoluteURI
-        } else {
-            throw new URIException(URIException.PARSING, "incorrect scheme");
-        }
-        _opaque = encode(schemeSpecificPart, allowed_opaque_part,
-            getProtocolCharset());
-        // Set flag
-        _is_opaque_part = true;
-        _fragment = fragment == null ? null : fragment.toCharArray();
-        setURI();
-    }
-
-    /**
-     * Construct a general URI from the given components.
-     * 
-     * <blockquote>
-     *
-     * <pre>
-     *   URI-reference = [ absoluteURI | relativeURI ] [ "#" fragment ]
-     *   absoluteURI   = scheme ":" ( hier_part | opaque_part )
-     *   relativeURI   = ( net_path | abs_path | rel_path ) [ "?" query ]
-     *   hier_part     = ( net_path | abs_path ) [ "?" query ]
-     * </pre>
-     *
-     * </blockquote>
-     * 
-     * It's for absolute URI = &lt;scheme&gt;:&lt;path&gt;?&lt;query&gt;#&lt;
-     * fragment&gt; and relative URI = &lt;path&gt;?&lt;query&gt;#&lt;fragment
-     * &gt;.
-     *
-     * @param scheme the scheme string
-     * @param authority the authority string
-     * @param path the path string
-     * @param query the query string
-     * @param fragment the fragment string
-     * @throws URIException If the new URI cannot be created.
-     * @see #getDefaultProtocolCharset
-     */
-    public URI(String scheme, String authority, String path, String query,
-            String fragment) throws URIException {
-
-        // validate and contruct the URI character sequence
-        StringBuilder buff = new StringBuilder();
-        if (scheme != null) {
-            buff.append(scheme);
-            buff.append(':');
-        }
-        if (authority != null) {
-            buff.append("//");
-            buff.append(authority);
-        }
-        if (path != null) { // accept empty path
-            if ((scheme != null || authority != null) && !path.startsWith("/")) {
-                throw new URIException(URIException.PARSING,
-                    "abs_path requested");
-            }
-            buff.append(path);
-        }
-        if (query != null) {
-            buff.append('?');
-            buff.append(query);
-        }
-        if (fragment != null) {
-            buff.append('#');
-            buff.append(fragment);
-        }
-        parseUriReference(buff.toString(), false);
-    }
-
-    /**
-     * Construct a general URI from the given components.
-     *
-     * @param scheme the scheme string
-     * @param userinfo the userinfo string
-     * @param host the host string
-     * @param port the port number
-     * @throws URIException If the new URI cannot be created.
-     * @see #getDefaultProtocolCharset
-     */
-    public URI(String scheme, String userinfo, String host, int port)
-            throws URIException {
-
-        this(scheme, userinfo, host, port, null, null, null);
-    }
-
-    /**
-     * Construct a general URI from the given components.
-     *
-     * @param scheme the scheme string
-     * @param userinfo the userinfo string
-     * @param host the host string
-     * @param port the port number
-     * @param path the path string
-     * @throws URIException If the new URI cannot be created.
-     * @see #getDefaultProtocolCharset
-     */
-    public URI(String scheme, String userinfo, String host, int port,
-            String path) throws URIException {
-
-        this(scheme, userinfo, host, port, path, null, null);
-    }
-
-    /**
-     * Construct a general URI from the given components.
-     *
-     * @param scheme the scheme string
-     * @param userinfo the userinfo string
-     * @param host the host string
-     * @param port the port number
-     * @param path the path string
-     * @param query the query string
-     * @throws URIException If the new URI cannot be created.
-     * @see #getDefaultProtocolCharset
-     */
-    public URI(String scheme, String userinfo, String host, int port,
-            String path, String query) throws URIException {
-
-        this(scheme, userinfo, host, port, path, query, null);
-    }
-
-    /**
-     * Construct a general URI from the given components.
-     *
-     * @param scheme the scheme string
-     * @param userinfo the userinfo string
-     * @param host the host string
-     * @param port the port number
-     * @param path the path string
-     * @param query the query string
-     * @param fragment the fragment string
-     * @throws URIException If the new URI cannot be created.
-     * @see #getDefaultProtocolCharset
-     */
-    public URI(String scheme, String userinfo, String host, int port,
-            String path, String query, String fragment) throws URIException {
-
-        this(scheme, (host == null) ? null : ((userinfo != null)
-                ? userinfo + '@'
-                : "")
-            + host + ((port != -1) ? ":" + port : ""), path, query, fragment);
-    }
-
-    /**
-     * Construct a general URI from the given components.
-     *
-     * @param scheme the scheme string
-     * @param host the host string
-     * @param path the path string
-     * @param fragment the fragment string
-     * @throws URIException If the new URI cannot be created.
-     * @see #getDefaultProtocolCharset
-     */
-    public URI(String scheme, String host, String path, String fragment)
-            throws URIException {
-
-        this(scheme, host, path, null, fragment);
-    }
-
-    /**
-     * Construct a general URI with the given relative URI string.
-     *
-     * @param base the base URI
-     * @param relative the relative URI string
-     * @param escaped <tt>true</tt> if URI character sequence is in escaped
-     *            form. <tt>false</tt> otherwise.
-     * @throws URIException If the new URI cannot be created.
-     * @since 3.0
-     */
-    public URI(URI base, String relative, boolean escaped) throws URIException {
-        this(base, new URI(relative, escaped));
-    }
-
-    /**
-     * Construct a general URI with the given relative URI.
-     * 
-     * <blockquote>
-     *
-     * <pre>
-     *   URI-reference = [ absoluteURI | relativeURI ] [ "#" fragment ]
-     *   relativeURI   = ( net_path | abs_path | rel_path ) [ "?" query ]
-     * </pre>
-     *
-     * </blockquote>
-     * 
-     * Resolving Relative References to Absolute Form. <strong>Examples of
-     * Resolving Relative URI References</strong> Within an object with a
-     * well-defined base URI of
-     * 
-     * <blockquote>
-     *
-     * <pre>
-     *   http://a/b/c/d;p?q
-     * </pre>
-     *
-     * </blockquote>
-     * 
-     * the relative URI would be resolved as follows: Normal Examples
-     * 
-     * <blockquote>
-     *
-     * <pre>
-     *   g:h           =  g:h
-     *   g             =  http://a/b/c/g
-     *   ./g           =  http://a/b/c/g
-     *   g/            =  http://a/b/c/g/
-     *   /g            =  http://a/g
-     *   //g           =  http://g
-     *   ?y            =  http://a/b/c/?y
-     *   g?y           =  http://a/b/c/g?y
-     *   #s            =  (current document)#s
-     *   g#s           =  http://a/b/c/g#s
-     *   g?y#s         =  http://a/b/c/g?y#s
-     *   ;x            =  http://a/b/c/;x
-     *   g;x           =  http://a/b/c/g;x
-     *   g;x?y#s       =  http://a/b/c/g;x?y#s
-     *   .             =  http://a/b/c/
-     *   ./            =  http://a/b/c/
-     *   ..            =  http://a/b/
-     *   ../           =  http://a/b/
-     *   ../g          =  http://a/b/g
-     *   ../..         =  http://a/
-     *   ../../        =  http://a/
-     *   ../../g       =  http://a/g
-     * </pre>
-     *
-     * </blockquote>
-     * 
-     * Some URI schemes do not allow a hierarchical syntax matching the
-     * <hier_part> syntax, and thus cannot use relative references.
-     *
-     * @param base the base URI
-     * @param relative the relative URI
-     * @throws URIException If the new URI cannot be created.
-     */
-    public URI(URI base, URI relative) throws URIException {
-
-        if (base._scheme == null) {
-            throw new URIException(URIException.PARSING, "base URI required");
-        }
-        if (base._scheme != null) {
-            this._scheme = base._scheme;
-            this._authority = base._authority;
-            this._is_net_path = base._is_net_path;
-        }
-        if (base._is_opaque_part || relative._is_opaque_part) {
-            this._scheme = base._scheme;
-            this._is_opaque_part = base._is_opaque_part
-                || relative._is_opaque_part;
-            this._opaque = relative._opaque;
-            this._fragment = relative._fragment;
-            this.setURI();
-            return;
-        }
-        boolean schemesEqual = Arrays.equals(base._scheme, relative._scheme);
-        if (relative._scheme != null
-            && (!schemesEqual || relative._authority != null)) {
-            this._scheme = relative._scheme;
-            this._is_net_path = relative._is_net_path;
-            this._authority = relative._authority;
-            if (relative._is_server) {
-                this._is_server = relative._is_server;
-                this._userinfo = relative._userinfo;
-                this._host = relative._host;
-                this._port = relative._port;
-            } else if (relative._is_reg_name) {
-                this._is_reg_name = relative._is_reg_name;
-            }
-            this._is_abs_path = relative._is_abs_path;
-            this._is_rel_path = relative._is_rel_path;
-            this._path = relative._path;
-        } else if (base._authority != null && relative._scheme == null) {
-            this._is_net_path = base._is_net_path;
-            this._authority = base._authority;
-            if (base._is_server) {
-                this._is_server = base._is_server;
-                this._userinfo = base._userinfo;
-                this._host = base._host;
-                this._port = base._port;
-            } else if (base._is_reg_name) {
-                this._is_reg_name = base._is_reg_name;
-            }
-        }
-        if (relative._authority != null) {
-            this._is_net_path = relative._is_net_path;
-            this._authority = relative._authority;
-            if (relative._is_server) {
-                this._is_server = relative._is_server;
-                this._userinfo = relative._userinfo;
-                this._host = relative._host;
-                this._port = relative._port;
-            } else if (relative._is_reg_name) {
-                this._is_reg_name = relative._is_reg_name;
-            }
-            this._is_abs_path = relative._is_abs_path;
-            this._is_rel_path = relative._is_rel_path;
-            this._path = relative._path;
-        }
-        // resolve the path and query if necessary
-        if (relative._authority == null
-            && (relative._scheme == null || schemesEqual)) {
-            if ((relative._path == null || relative._path.length == 0)
-                && relative._query == null) {
-                // handle a reference to the current document, see RFC 2396
-                // section 5.2 step 2
-                this._path = base._path;
-                this._query = base._query;
-            } else {
-                this._path = resolvePath(base._path, relative._path);
-            }
-        }
-        // base._query removed
-        if (relative._query != null) {
-            this._query = relative._query;
-        }
-        // base._fragment removed
-        if (relative._fragment != null) {
-            this._fragment = relative._fragment;
-        }
-        this.setURI();
-        // reparse the newly built URI, this will ensure that all flags are set
-        // correctly.
-        // TODO there must be a better way to do this
-        parseUriReference(new String(_uri), true);
-    }
-
-    // --------------------------------------------------- Instance Variables
-
-    /** Version ID for serialization */
-    static final long serialVersionUID = 604752400577948726L;
-
-    /**
-     * Cache the hash code for this URI.
-     */
-    protected int hash = 0;
-
-    /**
-     * This Uniform Resource Identifier (URI). The URI is always in an "escaped"
-     * form, since escaping or unescaping a completed URI might change its
-     * semantics.
-     */
-    protected char[] _uri = null;
-
-    /**
-     * The charset of the protocol used by this URI instance.
-     */
-    protected String protocolCharset = null;
-
-    /**
-     * The default charset of the protocol. RFC 2277, 2396
-     */
-    protected static String defaultProtocolCharset = "UTF-8";
-
-    /**
-     * The default charset of the document. RFC 2277, 2396 The platform's
-     * charset is used for the document by default.
-     */
-    protected static String defaultDocumentCharset = null;
-
-    protected static String defaultDocumentCharsetByLocale = null;
-
-    protected static String defaultDocumentCharsetByPlatform = null;
-    // Static initializer for defaultDocumentCharset
-    static {
-        Locale locale = Locale.getDefault();
-        // in order to support backward compatiblity
-        if (locale != null) {
-            defaultDocumentCharsetByLocale = LocaleToCharsetMap.getCharset(locale);
-            // set the default document charset
-            defaultDocumentCharset = defaultDocumentCharsetByLocale;
-        }
-        // in order to support platform encoding
-        try {
-            defaultDocumentCharsetByPlatform = System.getProperty("file.encoding");
-        } catch (SecurityException ignore) {
-        }
-        if (defaultDocumentCharset == null) {
-            // set the default document charset
-            defaultDocumentCharset = defaultDocumentCharsetByPlatform;
-        }
-    }
-
-    /**
-     * The scheme.
-     */
-    protected char[] _scheme = null;
-
-    /**
-     * The opaque.
-     */
-    protected char[] _opaque = null;
-
-    /**
-     * The authority.
-     */
-    protected char[] _authority = null;
-
-    /**
-     * The userinfo.
-     */
-    protected char[] _userinfo = null;
-
-    /**
-     * The host.
-     */
-    protected char[] _host = null;
-
-    /**
-     * The port.
-     */
-    protected int _port = -1;
-
-    /**
-     * The path.
-     */
-    protected char[] _path = null;
-
-    /**
-     * The query.
-     */
-    protected char[] _query = null;
-
-    /**
-     * The fragment.
-     */
-    protected char[] _fragment = null;
-
-    /**
-     * The root path.
-     */
-    protected static final char[] rootPath = { '/' };
-
-    // ---------------------- Generous characters for each component validation
-
-    /**
-     * The percent "%" character always has the reserved purpose of being the
-     * escape indicator, it must be escaped as "%25" in order to be used as data
-     * within a URI.
-     */
-    protected static final BitSet percent = new BitSet(256);
-    // Static initializer for percent
-    static {
-        percent.set('%');
-    }
-
-    /**
-     * BitSet for digit.
-     * 
-     * <blockquote>
-     *
-     * <pre>
-     * digit = &quot;0&quot; | &quot;1&quot; | &quot;2&quot; | &quot;3&quot; | &quot;4&quot; | &quot;5&quot; | &quot;6&quot; | &quot;7&quot; | &quot;8&quot; | &quot;9&quot;
-     * </pre>
-     *
-     * </blockquote>
-     * 
-     */
-    protected static final BitSet digit = new BitSet(256);
-    // Static initializer for digit
-    static {
-        for (int i = '0'; i <= '9'; i++) {
-            digit.set(i);
-        }
-    }
-
-    /**
-     * BitSet for alpha.
-     * 
-     * <blockquote>
-     *
-     * <pre>
-     * alpha = lowalpha | upalpha
-     * </pre>
-     *
-     * </blockquote>
-     * 
-     */
-    protected static final BitSet alpha = new BitSet(256);
-    // Static initializer for alpha
-    static {
-        for (int i = 'a'; i <= 'z'; i++) {
-            alpha.set(i);
-        }
-        for (int i = 'A'; i <= 'Z'; i++) {
-            alpha.set(i);
-        }
-    }
-
-    /**
-     * BitSet for alphanum (join of alpha &amp; digit).
-     * 
-     * <blockquote>
-     *
-     * <pre>
-     * alphanum = alpha | digit
-     * </pre>
-     *
-     * </blockquote>
-     * 
-     */
-    protected static final BitSet alphanum = new BitSet(256);
-    // Static initializer for alphanum
-    static {
-        alphanum.or(alpha);
-        alphanum.or(digit);
-    }
-
-    /**
-     * BitSet for hex.
-     * 
-     * <blockquote>
-     *
-     * <pre>
-     * hex = digit | &quot;A&quot; | &quot;B&quot; | &quot;C&quot; | &quot;D&quot; | &quot;E&quot; | &quot;F&quot; | &quot;a&quot; | &quot;b&quot; | &quot;c&quot; | &quot;d&quot; | &quot;e&quot;
-     *     | &quot;f&quot;
-     * </pre>
-     *
-     * </blockquote>
-     * 
-     */
-    protected static final BitSet hex = new BitSet(256);
-    // Static initializer for hex
-    static {
-        hex.or(digit);
-        for (int i = 'a'; i <= 'f'; i++) {
-            hex.set(i);
-        }
-        for (int i = 'A'; i <= 'F'; i++) {
-            hex.set(i);
-        }
-    }
-
-    /**
-     * BitSet for escaped.
-     * 
-     * <blockquote>
-     *
-     * <pre>
-     * escaped       = "%" hex hex
-     * </pre>
-     *
-     * </blockquote>
-     * 
-     */
-    protected static final BitSet escaped = new BitSet(256);
-    // Static initializer for escaped
-    static {
-        escaped.or(percent);
-        escaped.or(hex);
-    }
-
-    /**
-     * BitSet for mark.
-     * 
-     * <blockquote>
-     *
-     * <pre>
-     * mark = &quot;-&quot; | &quot;_&quot; | &quot;.&quot; | &quot;!&quot; | &quot;&tilde;&quot; | &quot;*&quot; | &quot;'&quot; | &quot;(&quot; | &quot;)&quot;
-     * </pre>
-     *
-     * </blockquote>
-     * 
-     */
-    protected static final BitSet mark = new BitSet(256);
-    // Static initializer for mark
-    static {
-        mark.set('-');
-        mark.set('_');
-        mark.set('.');
-        mark.set('!');
-        mark.set('~');
-        mark.set('*');
-        mark.set('\'');
-        mark.set('(');
-        mark.set(')');
-    }
-
-    /**
-     * Data characters that are allowed in a URI but do not have a reserved
-     * purpose are called unreserved.
-     * 
-     * <blockquote>
-     *
-     * <pre>
-     * unreserved = alphanum | mark
-     * </pre>
-     *
-     * </blockquote>
-     * 
-     */
-    protected static final BitSet unreserved = new BitSet(256);
-    // Static initializer for unreserved
-    static {
-        unreserved.or(alphanum);
-        unreserved.or(mark);
-    }
-
-    /**
-     * BitSet for reserved.
-     * 
-     * <blockquote>
-     *
-     * <pre>
-     * reserved = &quot;;&quot; | &quot;/&quot; | &quot;?&quot; | &quot;:&quot; | &quot;@&quot; | &quot;&amp;&quot; | &quot;=&quot; | &quot;+&quot; | &quot;$&quot; | &quot;,&quot;
-     * </pre>
-     *
-     * </blockquote>
-     * 
-     */
-    protected static final BitSet reserved = new BitSet(256);
-    // Static initializer for reserved
-    static {
-        reserved.set(';');
-        reserved.set('/');
-        reserved.set('?');
-        reserved.set(':');
-        reserved.set('@');
-        reserved.set('&');
-        reserved.set('=');
-        reserved.set('+');
-        reserved.set('$');
-        reserved.set(',');
-    }
-
-    /**
-     * BitSet for uric.
-     * 
-     * <blockquote>
-     *
-     * <pre>
-     * uric = reserved | unreserved | escaped
-     * </pre>
-     *
-     * </blockquote>
-     * 
-     */
-    protected static final BitSet uric = new BitSet(256);
-    // Static initializer for uric
-    static {
-        uric.or(reserved);
-        uric.or(unreserved);
-        uric.or(escaped);
-    }
-
-    /**
-     * BitSet for fragment (alias for uric).
-     * 
-     * <blockquote>
-     *
-     * <pre>
-     * fragment      = *uric
-     * </pre>
-     *
-     * </blockquote>
-     * 
-     */
-    protected static final BitSet fragment = uric;
-
-    /**
-     * BitSet for query (alias for uric).
-     * 
-     * <blockquote>
-     *
-     * <pre>
-     * query         = *uric
-     * </pre>
-     *
-     * </blockquote>
-     * 
-     */
-    protected static final BitSet query = uric;
-
-    /**
-     * BitSet for pchar.
-     * 
-     * <blockquote>
-     *
-     * <pre>
-     * pchar = unreserved | escaped | &quot;:&quot; | &quot;@&quot; | &quot;&amp;&quot; | &quot;=&quot; | &quot;+&quot; | &quot;$&quot; | &quot;,&quot;
-     * </pre>
-     *
-     * </blockquote>
-     * 
-     */
-    protected static final BitSet pchar = new BitSet(256);
-    // Static initializer for pchar
-    static {
-        pchar.or(unreserved);
-        pchar.or(escaped);
-        pchar.set(':');
-        pchar.set('@');
-        pchar.set('&');
-        pchar.set('=');
-        pchar.set('+');
-        pchar.set('$');
-        pchar.set(',');
-    }
-
-    /**
-     * BitSet for param (alias for pchar).
-     * 
-     * <blockquote>
-     *
-     * <pre>
-     * param         = *pchar
-     * </pre>
-     *
-     * </blockquote>
-     * 
-     */
-    protected static final BitSet param = pchar;
-
-    /**
-     * BitSet for segment.
-     * 
-     * <blockquote>
-     *
-     * <pre>
-     * segment       = *pchar *( ";" param )
-     * </pre>
-     *
-     * </blockquote>
-     * 
-     */
-    protected static final BitSet segment = new BitSet(256);
-    // Static initializer for segment
-    static {
-        segment.or(pchar);
-        segment.set(';');
-        segment.or(param);
-    }
-
-    /**
-     * BitSet for path segments.
-     * 
-     * <blockquote>
-     *
-     * <pre>
-     * path_segments = segment *( "/" segment )
-     * </pre>
-     *
-     * </blockquote>
-     * 
-     */
-    protected static final BitSet path_segments = new BitSet(256);
-    // Static initializer for path_segments
-    static {
-        path_segments.set('/');
-        path_segments.or(segment);
-    }
-
-    /**
-     * URI absolute path.
-     * 
-     * <blockquote>
-     *
-     * <pre>
-     * abs_path      = "/"  path_segments
-     * </pre>
-     *
-     * </blockquote>
-     * 
-     */
-    protected static final BitSet abs_path = new BitSet(256);
-    // Static initializer for abs_path
-    static {
-        abs_path.set('/');
-        abs_path.or(path_segments);
-    }
-
-    /**
-     * URI bitset for encoding typical non-slash characters.
-     * 
-     * <blockquote>
-     *
-     * <pre>
-     * uric_no_slash = unreserved | escaped | &quot;;&quot; | &quot;?&quot; | &quot;:&quot; | &quot;@&quot; | &quot;&amp;&quot; | &quot;=&quot; | &quot;+&quot;
-     *     | &quot;$&quot; | &quot;,&quot;
-     * </pre>
-     *
-     * </blockquote>
-     * 
-     */
-    protected static final BitSet uric_no_slash = new BitSet(256);
-    // Static initializer for uric_no_slash
-    static {
-        uric_no_slash.or(unreserved);
-        uric_no_slash.or(escaped);
-        uric_no_slash.set(';');
-        uric_no_slash.set('?');
-        uric_no_slash.set(';');
-        uric_no_slash.set('@');
-        uric_no_slash.set('&');
-        uric_no_slash.set('=');
-        uric_no_slash.set('+');
-        uric_no_slash.set('$');
-        uric_no_slash.set(',');
-    }
-
-    /**
-     * URI bitset that combines uric_no_slash and uric.
-     * 
-     * <blockquote>
-     *
-     * <pre>
-     * opaque_part = uric_no_slash * uric
-     * </pre>
-     *
-     * </blockquote>
-     * 
-     */
-    protected static final BitSet opaque_part = new BitSet(256);
-    // Static initializer for opaque_part
-    static {
-        // it's generous. because first character must not include a slash
-        opaque_part.or(uric_no_slash);
-        opaque_part.or(uric);
-    }
-
-    /**
-     * URI bitset that combines absolute path and opaque part.
-     * 
-     * <blockquote>
-     *
-     * <pre>
-     * path          = [ abs_path | opaque_part ]
-     * </pre>
-     *
-     * </blockquote>
-     * 
-     */
-    protected static final BitSet path = new BitSet(256);
-    // Static initializer for path
-    static {
-        path.or(abs_path);
-        path.or(opaque_part);
-    }
-
-    /**
-     * Port, a logical alias for digit.
-     */
-    protected static final BitSet port = digit;
-
-    /**
-     * Bitset that combines digit and dot fo IPv$address.
-     * 
-     * <blockquote>
-     *
-     * <pre>
-     * IPv4address   = 1*digit "." 1*digit "." 1*digit "." 1*digit
-     * </pre>
-     *
-     * </blockquote>
-     * 
-     */
-    protected static final BitSet IPv4address = new BitSet(256);
-    // Static initializer for IPv4address
-    static {
-        IPv4address.or(digit);
-        IPv4address.set('.');
-    }
-
-    /**
-     * RFC 2373.
-     * 
-     * <blockquote>
-     *
-     * <pre>
-     * IPv6address = hexpart [ ":" IPv4address ]
-     * </pre>
-     *
-     * </blockquote>
-     * 
-     */
-    protected static final BitSet IPv6address = new BitSet(256);
-    // Static initializer for IPv6address reference
-    static {
-        IPv6address.or(hex); // hexpart
-        IPv6address.set(':');
-        IPv6address.or(IPv4address);
-    }
-
-    /**
-     * RFC 2732, 2373.
-     * 
-     * <blockquote>
-     *
-     * <pre>
-     * IPv6reference   = "[" IPv6address "]"
-     * </pre>
-     *
-     * </blockquote>
-     * 
-     */
-    protected static final BitSet IPv6reference = new BitSet(256);
-    // Static initializer for IPv6reference
-    static {
-        IPv6reference.set('[');
-        IPv6reference.or(IPv6address);
-        IPv6reference.set(']');
-    }
-
-    /**
-     * BitSet for toplabel.
-     * 
-     * <blockquote>
-     *
-     * <pre>
-     * toplabel      = alpha | alpha *( alphanum | "-" ) alphanum
-     * </pre>
-     *
-     * </blockquote>
-     * 
-     */
-    protected static final BitSet toplabel = new BitSet(256);
-    // Static initializer for toplabel
-    static {
-        toplabel.or(alphanum);
-        toplabel.set('-');
-    }
-
-    /**
-     * BitSet for domainlabel.
-     * 
-     * <blockquote>
-     *
-     * <pre>
-     * domainlabel   = alphanum | alphanum *( alphanum | "-" ) alphanum
-     * </pre>
-     *
-     * </blockquote>
-     * 
-     */
-    protected static final BitSet domainlabel = toplabel;
-
-    /**
-     * BitSet for hostname.
-     * 
-     * <blockquote>
-     *
-     * <pre>
-     * hostname      = *( domainlabel "." ) toplabel [ "." ]
-     * </pre>
-     *
-     * </blockquote>
-     * 
-     */
-    protected static final BitSet hostname = new BitSet(256);
-    // Static initializer for hostname
-    static {
-        hostname.or(toplabel);
-        // hostname.or(domainlabel);
-        hostname.set('.');
-    }
-
-    /**
-     * BitSet for host.
-     * 
-     * <blockquote>
-     *
-     * <pre>
-     * host = hostname | IPv4address | IPv6reference
-     * </pre>
-     *
-     * </blockquote>
-     * 
-     */
-    protected static final BitSet host = new BitSet(256);
-    // Static initializer for host
-    static {
-        host.or(hostname);
-        // host.or(IPv4address);
-        host.or(IPv6reference); // IPv4address
-    }
-
-    /**
-     * BitSet for hostport.
-     * 
-     * <blockquote>
-     *
-     * <pre>
-     * hostport      = host [ ":" port ]
-     * </pre>
-     *
-     * </blockquote>
-     * 
-     */
-    protected static final BitSet hostport = new BitSet(256);
-    // Static initializer for hostport
-    static {
-        hostport.or(host);
-        hostport.set(':');
-        hostport.or(port);
-    }
-
-    /**
-     * Bitset for userinfo.
-     * 
-     * <blockquote>
-     *
-     * <pre>
-     * userinfo      = *( unreserved | escaped |
-     *                    ";" | ":" | "&amp;" | "=" | "+" | "$" | "," )
-     * </pre>
-     *
-     * </blockquote>
-     * 
-     */
-    protected static final BitSet userinfo = new BitSet(256);
-    // Static initializer for userinfo
-    static {
-        userinfo.or(unreserved);
-        userinfo.or(escaped);
-        userinfo.set(';');
-        userinfo.set(':');
-        userinfo.set('&');
-        userinfo.set('=');
-        userinfo.set('+');
-        userinfo.set('$');
-        userinfo.set(',');
-    }
-
-    /**
-     * BitSet for within the userinfo component like user and password.
-     */
-    public static final BitSet within_userinfo = new BitSet(256);
-    // Static initializer for within_userinfo
-    static {
-        within_userinfo.or(userinfo);
-        within_userinfo.clear(';'); // reserved within authority
-        within_userinfo.clear(':');
-        within_userinfo.clear('@');
-        within_userinfo.clear('?');
-        within_userinfo.clear('/');
-    }
-
-    /**
-     * Bitset for server.
-     * 
-     * <blockquote>
-     *
-     * <pre>
-     * server        = [ [ userinfo "@" ] hostport ]
-     * </pre>
-     *
-     * </blockquote>
-     * 
-     */
-    protected static final BitSet server = new BitSet(256);
-    // Static initializer for server
-    static {
-        server.or(userinfo);
-        server.set('@');
-        server.or(hostport);
-    }
-
-    /**
-     * BitSet for reg_name.
-     * 
-     * <blockquote>
-     *
-     * <pre>
-     * reg_name = 1 * (unreserved | escaped | &quot;$&quot; | &quot;,&quot; | &quot;;&quot; | &quot;:&quot; | &quot;@&quot; | &quot;&amp;&quot; | &quot;=&quot; | &quot;+&quot;)
-     * </pre>
-     *
-     * </blockquote>
-     * 
-     */
-    protected static final BitSet reg_name = new BitSet(256);
-    // Static initializer for reg_name
-    static {
-        reg_name.or(unreserved);
-        reg_name.or(escaped);
-        reg_name.set('$');
-        reg_name.set(',');
-        reg_name.set(';');
-        reg_name.set(':');
-        reg_name.set('@');
-        reg_name.set('&');
-        reg_name.set('=');
-        reg_name.set('+');
-    }
-
-    /**
-     * BitSet for authority.
-     * 
-     * <blockquote>
-     *
-     * <pre>
-     * authority = server | reg_name
-     * </pre>
-     *
-     * </blockquote>
-     * 
-     */
-    protected static final BitSet authority = new BitSet(256);
-    // Static initializer for authority
-    static {
-        authority.or(server);
-        authority.or(reg_name);
-    }
-
-    /**
-     * BitSet for scheme.
-     * 
-     * <blockquote>
-     *
-     * <pre>
-     * scheme = alpha * (alpha | digit | &quot;+&quot; | &quot;-&quot; | &quot;.&quot;)
-     * </pre>
-     *
-     * </blockquote>
-     * 
-     */
-    protected static final BitSet scheme = new BitSet(256);
-    // Static initializer for scheme
-    static {
-        scheme.or(alpha);
-        scheme.or(digit);
-        scheme.set('+');
-        scheme.set('-');
-        scheme.set('.');
-    }
-
-    /**
-     * BitSet for rel_segment.
-     * 
-     * <blockquote>
-     *
-     * <pre>
-     * rel_segment = 1 * (unreserved | escaped | &quot;;&quot; | &quot;@&quot; | &quot;&amp;&quot; | &quot;=&quot; | &quot;+&quot; | &quot;$&quot; | &quot;,&quot;)
-     * </pre>
-     *
-     * </blockquote>
-     * 
-     */
-    protected static final BitSet rel_segment = new BitSet(256);
-    // Static initializer for rel_segment
-    static {
-        rel_segment.or(unreserved);
-        rel_segment.or(escaped);
-        rel_segment.set(';');
-        rel_segment.set('@');
-        rel_segment.set('&');
-        rel_segment.set('=');
-        rel_segment.set('+');
-        rel_segment.set('$');
-        rel_segment.set(',');
-    }
-
-    /**
-     * BitSet for rel_path.
-     * 
-     * <blockquote>
-     *
-     * <pre>
-     * rel_path = rel_segment[abs_path]
-     * </pre>
-     *
-     * </blockquote>
-     * 
-     */
-    protected static final BitSet rel_path = new BitSet(256);
-    // Static initializer for rel_path
-    static {
-        rel_path.or(rel_segment);
-        rel_path.or(abs_path);
-    }
-
-    /**
-     * BitSet for net_path.
-     * 
-     * <blockquote>
-     *
-     * <pre>
-     * net_path      = "//" authority [ abs_path ]
-     * </pre>
-     *
-     * </blockquote>
-     * 
-     */
-    protected static final BitSet net_path = new BitSet(256);
-    // Static initializer for net_path
-    static {
-        net_path.set('/');
-        net_path.or(authority);
-        net_path.or(abs_path);
-    }
-
-    /**
-     * BitSet for hier_part.
-     * 
-     * <blockquote>
-     *
-     * <pre>
-     * hier_part     = ( net_path | abs_path ) [ "?" query ]
-     * </pre>
-     *
-     * </blockquote>
-     * 
-     */
-    protected static final BitSet hier_part = new BitSet(256);
-    // Static initializer for hier_part
-    static {
-        hier_part.or(net_path);
-        hier_part.or(abs_path);
-        // hier_part.set('?'); aleady included
-        hier_part.or(query);
-    }
-
-    /**
-     * BitSet for relativeURI.
-     * 
-     * <blockquote>
-     *
-     * <pre>
-     * relativeURI   = ( net_path | abs_path | rel_path ) [ "?" query ]
-     * </pre>
-     *
-     * </blockquote>
-     * 
-     */
-    protected static final BitSet relativeURI = new BitSet(256);
-    // Static initializer for relativeURI
-    static {
-        relativeURI.or(net_path);
-        relativeURI.or(abs_path);
-        relativeURI.or(rel_path);
-        // relativeURI.set('?'); aleady included
-        relativeURI.or(query);
-    }
-
-    /**
-     * BitSet for absoluteURI.
-     * 
-     * <blockquote>
-     *
-     * <pre>
-     * absoluteURI   = scheme ":" ( hier_part | opaque_part )
-     * </pre>
-     *
-     * </blockquote>
-     * 
-     */
-    protected static final BitSet absoluteURI = new BitSet(256);
-    // Static initializer for absoluteURI
-    static {
-        absoluteURI.or(scheme);
-        absoluteURI.set(':');
-        absoluteURI.or(hier_part);
-        absoluteURI.or(opaque_part);
-    }
-
-    /**
-     * BitSet for URI-reference.
-     * 
-     * <blockquote>
-     *
-     * <pre>
-     * URI-reference = [ absoluteURI | relativeURI ] [ "#" fragment ]
-     * </pre>
-     *
-     * </blockquote>
-     * 
-     */
-    protected static final BitSet URI_reference = new BitSet(256);
-    // Static initializer for URI_reference
-    static {
-        URI_reference.or(absoluteURI);
-        URI_reference.or(relativeURI);
-        URI_reference.set('#');
-        URI_reference.or(fragment);
-    }
-
-    // ---------------------------- Characters disallowed within the URI syntax
-    // Excluded US-ASCII Characters are like control, space, delims and unwise
-
-    /**
-     * BitSet for control.
-     */
-    public static final BitSet control = new BitSet(256);
-    // Static initializer for control
-    static {
-        for (int i = 0; i <= 0x1F; i++) {
-            control.set(i);
-        }
-        control.set(0x7F);
-    }
-
-    /**
-     * BitSet for space.
-     */
-    public static final BitSet space = new BitSet(256);
-    // Static initializer for space
-    static {
-        space.set(0x20);
-    }
-
-    /**
-     * BitSet for delims.
-     */
-    public static final BitSet delims = new BitSet(256);
-    // Static initializer for delims
-    static {
-        delims.set('<');
-        delims.set('>');
-        delims.set('#');
-        delims.set('%');
-        delims.set('"');
-    }
-
-    /**
-     * BitSet for unwise.
-     */
-    public static final BitSet unwise = new BitSet(256);
-    // Static initializer for unwise
-    static {
-        unwise.set('{');
-        unwise.set('}');
-        unwise.set('|');
-        unwise.set('\\');
-        unwise.set('^');
-        unwise.set('[');
-        unwise.set(']');
-        unwise.set('`');
-    }
-
-    /**
-     * Disallowed rel_path before escaping.
-     */
-    public static final BitSet disallowed_rel_path = new BitSet(256);
-    // Static initializer for disallowed_rel_path
-    static {
-        disallowed_rel_path.or(uric);
-        disallowed_rel_path.andNot(rel_path);
-    }
-
-    /**
-     * Disallowed opaque_part before escaping.
-     */
-    public static final BitSet disallowed_opaque_part = new BitSet(256);
-    // Static initializer for disallowed_opaque_part
-    static {
-        disallowed_opaque_part.or(uric);
-        disallowed_opaque_part.andNot(opaque_part);
-    }
-
-    // ----------------------- Characters allowed within and for each component
-
-    /**
-     * Those characters that are allowed for the authority component.
-     */
-    public static final BitSet allowed_authority = new BitSet(256);
-    // Static initializer for allowed_authority
-    static {
-        allowed_authority.or(authority);
-        allowed_authority.clear('%');
-    }
-
-    /**
-     * Those characters that are allowed for the opaque_part.
-     */
-    public static final BitSet allowed_opaque_part = new BitSet(256);
-    // Static initializer for allowed_opaque_part
-    static {
-        allowed_opaque_part.or(opaque_part);
-        allowed_opaque_part.clear('%');
-    }
-
-    /**
-     * Those characters that are allowed for the reg_name.
-     */
-    public static final BitSet allowed_reg_name = new BitSet(256);
-    // Static initializer for allowed_reg_name
-    static {
-        allowed_reg_name.or(reg_name);
-        // allowed_reg_name.andNot(percent);
-        allowed_reg_name.clear('%');
-    }
-
-    /**
-     * Those characters that are allowed for the userinfo component.
-     */
-    public static final BitSet allowed_userinfo = new BitSet(256);
-    // Static initializer for allowed_userinfo
-    static {
-        allowed_userinfo.or(userinfo);
-        // allowed_userinfo.andNot(percent);
-        allowed_userinfo.clear('%');
-    }
-
-    /**
-     * Those characters that are allowed for within the userinfo component.
-     */
-    public static final BitSet allowed_within_userinfo = new BitSet(256);
-    // Static initializer for allowed_within_userinfo
-    static {
-        allowed_within_userinfo.or(within_userinfo);
-        allowed_within_userinfo.clear('%');
-    }
-
-    /**
-     * Those characters that are allowed for the IPv6reference component. The
-     * characters '[', ']' in IPv6reference should be excluded.
-     */
-    public static final BitSet allowed_IPv6reference = new BitSet(256);
-    // Static initializer for allowed_IPv6reference
-    static {
-        allowed_IPv6reference.or(IPv6reference);
-        // allowed_IPv6reference.andNot(unwise);
-        allowed_IPv6reference.clear('[');
-        allowed_IPv6reference.clear(']');
-    }
-
-    /**
-     * Those characters that are allowed for the host component. The characters
-     * '[', ']' in IPv6reference should be excluded.
-     */
-    public static final BitSet allowed_host = new BitSet(256);
-    // Static initializer for allowed_host
-    static {
-        allowed_host.or(hostname);
-        allowed_host.or(allowed_IPv6reference);
-    }
-
-    /**
-     * Those characters that are allowed for the authority component.
-     */
-    public static final BitSet allowed_within_authority = new BitSet(256);
-    // Static initializer for allowed_within_authority
-    static {
-        allowed_within_authority.or(server);
-        allowed_within_authority.or(reg_name);
-        allowed_within_authority.clear(';');
-        allowed_within_authority.clear(':');
-        allowed_within_authority.clear('@');
-        allowed_within_authority.clear('?');
-        allowed_within_authority.clear('/');
-    }
-
-    /**
-     * Those characters that are allowed for the abs_path.
-     */
-    public static final BitSet allowed_abs_path = new BitSet(256);
-    // Static initializer for allowed_abs_path
-    static {
-        allowed_abs_path.or(abs_path);
-        // allowed_abs_path.set('/'); // aleady included
-        allowed_abs_path.andNot(percent);
-        allowed_abs_path.clear('+');
-    }
-
-    /**
-     * Those characters that are allowed for the rel_path.
-     */
-    public static final BitSet allowed_rel_path = new BitSet(256);
-    // Static initializer for allowed_rel_path
-    static {
-        allowed_rel_path.or(rel_path);
-        allowed_rel_path.clear('%');
-        allowed_rel_path.clear('+');
-    }
-
-    /**
-     * Those characters that are allowed within the path.
-     */
-    public static final BitSet allowed_within_path = new BitSet(256);
-    // Static initializer for allowed_within_path
-    static {
-        allowed_within_path.or(abs_path);
-        allowed_within_path.clear('/');
-        allowed_within_path.clear(';');
-        allowed_within_path.clear('=');
-        allowed_within_path.clear('?');
-    }
-
-    /**
-     * Those characters that are allowed for the query component.
-     */
-    public static final BitSet allowed_query = new BitSet(256);
-    // Static initializer for allowed_query
-    static {
-        allowed_query.or(uric);
-        allowed_query.clear('%');
-    }
-
-    /**
-     * Those characters that are allowed within the query component.
-     */
-    public static final BitSet allowed_within_query = new BitSet(256);
-    // Static initializer for allowed_within_query
-    static {
-        allowed_within_query.or(allowed_query);
-        allowed_within_query.andNot(reserved); // excluded 'reserved'
-    }
-
-    /**
-     * Those characters that are allowed for the fragment component.
-     */
-    public static final BitSet allowed_fragment = new BitSet(256);
-    // Static initializer for allowed_fragment
-    static {
-        allowed_fragment.or(uric);
-        allowed_fragment.clear('%');
-    }
-
-    // ------------------------------------------- Flags for this URI-reference
-
-    // TODO: Figure out what all these variables are for and provide javadoc
-
-    // URI-reference = [ absoluteURI | relativeURI ] [ "#" fragment ]
-    // absoluteURI = scheme ":" ( hier_part | opaque_part )
-    protected boolean _is_hier_part;
-
-    protected boolean _is_opaque_part;
-
-    // relativeURI = ( net_path | abs_path | rel_path ) [ "?" query ]
-    // hier_part = ( net_path | abs_path ) [ "?" query ]
-    protected boolean _is_net_path;
-
-    protected boolean _is_abs_path;
-
-    protected boolean _is_rel_path;
-
-    // net_path = "//" authority [ abs_path ]
-    // authority = server | reg_name
-    protected boolean _is_reg_name;
-
-    protected boolean _is_server; // = _has_server
-
-    // server = [ [ userinfo "@" ] hostport ]
-    // host = hostname | IPv4address | IPv6reference
-    protected boolean _is_hostname;
-
-    protected boolean _is_IPv4address;
-
-    protected boolean _is_IPv6reference;
-
-    // ------------------------------------------ Character and escape encoding
-
-    /**
-     * Encodes URI string. This is a two mapping, one from original characters
-     * to octets, and subsequently a second from octets to URI characters:
-     * 
-     * <blockquote>
-     *
-     * <pre>
-     *   original character sequence->octet sequence->URI character sequence
-     * </pre>
-     *
-     * </blockquote>
-     * 
-     * An escaped octet is encoded as a character triplet, consisting of the
-     * percent character "%" followed by the two hexadecimal digits representing
-     * the octet code. For example, "%20" is the escaped encoding for the
-     * US-ASCII space character.
-     * 
-     * Conversion from the local filesystem character set to UTF-8 will normally
-     * involve a two step process. First convert the local character set to the
-     * UCS; then convert the UCS to UTF-8. The first step in the process can be
-     * performed by maintaining a mapping table that includes the local
-     * character set code and the corresponding UCS code. The next step is to
-     * convert the UCS character code to the UTF-8 encoding.
-     * 
-     * Mapping between vendor codepages can be done in a very similar manner as
-     * described above.
-     * 
-     * The only time escape encodings can allowedly be made is when a URI is
-     * being created from its component parts. The escape and validate methods
-     * are internally performed within this method.
-     *
-     * @param original the original character sequence
-     * @param allowed those characters that are allowed within a component
-     * @param charset the protocol charset
-     * @return URI character sequence
-     * @throws URIException null component or unsupported character encoding
-     */
-
-    protected static char[] encode(String original, BitSet allowed,
-            String charset) throws URIException {
-        if (original == null) {
-            throw new IllegalArgumentException(
-                "Original string may not be null");
-        }
-        if (allowed == null) {
-            throw new IllegalArgumentException("Allowed bitset may not be null");
-        }
-        byte[] rawdata = encodeUrl(allowed, getBytes(original, charset));
-        return getAsciiString(rawdata).toCharArray();
-    }
-
-    /**
-     * Decodes URI encoded string. This is a two mapping, one from URI
-     * characters to octets, and subsequently a second from octets to original
-     * characters:
-     * 
-     * <blockquote>
-     *
-     * <pre>
-     *   URI character sequence->octet sequence->original character sequence
-     * </pre>
-     *
-     * </blockquote>
-     * 
-     * A URI must be separated into its components before the escaped characters
-     * within those components can be allowedly decoded.
-     * 
-     * Notice that there is a chance that URI characters that are non UTF-8 may
-     * be parsed as valid UTF-8. A recent non-scientific analysis found that EUC
-     * encoded Japanese words had a 2.7% false reading; SJIS had a 0.0005% false
-     * reading; other encoding such as ASCII or KOI-8 have a 0% false reading.
-     * 
-     * The percent "%" character always has the reserved purpose of being the
-     * escape indicator, it must be escaped as "%25" in order to be used as data
-     * within a URI.
-     * 
-     * The unescape method is internally performed within this method.
-     *
-     * @param component the URI character sequence
-     * @param charset the protocol charset
-     * @return original character sequence
-     * @throws URIException incomplete trailing escape pattern or unsupported
-     *             character encoding
-     */
-    protected static String decode(char[] component, String charset)
-            throws URIException {
-        if (component == null) {
-            throw new IllegalArgumentException(
-                "Component array of chars may not be null");
-        }
-        return decode(new String(component), charset);
-    }
-
-    /**
-     * Decodes URI encoded string. This is a two mapping, one from URI
-     * characters to octets, and subsequently a second from octets to original
-     * characters:
-     * 
-     * <blockquote>
-     *
-     * <pre>
-     *   URI character sequence->octet sequence->original character sequence
-     * </pre>
-     *
-     * </blockquote>
-     * 
-     * A URI must be separated into its components before the escaped characters
-     * within those components can be allowedly decoded.
-     * 
-     * Notice that there is a chance that URI characters that are non UTF-8 may
-     * be parsed as valid UTF-8. A recent non-scientific analysis found that EUC
-     * encoded Japanese words had a 2.7% false reading; SJIS had a 0.0005% false
-     * reading; other encoding such as ASCII or KOI-8 have a 0% false reading.
-     * 
-     * The percent "%" character always has the reserved purpose of being the
-     * escape indicator, it must be escaped as "%25" in order to be used as data
-     * within a URI.
-     * 
-     * The unescape method is internally performed within this method.
-     *
-     * @param component the URI character sequence
-     * @param charset the protocol charset
-     * @return original character sequence
-     * @throws URIException incomplete trailing escape pattern or unsupported
-     *             character encoding
-     * @since 3.0
-     */
-    protected static String decode(String component, String charset)
-            throws URIException {
-        if (component == null) {
-            throw new IllegalArgumentException(
-                "Component array of chars may not be null");
-        }
-        byte[] rawdata = decodeUrl(getAsciiBytes(component));
-        return getString(rawdata, charset);
-    }
-
-    /**
-     * Pre-validate the unescaped URI string within a specific component.
-     *
-     * @param component the component string within the component
-     * @param disallowed those characters disallowed within the component
-     * @return if true, it doesn't have the disallowed characters if false, the
-     *         component is undefined or an incorrect one
-     */
-    protected boolean prevalidate(String component, BitSet disallowed) {
-        // prevalidate the given component by disallowed characters
-        if (component == null) {
-            return false; // undefined
-        }
-        char[] target = component.toCharArray();
-        for (int i = 0; i < target.length; i++) {
-            if (disallowed.get(target[i])) {
-                return false;
-            }
-        }
-        return true;
-    }
-
-    /**
-     * Validate the URI characters within a specific component. The component
-     * must be performed after escape encoding. Or it doesn't include escaped
-     * characters.
-     *
-     * @param component the characters sequence within the component
-     * @param generous those characters that are allowed within a component
-     * @return if true, it's the correct URI character sequence
-     */
-    protected boolean validate(char[] component, BitSet generous) {
-        // validate each component by generous characters
-        return validate(component, 0, -1, generous);
-    }
-
-    /**
-     * Validate the URI characters within a specific component. The component
-     * must be performed after escape encoding. Or it doesn't include escaped
-     * characters.
-     * 
-     * It's not that much strict, generous. The strict validation might be
-     * performed before being called this method.
-     *
-     * @param component the characters sequence within the component
-     * @param soffset the starting offset of the given component
-     * @param eoffset the ending offset of the given component if -1, it means
-     *            the length of the component
-     * @param generous those characters that are allowed within a component
-     * @return if true, it's the correct URI character sequence
-     */
-    protected boolean validate(char[] component, int soffset, int eoffset,
-            BitSet generous) {
-        // validate each component by generous characters
-        if (eoffset == -1) {
-            eoffset = component.length - 1;
-        }
-        for (int i = soffset; i <= eoffset; i++) {
-            if (!generous.get(component[i])) {
-                return false;
-            }
-        }
-        return true;
-    }
-
-    /**
-     * In order to avoid any possilbity of conflict with non-ASCII characters,
-     * Parse a URI reference as a <code>String</code> with the character
-     * encoding of the local system or the document.
-     * 
-     * The following line is the regular expression for breaking-down a URI
-     * reference into its components.
-     * 
-     * <blockquote>
-     *
-     * <pre>
-     *   ^(([^:/?#]+):)?(//([^/?#]*))?([^?#]*)(\?([^#]*))?(#(.*))?
-     *    12            3  4          5       6  7        8 9
-     * </pre>
-     *
-     * </blockquote>
-     * 
-     * For example, matching the above expression to
-     * http://jakarta.apache.org/ietf/uri/#Related results in the following
-     * subexpression matches:
-     * 
-     * <blockquote>
-     *
-     * <pre>
-     *               $1 = http:
-     *  scheme    =  $2 = http
-     *               $3 = //jakarta.apache.org
-     *  authority =  $4 = jakarta.apache.org
-     *  path      =  $5 = /ietf/uri/
-     *               $6 = <undefined>
-     *  query     =  $7 = <undefined>
-     *               $8 = #Related
-     *  fragment  =  $9 = Related
-     * </pre>
-     *
-     * </blockquote>
-     * 
-     *
-     * @param original the original character sequence
-     * @param escaped <code>true</code> if <code>original</code> is escaped
-     * @throws URIException If an error occurs.
-     */
-    protected void parseUriReference(String original, boolean escaped)
-            throws URIException {
-
-        // validate and contruct the URI character sequence
-        if (original == null) {
-            throw new URIException("URI-Reference required");
-        }
-
-        /*
-         * @ ^(([^:/?#]+):)?(//([^/?#]*))?([^?#]*)(\?([^#]*))?(#(.*))?
-         */
-        String tmp = original.trim();
-
-        /*
-         * The length of the string sequence of characters. It may not be equal
-         * to the length of the byte array.
-         */
-        int length = tmp.length();
-
-        /*
-         * Remove the delimiters like angle brackets around an URI.
-         */
-        if (length > 0) {
-            char[] firstDelimiter = { tmp.charAt(0) };
-            if (validate(firstDelimiter, delims)) {
-                if (length >= 2) {
-                    char[] lastDelimiter = { tmp.charAt(length - 1) };
-                    if (validate(lastDelimiter, delims)) {
-                        tmp = tmp.substring(1, length - 1);
-                        length = length - 2;
-                    }
-                }
-            }
-        }
-
-        /*
-         * The starting index
-         */
-        int from = 0;
-
-        /*
-         * The test flag whether the URI is started from the path component.
-         */
-        boolean isStartedFromPath = false;
-        int atColon = tmp.indexOf(':');
-        int atSlash = tmp.indexOf('/');
-        if ((atColon <= 0 && !tmp.startsWith("//"))
-            || (atSlash >= 0 && atSlash < atColon)) {
-            isStartedFromPath = true;
-        }
-
-        /*
-         * <blockquote><pre>
-         * @@@@@@@@ ^(([^:/?#]+):)?(//([^/?#]*))?([^?#]*)(\?([^#]*))?(#(.*))?
-         * </pre></blockquote>
-         */
-        int at = indexFirstOf(tmp, isStartedFromPath ? "/?#" : ":/?#", from);
-        if (at == -1) {
-            at = 0;
-        }
-
-        /*
-         * Parse the scheme. <blockquote><pre> scheme = $2 = http
-         * @ ^(([^:/?#]+):)?(//([^/?#]*))?([^?#]*)(\?([^#]*))?(#(.*))?
-         * </pre></blockquote>
-         */
-        if (at > 0 && at < length && tmp.charAt(at) == ':') {
-            char[] target = tmp.substring(0, at).toLowerCase().toCharArray();
-            if (validate(target, scheme)) {
-                _scheme = target;
-            } else {
-                throw new URIException("incorrect scheme");
-            }
-            from = ++at;
-        }
-
-        /*
-         * Parse the authority component. <blockquote><pre> authority = $4 =
-         * jakarta.apache.org
-         * @@ ^(([^:/?#]+):)?(//([^/?#]*))?([^?#]*)(\?([^#]*))?(#(.*))?
-         * </pre></blockquote>
-         */
-        // Reset flags
-        _is_net_path = _is_abs_path = _is_rel_path = _is_hier_part = false;
-        if (0 <= at && at < length && tmp.charAt(at) == '/') {
-            // Set flag
-            _is_hier_part = true;
-            if (at + 2 < length && tmp.charAt(at + 1) == '/'
-                && !isStartedFromPath) {
-                // the temporary index to start the search from
-                int next = indexFirstOf(tmp, "/?#", at + 2);
-                if (next == -1) {
-                    next = (tmp.substring(at + 2).length() == 0)
-                            ? at + 2
-                            : tmp.length();
-                }
-                parseAuthority(tmp.substring(at + 2, next), escaped);
-                from = at = next;
-                // Set flag
-                _is_net_path = true;
-            }
-            if (from == at) {
-                // Set flag
-                _is_abs_path = true;
-            }
-        }
-
-        /*
-         * Parse the path component. <blockquote><pre> path = $5 = /ietf/uri/
-         * @@@@@@ ^(([^:/?#]+):)?(//([^/?#]*))?([^?#]*)(\?([^#]*))?(#(.*))?
-         * </pre></blockquote>
-         */
-        if (from < length) {
-            // rel_path = rel_segment [ abs_path ]
-            int next = indexFirstOf(tmp, "?#", from);
-            if (next == -1) {
-                next = tmp.length();
-            }
-            if (!_is_abs_path) {
-                if (!escaped
-                    && prevalidate(tmp.substring(from, next),
-                        disallowed_rel_path)
-                    || escaped
-                    && validate(tmp.substring(from, next).toCharArray(),
-                        rel_path)) {
-                    // Set flag
-                    _is_rel_path = true;
-                } else if (!escaped
-                    && prevalidate(tmp.substring(from, next),
-                        disallowed_opaque_part)
-                    || escaped
-                    && validate(tmp.substring(from, next).toCharArray(),
-                        opaque_part)) {
-                    // Set flag
-                    _is_opaque_part = true;
-                } else {
-                    // the path component may be empty
-                    _path = null;
-                }
-            }
-            String s = tmp.substring(from, next);
-            if (escaped) {
-                setRawPath(s.toCharArray());
-            } else {
-                setPath(s);
-            }
-            at = next;
-        }
-
-        // set the charset to do escape encoding
-        String charset = getProtocolCharset();
-
-        /*
-         * Parse the query component. <blockquote><pre> query = $7 =
-         * <undefined>
-         * @@@@@@@@@ ^(([^:/?#]+):)?(//([^/?#]*))?([^?#]*)(\?([^#]*))?(#(.*))?
-         * </pre></blockquote>
-         */
-        if (0 <= at && at + 1 < length && tmp.charAt(at) == '?') {
-            int next = tmp.indexOf('#', at + 1);
-            if (next == -1) {
-                next = tmp.length();
-            }
-            if (escaped) {
-                _query = tmp.substring(at + 1, next).toCharArray();
-                if (!validate(_query, uric)) {
-                    throw new URIException("Invalid query");
-                }
-            } else {
-                _query = encode(tmp.substring(at + 1, next), allowed_query,
-                    charset);
-            }
-            at = next;
-        }
-
-        /*
-         * Parse the fragment component. <blockquote><pre> fragment = $9 =
-         * Related
-         * @@@@@@@@ ^(([^:/?#]+):)?(//([^/?#]*))?([^?#]*)(\?([^#]*))?(#(.*))?
-         * </pre></blockquote>
-         */
-        if (0 <= at && at + 1 <= length && tmp.charAt(at) == '#') {
-            if (at + 1 == length) { // empty fragment
-                _fragment = "".toCharArray();
-            } else {
-                _fragment = (escaped)
-                        ? tmp.substring(at + 1).toCharArray()
-                        : encode(tmp.substring(at + 1), allowed_fragment,
-                            charset);
-            }
-        }
-
-        // set this URI.
-        setURI();
-    }
-
-    /**
-     * Get the earlier index that to be searched for the first occurrance in one
-     * of any of the given string.
-     *
-     * @param s the string to be indexed
-     * @param delims the delimiters used to index
-     * @return the earlier index if there are delimiters
-     */
-    protected int indexFirstOf(String s, String delims) {
-        return indexFirstOf(s, delims, -1);
-    }
-
-    /**
-     * Get the earlier index that to be searched for the first occurrance in one
-     * of any of the given string.
-     *
-     * @param s the string to be indexed
-     * @param delims the delimiters used to index
-     * @param offset the from index
-     * @return the earlier index if there are delimiters
-     */
-    protected int indexFirstOf(String s, String delims, int offset) {
-        if (s == null || s.length() == 0) {
-            return -1;
-        }
-        if (delims == null || delims.length() == 0) {
-            return -1;
-        }
-        // check boundaries
-        if (offset < 0) {
-            offset = 0;
-        } else if (offset > s.length()) {
-            return -1;
-        }
-        // s is never null
-        int min = s.length();
-        char[] delim = delims.toCharArray();
-        for (int i = 0; i < delim.length; i++) {
-            int at = s.indexOf(delim[i], offset);
-            if (at >= 0 && at < min) {
-                min = at;
-            }
-        }
-        return (min == s.length()) ? -1 : min;
-    }
-
-    /**
-     * Get the earlier index that to be searched for the first occurrance in one
-     * of any of the given array.
-     *
-     * @param s the character array to be indexed
-     * @param delim the delimiter used to index
-     * @return the ealier index if there are a delimiter
-     */
-    protected int indexFirstOf(char[] s, char delim) {
-        return indexFirstOf(s, delim, 0);
-    }
-
-    /**
-     * Get the earlier index that to be searched for the first occurrance in one
-     * of any of the given array.
-     *
-     * @param s the character array to be indexed
-     * @param delim the delimiter used to index
-     * @param offset The offset.
-     * @return the ealier index if there is a delimiter
-     */
-    protected int indexFirstOf(char[] s, char delim, int offset) {
-        if (s == null || s.length == 0) {
-            return -1;
-        }
-        // check boundaries
-        if (offset < 0) {
-            offset = 0;
-        } else if (offset > s.length) {
-            return -1;
-        }
-        for (int i = offset; i < s.length; i++) {
-            if (s[i] == delim) {
-                return i;
-            }
-        }
-        return -1;
-    }
-
-    /**
-     * Parse the authority component.
-     *
-     * @param original the original character sequence of authority component
-     * @param escaped <code>true</code> if <code>original</code> is escaped
-     * @throws URIException If an error occurs.
-     */
-    protected void parseAuthority(String original, boolean escaped)
-            throws URIException {
-
-        // Reset flags
-        _is_reg_name = _is_server = _is_hostname = _is_IPv4address = _is_IPv6reference = false;
-
-        // set the charset to do escape encoding
-        String charset = getProtocolCharset();
-
-        boolean hasPort = true;
-        int from = 0;
-        int next = original.indexOf('@');
-        if (next != -1) { // neither -1 and 0
-            // each protocol extented from URI supports the specific userinfo
-            _userinfo = (escaped)
-                    ? original.substring(0, next).toCharArray()
-                    : encode(original.substring(0, next), allowed_userinfo,
-                        charset);
-            from = next + 1;
-        }
-        next = original.indexOf('[', from);
-        if (next >= from) {
-            next = original.indexOf(']', from);
-            if (next == -1) {
-                throw new URIException(URIException.PARSING, "IPv6reference");
-            }
-            next++;
-            // In IPv6reference, '[', ']' should be excluded
-            _host = (escaped)
-                    ? original.substring(from, next).toCharArray()
-                    : encode(original.substring(from, next),
-                        allowed_IPv6reference, charset);
-            // Set flag
-            _is_IPv6reference = true;
-        } else { // only for !_is_IPv6reference
-            next = original.indexOf(':', from);
-            if (next == -1) {
-                next = original.length();
-                hasPort = false;
-            }
-            // REMINDME: it doesn't need the pre-validation
-            _host = original.substring(from, next).toCharArray();
-            if (validate(_host, IPv4address)) {
-                // Set flag
-                _is_IPv4address = true;
-            } else if (validate(_host, hostname)) {
-                // Set flag
-                _is_hostname = true;
-            } else {
-                // Set flag
-                _is_reg_name = true;
-            }
-        }
-        if (_is_reg_name) {
-            // Reset flags for a server-based naming authority
-            _is_server = _is_hostname = _is_IPv4address = _is_IPv6reference = false;
-            // set a registry-based naming authority
-            if (escaped) {
-                _authority = original.toCharArray();
-                if (!validate(_authority, reg_name)) {
-                    throw new URIException("Invalid authority");
-                }
-            } else {
-                _authority = encode(original, allowed_reg_name, charset);
-            }
-        } else {
-            if (original.length() - 1 > next && hasPort
-                && original.charAt(next) == ':') { // not empty
-                from = next + 1;
-                try {
-                    _port = Integer.parseInt(original.substring(from));
-                } catch (NumberFormatException error) {
-                    throw new URIException(URIException.PARSING,
-                        "invalid port number");
-                }
-            }
-            // set a server-based naming authority
-            StringBuilder buf = new StringBuilder();
-            if (_userinfo != null) { // has_userinfo
-                buf.append(_userinfo);
-                buf.append('@');
-            }
-            if (_host != null) {
-                buf.append(_host);
-                if (_port != -1) {
-                    buf.append(':');
-                    buf.append(_port);
-                }
-            }
-            _authority = buf.toString().toCharArray();
-            // Set flag
-            _is_server = true;
-        }
-    }
-
-    /**
-     * Once it's parsed successfully, set this URI.
-     *
-     * @see #getRawURI
-     */
-    protected void setURI() {
-        // set _uri
-        StringBuilder buf = new StringBuilder();
-        // ^(([^:/?#]+):)?(//([^/?#]*))?([^?#]*)(\?([^#]*))?(#(.*))?
-        if (_scheme != null) {
-            buf.append(_scheme);
-            buf.append(':');
-        }
-        if (_is_net_path) {
-            buf.append("//");
-            if (_authority != null) { // has_authority
-                buf.append(_authority);
-            }
-        }
-        if (_opaque != null && _is_opaque_part) {
-            buf.append(_opaque);
-        } else if (_path != null) {
-            // _is_hier_part or _is_relativeURI
-            if (_path.length != 0) {
-                buf.append(_path);
-            }
-        }
-        if (_query != null) { // has_query
-            buf.append('?');
-            buf.append(_query);
-        }
-        // ignore the fragment identifier
-        _uri = buf.toString().toCharArray();
-        hash = 0;
-    }
-
-    // ----------------------------------------------------------- Test methods
-
-    /**
-     * Tell whether or not this URI is absolute.
-     *
-     * @return true iif this URI is absoluteURI
-     */
-    public boolean isAbsoluteURI() {
-        return (_scheme != null);
-    }
-
-    /**
-     * Tell whether or not this URI is relative.
-     *
-     * @return true iif this URI is relativeURI
-     */
-    public boolean isRelativeURI() {
-        return (_scheme == null);
-    }
-
-    /**
-     * Tell whether or not the absoluteURI of this URI is hier_part.
-     *
-     * @return true iif the absoluteURI is hier_part
-     */
-    public boolean isHierPart() {
-        return _is_hier_part;
-    }
-
-    /**
-     * Tell whether or not the absoluteURI of this URI is opaque_part.
-     *
-     * @return true iif the absoluteURI is opaque_part
-     */
-    public boolean isOpaquePart() {
-        return _is_opaque_part;
-    }
-
-    /**
-     * Tell whether or not the relativeURI or heir_part of this URI is net_path.
-     * It's the same function as the has_authority() method.
-     *
-     * @return true iif the relativeURI or heir_part is net_path
-     * @see #hasAuthority
-     */
-    public boolean isNetPath() {
-        return _is_net_path || (_authority != null);
-    }
-
-    /**
-     * Tell whether or not the relativeURI or hier_part of this URI is abs_path.
-     *
-     * @return true iif the relativeURI or hier_part is abs_path
-     */
-    public boolean isAbsPath() {
-        return _is_abs_path;
-    }
-
-    /**
-     * Tell whether or not the relativeURI of this URI is rel_path.
-     *
-     * @return true iif the relativeURI is rel_path
-     */
-    public boolean isRelPath() {
-        return _is_rel_path;
-    }
-
-    /**
-     * Tell whether or not this URI has authority. It's the same function as the
-     * is_net_path() method.
-     *
-     * @return true iif this URI has authority
-     * @see #isNetPath
-     */
-    public boolean hasAuthority() {
-        return (_authority != null) || _is_net_path;
-    }
-
-    /**
-     * Tell whether or not the authority component of this URI is reg_name.
-     *
-     * @return true iif the authority component is reg_name
-     */
-    public boolean isRegName() {
-        return _is_reg_name;
-    }
-
-    /**
-     * Tell whether or not the authority component of this URI is server.
-     *
-     * @return true iif the authority component is server
-     */
-    public boolean isServer() {
-        return _is_server;
-    }
-
-    /**
-     * Tell whether or not this URI has userinfo.
-     *
-     * @return true iif this URI has userinfo
-     */
-    public boolean hasUserinfo() {
-        return (_userinfo != null);
-    }
-
-    /**
-     * Tell whether or not the host part of this URI is hostname.
-     *
-     * @return true iif the host part is hostname
-     */
-    public boolean isHostname() {
-        return _is_hostname;
-    }
-
-    /**
-     * Tell whether or not the host part of this URI is IPv4address.
-     *
-     * @return true iif the host part is IPv4address
-     */
-    public boolean isIPv4address() {
-        return _is_IPv4address;
-    }
-
-    /**
-     * Tell whether or not the host part of this URI is IPv6reference.
-     *
-     * @return true iif the host part is IPv6reference
-     */
-    public boolean isIPv6reference() {
-        return _is_IPv6reference;
-    }
-
-    /**
-     * Tell whether or not this URI has query.
-     *
-     * @return true iif this URI has query
-     */
-    public boolean hasQuery() {
-        return (_query != null);
-    }
-
-    /**
-     * Tell whether or not this URI has fragment.
-     *
-     * @return true iif this URI has fragment
-     */
-    public boolean hasFragment() {
-        return (_fragment != null);
-    }
-
-    // ---------------------------------------------------------------- Charset
-
-    /**
-     * Set the default charset of the protocol.
-     * 
-     * The character set used to store files SHALL remain a local decision and
-     * MAY depend on the capability of local operating systems. Prior to the
-     * exchange of URIs they SHOULD be converted into a ISO/IEC 10646 format and
-     * UTF-8 encoded. This approach, while allowing international exchange of
-     * URIs, will still allow backward compatibility with older systems because
-     * the code set positions for ASCII characters are identical to the one byte
-     * sequence in UTF-8.
-     * 
-     * An individual URI scheme may require a single charset, define a default
-     * charset, or provide a way to indicate the charset used.
-     * 
-     * Always all the time, the setter method is always succeeded and throws
-     * <code>DefaultCharsetChanged</code> exception. So API programmer must
-     * follow the following way: <code><pre>
-     *  import org.apache.util.URI$DefaultCharsetChanged;
-     *      .
-     *      .
-     *      .
-     *  try {
-     *      URI.setDefaultProtocolCharset("UTF-8");
-     *  } catch (DefaultCharsetChanged cc) {
-     *      // CASE 1: the exception could be ignored, when it is set by user
-     *      if (cc.getReasonCode() == DefaultCharsetChanged.PROTOCOL_CHARSET) {
-     *      // CASE 2: let user know the default protocol charset changed
-     *      } else {
-     *      // CASE 2: let user know the default document charset changed
-     *      }
-     *  }
-     *  </pre></code> The API programmer is responsible to set the correct
-     * charset. And each application should remember its own charset to support.
-     *
-     * @param charset the default charset for each protocol
-     * @throws DefaultCharsetChanged default charset changed
-     */
-    public static void setDefaultProtocolCharset(String charset)
-            throws DefaultCharsetChanged {
-
-        defaultProtocolCharset = charset;
-        throw new DefaultCharsetChanged(DefaultCharsetChanged.PROTOCOL_CHARSET,
-            "the default protocol charset changed");
-    }
-
-    /**
-     * Get the default charset of the protocol.
-     * 
-     * An individual URI scheme may require a single charset, define a default
-     * charset, or provide a way to indicate the charset used.
-     * 
-     * To work globally either requires support of a number of character sets
-     * and to be able to convert between them, or the use of a single preferred
-     * character set. For support of global compatibility it is STRONGLY
-     * RECOMMENDED that clients and servers use UTF-8 encoding when exchanging
-     * URIs.
-     *
-     * @return the default charset string
-     */
-    public static String getDefaultProtocolCharset() {
-        return defaultProtocolCharset;
-    }
-
-    /**
-     * Get the protocol charset used by this current URI instance. It was set by
-     * the constructor for this instance. If it was not set by contructor, it
-     * will return the default protocol charset.
-     *
-     * @return the protocol charset string
-     * @see #getDefaultProtocolCharset
-     */
-    public String getProtocolCharset() {
-        return (protocolCharset != null)
-                ? protocolCharset
-                : defaultProtocolCharset;
-    }
-
-    /**
-     * Set the default charset of the document.
-     * 
-     * Notice that it will be possible to contain mixed characters (e.g.
-     * ftp://host/KoreanNamespace/ChineseResource). To handle the Bi-directional
-     * display of these character sets, the protocol charset could be simply
-     * used again. Because it's not yet implemented that the insertion of BIDI
-     * control characters at different points during composition is extracted.
-     * 
-     * Always all the time, the setter method is always succeeded and throws
-     * <code>DefaultCharsetChanged</code> exception. So API programmer must
-     * follow the following way: <code><pre>
-     *  import org.apache.util.URI$DefaultCharsetChanged;
-     *      .
-     *      .
-     *      .
-     *  try {
-     *      URI.setDefaultDocumentCharset("EUC-KR");
-     *  } catch (DefaultCharsetChanged cc) {
-     *      // CASE 1: the exception could be ignored, when it is set by user
-     *      if (cc.getReasonCode() == DefaultCharsetChanged.DOCUMENT_CHARSET) {
-     *      // CASE 2: let user know the default document charset changed
-     *      } else {
-     *      // CASE 2: let user know the default protocol charset changed
-     *      }
-     *  }
-     *  </pre></code> The API programmer is responsible to set the correct
-     * charset. And each application should remember its own charset to support.
-     *
-     * @param charset the default charset for the document
-     * @throws DefaultCharsetChanged default charset changed
-     */
-    public static void setDefaultDocumentCharset(String charset)
-            throws DefaultCharsetChanged {
-
-        defaultDocumentCharset = charset;
-        throw new DefaultCharsetChanged(DefaultCharsetChanged.DOCUMENT_CHARSET,
-            "the default document charset changed");
-    }
-
-    /**
-     * Get the recommended default charset of the document.
-     *
-     * @return the default charset string
-     */
-    public static String getDefaultDocumentCharset() {
-        return defaultDocumentCharset;
-    }
-
-    /**
-     * Get the default charset of the document by locale.
-     *
-     * @return the default charset string by locale
-     */
-    public static String getDefaultDocumentCharsetByLocale() {
-        return defaultDocumentCharsetByLocale;
-    }
-
-    /**
-     * Get the default charset of the document by platform.
-     *
-     * @return the default charset string by platform
-     */
-    public static String getDefaultDocumentCharsetByPlatform() {
-        return defaultDocumentCharsetByPlatform;
-    }
-
-    // ------------------------------------------------------------- The scheme
-
-    /**
-     * Get the scheme.
-     *
-     * @return the scheme
-     */
-    public char[] getRawScheme() {
-        return _scheme;
-    }
-
-    /**
-     * Get the scheme.
-     *
-     * @return the scheme null if undefined scheme
-     */
-    public String getScheme() {
-        return (_scheme == null) ? null : new String(_scheme);
-    }
-
-    // ---------------------------------------------------------- The authority
-
-    /**
-     * Set the authority. It can be one type of server, hostport, hostname,
-     * IPv4address, IPv6reference and reg_name.
-     * 
-     * <blockquote>
-     *
-     * <pre>
-     * authority = server | reg_name
-     * </pre>
-     *
-     * </blockquote>
-     * 
-     *
-     * @param escapedAuthority the raw escaped authority
-     * @throws URIException If {@link #parseAuthority(java.lang.String,boolean)}
-     *             fails
-     * @throws NullPointerException null authority
-     */
-    public void setRawAuthority(char[] escapedAuthority) throws URIException,
-            NullPointerException {
-
-        parseAuthority(new String(escapedAuthority), true);
-        setURI();
-    }
-
-    /**
-     * Set the authority. It can be one type of server, hostport, hostname,
-     * IPv4address, IPv6reference and reg_name. Note that there is no
-     * setAuthority method by the escape encoding reason.
-     *
-     * @param escapedAuthority the escaped authority string
-     * @throws URIException If {@link #parseAuthority(java.lang.String,boolean)}
-     *             fails
-     */
-    public void setEscapedAuthority(String escapedAuthority)
-            throws URIException {
-
-        parseAuthority(escapedAuthority, true);
-        setURI();
-    }
-
-    /**
-     * Get the raw-escaped authority.
-     *
-     * @return the raw-escaped authority
-     */
-    public char[] getRawAuthority() {
-        return _authority;
-    }
-
-    /**
-     * Get the escaped authority.
-     *
-     * @return the escaped authority
-     */
-    public String getEscapedAuthority() {
-        return (_authority == null) ? null : new String(_authority);
-    }
-
-    /**
-     * Get the authority.
-     *
-     * @return the authority
-     * @throws URIException If {@link #decode} fails
-     */
-    public String getAuthority() throws URIException {
-        return (_authority == null) ? null : decode(_authority,
-            getProtocolCharset());
-    }
-
-    // ----------------------------------------------------------- The userinfo
-
-    /**
-     * Get the raw-escaped userinfo.
-     *
-     * @return the raw-escaped userinfo
-     * @see #getAuthority
-     */
-    public char[] getRawUserinfo() {
-        return _userinfo;
-    }
-
-    /**
-     * Get the escaped userinfo.
-     *
-     * @return the escaped userinfo
-     * @see #getAuthority
-     */
-    public String getEscapedUserinfo() {
-        return (_userinfo == null) ? null : new String(_userinfo);
-    }
-
-    /**
-     * Get the userinfo.
-     *
-     * @return the userinfo
-     * @throws URIException If {@link #decode} fails
-     * @see #getAuthority
-     */
-    public String getUserinfo() throws URIException {
-        return (_userinfo == null) ? null : decode(_userinfo,
-            getProtocolCharset());
-    }
-
-    // --------------------------------------------------------------- The host
-
-    /**
-     * Get the host.
-     * 
-     * <blockquote>
-     *
-     * <pre>
-     * host = hostname | IPv4address | IPv6reference
-     * </pre>
-     *
-     * </blockquote>
-     * 
-     *
-     * @return the host
-     * @see #getAuthority
-     */
-    public char[] getRawHost() {
-        return _host;
-    }
-
-    /**
-     * Get the host.
-     * 
-     * <blockquote>
-     *
-     * <pre>
-     * host = hostname | IPv4address | IPv6reference
-     * </pre>
-     *
-     * </blockquote>
-     * 
-     *
-     * @return the host
-     * @throws URIException If {@link #decode} fails
-     * @see #getAuthority
-     */
-    public String getHost() throws URIException {
-        if (_host != null) {
-            return decode(_host, getProtocolCharset());
-        }
-        return null;
-    }
-
-    // --------------------------------------------------------------- The port
-
-    /**
-     * Get the port. In order to get the specfic default port, the specific
-     * protocol-supported class extended from the URI class should be used. It
-     * has the server-based naming authority.
-     *
-     * @return the port if -1, it has the default port for the scheme or the
-     *         server-based naming authority is not supported in the specific
-     *         URI.
-     */
-    public int getPort() {
-        return _port;
-    }
-
-    // --------------------------------------------------------------- The path
-
-    /**
-     * Set the raw-escaped path.
-     *
-     * @param escapedPath the path character sequence
-     * @throws URIException encoding error or not proper for initial instance
-     * @see #encode
-     */
-    public void setRawPath(char[] escapedPath) throws URIException {
-        if (escapedPath == null || escapedPath.length == 0) {
-            _path = _opaque = escapedPath;
-            setURI();
-            return;
-        }
-        // remove the fragment identifier
-        escapedPath = removeFragmentIdentifier(escapedPath);
-        if (_is_net_path || _is_abs_path) {
-            if (escapedPath[0] != '/') {
-                throw new URIException(URIException.PARSING,
-                    "not absolute path");
-            }
-            if (!validate(escapedPath, abs_path)) {
-                throw new URIException(URIException.ESCAPING,
-                    "escaped absolute path not valid");
-            }
-            _path = escapedPath;
-        } else if (_is_rel_path) {
-            int at = indexFirstOf(escapedPath, '/');
-            if (at == 0) {
-                throw new URIException(URIException.PARSING, "incorrect path");
-            }
-            if (at > 0 && !validate(escapedPath, 0, at - 1, rel_segment)
-                && !validate(escapedPath, at, -1, abs_path) || at < 0
-                && !validate(escapedPath, 0, -1, rel_segment)) {
-
-                throw new URIException(URIException.ESCAPING,
-                    "escaped relative path not valid");
-            }
-            _path = escapedPath;
-        } else if (_is_opaque_part) {
-            if (!uric_no_slash.get(escapedPath[0])
-                && !validate(escapedPath, 1, -1, uric)) {
-                throw new URIException(URIException.ESCAPING,
-                    "escaped opaque part not valid");
-            }
-            _opaque = escapedPath;
-        } else {
-            throw new URIException(URIException.PARSING, "incorrect path");
-        }
-        setURI();
-    }
-
-    /**
-     * Set the escaped path.
-     *
-     * @param escapedPath the escaped path string
-     * @throws URIException encoding error or not proper for initial instance
-     * @see #encode
-     */
-    public void setEscapedPath(String escapedPath) throws URIException {
-        if (escapedPath == null) {
-            _path = _opaque = null;
-            setURI();
-            return;
-        }
-        setRawPath(escapedPath.toCharArray());
-    }
-
-    /**
-     * Set the path.
-     *
-     * @param path the path string
-     * @throws URIException set incorrectly or fragment only
-     * @see #encode
-     */
-    public void setPath(String path) throws URIException {
-
-        if (path == null || path.length() == 0) {
-            _path = _opaque = (path == null) ? null : path.toCharArray();
-            setURI();
-            return;
-        }
-        // set the charset to do escape encoding
-        String charset = getProtocolCharset();
-
-        if (_is_net_path || _is_abs_path) {
-            _path = encode(path, allowed_abs_path, charset);
-        } else if (_is_rel_path) {
-            StringBuilder buff = new StringBuilder(path.length());
-            int at = path.indexOf('/');
-            if (at == 0) { // never 0
-                throw new URIException(URIException.PARSING,
-                    "incorrect relative path");
-            }
-            if (at > 0) {
-                buff.append(encode(path.substring(0, at), allowed_rel_path,
-                    charset));
-                buff.append(encode(path.substring(at), allowed_abs_path,
-                    charset));
-            } else {
-                buff.append(encode(path, allowed_rel_path, charset));
-            }
-            _path = buff.toString().toCharArray();
-        } else if (_is_opaque_part) {
-            StringBuilder buf = new StringBuilder();
-            buf.insert(0, encode(path.substring(0, 1), uric_no_slash, charset));
-            buf.insert(1, encode(path.substring(1), uric, charset));
-            _opaque = buf.toString().toCharArray();
-        } else {
-            throw new URIException(URIException.PARSING, "incorrect path");
-        }
-        setURI();
-    }
-
-    /**
-     * Resolve the base and relative path.
-     *
-     * @param basePath a character array of the basePath
-     * @param relPath a character array of the relPath
-     * @return the resolved path
-     * @throws URIException no more higher path level to be resolved
-     */
-    protected char[] resolvePath(char[] basePath, char[] relPath)
-            throws URIException {
-
-        // REMINDME: paths are never null
-        String base = (basePath == null) ? "" : new String(basePath);
-
-        // _path could be empty
-        if (relPath == null || relPath.length == 0) {
-            return normalize(basePath);
-        } else if (relPath[0] == '/') {
-            return normalize(relPath);
-        } else {
-            int at = base.lastIndexOf('/');
-            if (at != -1) {
-                basePath = base.substring(0, at + 1).toCharArray();
-            }
-            StringBuilder buff = new StringBuilder(base.length() + relPath.length);
-            buff.append((at != -1) ? base.substring(0, at + 1) : "/");
-            buff.append(relPath);
-            return normalize(buff.toString().toCharArray());
-        }
-    }
-
-    /**
-     * Get the raw-escaped current hierarchy level in the given path. If the
-     * last namespace is a collection, the slash mark ('/') should be ended with
-     * at the last character of the path string.
-     *
-     * @param path the path
-     * @return the current hierarchy level
-     * @throws URIException no hierarchy level
-     */
-    protected char[] getRawCurrentHierPath(char[] path) throws URIException {
-
-        if (_is_opaque_part) {
-            throw new URIException(URIException.PARSING, "no hierarchy level");
-        }
-        if (path == null) {
-            throw new URIException(URIException.PARSING, "empty path");
-        }
-        String buff = new String(path);
-        int first = buff.indexOf('/');
-        int last = buff.lastIndexOf('/');
-        if (last == 0) {
-            return rootPath;
-        } else if (first != last && last != -1) {
-            return buff.substring(0, last).toCharArray();
-        }
-        // FIXME: it could be a document on the server side
-        return path;
-    }
-
-    /**
-     * Get the raw-escaped current hierarchy level.
-     *
-     * @return the raw-escaped current hierarchy level
-     * @throws URIException If {@link #getRawCurrentHierPath(char[])} fails.
-     */
-    public char[] getRawCurrentHierPath() throws URIException {
-        return (_path == null) ? null : getRawCurrentHierPath(_path);
-    }
-
-    /**
-     * Get the escaped current hierarchy level.
-     *
-     * @return the escaped current hierarchy level
-     * @throws URIException If {@link #getRawCurrentHierPath(char[])} fails.
-     */
-    public String getEscapedCurrentHierPath() throws URIException {
-        char[] path = getRawCurrentHierPath();
-        return (path == null) ? null : new String(path);
-    }
-
-    /**
-     * Get the current hierarchy level.
-     *
-     * @return the current hierarchy level
-     * @throws URIException If {@link #getRawCurrentHierPath(char[])} fails.
-     * @see #decode
-     */
-    public String getCurrentHierPath() throws URIException {
-        char[] path = getRawCurrentHierPath();
-        return (path == null) ? null : decode(path, getProtocolCharset());
-    }
-
-    /**
-     * Get the level above the this hierarchy level.
-     *
-     * @return the raw above hierarchy level
-     * @throws URIException If {@link #getRawCurrentHierPath(char[])} fails.
-     */
-    public char[] getRawAboveHierPath() throws URIException {
-        char[] path = getRawCurrentHierPath();
-        return (path == null) ? null : getRawCurrentHierPath(path);
-    }
-
-    /**
-     * Get the level above the this hierarchy level.
-     *
-     * @return the raw above hierarchy level
-     * @throws URIException If {@link #getRawCurrentHierPath(char[])} fails.
-     */
-    public String getEscapedAboveHierPath() throws URIException {
-        char[] path = getRawAboveHierPath();
-        return (path == null) ? null : new String(path);
-    }
-
-    /**
-     * Get the level above the this hierarchy level.
-     *
-     * @return the above hierarchy level
-     * @throws URIException If {@link #getRawCurrentHierPath(char[])} fails.
-     * @see #decode
-     */
-    public String getAboveHierPath() throws URIException {
-        char[] path = getRawAboveHierPath();
-        return (path == null) ? null : decode(path, getProtocolCharset());
-    }
-
-    /**
-     * Get the raw-escaped path.
-     * 
-     * <blockquote>
-     *
-     * <pre>
-     *   path          = [ abs_path | opaque_part ]
-     * </pre>
-     *
-     * </blockquote>
-     * 
-     *
-     * @return the raw-escaped path
-     */
-    public char[] getRawPath() {
-        return _is_opaque_part ? _opaque : _path;
-    }
-
-    /**
-     * Get the escaped path.
-     * 
-     * <blockquote>
-     *
-     * <pre>
-     *   path          = [ abs_path | opaque_part ]
-     *   abs_path      = "/"  path_segments
-     *   opaque_part   = uric_no_slash *uric
-     * </pre>
-     *
-     * </blockquote>
-     * 
-     *
-     * @return the escaped path string
-     */
-    public String getEscapedPath() {
-        char[] path = getRawPath();
-        return (path == null) ? null : new String(path);
-    }
-
-    /**
-     * Get the path.
-     * 
-     * <blockquote>
-     *
-     * <pre>
-     *   path          = [ abs_path | opaque_part ]
-     * </pre>
-     *
-     * </blockquote>
-     * 
-     *
-     * @return the path string
-     * @throws URIException If {@link #decode} fails.
-     * @see #decode
-     */
-    public String getPath() throws URIException {
-        char[] path = getRawPath();
-        return (path == null) ? null : decode(path, getProtocolCharset());
-    }
-
-    /**
-     * Get the raw-escaped basename of the path.
-     *
-     * @return the raw-escaped basename
-     */
-    public char[] getRawName() {
-        if (_path == null) {
-            return null;
-        }
-
-        int at = 0;
-        for (int i = _path.length - 1; i >= 0; i--) {
-            if (_path[i] == '/') {
-                at = i + 1;
-                break;
-            }
-        }
-        int len = _path.length - at;
-        char[] basename = new char[len];
-        System.arraycopy(_path, at, basename, 0, len);
-        return basename;
-    }
-
-    /**
-     * Get the escaped basename of the path.
-     *
-     * @return the escaped basename string
-     */
-    public String getEscapedName() {
-        char[] basename = getRawName();
-        return (basename == null) ? null : new String(basename);
-    }
-
-    /**
-     * Get the basename of the path.
-     *
-     * @return the basename string
-     * @throws URIException incomplete trailing escape pattern or unsupported
-     *             character encoding
-     * @see #decode
-     */
-    public String getName() throws URIException {
-        char[] basename = getRawName();
-        return (basename == null) ? null : decode(getRawName(),
-            getProtocolCharset());
-    }
-
-    // ----------------------------------------------------- The path and query
-
-    /**
-     * Get the raw-escaped path and query.
-     *
-     * @return the raw-escaped path and query
-     */
-    public char[] getRawPathQuery() {
-
-        if (_path == null && _query == null) {
-            return null;
-        }
-        StringBuilder buff = new StringBuilder();
-        if (_path != null) {
-            buff.append(_path);
-        }
-        if (_query != null) {
-            buff.append('?');
-            buff.append(_query);
-        }
-        return buff.toString().toCharArray();
-    }
-
-    /**
-     * Get the escaped query.
-     *
-     * @return the escaped path and query string
-     */
-    public String getEscapedPathQuery() {
-        char[] rawPathQuery = getRawPathQuery();
-        return (rawPathQuery == null) ? null : new String(rawPathQuery);
-    }
-
-    /**
-     * Get the path and query.
-     *
-     * @return the path and query string.
-     * @throws URIException incomplete trailing escape pattern or unsupported
-     *             character encoding
-     * @see #decode
-     */
-    public String getPathQuery() throws URIException {
-        char[] rawPathQuery = getRawPathQuery();
-        return (rawPathQuery == null) ? null : decode(rawPathQuery,
-            getProtocolCharset());
-    }
-
-    // -------------------------------------------------------------- The query
-
-    /**
-     * Set the raw-escaped query.
-     *
-     * @param escapedQuery the raw-escaped query
-     * @throws URIException escaped query not valid
-     */
-    public void setRawQuery(char[] escapedQuery) throws URIException {
-        if (escapedQuery == null || escapedQuery.length == 0) {
-            _query = escapedQuery;
-            setURI();
-            return;
-        }
-        // remove the fragment identifier
-        escapedQuery = removeFragmentIdentifier(escapedQuery);
-        if (!validate(escapedQuery, query)) {
-            throw new URIException(URIException.ESCAPING,
-                "escaped query not valid");
-        }
-        _query = escapedQuery;
-        setURI();
-    }
-
-    /**
-     * Set the escaped query string.
-     *
-     * @param escapedQuery the escaped query string
-     * @throws URIException escaped query not valid
-     */
-    public void setEscapedQuery(String escapedQuery) throws URIException {
-        if (escapedQuery == null) {
-            _query = null;
-            setURI();
-            return;
-        }
-        setRawQuery(escapedQuery.toCharArray());
-    }
-
-    /**
-     * Set the query.
-     * 
-     * When a query string is not misunderstood the reserved special characters
-     * ("&amp;", "=", "+", ",", and "$") within a query component, it is
-     * recommended to use in encoding the whole query with this method.
-     * 
-     * The additional APIs for the special purpose using by the reserved special
-     * characters used in each protocol are implemented in each protocol classes
-     * inherited from <code>URI</code>. So refer to the same-named APIs
-     * implemented in each specific protocol instance.
-     *
-     * @param query the query string.
-     * @throws URIException incomplete trailing escape pattern or unsupported
-     *             character encoding
-     * @see #encode
-     */
-    public void setQuery(String query) throws URIException {
-        if (query == null || query.length() == 0) {
-            _query = (query == null) ? null : query.toCharArray();
-            setURI();
-            return;
-        }
-        setRawQuery(encode(query, allowed_query, getProtocolCharset()));
-    }
-
-    /**
-     * Get the raw-escaped query.
-     *
-     * @return the raw-escaped query
-     */
-    public char[] getRawQuery() {
-        return _query;
-    }
-
-    /**
-     * Get the escaped query.
-     *
-     * @return the escaped query string
-     */
-    public String getEscapedQuery() {
-        return (_query == null) ? null : new String(_query);
-    }
-
-    /**
-     * Get the query.
-     *
-     * @return the query string.
-     * @throws URIException incomplete trailing escape pattern or unsupported
-     *             character encoding
-     * @see #decode
-     */
-    public String getQuery() throws URIException {
-        return (_query == null) ? null : decode(_query, getProtocolCharset());
-    }
-
-    // ----------------------------------------------------------- The fragment
-
-    /**
-     * Set the raw-escaped fragment.
-     *
-     * @param escapedFragment the raw-escaped fragment
-     * @throws URIException escaped fragment not valid
-     */
-    public void setRawFragment(char[] escapedFragment) throws URIException {
-        if (escapedFragment == null || escapedFragment.length == 0) {
-            _fragment = escapedFragment;
-            hash = 0;
-            return;
-        }
-        if (!validate(escapedFragment, fragment)) {
-            throw new URIException(URIException.ESCAPING,
-                "escaped fragment not valid");
-        }
-        _fragment = escapedFragment;
-        hash = 0;
-    }
-
-    /**
-     * Set the escaped fragment string.
-     *
-     * @param escapedFragment the escaped fragment string
-     * @throws URIException escaped fragment not valid
-     */
-    public void setEscapedFragment(String escapedFragment) throws URIException {
-        if (escapedFragment == null) {
-            _fragment = null;
-            hash = 0;
-            return;
-        }
-        setRawFragment(escapedFragment.toCharArray());
-    }
-
-    /**
-     * Set the fragment.
-     *
-     * @param fragment the fragment string.
-     * @throws URIException If an error occurs.
-     */
-    public void setFragment(String fragment) throws URIException {
-        if (fragment == null || fragment.length() == 0) {
-            _fragment = (fragment == null) ? null : fragment.toCharArray();
-            hash = 0;
-            return;
-        }
-        _fragment = encode(fragment, allowed_fragment, getProtocolCharset());
-        hash = 0;
-    }
-
-    /**
-     * Get the raw-escaped fragment.
-     * 
-     * The optional fragment identifier is not part of a URI, but is often used
-     * in conjunction with a URI.
-     * 
-     * The format and interpretation of fragment identifiers is dependent on the
-     * media type [RFC2046] of the retrieval result.
-     * 
-     * A fragment identifier is only meaningful when a URI reference is intended
-     * for retrieval and the result of that retrieval is a document for which
-     * the identified fragment is consistently defined.
-     *
-     * @return the raw-escaped fragment
-     */
-    public char[] getRawFragment() {
-        return _fragment;
-    }
-
-    /**
-     * Get the escaped fragment.
-     *
-     * @return the escaped fragment string
-     */
-    public String getEscapedFragment() {
-        return (_fragment == null) ? null : new String(_fragment);
-    }
-
-    /**
-     * Get the fragment.
-     *
-     * @return the fragment string
-     * @throws URIException incomplete trailing escape pattern or unsupported
-     *             character encoding
-     * @see #decode
-     */
-    public String getFragment() throws URIException {
-        return (_fragment == null) ? null : decode(_fragment,
-            getProtocolCharset());
-    }
-
-    // ------------------------------------------------------------- Utilities
-
-    /**
-     * Remove the fragment identifier of the given component.
-     *
-     * @param component the component that a fragment may be included
-     * @return the component that the fragment identifier is removed
-     */
-    protected char[] removeFragmentIdentifier(char[] component) {
-        if (component == null) {
-            return null;
-        }
-        int lastIndex = new String(component).indexOf('#');
-        if (lastIndex != -1) {
-            component = new String(component).substring(0, lastIndex).toCharArray();
-        }
-        return component;
-    }
-
-    /**
-     * Normalize the given hier path part.
-     * 
-     * Algorithm taken from URI reference parser at
-     * http://www.apache.org/~fielding/uri/rev-2002/issues.html.
-     *
-     * @param path the path to normalize
-     * @return the normalized path
-     * @throws URIException no more higher path level to be normalized
-     */
-    protected char[] normalize(char[] path) throws URIException {
-
-        if (path == null) {
-            return null;
-        }
-
-        String normalized = new String(path);
-
-        // If the buffer begins with "./" or "../", the "." or ".." is removed.
-        if (normalized.startsWith("./")) {
-            normalized = normalized.substring(1);
-        } else if (normalized.startsWith("../")) {
-            normalized = normalized.substring(2);
-        } else if (normalized.startsWith("..")) {
-            normalized = normalized.substring(2);
-        }
-
-        // All occurrences of "/./" in the buffer are replaced with "/"
-        int index = -1;
-        while ((index = normalized.indexOf("/./")) != -1) {
-            normalized = normalized.substring(0, index)
-                + normalized.substring(index + 2);
-        }
-
-        // If the buffer ends with "/.", the "." is removed.
-        if (normalized.endsWith("/.")) {
-            normalized = normalized.substring(0, normalized.length() - 1);
-        }
-
-        int startIndex = 0;
-
-        // All occurrences of "/<segment>/../" in the buffer, where ".."
-        // and <segment> are complete path segments, are iteratively replaced
-        // with "/" in order from left to right until no matching pattern
-        // remains.
-        // If the buffer ends with "/<segment>/..", that is also replaced
-        // with "/". Note that <segment> may be empty.
-        while ((index = normalized.indexOf("/../", startIndex)) != -1) {
-            int slashIndex = normalized.lastIndexOf('/', index - 1);
-            if (slashIndex >= 0) {
-                normalized = normalized.substring(0, slashIndex)
-                    + normalized.substring(index + 3);
-            } else {
-                startIndex = index + 3;
-            }
-        }
-        if (normalized.endsWith("/..")) {
-            int slashIndex = normalized.lastIndexOf('/',
-                normalized.length() - 4);
-            if (slashIndex >= 0) {
-                normalized = normalized.substring(0, slashIndex + 1);
-            }
-        }
-
-        // All prefixes of "<segment>/../" in the buffer, where ".."
-        // and <segment> are complete path segments, are iteratively replaced
-        // with "/" in order from left to right until no matching pattern
-        // remains.
-        // If the buffer ends with "<segment>/..", that is also replaced
-        // with "/". Note that <segment> may be empty.
-        while ((index = normalized.indexOf("/../")) != -1) {
-            int slashIndex = normalized.lastIndexOf('/', index - 1);
-            if (slashIndex >= 0) {
-                break;
-            }
-            normalized = normalized.substring(index + 3);
-        }
-        if (normalized.endsWith("/..")) {
-            int slashIndex = normalized.lastIndexOf('/',
-                normalized.length() - 4);
-            if (slashIndex < 0) {
-                normalized = "/";
-            }
-        }
-
-        return normalized.toCharArray();
-    }
-
-    /**
-     * Normalizes the path part of this URI. Normalization is only meant to be
-     * performed on URIs with an absolute path. Calling this method on a
-     * relative path URI will have no effect.
-     *
-     * @throws URIException no more higher path level to be normalized
-     * @see #isAbsPath()
-     */
-    public void normalize() throws URIException {
-        if (isAbsPath()) {
-            _path = normalize(_path);
-            setURI();
-        }
-    }
-
-    /**
-     * Test if the first array is equal to the second array.
-     *
-     * @param first the first character array
-     * @param second the second character array
-     * @return true if they're equal
-     */
-    protected boolean equals(char[] first, char[] second) {
-
-        if (first == null && second == null) {
-            return true;
-        }
-        if (first == null || second == null) {
-            return false;
-        }
-        if (first.length != second.length) {
-            return false;
-        }
-        for (int i = 0; i < first.length; i++) {
-            if (first[i] != second[i]) {
-                return false;
-            }
-        }
-        return true;
-    }
-
-    /**
-     * Test an object if this URI is equal to another.
-     *
-     * @param obj an object to compare
-     * @return true if two URI objects are equal
-     */
-    public boolean equals(Object obj) {
-
-        // normalize and test each components
-        if (obj == this) {
-            return true;
-        }
-        if (!(obj instanceof URI)) {
-            return false;
-        }
-        URI another = (URI) obj;
-        // scheme
-        if (!equals(_scheme, another._scheme)) {
-            return false;
-        }
-        // is_opaque_part or is_hier_part? and opaque
-        if (!equals(_opaque, another._opaque)) {
-            return false;
-        }
-        // is_hier_part
-        // has_authority
-        if (!equals(_authority, another._authority)) {
-            return false;
-        }
-        // path
-        if (!equals(_path, another._path)) {
-            return false;
-        }
-        // has_query
-        if (!equals(_query, another._query)) {
-            return false;
-        }
-        // has_fragment? should be careful of the only fragment case.
-        if (!equals(_fragment, another._fragment)) {
-            return false;
-        }
-        return true;
-    }
-
-    // ---------------------------------------------------------- Serialization
-
-    /**
-     * Write the content of this URI.
-     *
-     * @param oos the object-output stream
-     * @throws IOException If an IO problem occurs.
-     */
-    private void writeObject(ObjectOutputStream oos) throws IOException {
-
-        oos.defaultWriteObject();
-    }
-
-    /**
-     * Read a URI.
-     *
-     * @param ois the object-input stream
-     * @throws ClassNotFoundException If one of the classes specified in the
-     *             input stream cannot be found.
-     * @throws IOException If an IO problem occurs.
-     */
-    private void readObject(ObjectInputStream ois)
-            throws ClassNotFoundException, IOException {
-
-        ois.defaultReadObject();
-    }
-
-    // -------------------------------------------------------------- Hash code
-
-    /**
-     * Return a hash code for this URI.
-     *
-     * @return a has code value for this URI
-     */
-    public int hashCode() {
-        if (hash == 0) {
-            char[] c = _uri;
-            if (c != null) {
-                for (int i = 0, len = c.length; i < len; i++) {
-                    hash = 31 * hash + c[i];
-                }
-            }
-            c = _fragment;
-            if (c != null) {
-                for (int i = 0, len = c.length; i < len; i++) {
-                    hash = 31 * hash + c[i];
-                }
-            }
-        }
-        return hash;
-    }
-
-    // ------------------------------------------------------------- Comparison
-
-    /**
-     * Compare this URI to another object.
-     *
-     * @param another the object to be compared.
-     * @return 0, if it's same, -1, if failed, first being compared with in the
-     *         authority component
-     * @throws ClassCastException not URI argument
-     */
-    public int compareTo(URI another) {
-
-        if (!equals(_authority, another.getRawAuthority())) {
-            return -1;
-        }
-        return toString().compareTo(another.toString());
-    }
-
-    // ------------------------------------------------------------------ Clone
-
-    /**
-     * Create and return a copy of this object, the URI-reference containing the
-     * userinfo component. Notice that the whole URI-reference including the
-     * userinfo component counld not be gotten as a <code>String</code>.
-     * 
-     * To copy the identical <code>URI</code> object including the userinfo
-     * component, it should be used.
-     *
-     * @return a clone of this instance
-     */
-    public synchronized Object clone() throws CloneNotSupportedException {
-
-        URI instance = (URI) super.clone();
-
-        instance._uri = _uri;
-        instance._scheme = _scheme;
-        instance._opaque = _opaque;
-        instance._authority = _authority;
-        instance._userinfo = _userinfo;
-        instance._host = _host;
-        instance._port = _port;
-        instance._path = _path;
-        instance._query = _query;
-        instance._fragment = _fragment;
-        // the charset to do escape encoding for this instance
-        instance.protocolCharset = protocolCharset;
-        // flags
-        instance._is_hier_part = _is_hier_part;
-        instance._is_opaque_part = _is_opaque_part;
-        instance._is_net_path = _is_net_path;
-        instance._is_abs_path = _is_abs_path;
-        instance._is_rel_path = _is_rel_path;
-        instance._is_reg_name = _is_reg_name;
-        instance._is_server = _is_server;
-        instance._is_hostname = _is_hostname;
-        instance._is_IPv4address = _is_IPv4address;
-        instance._is_IPv6reference = _is_IPv6reference;
-
-        return instance;
-    }
-
-    // ------------------------------------------------------------ Get the URI
-
-    /**
-     * It can be gotten the URI character sequence. It's raw-escaped. For the
-     * purpose of the protocol to be transported, it will be useful.
-     * 
-     * It is clearly unwise to use a URL that contains a password which is
-     * intended to be secret. In particular, the use of a password within the
-     * 'userinfo' component of a URL is strongly disrecommended except in those
-     * rare cases where the 'password' parameter is intended to be public.
-     * 
-     * When you want to get each part of the userinfo, you need to use the
-     * specific methods in the specific URL. It depends on the specific URL.
-     *
-     * @return the URI character sequence
-     */
-    public char[] getRawURI() {
-        return _uri;
-    }
-
-    /**
-     * It can be gotten the URI character sequence. It's escaped. For the
-     * purpose of the protocol to be transported, it will be useful.
-     *
-     * @return the escaped URI string
-     */
-    public String getEscapedURI() {
-        return (_uri == null) ? null : new String(_uri);
-    }
-
-    /**
-     * It can be gotten the URI character sequence.
-     *
-     * @return the original URI string
-     * @throws URIException incomplete trailing escape pattern or unsupported
-     *             character encoding
-     * @see #decode
-     */
-    public String getURI() throws URIException {
-        return (_uri == null) ? null : decode(_uri, getProtocolCharset());
-    }
-
-    /**
-     * Get the URI reference character sequence.
-     *
-     * @return the URI reference character sequence
-     */
-    public char[] getRawURIReference() {
-        if (_fragment == null) {
-            return _uri;
-        }
-        if (_uri == null) {
-            return _fragment;
-        }
-        // if _uri != null && _fragment != null
-        String uriReference = new String(_uri) + "#" + new String(_fragment);
-        return uriReference.toCharArray();
-    }
-
-    /**
-     * Get the escaped URI reference string.
-     *
-     * @return the escaped URI reference string
-     */
-    public String getEscapedURIReference() {
-        char[] uriReference = getRawURIReference();
-        return (uriReference == null) ? null : new String(uriReference);
-    }
-
-    /**
-     * Get the original URI reference string.
-     *
-     * @return the original URI reference string
-     * @throws URIException If {@link #decode} fails.
-     */
-    public String getURIReference() throws URIException {
-        char[] uriReference = getRawURIReference();
-        return (uriReference == null) ? null : decode(uriReference,
-            getProtocolCharset());
-    }
-
-    /**
-     * Get the escaped URI string.
-     * 
-     * On the document, the URI-reference form is only used without the userinfo
-     * component like http://jakarta.apache.org/ by the security reason. But the
-     * URI-reference form with the userinfo component could be parsed.
-     * 
-     * In other words, this URI and any its subclasses must not expose the
-     * URI-reference expression with the userinfo component like
-     * http://user:password@hostport/restricted_zone.<br>
-     * It means that the API client programmer should extract each user and
-     * password to access manually. Probably it will be supported in the each
-     * subclass, however, not a whole URI-reference expression.
-     *
-     * @return the escaped URI string
-     * @see #clone()
-     */
-    public String toString() {
-        return getEscapedURI();
-    }
-
-    // ------------------------------------------------------------ Inner class
-
-    /**
-     * The charset-changed normal operation to represent to be required to alert
-     * to user the fact the default charset is changed.
-     */
-    @SuppressWarnings("serial")
-    public static class DefaultCharsetChanged extends SlingException {
-
-        // ------------------------------------------------------- constructors
-
-        /**
-         * The constructor with a reason string and its code arguments.
-         *
-         * @param reasonCode the reason code
-         * @param reason the reason
-         */
-        public DefaultCharsetChanged(int reasonCode, String reason) {
-            super(reason);
-            this.reason = reason;
-            this.reasonCode = reasonCode;
-        }
-
-        // ---------------------------------------------------------- constants
-
-        /** No specified reason code. */
-        public static final int UNKNOWN = 0;
-
-        /** Protocol charset changed. */
-        public static final int PROTOCOL_CHARSET = 1;
-
-        /** Document charset changed. */
-        public static final int DOCUMENT_CHARSET = 2;
-
-        // ------------------------------------------------- instance variables
-
-        /** The reason code. */
-        private int reasonCode;
-
-        /** The reason message. */
-        private String reason;
-
-        // ------------------------------------------------------------ methods
-
-        /**
-         * Get the reason code.
-         *
-         * @return the reason code
-         */
-        public int getReasonCode() {
-            return reasonCode;
-        }
-
-        /**
-         * Get the reason message.
-         *
-         * @return the reason message
-         */
-        public String getReason() {
-            return reason;
-        }
-
-    }
-
-    /**
-     * A mapping to determine the (somewhat arbitrarily) preferred charset for a
-     * given locale. Supports all locales recognized in JDK 1.1.
-     * 
-     * The distribution of this class is Servlets.com. It was originally written
-     * by Jason Hunter [jhunter at acm.org] and used by with permission.
-     */
-    public static class LocaleToCharsetMap {
-
-        /** A mapping of language code to charset */
-        private static final HashMap<String, String> LOCALE_TO_CHARSET_MAP;
-        static {
-            LOCALE_TO_CHARSET_MAP = new HashMap<String, String>();
-            LOCALE_TO_CHARSET_MAP.put("ar", "ISO-8859-6");
-            LOCALE_TO_CHARSET_MAP.put("be", "ISO-8859-5");
-            LOCALE_TO_CHARSET_MAP.put("bg", "ISO-8859-5");
-            LOCALE_TO_CHARSET_MAP.put("ca", "ISO-8859-1");
-            LOCALE_TO_CHARSET_MAP.put("cs", "ISO-8859-2");
-            LOCALE_TO_CHARSET_MAP.put("da", "ISO-8859-1");
-            LOCALE_TO_CHARSET_MAP.put("de", "ISO-8859-1");
-            LOCALE_TO_CHARSET_MAP.put("el", "ISO-8859-7");
-            LOCALE_TO_CHARSET_MAP.put("en", "ISO-8859-1");
-            LOCALE_TO_CHARSET_MAP.put("es", "ISO-8859-1");
-            LOCALE_TO_CHARSET_MAP.put("et", "ISO-8859-1");
-            LOCALE_TO_CHARSET_MAP.put("fi", "ISO-8859-1");
-            LOCALE_TO_CHARSET_MAP.put("fr", "ISO-8859-1");
-            LOCALE_TO_CHARSET_MAP.put("hr", "ISO-8859-2");
-            LOCALE_TO_CHARSET_MAP.put("hu", "ISO-8859-2");
-            LOCALE_TO_CHARSET_MAP.put("is", "ISO-8859-1");
-            LOCALE_TO_CHARSET_MAP.put("it", "ISO-8859-1");
-            LOCALE_TO_CHARSET_MAP.put("iw", "ISO-8859-8");
-            LOCALE_TO_CHARSET_MAP.put("ja", "Shift_JIS");
-            LOCALE_TO_CHARSET_MAP.put("ko", "EUC-KR");
-            LOCALE_TO_CHARSET_MAP.put("lt", "ISO-8859-2");
-            LOCALE_TO_CHARSET_MAP.put("lv", "ISO-8859-2");
-            LOCALE_TO_CHARSET_MAP.put("mk", "ISO-8859-5");
-            LOCALE_TO_CHARSET_MAP.put("nl", "ISO-8859-1");
-            LOCALE_TO_CHARSET_MAP.put("no", "ISO-8859-1");
-            LOCALE_TO_CHARSET_MAP.put("pl", "ISO-8859-2");
-            LOCALE_TO_CHARSET_MAP.put("pt", "ISO-8859-1");
-            LOCALE_TO_CHARSET_MAP.put("ro", "ISO-8859-2");
-            LOCALE_TO_CHARSET_MAP.put("ru", "ISO-8859-5");
-            LOCALE_TO_CHARSET_MAP.put("sh", "ISO-8859-5");
-            LOCALE_TO_CHARSET_MAP.put("sk", "ISO-8859-2");
-            LOCALE_TO_CHARSET_MAP.put("sl", "ISO-8859-2");
-            LOCALE_TO_CHARSET_MAP.put("sq", "ISO-8859-2");
-            LOCALE_TO_CHARSET_MAP.put("sr", "ISO-8859-5");
-            LOCALE_TO_CHARSET_MAP.put("sv", "ISO-8859-1");
-            LOCALE_TO_CHARSET_MAP.put("tr", "ISO-8859-9");
-            LOCALE_TO_CHARSET_MAP.put("uk", "ISO-8859-5");
-            LOCALE_TO_CHARSET_MAP.put("zh", "GB2312");
-            LOCALE_TO_CHARSET_MAP.put("zh_TW", "Big5");
-        }
-
-        /**
-         * Get the preferred charset for the given locale.
-         *
-         * @param locale the locale
-         * @return the preferred charset or null if the locale is not
-         *         recognized.
-         */
-        public static String getCharset(Locale locale) {
-            // try for an full name match (may include country)
-            String charset = LOCALE_TO_CHARSET_MAP.get(locale.toString());
-            if (charset != null) {
-                return charset;
-            }
-
-            // if a full name didn't match, try just the language
-            charset = LOCALE_TO_CHARSET_MAP.get(locale.getLanguage());
-            return charset; // may be null
-        }
-
-    }
-
-    // from EncodingUtils...
-
-    /**
-     * Converts the specified string to a byte array. If the charset is not
-     * supported the default system charset is used.
-     *
-     * @param data the string to be encoded
-     * @param charset the desired character encoding
-     * @return The resulting byte array.
-     * @since 3.0
-     */
-    private static byte[] getBytes(final String data, String charset) {
-
-        if (data == null) {
-            throw new IllegalArgumentException("data may not be null");
-        }
-
-        if (charset == null || charset.length() == 0) {
-            throw new IllegalArgumentException(
-                "charset may not be null or empty");
-        }
-
-        try {
-            return data.getBytes(charset);
-        } catch (UnsupportedEncodingException e) {
-
-            // if (LOG.isWarnEnabled()) {
-            // LOG.warn("Unsupported encoding: " + charset +
-            // ". System encoding used.");
-            // }
-
-            return data.getBytes();
-        }
-    }
-
-    /**
-     * Converts the byte array of ASCII characters to a string. This method is
-     * to be used when decoding content of HTTP elements (such as response
-     * headers)
-     *
-     * @param data the byte array to be encoded
-     * @param offset the index of the first byte to encode
-     * @param length the number of bytes to encode
-     * @return The string representation of the byte array
-     * @since 3.0
-     */
-    private static String getAsciiString(final byte[] data) {
-
-        if (data == null) {
-            throw new IllegalArgumentException("Parameter may not be null");
-        }
-
-        try {
-            return new String(data, "US-ASCII");
-        } catch (UnsupportedEncodingException e) {
-            throw new URIException("HttpClient requires ASCII support");
-        }
-    }
-
-    /**
-     * Converts the byte array of HTTP content characters to a string. If the
-     * specified charset is not supported, default system encoding is used.
-     *
-     * @param data the byte array to be encoded
-     * @param charset the desired character encoding
-     * @return The result of the conversion.
-     * @since 3.0
-     */
-    public static String getString(final byte[] data, String charset) {
-
-        if (data == null) {
-            throw new IllegalArgumentException("Parameter may not be null");
-        }
-
-        if (charset == null || charset.length() == 0) {
-            throw new IllegalArgumentException(
-                "charset may not be null or empty");
-        }
-
-        try {
-            return new String(data, charset);
-        } catch (UnsupportedEncodingException e) {
-
-            // if (LOG.isWarnEnabled()) {
-            // LOG.warn("Unsupported encoding: " + charset +
-            // ". System encoding used");
-            // }
-            return new String(data);
-        }
-    }
-
-    /**
-     * Converts the specified string to byte array of ASCII characters.
-     *
-     * @param data the string to be encoded
-     * @return The string as a byte array.
-     * @since 3.0
-     */
-    public static byte[] getAsciiBytes(final String data) {
-
-        if (data == null) {
-            throw new IllegalArgumentException("Parameter may not be null");
-        }
-
-        try {
-            return data.getBytes("US-ASCII");
-        } catch (UnsupportedEncodingException e) {
-            throw new URIException("HttpClient requires ASCII support");
-        }
-    }
-
-    /**
-     * Encodes an array of bytes into an array of URL safe 7-bit characters.
-     * Unsafe characters are escaped.
-     *
-     * @param urlsafe bitset of characters deemed URL safe
-     * @param bytes array of bytes to convert to URL safe characters
-     * @return array of bytes containing URL safe characters
-     */
-    private static final byte[] encodeUrl(BitSet urlsafe, byte[] bytes) {
-        if (bytes == null) {
-            return null;
-        }
-
-        ByteArrayOutputStream buffer = new ByteArrayOutputStream();
-        for (int i = 0; i < bytes.length; i++) {
-            int b = bytes[i];
-            if (b < 0) {
-                b = 256 + b;
-            }
-            if (urlsafe.get(b)) {
-                if (b == ' ') {
-                    b = '+';
-                }
-                buffer.write(b);
-            } else {
-                buffer.write('%');
-                char hex1 = Character.toUpperCase(Character.forDigit(
-                    (b >> 4) & 0xF, 16));
-                char hex2 = Character.toUpperCase(Character.forDigit(b & 0xF,
-                    16));
-                buffer.write(hex1);
-                buffer.write(hex2);
-            }
-        }
-        return buffer.toByteArray();
-    }
-
-    /**
-     * Decodes an array of URL safe 7-bit characters into an array of original
-     * bytes. Escaped characters are converted back to their original
-     * representation.
-     *
-     * @param bytes array of URL safe characters
-     * @return array of original bytes
-     * @throws URIException Thrown if URL decoding is unsuccessful
-     */
-    private static final byte[] decodeUrl(byte[] bytes) {
-        if (bytes == null) {
-            return null;
-        }
-        ByteArrayOutputStream buffer = new ByteArrayOutputStream();
-        for (int i = 0; i < bytes.length; i++) {
-            int b = bytes[i];
-            if (b == '+') {
-                buffer.write(' ');
-            } else if (b == '%') {
-                try {
-                    int u = Character.digit((char) bytes[++i], 16);
-                    int l = Character.digit((char) bytes[++i], 16);
-                    if (u == -1 || l == -1) {
-                        throw new URIException("Invalid URL encoding");
-                    }
-                    buffer.write((char) ((u << 4) + l));
-                } catch (ArrayIndexOutOfBoundsException e) {
-                    throw new URIException("Invalid URL encoding");
-                }
-            } else {
-                buffer.write(b);
-            }
-        }
-        return buffer.toByteArray();
-    }
-}
diff --git a/src/main/java/org/apache/sling/resourceresolver/impl/helper/URIException.java b/src/main/java/org/apache/sling/resourceresolver/impl/helper/URIException.java
deleted file mode 100644
index 435cc5c..0000000
--- a/src/main/java/org/apache/sling/resourceresolver/impl/helper/URIException.java
+++ /dev/null
@@ -1,124 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *   http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-package org.apache.sling.resourceresolver.impl.helper;
-
-import org.apache.sling.api.SlingException;
-
-/**
- * The URI parsing and escape encoding exception.
- * <p>
- * This class is a slightly modified version of the URIException class
- * distributed with Http Client 3.1. The changes are removal of deprecated
- * methods and have the class itself extend the <code>SlingException</code> to
- * adapt it to the exception hierarchy of Sling.
- */
-@SuppressWarnings("serial")
-public class URIException extends SlingException {
-
-    // ----------------------------------------------------------- constructors
-
-    /**
-     * Default constructor.
-     */
-    public URIException() {
-    }
-
-    /**
-     * The constructor with a reason code argument.
-     *
-     * @param reasonCode the reason code
-     */
-    public URIException(int reasonCode) {
-        this.reasonCode = reasonCode;
-    }
-
-    /**
-     * The constructor with a reason string and its code arguments.
-     *
-     * @param reasonCode the reason code
-     * @param reason the reason
-     */
-    public URIException(int reasonCode, String reason) {
-        super(reason); // for backward compatibility of Throwable
-        this.reason = reason;
-        this.reasonCode = reasonCode;
-    }
-
-    /**
-     * The constructor with a reason string argument.
-     *
-     * @param reason the reason
-     */
-    public URIException(String reason) {
-        super(reason); // for backward compatibility of Throwable
-        this.reason = reason;
-        this.reasonCode = UNKNOWN;
-    }
-
-    // -------------------------------------------------------------- constants
-
-    /**
-     * No specified reason code.
-     */
-    public static final int UNKNOWN = 0;
-
-    /**
-     * The URI parsing error.
-     */
-    public static final int PARSING = 1;
-
-    /**
-     * The unsupported character encoding.
-     */
-    public static final int UNSUPPORTED_ENCODING = 2;
-
-    /**
-     * The URI escape encoding and decoding error.
-     */
-    public static final int ESCAPING = 3;
-
-    /**
-     * The DNS punycode encoding or decoding error.
-     */
-    public static final int PUNYCODE = 4;
-
-    // ------------------------------------------------------------- properties
-
-    /**
-     * The reason code.
-     */
-    protected int reasonCode;
-
-    /**
-     * The reason message.
-     */
-    protected String reason;
-
-    // ---------------------------------------------------------------- methods
-
-    /**
-     * Get the reason code.
-     *
-     * @return the reason code
-     */
-    public int getReasonCode() {
-        return reasonCode;
-    }
-
-}
diff --git a/src/main/java/org/apache/sling/resourceresolver/impl/helper/UniqueResourceIterator.java b/src/main/java/org/apache/sling/resourceresolver/impl/helper/UniqueResourceIterator.java
deleted file mode 100644
index 1f0cade..0000000
--- a/src/main/java/org/apache/sling/resourceresolver/impl/helper/UniqueResourceIterator.java
+++ /dev/null
@@ -1,59 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *   http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-package org.apache.sling.resourceresolver.impl.helper;
-
-import java.util.Iterator;
-import java.util.Set;
-
-import org.apache.sling.api.resource.Resource;
-
-/**
- * This iterator removes duplicated Resource entries. Regular resources
- * overrides the synthetic ones.
- */
-public class UniqueResourceIterator extends AbstractIterator<Resource> {
-
-    private final Iterator<Resource> input;
-
-    private final Set<String> visited;
-
-    public UniqueResourceIterator(final Set<String> visited, final Iterator<Resource> input) {
-        this.input = input;
-        this.visited = visited;
-    }
-
-    @Override
-    protected Resource seek() {
-        while (input.hasNext()) {
-            final Resource next = input.next();
-            final String name = next.getName();
-
-            if (visited.contains(name)) {
-                continue;
-            } else {
-                visited.add(name);
-                next.getResourceMetadata().setResolutionPath(next.getPath());
-                return next;
-            }
-        }
-
-        return null;
-    }
-}
-
diff --git a/src/main/java/org/apache/sling/resourceresolver/impl/legacy/LegacyResourceProviderAdapter.java b/src/main/java/org/apache/sling/resourceresolver/impl/legacy/LegacyResourceProviderAdapter.java
deleted file mode 100644
index 7c94ffb..0000000
--- a/src/main/java/org/apache/sling/resourceresolver/impl/legacy/LegacyResourceProviderAdapter.java
+++ /dev/null
@@ -1,257 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *   http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-package org.apache.sling.resourceresolver.impl.legacy;
-
-import java.io.Closeable;
-import java.io.IOException;
-import java.util.Collection;
-import java.util.Iterator;
-import java.util.Map;
-
-import javax.annotation.CheckForNull;
-import javax.annotation.Nonnull;
-
-import org.apache.sling.api.adapter.Adaptable;
-import org.apache.sling.api.resource.AttributableResourceProvider;
-import org.apache.sling.api.resource.DynamicResourceProvider;
-import org.apache.sling.api.resource.ModifyingResourceProvider;
-import org.apache.sling.api.resource.ParametrizableResourceProvider;
-import org.apache.sling.api.resource.PersistenceException;
-import org.apache.sling.api.resource.QueriableResourceProvider;
-import org.apache.sling.api.resource.RefreshableResourceProvider;
-import org.apache.sling.api.resource.Resource;
-import org.apache.sling.api.resource.ResourceMetadata;
-import org.apache.sling.api.resource.ValueMap;
-import org.apache.sling.spi.resource.provider.QueryLanguageProvider;
-import org.apache.sling.spi.resource.provider.ResolveContext;
-import org.apache.sling.spi.resource.provider.ResourceContext;
-import org.apache.sling.spi.resource.provider.ResourceProvider;
-
-@SuppressWarnings("deprecation")
-public class LegacyResourceProviderAdapter extends ResourceProvider<Object> implements Closeable {
-
-    private final org.apache.sling.api.resource.ResourceProvider rp;
-
-    private final String[] languages;
-
-    private final boolean ownsRoot;
-
-    public LegacyResourceProviderAdapter(org.apache.sling.api.resource.ResourceProvider rp, String[] languages, boolean ownsRoot) {
-        this.rp = rp;
-        this.languages = languages;
-        this.ownsRoot = ownsRoot;
-    }
-
-    @SuppressWarnings({ "rawtypes", "unchecked" })
-    @Override
-    public Resource getResource(ResolveContext<Object> ctx, String path, ResourceContext resourceContext, Resource parent) {
-        Resource resourceCandidate;
-        if (rp instanceof ParametrizableResourceProvider) {
-            resourceCandidate = ((ParametrizableResourceProvider) rp).getResource(ctx.getResourceResolver(), path,
-                    resourceContext.getResolveParameters());
-        } else {
-            resourceCandidate = rp.getResource(ctx.getResourceResolver(), path);
-        }
-
-        ResourceProvider<?> parentProvider = ctx.getParentResourceProvider();
-        ResolveContext parentCtx = ctx.getParentResolveContext();
-        // Ask the parent provider
-        if (resourceCandidate == null && !ownsRoot && parentProvider != null) {
-            return parentProvider.getResource(parentCtx, path, resourceContext, parent);
-        }
-
-        // Support the INTERNAL_CONTINUE_RESOLVING flag
-        Resource fallbackResource = resourceCandidate;
-        if (resourceCandidate != null && parentProvider != null && isContinueResolving(resourceCandidate)) {
-            resourceCandidate = ctx.getParentResourceProvider().getResource(parentCtx, path, resourceContext, parent);
-        }
-        if (resourceCandidate != null) {
-            return resourceCandidate;
-        } else {
-            return fallbackResource;
-        }
-    }
-
-    private boolean isContinueResolving(Resource resource) {
-        return resource.getResourceMetadata() != null
-                && resource.getResourceMetadata().containsKey(ResourceMetadata.INTERNAL_CONTINUE_RESOLVING);
-    }
-
-    @SuppressWarnings({ "rawtypes", "unchecked" })
-    @Override
-    public Iterator<Resource> listChildren(ResolveContext<Object> ctx, Resource parent) {
-        Iterator<Resource> children = rp.listChildren(parent);
-        if (children == null && !ownsRoot && ctx.getParentResourceProvider() != null) {
-            children = ctx.getParentResourceProvider().listChildren((ResolveContext) ctx.getParentResolveContext(),
-                    parent);
-        }
-        return children;
-    }
-
-    @Override
-    public void refresh(final @Nonnull ResolveContext<Object> ctx) {
-        if (rp instanceof RefreshableResourceProvider) {
-            ((RefreshableResourceProvider) rp).refresh();
-        }
-    }
-
-    @Override
-    public @CheckForNull QueryLanguageProvider<Object> getQueryLanguageProvider() {
-        if (rp instanceof QueriableResourceProvider) {
-            return new JCRQueryProviderAdapter((QueriableResourceProvider) rp, languages);
-        } else {
-            return super.getQueryLanguageProvider();
-        }
-    }
-
-    @Override
-    public Collection<String> getAttributeNames(final @Nonnull ResolveContext<Object> ctx) {
-        if (rp instanceof AttributableResourceProvider) {
-            return ((AttributableResourceProvider) rp).getAttributeNames(ctx.getResourceResolver());
-        } else {
-            return super.getAttributeNames(ctx);
-        }
-    }
-
-    @Override
-    public Object getAttribute(final @Nonnull ResolveContext<Object> ctx, final @Nonnull String name) {
-        if (rp instanceof AttributableResourceProvider) {
-            return ((AttributableResourceProvider) rp).getAttribute(ctx.getResourceResolver(), name);
-        } else {
-            return super.getAttribute(ctx, name);
-        }
-    }
-
-    @Override
-    public boolean isLive(final @Nonnull ResolveContext<Object> ctx) {
-        if (rp instanceof DynamicResourceProvider) {
-            return ((DynamicResourceProvider) rp).isLive();
-        } else {
-            return super.isLive(ctx);
-        }
-    }
-
-    @Override
-    public void logout(final @Nonnull Object state) {
-        if (rp instanceof DynamicResourceProvider) {
-            ((DynamicResourceProvider) rp).close();
-        }
-    }
-
-    @Override
-    public void close() throws IOException {
-        logout(null);
-    }
-
-    @SuppressWarnings({ "rawtypes", "unchecked" })
-    @Override
-    public Resource create(final @Nonnull ResolveContext<Object> ctx, final String path,
-            final Map<String, Object> properties) throws PersistenceException {
-        Resource createdResource = null;
-        if (rp instanceof ModifyingResourceProvider) {
-            createdResource = ((ModifyingResourceProvider) rp).create(ctx.getResourceResolver(), path, properties);
-        }
-        if (createdResource == null && !ownsRoot && ctx.getParentResourceProvider() != null) {
-            createdResource = ctx.getParentResourceProvider().create((ResolveContext) ctx.getParentResolveContext(),
-                    path, properties);
-        }
-        return createdResource;
-    }
-
-    @Override
-    public void delete(final @Nonnull ResolveContext<Object> ctx, final @Nonnull Resource resource)
-            throws PersistenceException {
-        if (rp instanceof ModifyingResourceProvider) {
-            ((ModifyingResourceProvider) rp).delete(ctx.getResourceResolver(), resource.getPath());
-        } else {
-            super.delete(ctx, resource);
-        }
-    }
-
-    @Override
-    public void revert(final @Nonnull ResolveContext<Object> ctx) {
-        if (rp instanceof ModifyingResourceProvider) {
-            ((ModifyingResourceProvider) rp).revert(ctx.getResourceResolver());
-        } else {
-            super.revert(ctx);
-        }
-    }
-
-    @Override
-    public void commit(final @Nonnull ResolveContext<Object> ctx) throws PersistenceException {
-        if (rp instanceof ModifyingResourceProvider) {
-            ((ModifyingResourceProvider) rp).commit(ctx.getResourceResolver());
-        } else {
-            super.commit(ctx);
-        }
-    }
-
-    @Override
-    public boolean hasChanges(final @Nonnull ResolveContext<Object> ctx) {
-        if (rp instanceof ModifyingResourceProvider) {
-            return ((ModifyingResourceProvider) rp).hasChanges(ctx.getResourceResolver());
-        } else {
-            return super.hasChanges(ctx);
-        }
-    }
-
-    @SuppressWarnings("unchecked")
-    @Override
-    public <AdapterType> AdapterType adaptTo(final @Nonnull ResolveContext<Object> ctx, final @Nonnull Class<AdapterType> type) {
-        if ( rp instanceof Adaptable ) {
-            final Object value = ((Adaptable)rp).adaptTo(type);
-            if ( value != null ) {
-                return (AdapterType) value;
-            }
-        }
-        return super.adaptTo(ctx, type);
-    }
-
-    private static class JCRQueryProviderAdapter implements QueryLanguageProvider<Object> {
-
-        private final QueriableResourceProvider rp;
-
-        private final String[] languages;
-
-        public JCRQueryProviderAdapter(QueriableResourceProvider rp, String[] languages) {
-            this.rp = rp;
-            this.languages = languages;
-        }
-
-        @Override
-        public String[] getSupportedLanguages(ResolveContext<Object> ctx) {
-            return languages;
-        }
-
-        @Override
-        public Iterator<Resource> findResources(ResolveContext<Object> ctx, String query, String language) {
-            return rp.findResources(ctx.getResourceResolver(), query, language);
-        }
-
-        @Override
-        public Iterator<ValueMap> queryResources(ResolveContext<Object> ctx, String query, String language) {
-            return rp.queryResources(ctx.getResourceResolver(), query, language);
-        }
-    }
-
-    @Override
-    public String toString() {
-        return "[" + getClass().getSimpleName() + ": " + rp.toString() + " ]";
-    }
-}
diff --git a/src/main/java/org/apache/sling/resourceresolver/impl/legacy/LegacyResourceProviderFactoryAdapter.java b/src/main/java/org/apache/sling/resourceresolver/impl/legacy/LegacyResourceProviderFactoryAdapter.java
deleted file mode 100644
index ff75009..0000000
--- a/src/main/java/org/apache/sling/resourceresolver/impl/legacy/LegacyResourceProviderFactoryAdapter.java
+++ /dev/null
@@ -1,164 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *   http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-package org.apache.sling.resourceresolver.impl.legacy;
-
-import java.util.Collection;
-import java.util.Iterator;
-import java.util.Map;
-
-import javax.annotation.CheckForNull;
-import javax.annotation.Nonnull;
-
-import org.apache.commons.lang.ArrayUtils;
-import org.apache.sling.api.resource.LoginException;
-import org.apache.sling.api.resource.PersistenceException;
-import org.apache.sling.api.resource.Resource;
-import org.apache.sling.api.resource.ResourceProviderFactory;
-import org.apache.sling.api.resource.ValueMap;
-import org.apache.sling.spi.resource.provider.QueryLanguageProvider;
-import org.apache.sling.spi.resource.provider.ResolveContext;
-import org.apache.sling.spi.resource.provider.ResourceContext;
-import org.apache.sling.spi.resource.provider.ResourceProvider;
-
-@SuppressWarnings({ "deprecation", "rawtypes", "unchecked" })
-public class LegacyResourceProviderFactoryAdapter extends ResourceProvider<LegacyResourceProviderAdapter> {
-
-    private final ResourceProviderFactory rpFactory;
-
-    private final String[] languages;
-
-    private final boolean ownsRoot;
-
-    public LegacyResourceProviderFactoryAdapter(ResourceProviderFactory rpFactory, String[] languages, boolean ownsRoot) {
-        this.rpFactory = rpFactory;
-        this.languages = languages;
-        this.ownsRoot = ownsRoot;
-    }
-
-    @Override
-    @Nonnull
-    public LegacyResourceProviderAdapter authenticate(final @Nonnull Map<String, Object> authenticationInfo)
-            throws LoginException {
-        return new LegacyResourceProviderAdapter(rpFactory.getResourceProvider(authenticationInfo), languages, ownsRoot);
-    }
-
-    @Override
-    public void logout(final @Nonnull LegacyResourceProviderAdapter state) {
-        state.logout(null);
-    }
-
-    @Override
-    public Resource getResource(ResolveContext<LegacyResourceProviderAdapter> ctx, String path, ResourceContext resourceContext, Resource parent) {
-        return ctx.getProviderState().getResource((ResolveContext) ctx, path, resourceContext, parent);
-    }
-
-    @Override
-    public Iterator<Resource> listChildren(ResolveContext<LegacyResourceProviderAdapter> ctx, Resource parent) {
-        return ctx.getProviderState().listChildren((ResolveContext) ctx, parent);
-    }
-
-    @Override
-    public void refresh(final @Nonnull ResolveContext<LegacyResourceProviderAdapter> ctx) {
-        ctx.getProviderState().refresh((ResolveContext) ctx);
-    }
-
-    @Override
-    public @CheckForNull QueryLanguageProvider<LegacyResourceProviderAdapter> getQueryLanguageProvider() {
-        if (ArrayUtils.isEmpty(languages)) {
-            return super.getQueryLanguageProvider();
-        } else {
-            return new JCRQueryProviderAdapter(languages);
-        }
-    }
-
-    @Override
-    public Collection<String> getAttributeNames(final @Nonnull ResolveContext<LegacyResourceProviderAdapter> ctx) {
-        return ctx.getProviderState().getAttributeNames((ResolveContext) ctx);
-    }
-
-    @Override
-    public Object getAttribute(final @Nonnull ResolveContext<LegacyResourceProviderAdapter> ctx,
-            final @Nonnull String name) {
-        return ctx.getProviderState().getAttribute((ResolveContext) ctx, name);
-    }
-
-    @Override
-    public boolean isLive(final @Nonnull ResolveContext<LegacyResourceProviderAdapter> ctx) {
-        return ctx.getProviderState().isLive((ResolveContext) ctx);
-    }
-
-    @Override
-    public Resource create(final @Nonnull ResolveContext<LegacyResourceProviderAdapter> ctx, final String path,
-            final Map<String, Object> properties) throws PersistenceException {
-        return ctx.getProviderState().create((ResolveContext) ctx, path, properties);
-    }
-
-    @Override
-    public void delete(final @Nonnull ResolveContext<LegacyResourceProviderAdapter> ctx,
-            final @Nonnull Resource resource) throws PersistenceException {
-        ctx.getProviderState().delete((ResolveContext) ctx, resource);
-    }
-
-    @Override
-    public void revert(final @Nonnull ResolveContext<LegacyResourceProviderAdapter> ctx) {
-        ctx.getProviderState().revert((ResolveContext) ctx);
-    }
-
-    @Override
-    public void commit(final @Nonnull ResolveContext<LegacyResourceProviderAdapter> ctx) throws PersistenceException {
-        ctx.getProviderState().commit((ResolveContext) ctx);
-    }
-
-    @Override
-    public boolean hasChanges(final @Nonnull ResolveContext<LegacyResourceProviderAdapter> ctx) {
-        return ctx.getProviderState().hasChanges((ResolveContext) ctx);
-    }
-
-    @SuppressWarnings("unchecked")
-    @Override
-    public <AdapterType> AdapterType adaptTo(final @Nonnull ResolveContext<LegacyResourceProviderAdapter> ctx, final @Nonnull Class<AdapterType> type) {
-        return (AdapterType) ctx.getProviderState().adaptTo((ResolveContext)ctx, type);
-    }
-
-    private static class JCRQueryProviderAdapter implements QueryLanguageProvider<LegacyResourceProviderAdapter> {
-
-        private final String[] languages;
-
-        public JCRQueryProviderAdapter(String[] languages) {
-            this.languages = languages;
-        }
-
-        @Override
-        public String[] getSupportedLanguages(ResolveContext<LegacyResourceProviderAdapter> ctx) {
-            return languages;
-        }
-
-        @Override
-        public Iterator<Resource> findResources(ResolveContext<LegacyResourceProviderAdapter> ctx, String query,
-                String language) {
-            return ctx.getProviderState().getQueryLanguageProvider().findResources((ResolveContext) ctx, query, language);
-        }
-
-        @Override
-        public Iterator<ValueMap> queryResources(ResolveContext<LegacyResourceProviderAdapter> ctx, String query,
-                String language) {
-            return ctx.getProviderState().getQueryLanguageProvider().queryResources((ResolveContext) ctx, query, language);
-        }
-    }
-}
diff --git a/src/main/java/org/apache/sling/resourceresolver/impl/legacy/LegacyResourceProviderWhiteboard.java b/src/main/java/org/apache/sling/resourceresolver/impl/legacy/LegacyResourceProviderWhiteboard.java
deleted file mode 100644
index 088d067..0000000
--- a/src/main/java/org/apache/sling/resourceresolver/impl/legacy/LegacyResourceProviderWhiteboard.java
+++ /dev/null
@@ -1,177 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *   http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-package org.apache.sling.resourceresolver.impl.legacy;
-
-import static org.apache.sling.api.resource.QueriableResourceProvider.LANGUAGES;
-import static org.apache.sling.api.resource.ResourceProvider.OWNS_ROOTS;
-import static org.apache.sling.api.resource.ResourceProvider.ROOTS;
-import static org.apache.sling.api.resource.ResourceProvider.USE_RESOURCE_ACCESS_SECURITY;
-import static org.apache.sling.api.resource.ResourceProviderFactory.PROPERTY_REQUIRED;
-import static org.apache.sling.commons.osgi.PropertiesUtil.toBoolean;
-import static org.apache.sling.spi.resource.provider.ResourceProvider.PROPERTY_ADAPTABLE;
-import static org.apache.sling.spi.resource.provider.ResourceProvider.PROPERTY_ATTRIBUTABLE;
-import static org.apache.sling.spi.resource.provider.ResourceProvider.PROPERTY_AUTHENTICATE;
-import static org.apache.sling.spi.resource.provider.ResourceProvider.PROPERTY_MODIFIABLE;
-import static org.apache.sling.spi.resource.provider.ResourceProvider.PROPERTY_NAME;
-import static org.apache.sling.spi.resource.provider.ResourceProvider.PROPERTY_REFRESHABLE;
-import static org.apache.sling.spi.resource.provider.ResourceProvider.PROPERTY_ROOT;
-import static org.apache.sling.spi.resource.provider.ResourceProvider.PROPERTY_USE_RESOURCE_ACCESS_SECURITY;
-import static org.osgi.framework.Constants.SERVICE_PID;
-import static org.osgi.framework.Constants.SERVICE_RANKING;
-
-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 org.apache.commons.lang.ArrayUtils;
-import org.apache.commons.lang.StringUtils;
-import org.apache.felix.scr.annotations.Component;
-import org.apache.felix.scr.annotations.Reference;
-import org.apache.felix.scr.annotations.ReferenceCardinality;
-import org.apache.felix.scr.annotations.ReferencePolicy;
-import org.apache.felix.scr.annotations.References;
-import org.apache.sling.api.adapter.Adaptable;
-import org.apache.sling.api.resource.AttributableResourceProvider;
-import org.apache.sling.api.resource.ModifyingResourceProvider;
-import org.apache.sling.api.resource.RefreshableResourceProvider;
-import org.apache.sling.api.resource.ResourceProvider;
-import org.apache.sling.api.resource.ResourceProviderFactory;
-import org.apache.sling.api.resource.runtime.dto.AuthType;
-import org.apache.sling.commons.osgi.PropertiesUtil;
-import org.osgi.framework.BundleContext;
-import org.osgi.framework.ServiceReference;
-import org.osgi.framework.ServiceRegistration;
-
-@SuppressWarnings("deprecation")
-@Component(immediate = true)
-@References({
-        @Reference(name = "ResourceProvider", referenceInterface = ResourceProvider.class, cardinality = ReferenceCardinality.OPTIONAL_MULTIPLE, policy = ReferencePolicy.DYNAMIC),
-        @Reference(name = "ResourceProviderFactory", referenceInterface = ResourceProviderFactory.class, cardinality = ReferenceCardinality.OPTIONAL_MULTIPLE, policy = ReferencePolicy.DYNAMIC) })
-public class LegacyResourceProviderWhiteboard {
-
-    public static final String ORIGINAL_SERVICE_PID = "original.service.pid";
-
-    private Map<Object, List<ServiceRegistration>> registrations = new HashMap<Object, List<ServiceRegistration>>();
-
-    protected void bindResourceProvider(final ServiceReference ref) {
-        final BundleContext bundleContext = ref.getBundle().getBundleContext();
-        final ResourceProvider provider = (ResourceProvider) bundleContext.getService(ref);
-        if ( provider != null ) {
-            final String[] propertyNames = ref.getPropertyKeys();
-            final boolean ownsRoot = toBoolean(ref.getProperty(OWNS_ROOTS), false);
-
-            final List<ServiceRegistration> newServices = new ArrayList<ServiceRegistration>();
-            for (final String path : PropertiesUtil.toStringArray(ref.getProperty(ROOTS), new String[0])) {
-                if ( path != null && !path.isEmpty() ) {
-                    final Dictionary<String, Object> newProps = new Hashtable<String, Object>();
-                    newProps.put(PROPERTY_AUTHENTICATE, AuthType.no.toString());
-                    newProps.put(PROPERTY_MODIFIABLE, provider instanceof ModifyingResourceProvider);
-                    newProps.put(PROPERTY_ADAPTABLE, provider instanceof Adaptable);
-                    newProps.put(PROPERTY_ATTRIBUTABLE, provider instanceof AttributableResourceProvider);
-                    newProps.put(PROPERTY_REFRESHABLE, provider instanceof RefreshableResourceProvider);
-                    newProps.put(PROPERTY_NAME, provider.getClass().getName());
-                    newProps.put(PROPERTY_ROOT, normalizePath(path));
-                    if (ArrayUtils.contains(propertyNames, SERVICE_PID)) {
-                        newProps.put(ORIGINAL_SERVICE_PID, ref.getProperty(SERVICE_PID));
-                    }
-                    if (ArrayUtils.contains(propertyNames, USE_RESOURCE_ACCESS_SECURITY)) {
-                        newProps.put(PROPERTY_USE_RESOURCE_ACCESS_SECURITY, ref.getProperty(USE_RESOURCE_ACCESS_SECURITY));
-                    }
-                    if (ArrayUtils.contains(propertyNames, SERVICE_RANKING)) {
-                        newProps.put(SERVICE_RANKING, ref.getProperty(SERVICE_RANKING));
-                    }
-
-                    String[] languages = PropertiesUtil.toStringArray(ref.getProperty(LANGUAGES), new String[0]);
-                    ServiceRegistration reg = bundleContext.registerService(
-                            org.apache.sling.spi.resource.provider.ResourceProvider.class.getName(),
-                            new LegacyResourceProviderAdapter(provider, languages, ownsRoot), newProps);
-                    newServices.add(reg);
-                }
-            }
-            registrations.put(provider, newServices);
-        }
-    }
-
-    protected void unbindResourceProvider(final ResourceProvider provider, final Map<String, Object> props) {
-        for (ServiceRegistration r : registrations.remove(provider)) {
-            r.unregister();
-        }
-    }
-
-    protected void bindResourceProviderFactory(final ServiceReference ref) {
-        final BundleContext bundleContext = ref.getBundle().getBundleContext();
-        final ResourceProviderFactory factory = (ResourceProviderFactory) bundleContext.getService(ref);
-        if ( factory != null ) {
-            final String[] propertyNames = ref.getPropertyKeys();
-            final boolean ownsRoot = toBoolean(ref.getProperty(OWNS_ROOTS), false);
-
-            final List<ServiceRegistration> newServices = new ArrayList<ServiceRegistration>();
-            for (final String path : PropertiesUtil.toStringArray(ref.getProperty(ROOTS), new String[0])) {
-                if ( path != null && !path.isEmpty() ) {
-                    final Dictionary<String, Object> newProps = new Hashtable<String, Object>();
-                    if (PropertiesUtil.toBoolean(ref.getProperty(PROPERTY_REQUIRED), false)) {
-                        newProps.put(PROPERTY_AUTHENTICATE, AuthType.required.toString());
-                    } else {
-                        newProps.put(PROPERTY_AUTHENTICATE, AuthType.lazy.toString());
-                    }
-                    newProps.put(PROPERTY_MODIFIABLE, true);
-                    newProps.put(PROPERTY_ADAPTABLE, true);
-                    newProps.put(PROPERTY_ATTRIBUTABLE, true);
-                    newProps.put(PROPERTY_REFRESHABLE, true);
-                    newProps.put(PROPERTY_NAME, factory.getClass().getName());
-                    newProps.put(PROPERTY_ROOT, normalizePath(path));
-                    if (ArrayUtils.contains(propertyNames, SERVICE_PID)) {
-                        newProps.put(ORIGINAL_SERVICE_PID, ref.getProperty(SERVICE_PID));
-                    }
-                    if (ArrayUtils.contains(propertyNames, USE_RESOURCE_ACCESS_SECURITY)) {
-                        newProps.put(PROPERTY_USE_RESOURCE_ACCESS_SECURITY, ref.getProperty(USE_RESOURCE_ACCESS_SECURITY));
-                    }
-                    if (ArrayUtils.contains(propertyNames, SERVICE_RANKING)) {
-                        newProps.put(SERVICE_RANKING, ref.getProperty(SERVICE_RANKING));
-                    }
-                    String[] languages = PropertiesUtil.toStringArray(ref.getProperty(LANGUAGES), new String[0]);
-                    ServiceRegistration reg = bundleContext.registerService(
-                            org.apache.sling.spi.resource.provider.ResourceProvider.class.getName(),
-                            new LegacyResourceProviderFactoryAdapter(factory, languages, ownsRoot), newProps);
-                    newServices.add(reg);
-                }
-            }
-            registrations.put(factory, newServices);
-        }
-    }
-
-    protected void unbindResourceProviderFactory(final ResourceProviderFactory factory,
-            final Map<String, Object> props) {
-        for (ServiceRegistration r : registrations.remove(factory)) {
-            r.unregister();
-        }
-    }
-
-    private static String normalizePath(final String path) {
-        String result = path;
-        result = StringUtils.removeEnd(path, "/");
-        if (result != null && !result.startsWith("/")) {
-            result = "/" + result;
-        }
-        return result;
-    }
-}
diff --git a/src/main/java/org/apache/sling/resourceresolver/impl/mapping/BloomFilterUtils.java b/src/main/java/org/apache/sling/resourceresolver/impl/mapping/BloomFilterUtils.java
deleted file mode 100644
index a947a2c..0000000
--- a/src/main/java/org/apache/sling/resourceresolver/impl/mapping/BloomFilterUtils.java
+++ /dev/null
@@ -1,110 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements.  See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.apache.sling.resourceresolver.impl.mapping;
-
-/**
- * Bloom filter utilities.
- */
-public class BloomFilterUtils {
-
-    /**
-     * The number of bits needed per stored element.
-     * Using the formula m = - (n * ln(p)) / (ln(2)^2) as described in
-     * http://en.wikipedia.org/wiki/Bloom_filter
-     * (simplified, as we used a fixed K: 2).
-     */
-    private static final double BIT_FACTOR = -Math.log(0.02) / Math.pow(Math.log(2), 2);
-
-    /**
-     * Create a bloom filter array for the given number of elements.
-     *
-     * @param elementCount the number of entries
-     * @param maxBytes the maximum number of bytes
-     * @return the empty bloom filter
-     */
-    public static byte[] createFilter(int elementCount, int maxBytes) {
-        int bits = (int) (elementCount * BIT_FACTOR) + 7;
-        return new byte[Math.min(maxBytes, bits / 8)];
-    }
-
-    /**
-     * Add the key.
-     *
-     * @param bloom the bloom filter
-     * @param key the key
-     */
-    public static void add(byte[] bloom, Object key) {
-        int len = bloom.length;
-        if (len > 0) {
-            int h1 = hash(key.hashCode()), h2 = hash(h1);
-            bloom[(h1 >>> 3) % len] |= 1 << (h1 & 7);
-            bloom[(h2 >>> 3) % len] |= 1 << (h2 & 7);
-        }
-    }
-
-    /**
-     * Remove the key.
-     *
-     * @param bloom the bloom filter
-     * @param key the key
-     */
-    public static void remove(byte[] bloom, Object key){
-        throw new UnsupportedOperationException();
-    }
-
-    /**
-     * Check whether the given key is probably in the set. This method never
-     * returns false if the key is in the set, but possibly returns true even if
-     * it isn't.
-     *
-     * @param bloom the bloom filter
-     * @param key the key
-     * @return true if the given key is probably in the set
-     */
-    public static boolean probablyContains(byte[] bloom, Object key) {
-        int len = bloom.length;
-        if (len == 0) {
-            return true;
-        }
-        int h1 = hash(key.hashCode());
-        long x = bloom[(h1 >>> 3) % len] & (1 << (h1 & 7));
-        if (x != 0) {
-            int h2 = hash(h1);
-            x = bloom[(h2 >>> 3) % len] & (1 << (h2 & 7));
-        }
-        return x != 0;
-    }
-
-    /**
-     * Get the hash value for the given key. The returned hash value is
-     * stretched so that it should work well even for relatively bad hashCode
-     * implementations.
-     *
-     * @param key the key
-     * @return the hash value
-     */
-    private static int hash(int key) {
-        int hash = key;
-        // a supplemental secondary hash function
-        // to protect against hash codes that don't differ much
-        hash = ((hash >>> 16) ^ hash) * 0x45d9f3b;
-        hash = ((hash >>> 16) ^ hash) * 0x45d9f3b;
-        hash = (hash >>> 16) ^ hash;
-        return hash;
-    }
-
-}
diff --git a/src/main/java/org/apache/sling/resourceresolver/impl/mapping/MapConfigurationProvider.java b/src/main/java/org/apache/sling/resourceresolver/impl/mapping/MapConfigurationProvider.java
deleted file mode 100644
index 0dd8f70..0000000
--- a/src/main/java/org/apache/sling/resourceresolver/impl/mapping/MapConfigurationProvider.java
+++ /dev/null
@@ -1,72 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with this
- * work for additional information regarding copyright ownership. The ASF
- * licenses this file to You under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
- * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
- * License for the specific language governing permissions and limitations under
- * the License.
- */
-package org.apache.sling.resourceresolver.impl.mapping;
-
-import java.util.List;
-import java.util.Map;
-
-import org.apache.sling.api.resource.ResourceResolverFactory;
-
-/**
- * Internal interface representing the additional methods
- * MapEntries needs from the ResourceResolverFactory.
- *
- * Exists primarily to facilitate mocking of the ResourceResolverFactory
- * when testing MapEntries.
- */
-public interface MapConfigurationProvider extends ResourceResolverFactory {
-
-    String getMapRoot();
-
-    Map<?, ?> getVirtualURLMap();
-
-    Mapping[] getMappings();
-
-    int getDefaultVanityPathRedirectStatus();
-
-    boolean isVanityPathEnabled();
-    
-    long getMaxCachedVanityPathEntries();
-    
-    boolean isMaxCachedVanityPathEntriesStartup();
-    
-    int getVanityBloomFilterMaxBytes();
-
-    boolean isOptimizeAliasResolutionEnabled();
-    
-    boolean hasVanityPathPrecedence();
-
-    public class VanityPathConfig implements Comparable<VanityPathConfig> {
-        public final boolean isExclude;
-        public final String prefix;
-
-        public VanityPathConfig(final String prefix, final boolean isExclude) {
-            this.prefix = prefix;
-            this.isExclude = isExclude;
-        }
-
-        public int compareTo(VanityPathConfig o2) {
-            return new Integer(o2.prefix.length()).compareTo(this.prefix.length());
-        }
-    }
-
-    /**
-     * A list of white and black list prefixes all ending with a slash.
-     * If <code>null</code> is returned, all paths are allowed.
-     */
-    List<VanityPathConfig> getVanityPathConfig();
-}
diff --git a/src/main/java/org/apache/sling/resourceresolver/impl/mapping/MapEntries.java b/src/main/java/org/apache/sling/resourceresolver/impl/mapping/MapEntries.java
deleted file mode 100644
index 69cc457..0000000
--- a/src/main/java/org/apache/sling/resourceresolver/impl/mapping/MapEntries.java
+++ /dev/null
@@ -1,1575 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *   http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-package org.apache.sling.resourceresolver.impl.mapping;
-
-import java.io.DataInputStream;
-import java.io.File;
-import java.io.FileInputStream;
-import java.io.FileOutputStream;
-import java.io.IOException;
-import java.net.MalformedURLException;
-import java.net.URL;
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.Collections;
-import java.util.Dictionary;
-import java.util.HashMap;
-import java.util.Hashtable;
-import java.util.Iterator;
-import java.util.LinkedHashMap;
-import java.util.List;
-import java.util.Map;
-import java.util.Map.Entry;
-import java.util.NoSuchElementException;
-import java.util.SortedMap;
-import java.util.Timer;
-import java.util.TimerTask;
-import java.util.TreeMap;
-import java.util.TreeSet;
-import java.util.concurrent.ConcurrentHashMap;
-import java.util.concurrent.TimeUnit;
-import java.util.concurrent.atomic.AtomicLong;
-import java.util.concurrent.locks.ReentrantLock;
-
-import javax.servlet.http.HttpServletResponse;
-
-import org.apache.sling.api.SlingConstants;
-import org.apache.sling.api.resource.LoginException;
-import org.apache.sling.api.resource.Resource;
-import org.apache.sling.api.resource.ResourceResolver;
-import org.apache.sling.api.resource.ResourceUtil;
-import org.apache.sling.api.resource.ValueMap;
-import org.apache.sling.resourceresolver.impl.ResourceResolverImpl;
-import org.apache.sling.resourceresolver.impl.mapping.MapConfigurationProvider.VanityPathConfig;
-import org.osgi.framework.BundleContext;
-import org.osgi.framework.Constants;
-import org.osgi.framework.ServiceRegistration;
-import org.osgi.service.event.Event;
-import org.osgi.service.event.EventAdmin;
-import org.osgi.service.event.EventConstants;
-import org.osgi.service.event.EventHandler;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-public class MapEntries implements EventHandler {
-
-    public static final MapEntries EMPTY = new MapEntries();
-
-    private static final String PROP_REG_EXP = "sling:match";
-
-    public static final String PROP_REDIRECT_EXTERNAL = "sling:redirect";
-
-    public static final String PROP_REDIRECT_EXTERNAL_STATUS = "sling:status";
-
-    public static final String PROP_REDIRECT_EXTERNAL_REDIRECT_STATUS = "sling:redirectStatus";
-    
-    public static final String PROP_VANITY_PATH = "sling:vanityPath";
-    
-    public static final String PROP_VANITY_ORDER = "sling:vanityOrder";
-    
-    private static final String VANITY_BLOOM_FILTER_NAME = "vanityBloomFilter.txt";
-    
-    private static final int VANITY_BLOOM_FILTER_MAX_ENTRIES = 10000000;
-
-    /** Key for the global list. */
-    private static final String GLOBAL_LIST_KEY = "*";
-
-    public static final String DEFAULT_MAP_ROOT = "/etc/map";
-
-    public static final int DEFAULT_DEFAULT_VANITY_PATH_REDIRECT_STATUS = HttpServletResponse.SC_FOUND;
-
-    private static final String JCR_SYSTEM_PREFIX = "/jcr:system/";
-
-    static final String ANY_SCHEME_HOST = "[^/]+/[^/]+";
-
-    /** default log */
-    private final Logger log = LoggerFactory.getLogger(getClass());
-
-    private MapConfigurationProvider factory;
-
-    private volatile ResourceResolver resolver;
-
-    private final String mapRoot;
-
-    private Map<String, List<MapEntry>> resolveMapsMap;
-
-    private Collection<MapEntry> mapMaps;
-
-    private Map <String,List <String>> vanityTargets;
-
-    private Map<String, Map<String, String>> aliasMap;
-
-    private ServiceRegistration registration;
-
-    private EventAdmin eventAdmin;
-
-    private final ReentrantLock initializing = new ReentrantLock();
-
-    private final boolean enabledVanityPaths;
-    
-    private final long maxCachedVanityPathEntries;
-    
-    private final boolean maxCachedVanityPathEntriesStartup;
-    
-    private final int vanityBloomFilterMaxBytes;
-
-    private final boolean enableOptimizeAliasResolution;
-    
-    private final boolean vanityPathPrecedence;
-
-    private final List<VanityPathConfig> vanityPathConfig;
-    
-    private final AtomicLong vanityCounter;
-
-    private final File vanityBloomFilterFile;
-
-    private byte[] vanityBloomFilter;
-
-    private Timer timer;
-
-    private boolean updateBloomFilterFile = false;
-
-    @SuppressWarnings("unchecked")
-    private MapEntries() {
-        this.factory = null;
-        this.resolver = null;
-        this.mapRoot = DEFAULT_MAP_ROOT;
-
-        this.resolveMapsMap = Collections.singletonMap(GLOBAL_LIST_KEY, (List<MapEntry>)Collections.EMPTY_LIST);
-        this.mapMaps = Collections.<MapEntry> emptyList();
-        this.vanityTargets = Collections.<String,List <String>>emptyMap();
-        this.aliasMap = Collections.<String, Map<String, String>>emptyMap();
-        this.registration = null;
-        this.eventAdmin = null;
-        this.enabledVanityPaths = true;
-        this.maxCachedVanityPathEntries = -1;
-        this.maxCachedVanityPathEntriesStartup = true;
-        this.vanityBloomFilterMaxBytes = 0;
-        this.enableOptimizeAliasResolution = true;
-        this.vanityPathConfig = null;
-        this.vanityPathPrecedence = false;
-        this.vanityCounter = new AtomicLong(0);
-        this.vanityBloomFilterFile = null;
-    }
-
-    @SuppressWarnings({ "unchecked", "deprecation" })
-    public MapEntries(final MapConfigurationProvider factory, final BundleContext bundleContext, final EventAdmin eventAdmin)
-                    throws LoginException, IOException {
-        this.resolver = factory.getAdministrativeResourceResolver(null);
-        this.factory = factory;
-        this.mapRoot = factory.getMapRoot();
-        this.enabledVanityPaths = factory.isVanityPathEnabled();
-        this.maxCachedVanityPathEntries = factory.getMaxCachedVanityPathEntries();
-        this.maxCachedVanityPathEntriesStartup = factory.isMaxCachedVanityPathEntriesStartup();
-        this.vanityBloomFilterMaxBytes = factory.getVanityBloomFilterMaxBytes();
-        this.vanityPathConfig = factory.getVanityPathConfig();
-        this.enableOptimizeAliasResolution = factory.isOptimizeAliasResolutionEnabled();
-        this.vanityPathPrecedence = factory.hasVanityPathPrecedence();
-        this.eventAdmin = eventAdmin;
-
-        this.resolveMapsMap = Collections.singletonMap(GLOBAL_LIST_KEY, (List<MapEntry>)Collections.EMPTY_LIST);
-        this.mapMaps = Collections.<MapEntry> emptyList();
-        this.vanityTargets = Collections.<String,List <String>>emptyMap();
-        this.aliasMap = Collections.<String, Map<String, String>>emptyMap();
-
-        doInit();
-
-        final Dictionary<String, String> props = new Hashtable<String, String>();
-        props.put(EventConstants.EVENT_TOPIC, "org/apache/sling/api/resource/*");
-        props.put(EventConstants.EVENT_FILTER, createFilter(this.enabledVanityPaths));
-        props.put(Constants.SERVICE_DESCRIPTION, "Map Entries Observation");
-        props.put(Constants.SERVICE_VENDOR, "The Apache Software Foundation");
-        this.registration = bundleContext.registerService(EventHandler.class.getName(), this, props);
-        
-        this.vanityCounter = new AtomicLong(0);
-        this.vanityBloomFilterFile = bundleContext.getDataFile(VANITY_BLOOM_FILTER_NAME);
-        initializeVanityPaths();
-    }
-
-    /**
-     * Actual initializer. Guards itself against concurrent use by using a
-     * ReentrantLock. Does nothing if the resource resolver has already been
-     * null-ed.
-     */
-    protected void doInit() {
-
-        this.initializing.lock();
-        try {
-            final ResourceResolver resolver = this.resolver;
-            final MapConfigurationProvider factory = this.factory;
-            if (resolver == null || factory == null) {
-                return;
-            }
-
-            final Map<String, List<MapEntry>> newResolveMapsMap = new ConcurrentHashMap<String, List<MapEntry>>();  
-            
-            //optimization made in SLING-2521
-            if (enableOptimizeAliasResolution){
-                final Map<String, Map<String, String>> aliasMap = this.loadAliases(resolver);
-                this.aliasMap = aliasMap;
-            }
-
-            this.resolveMapsMap = newResolveMapsMap; 
-
-            doUpdateConfiguration();
-
-            sendChangeEvent();
-        } catch (final Exception e) {
-
-            log.warn("doInit: Unexpected problem during initialization", e);
-
-        } finally {
-
-            this.initializing.unlock();
-
-        }
-    }
-    
-    /**
-     * Actual vanity paths initializer. Guards itself against concurrent use by
-     * using a ReentrantLock. Does nothing if the resource resolver has already
-     * been null-ed.
-     * 
-     * @throws IOException
-     */
-    protected void initializeVanityPaths() throws IOException {
-        this.initializing.lock();
-        try {
-            if (this.enabledVanityPaths) {
-
-                if (vanityBloomFilterFile == null) {
-                    throw new RuntimeException(
-                            "This platform does not have file system support");
-                }
-                boolean createVanityBloomFilter = false;
-                if (!vanityBloomFilterFile.exists()) {
-                    log.debug("creating bloom filter file {}",
-                            vanityBloomFilterFile.getAbsolutePath());
-                    vanityBloomFilter = createVanityBloomFilter();
-                    persistBloomFilter();
-                    createVanityBloomFilter = true;
-                } else {
-                    // initialize bloom filter from disk
-                    vanityBloomFilter = new byte[(int) vanityBloomFilterFile
-                            .length()];
-                    DataInputStream dis = new DataInputStream(
-                            new FileInputStream(vanityBloomFilterFile));
-                    try {
-                        dis.readFully(vanityBloomFilter);
-                    } finally {
-                        dis.close();
-                    }
-                }
-
-                // task for persisting the bloom filter every minute (if changes
-                // exist)
-                timer = new Timer();
-                timer.schedule(new BloomFilterTask(), 60 * 1000);
-
-                final Map<String, List<String>> vanityTargets = this
-                        .loadVanityPaths(createVanityBloomFilter);
-                this.vanityTargets = vanityTargets;
-            }
-        } finally {
-            this.initializing.unlock();
-        }
-
-    }
-
-    private boolean doNodeAdded(String path, boolean refreshed) {
-        this.initializing.lock();
-        boolean newRefreshed = refreshed;
-        if (!newRefreshed) {
-            resolver.refresh();
-            newRefreshed = true;
-        }
-        try {
-            Resource resource = resolver.getResource(path);
-            if (resource != null) {
-                final ValueMap props = resource.adaptTo(ValueMap.class);
-                if (props.containsKey(PROP_VANITY_PATH)) {
-                    doAddVanity(path);
-                }
-                if (props.containsKey(ResourceResolverImpl.PROP_ALIAS)) {
-                    doAddAlias(path);
-                }
-                if (path.startsWith(this.mapRoot)) {
-                    doUpdateConfiguration();
-                }
-            }
-            sendChangeEvent();
-            
-        } finally {
-            this.initializing.unlock();
-        }
-        return newRefreshed;
-    }
-    
-    private boolean doAddAttributes(String path, String[] addedAttributes, boolean refreshed) {
-        this.initializing.lock();
-        boolean newRefreshed = refreshed;
-        if (!newRefreshed) {
-            resolver.refresh();
-            newRefreshed = true;
-        }
-        try {
-            for (String changedAttribute:addedAttributes){
-                if (PROP_VANITY_PATH.equals(changedAttribute)) {
-                    doAddVanity(path); 
-                } else if (PROP_VANITY_ORDER.equals(changedAttribute)) {
-                    doUpdateVanityOrder(path, false);
-                } else if (PROP_REDIRECT_EXTERNAL.equals(changedAttribute) 
-                        || PROP_REDIRECT_EXTERNAL_REDIRECT_STATUS.equals(changedAttribute)) {
-                    doUpdateRedirectStatus(path);
-                } else if (ResourceResolverImpl.PROP_ALIAS.equals(changedAttribute)) {
-                    if (enableOptimizeAliasResolution) {
-                       doAddAlias(path);
-                    }
-                }
-            }
-            if (path.startsWith(this.mapRoot)) {
-                doUpdateConfiguration();
-            }
-            sendChangeEvent();
-        } finally {
-            this.initializing.unlock();
-        }
-        return newRefreshed;
-    }
-
-    private boolean doUpdateAttributes(String path, String[] changedAttributes, boolean refreshed) {
-        this.initializing.lock();
-        boolean newRefreshed = refreshed;
-        if (!newRefreshed) {
-            resolver.refresh();
-            newRefreshed = true;
-        }
-        try {
-            for (String changedAttribute:changedAttributes){
-                if (PROP_VANITY_PATH.equals(changedAttribute)) {
-                    doUpdateVanity(path);
-                } else if (PROP_VANITY_ORDER.equals(changedAttribute)) {
-                    doUpdateVanityOrder(path, false);
-                } else if (PROP_REDIRECT_EXTERNAL.equals(changedAttribute)
-                        || PROP_REDIRECT_EXTERNAL_REDIRECT_STATUS.equals(changedAttribute)) {
-                    doUpdateRedirectStatus(path);
-                } else if (ResourceResolverImpl.PROP_ALIAS.equals(changedAttribute)) {
-                    if (enableOptimizeAliasResolution) {
-                        doRemoveAlias(path, false);
-                        doAddAlias(path);
-                        doUpdateAlias(path, false);
-                     }                    
-                }
-            }
-            if (path.startsWith(this.mapRoot)) {
-                doUpdateConfiguration();
-            }
-            sendChangeEvent();
-        } finally {
-            this.initializing.unlock();
-        }
-        return newRefreshed;
-    }
-
-    private boolean doRemoveAttributes(String path, String[] removedAttributes, boolean nodeDeletion, boolean refreshed) {
-        this.initializing.lock();
-        boolean newRefreshed = refreshed;
-        if (!newRefreshed) {
-            resolver.refresh();
-            newRefreshed = true;
-        }
-        try {
-            for (String changedAttribute:removedAttributes){
-                if (PROP_VANITY_PATH.equals(changedAttribute)){
-                    doRemoveVanity(path);
-                } else if (PROP_VANITY_ORDER.equals(changedAttribute)) {
-                    doUpdateVanityOrder(path, true);
-                } else if (PROP_REDIRECT_EXTERNAL.equals(changedAttribute)
-                        || PROP_REDIRECT_EXTERNAL_REDIRECT_STATUS.equals(changedAttribute)) {
-                    doUpdateRedirectStatus(path);
-                } else if (ResourceResolverImpl.PROP_ALIAS.equals(changedAttribute)) {
-                    if (enableOptimizeAliasResolution) {
-                        doRemoveAlias(path, nodeDeletion); 
-                        doUpdateAlias(path, nodeDeletion);                        
-                    }
-                }
-            }
-            if (path.startsWith(this.mapRoot)) {
-                doUpdateConfiguration();
-            }
-            sendChangeEvent();
-        } finally {
-            this.initializing.unlock();
-        }
-        return newRefreshed;
-    }
-    
-    private boolean doUpdateConfiguration(boolean refreshed){
-        this.initializing.lock();
-        boolean newRefreshed = refreshed;
-        if (!newRefreshed) {
-            resolver.refresh();
-            newRefreshed = true;
-        }
-        try {
-            doUpdateConfiguration();
-            sendChangeEvent();
-        } finally {
-            this.initializing.unlock();
-        }
-        return newRefreshed;
-    }
-
-    private void doUpdateConfiguration(){
-        final List<MapEntry> globalResolveMap = new ArrayList<MapEntry>();
-        final SortedMap<String, MapEntry> newMapMaps = new TreeMap<String, MapEntry>();
-        // load the /etc/map entries into the maps
-        loadResolverMap(resolver, globalResolveMap, newMapMaps);
-        // load the configuration into the resolver map
-        loadConfiguration(factory, globalResolveMap);
-        // load the configuration into the mapper map
-        loadMapConfiguration(factory, newMapMaps);
-        // sort global list and add to map
-        Collections.sort(globalResolveMap);
-        resolveMapsMap.put(GLOBAL_LIST_KEY, globalResolveMap);
-        this.mapMaps = Collections.unmodifiableSet(new TreeSet<MapEntry>(newMapMaps.values()));
-    }
-
-    private void doAddVanity(String path) {
-        Resource resource = resolver.getResource(path);
-        if (isAllVanityPathEntriesCached() || vanityCounter.longValue() < maxCachedVanityPathEntries) {
-            // fill up the cache and the bloom filter
-            loadVanityPath(resource, resolveMapsMap, vanityTargets, true, true);
-        } else {
-            // fill up the bloom filter
-            loadVanityPath(resource, resolveMapsMap, vanityTargets, false, true);
-        }
-        updateBloomFilterFile = true;
-    }
-
-    private void doUpdateVanity(String path) {
-         doRemoveVanity(path);
-         doAddVanity(path);
-    }
-
-    private void doRemoveVanity(String path) {
-        String actualContentPath = getActualContentPath(path);
-        List <String> l = vanityTargets.get(actualContentPath);
-        if (l != null){
-            for (String s : l){
-                List<MapEntry> entries = this.resolveMapsMap.get(s);
-                if (entries!= null) {
-                    for (Iterator<MapEntry> iterator =entries.iterator(); iterator.hasNext(); ) {
-                        MapEntry entry = iterator.next();
-                        String redirect = getMapEntryRedirect(entry);
-                        if (redirect != null && redirect.equals(actualContentPath)) {
-                            iterator.remove();
-                        }
-                    }
-                }
-                if (entries!= null && entries.isEmpty()) {
-                    this.resolveMapsMap.remove(s);
-                }     
-            }
-        }
-        vanityTargets.remove(actualContentPath);
-        if (vanityCounter.longValue() > 0) {
-            vanityCounter.addAndGet(-2);
-        }     
-    }
-
-    private void doUpdateVanityOrder(String path, boolean deletion) {
-        Resource resource = resolver.getResource(path);
-        final ValueMap props = resource.adaptTo(ValueMap.class);
-
-        long vanityOrder;
-        if (deletion) {
-            vanityOrder = 0;
-        } else {
-            vanityOrder = props.get(PROP_VANITY_ORDER, Long.class);
-        }
-
-        String actualContentPath = getActualContentPath(path);
-        List<String> vanityPaths = vanityTargets.get(actualContentPath);
-        if (vanityPaths != null) {
-            boolean updatedOrder = false;
-            for (String vanityTarget : vanityPaths) {
-                List<MapEntry> entries = this.resolveMapsMap.get(vanityTarget);
-                for (MapEntry entry : entries) {
-                    String redirect = getMapEntryRedirect(entry);
-                    if (redirect != null && redirect.equals(actualContentPath)) {
-                        entry.setOrder(vanityOrder);
-                        updatedOrder = true;
-                    }
-                }
-                if (updatedOrder) {
-                    Collections.sort(entries);
-                }
-            }
-        }
-    }
-    
-    private void doUpdateRedirectStatus(String path) {
-        String actualContentPath = getActualContentPath(path);
-        List<String> vanityPaths = vanityTargets.get(actualContentPath);
-        if (vanityPaths != null) {
-            doUpdateVanity(path);
-        }
-    }
-
-    private void doAddAlias(String path) {
-        Resource resource = resolver.getResource(path);
-        loadAlias(resource, this.aliasMap);
-    }
-
-    private void doUpdateAlias(String path, boolean nodeDeletion) {
-        if (nodeDeletion){
-            if (path.endsWith("/jcr:content")) {
-                path =  path.substring(0, path.length() - "/jcr:content".length());
-                final Resource resource = resolver.getResource(path);  
-                if (resource != null) {
-                    path =  resource.getPath();            
-                    final ValueMap props = resource.adaptTo(ValueMap.class);
-                    if (props.get(ResourceResolverImpl.PROP_ALIAS, String[].class) != null) {
-                        doAddAlias(path);
-                    }
-                }
-            }  
-        } else {
-            final Resource resource = resolver.getResource(path);  
-            if (resource != null) {
-                if (resource.getName().equals("jcr:content")) {  
-                    final Resource parent = resource.getParent();
-                    path =  parent.getPath();            
-                    final ValueMap props = parent.adaptTo(ValueMap.class);
-                    if (props.get(ResourceResolverImpl.PROP_ALIAS, String[].class) != null) {
-                        doAddAlias(path);
-                    }
-                } else if (resource.getChild("jcr:content") != null) {
-                    Resource jcrContent = resource.getChild("jcr:content");
-                    path =  jcrContent.getPath();         
-                    final ValueMap props = jcrContent.adaptTo(ValueMap.class);
-                    if (props.get(ResourceResolverImpl.PROP_ALIAS, String[].class) != null) {
-                        doAddAlias(path);
-                    }
-                } 
-            }
-        }
-    }
-
-    private void doRemoveAlias(String path, boolean nodeDeletion) {
-        String resourceName = null;
-        if (nodeDeletion) { 
-            if (!"/".equals(path)){
-                if (path.endsWith("/jcr:content")) {
-                    path =  path.substring(0, path.length() - "/jcr:content".length());
-                }
-                resourceName = path.substring(path.lastIndexOf("/") + 1);
-                path = ResourceUtil.getParent(path);      
-            } else {
-                resourceName = "";
-            }
-        } else {
-            final Resource resource = resolver.getResource(path); 
-            if (resource.getName().equals("jcr:content")) {
-                final Resource containingResource = resource.getParent();
-                path = containingResource.getParent().getPath();   
-                resourceName = containingResource.getName();
-            } else {
-                path =  resource.getParent().getPath();
-                resourceName = resource.getName();
-            }            
-        }
-        Map<String, String> aliasMapEntry = aliasMap.get(path);
-        if (aliasMapEntry != null) {
-            for (Iterator<String> iterator =aliasMapEntry.keySet().iterator(); iterator.hasNext(); ) {
-                String key = iterator.next();
-                if (resourceName.equals(aliasMapEntry.get(key))){
-                    iterator.remove();
-                }
-            }
-        }
-        if (aliasMapEntry != null && aliasMapEntry.isEmpty()) {
-            this.aliasMap.remove(path);
-        }
-    }
-
-    public boolean isOptimizeAliasResolutionEnabled() {
-        return this.enableOptimizeAliasResolution;
-    }
-
-    /**
-     * Cleans up this class.
-     */
-    public void dispose() {
-        try {
-            persistBloomFilter();
-        } catch (IOException e) {
-           log.error("Error while saving bloom filter to disk", e);
-        }
-        
-        if (this.registration != null) {
-            this.registration.unregister();
-            this.registration = null;
-        }
-
-        /*
-         * Cooperation with doInit: The same lock as used by doInit is acquired
-         * thus preventing doInit from running and waiting for a concurrent
-         * doInit to terminate. Once the lock has been acquired, the resource
-         * resolver is null-ed (thus causing the init to terminate when
-         * triggered the right after and prevent the doInit method from doing
-         * any thing).
-         */
-
-        // wait at most 10 seconds for a notifcation during initialization
-        boolean initLocked;
-        try {
-            initLocked = this.initializing.tryLock(10, TimeUnit.SECONDS);
-        } catch (final InterruptedException ie) {
-            initLocked = false;
-        }
-
-        try {
-            if (!initLocked) {
-                log.warn("dispose: Could not acquire initialization lock within 10 seconds; ongoing intialization may fail");
-            }
-
-            // immediately set the resolver field to null to indicate
-            // that we have been disposed (this also signals to the
-            // event handler to stop working
-            final ResourceResolver oldResolver = this.resolver;
-            this.resolver = null;
-
-            if (oldResolver != null) {
-                oldResolver.close();
-            } else {
-                log.warn("dispose: ResourceResolver has already been cleared before; duplicate call to dispose ?");
-            }
-        } finally {
-            if (initLocked) {
-                this.initializing.unlock();
-            }
-        }
-
-        // clear the rest of the fields
-        this.factory = null;
-        this.eventAdmin = null;
-    }
-
-    /**
-     * This is for the web console plugin
-     */
-    public List<MapEntry> getResolveMaps() {
-        final List<MapEntry> entries = new ArrayList<MapEntry>();
-        for (final List<MapEntry> list : this.resolveMapsMap.values()) {
-            entries.addAll(list);
-        }
-        Collections.sort(entries);
-        return Collections.unmodifiableList(entries);
-    }
-
-    /**
-     * Calculate the resolve maps. As the entries have to be sorted by pattern
-     * length, we have to create a new list containing all relevant entries.
-     */
-    public Iterator<MapEntry> getResolveMapsIterator(final String requestPath) {
-        String key = null;
-        final int firstIndex = requestPath.indexOf('/');
-        final int secondIndex = requestPath.indexOf('/', firstIndex + 1);
-        if (secondIndex != -1) {
-            key = requestPath.substring(secondIndex);
-        }
-
-        return new MapEntryIterator(key, resolveMapsMap, vanityPathPrecedence);
-    }
-
-    public Collection<MapEntry> getMapMaps() {
-        return mapMaps;
-    }
-
-    public Map<String, String> getAliasMap(final String parentPath) {
-        return aliasMap.get(parentPath);
-    }
-    
-    /**
-     * get the MapEnty containing all the nodes having a specific vanityPath
-     */
-    private List<MapEntry> getMapEntryList(String vanityPath){
-        List<MapEntry> mapEntries = null;  
-        
-        if (BloomFilterUtils.probablyContains(vanityBloomFilter, vanityPath)) {
-            mapEntries = this.resolveMapsMap.get(vanityPath);
-            if (mapEntries == null) {
-                Map<String, List<MapEntry>>  mapEntry = getVanityPaths(vanityPath);
-                mapEntries = mapEntry.get(vanityPath);
-            } 
-        }  
-        
-        return mapEntries;
-    }
-
-    // ---------- EventListener interface
-
-    /**
-     * Handles the change to any of the node properties relevant for vanity URL
-     * mappings. The {@link #MapEntries(ResourceResolverFactoryImpl, BundleContext, EventAdmin)}
-     * constructor makes sure the event listener is registered to only get
-     * appropriate events.
-     */
-    public void handleEvent(final Event event) {
-
-        // check for path (used for some tests below
-        final Object p = event.getProperty(SlingConstants.PROPERTY_PATH);
-        final String path;
-        if (p instanceof String) {
-            path = (String) p;
-            log.debug("handleEvent, topic={}, path={}", event.getTopic(), path);
-        } else {
-            log.debug("handleEvent, topic={}, no path provided, event ignored", event.getTopic());
-            return;
-        }
-
-        // don't care for system area
-        if (path.startsWith(JCR_SYSTEM_PREFIX)) {
-            return;
-        }
-
-        boolean wasResolverRefreshed = false;
-
-        //removal of a node is handled differently
-        if (SlingConstants.TOPIC_RESOURCE_REMOVED.equals(event.getTopic())) {
-            final String actualContentPath = getActualContentPath(path);
-            for (final String target : this.vanityTargets.keySet()) {
-                if (target.startsWith(actualContentPath)) {
-                    wasResolverRefreshed = doRemoveAttributes(path, new String [] {PROP_VANITY_PATH}, true, wasResolverRefreshed);
-                }
-            }
-            for (final String target : this.aliasMap.keySet()) {
-                if (actualContentPath.startsWith(target)) {
-                    wasResolverRefreshed = doRemoveAttributes(path, new String [] {ResourceResolverImpl.PROP_ALIAS}, true, wasResolverRefreshed);
-                }
-            }
-            if (path.startsWith(this.mapRoot)) {
-                //need to update the configuration
-                wasResolverRefreshed = doUpdateConfiguration(wasResolverRefreshed);
-            }
-        //session.move() is handled differently see also SLING-3713 and    
-        } else if (SlingConstants.TOPIC_RESOURCE_ADDED.equals(event.getTopic()) && event.getProperty(SlingConstants.PROPERTY_ADDED_ATTRIBUTES) == null) {
-            wasResolverRefreshed = doNodeAdded(path, wasResolverRefreshed);
-        } else {
-            String [] addedAttributes = (String []) event.getProperty(SlingConstants.PROPERTY_ADDED_ATTRIBUTES);
-            if (addedAttributes != null) {
-                if (log.isDebugEnabled()) {
-                    log.debug("found added attributes {}", addedAttributes);
-                }
-                wasResolverRefreshed = doAddAttributes(path, addedAttributes, wasResolverRefreshed);
-            }
-
-            String [] changedAttributes = (String []) event.getProperty(SlingConstants.PROPERTY_CHANGED_ATTRIBUTES);
-            if (changedAttributes != null) {
-                if (log.isDebugEnabled()) {
-                    log.debug("found changed attributes {}", changedAttributes);
-                }
-                wasResolverRefreshed = doUpdateAttributes(path, changedAttributes, wasResolverRefreshed);
-            }
-
-            String [] removedAttributes = (String []) event.getProperty(SlingConstants.PROPERTY_REMOVED_ATTRIBUTES);
-            if (removedAttributes != null) {
-                if (log.isDebugEnabled()) {
-                    log.debug("found removed attributes {}", removedAttributes);
-                }
-                wasResolverRefreshed = doRemoveAttributes(path, removedAttributes, false, wasResolverRefreshed);
-            } 
-        }
-    }
-
-    // ---------- internal
-    
-    private byte[] createVanityBloomFilter() throws IOException {
-        byte bloomFilter[] = null;
-        if (vanityBloomFilter == null) {            
-            bloomFilter = BloomFilterUtils.createFilter(VANITY_BLOOM_FILTER_MAX_ENTRIES, this.vanityBloomFilterMaxBytes);
-        }
-        return bloomFilter;
-    }
-
-    private void persistBloomFilter() throws IOException {
-        if (vanityBloomFilterFile != null && vanityBloomFilter != null) {
-            FileOutputStream out = new FileOutputStream(vanityBloomFilterFile);
-            try {
-                out.write(this.vanityBloomFilter);
-            } finally {
-                out.close();
-            }
-        }
-    }
-
-    private boolean isAllVanityPathEntriesCached() {
-        return maxCachedVanityPathEntries == -1;
-    }
-
-    /**
-     * Escapes illegal XPath search characters at the end of a string.
-     * <p>
-     * Example:<br>
-     * A search string like 'test?' will run into a ParseException documented in
-     * http://issues.apache.org/jira/browse/JCR-1248
-     * 
-     * @param s
-     *            the string to encode
-     * @return the escaped string
-     */
-    private static String escapeIllegalXpathSearchChars(String s) {
-        StringBuilder sb = new StringBuilder();
-        if (s != null && s.length() > 1) {
-            sb.append(s.substring(0, (s.length() - 1)));
-            char c = s.charAt(s.length() - 1);
-            // NOTE: keep this in sync with _ESCAPED_CHAR below!
-            if (c == '!' || c == '(' || c == ':' || c == '^' || c == '['
-                    || c == ']' || c == '{' || c == '}' || c == '?') {
-                sb.append('\\');
-            }
-            sb.append(c);
-        }        
-        return sb.toString();
-    }
-    
-    /**
-     * get the vanity paths  Search for all nodes having a specific vanityPath
-     */
-    @SuppressWarnings("deprecation")
-    private Map<String, List<MapEntry>> getVanityPaths(String vanityPath) {
-
-        Map<String, List<MapEntry>> entryMap = new HashMap<String, List<MapEntry>>();    
-        
-        // sling:VanityPath (uppercase V) is the mixin name
-        // sling:vanityPath (lowercase) is the property name        
-        final String queryString = "SELECT sling:vanityPath, sling:redirect, sling:redirectStatus FROM sling:VanityPath WHERE sling:vanityPath ="
-                + "'"+escapeIllegalXpathSearchChars(vanityPath).replaceAll("'", "''")+"' OR sling:vanityPath ="+ "'"+escapeIllegalXpathSearchChars(vanityPath.substring(1)).replaceAll("'", "''")+"' ORDER BY sling:vanityOrder DESC";
-        
-        ResourceResolver queryResolver = null;
-
-        try {
-            queryResolver = factory.getAdministrativeResourceResolver(null);
-            final Iterator<Resource> i = queryResolver.findResources(queryString, "sql");
-            while (i.hasNext()) {
-                final Resource resource = i.next();
-                if (maxCachedVanityPathEntriesStartup || vanityCounter.longValue() < maxCachedVanityPathEntries) {                    
-                    loadVanityPath(resource, resolveMapsMap, vanityTargets, true, false);
-                    entryMap = resolveMapsMap;
-                } else {                    
-                    final Map <String, List<String>> targetPaths = new HashMap <String, List<String>>();
-                    loadVanityPath(resource, entryMap, targetPaths, true, false);
-                }               
-            }
-        } catch (LoginException e) {
-            log.error("Exception while obtaining queryResolver", e);
-        } finally {
-            if (queryResolver != null) {
-                queryResolver.close();
-            }
-        }
-        return entryMap;        
-    }
-    
-    private boolean isValidVanityPath(Resource resource){
-        // ignore system tree
-        if (resource.getPath().startsWith(JCR_SYSTEM_PREFIX)) {
-            log.debug("isValidVanityPath: not valid {}", resource);
-            return false;
-        }
-
-        // check white list
-        if ( this.vanityPathConfig != null ) {
-            boolean allowed = false;
-            for(final VanityPathConfig config : this.vanityPathConfig) {
-                if ( resource.getPath().startsWith(config.prefix) ) {
-                    allowed = !config.isExclude;
-                    break;
-                }
-            }
-            if ( !allowed ) {
-                log.debug("isValidVanityPath: not valid as not in white list {}", resource);
-                return false;
-            }
-        }
-        // require properties
-        final ValueMap props = resource.adaptTo(ValueMap.class);
-        if (props == null) {
-            log.debug("isValidVanityPath: not valid {} without properties", resource);
-            return false;
-        }
-        return true;
-    }
-
-    private String getActualContentPath(String path){
-        final String checkPath;
-        if ( path.endsWith("/jcr:content") ) {
-            checkPath = path.substring(0, path.length() - "/jcr:content".length());
-        } else {
-            checkPath = path;
-        }
-        return checkPath;
-    }
-
-    private String getMapEntryRedirect(MapEntry mapEntry) {
-        String[] redirect = mapEntry.getRedirect();
-        if (redirect.length > 1) {
-            log.warn("something went wrong, please restart the bundle");
-            return null;
-        }
-
-        String path = redirect[0];
-        if (path.endsWith("$1")) {
-            path = path.substring(0, path.length() - "$1".length());
-        } else if (path.endsWith(".html")) {
-            path = path.substring(0, path.length() - ".html".length());
-        }
-
-        return path;
-    }
-
-    /**
-     * Send an OSGi event
-     */
-    private void sendChangeEvent() {
-        if (this.eventAdmin != null) {
-            final Event event = new Event(SlingConstants.TOPIC_RESOURCE_RESOLVER_MAPPING_CHANGED,
-                            (Dictionary<?, ?>) null);
-            this.eventAdmin.postEvent(event);
-        }
-    }
-
-    private void loadResolverMap(final ResourceResolver resolver, final List<MapEntry> entries, final Map<String, MapEntry> mapEntries) {
-        // the standard map configuration
-        final Resource res = resolver.getResource(mapRoot);
-        if (res != null) {
-            gather(resolver, entries, mapEntries, res, "");
-        }
-    }
-
-    private void gather(final ResourceResolver resolver, final List<MapEntry> entries, final Map<String, MapEntry> mapEntries,
-                    final Resource parent, final String parentPath) {
-        // scheme list
-        final Iterator<Resource> children = parent.listChildren();
-        while (children.hasNext()) {
-            final Resource child = children.next();
-            final ValueMap vm = ResourceUtil.getValueMap(child);
-
-            String name = vm.get(PROP_REG_EXP, String.class);
-            boolean trailingSlash = false;
-            if (name == null) {
-                name = child.getName().concat("/");
-                trailingSlash = true;
-            }
-
-            final String childPath = parentPath.concat(name);
-
-            // gather the children of this entry (only if child is not end
-            // hooked)
-            if (!childPath.endsWith("$")) {
-
-                // add trailing slash to child path to append the child
-                String childParent = childPath;
-                if (!trailingSlash) {
-                    childParent = childParent.concat("/");
-                }
-
-                gather(resolver, entries, mapEntries, child, childParent);
-            }
-
-            // add resolution entries for this node
-            MapEntry childResolveEntry = null;
-            try{
-                childResolveEntry=MapEntry.createResolveEntry(childPath, child, trailingSlash);
-            }catch (IllegalArgumentException iae){
-                //ignore this entry
-                log.debug("ignored entry due exception ",iae);
-            }
-            if (childResolveEntry != null) {
-                entries.add(childResolveEntry);
-            }
-
-            // add map entries for this node
-            final List<MapEntry> childMapEntries = MapEntry.createMapEntry(childPath, child, trailingSlash);
-            if (childMapEntries != null) {
-                for (final MapEntry mapEntry : childMapEntries) {
-                    addMapEntry(mapEntries, mapEntry.getPattern(), mapEntry.getRedirect()[0], mapEntry.getStatus());
-                }
-            }
-
-        }
-    }
-
-    /**
-     * Add an entry to the resolve map.
-     */
-    private boolean addEntry(final Map<String, List<MapEntry>> entryMap, final String key, final MapEntry entry) {
-        
-        if (entry==null){
-            return false;
-        }
-        
-        List<MapEntry> entries = entryMap.get(key);
-        if (entries == null) {
-            entries = new ArrayList<MapEntry>();
-            entries.add(entry);
-            // and finally sort list
-            Collections.sort(entries);
-            entryMap.put(key, entries);
-        } else {
-            List<MapEntry> entriesCopy =new ArrayList<MapEntry>(entries);
-            entriesCopy.add(entry);
-            // and finally sort list
-            Collections.sort( entriesCopy);
-            entryMap.put(key, entriesCopy);
-        }
-        return true;
-    }
-
-    /**
-     * Load aliases Search for all nodes inheriting the sling:alias
-     * property
-     */
-    private Map<String, Map<String, String>> loadAliases(final ResourceResolver resolver) {
-        final Map<String, Map<String, String>> map = new ConcurrentHashMap<String, Map<String, String>>();
-        final String queryString = "SELECT sling:alias FROM nt:base WHERE sling:alias IS NOT NULL";
-        final Iterator<Resource> i = resolver.findResources(queryString, "sql");
-        while (i.hasNext()) {
-            final Resource resource = i.next();         
-            loadAlias(resource, map);
-        }
-        return map;
-    }
-    
-    /**
-     * Load alias given a resource
-     */
-    private void loadAlias(final Resource resource, Map<String, Map<String, String>> map) {
-        // ignore system tree
-        if (resource.getPath().startsWith(JCR_SYSTEM_PREFIX)) {
-            log.debug("loadAliases: Ignoring {}", resource);
-            return;
-        }
-
-        // require properties
-        final ValueMap props = resource.adaptTo(ValueMap.class);
-        if (props == null) {
-            log.debug("loadAliases: Ignoring {} without properties", resource);
-            return;
-        }
-
-        final String resourceName;
-        final String parentPath;
-        if (resource.getName().equals("jcr:content")) {
-            final Resource containingResource = resource.getParent();
-            parentPath = containingResource.getParent().getPath();
-            resourceName = containingResource.getName();
-        } else {
-            parentPath = resource.getParent().getPath();
-            resourceName = resource.getName();
-        }
-        Map<String, String> parentMap = map.get(parentPath);
-        for (final String alias : props.get(ResourceResolverImpl.PROP_ALIAS, String[].class)) {
-            if (parentMap != null && parentMap.containsKey(alias)) {
-                log.warn("Encountered duplicate alias {} under parent path {}. Refusing to replace current target {} with {}.", new Object[] {
-                        alias,
-                        parentPath,
-                        parentMap.get(alias),
-                        resourceName
-                });
-            } else {
-                // check alias
-                boolean invalid = alias.equals("..") || alias.equals(".");
-                if ( !invalid ) {
-                    for(final char c : alias.toCharArray()) {
-                        // invalid if / or # or a ?
-                        if ( c == '/' || c == '#' || c == '?' ) {
-                            invalid = true;
-                            break;
-                        }
-                    }
-                }
-                if ( invalid ) {
-                    log.warn("Encountered invalid alias {} under parent path {}. Refusing to use it.",
-                            alias, parentPath);
-                } else {
-                    if (parentMap == null) {
-                        parentMap = new LinkedHashMap<String, String>();
-                        map.put(parentPath, parentMap);
-                    }
-                    parentMap.put(alias, resourceName);
-                }
-            }
-        }
-    }
-
-    /**
-     * Load vanity paths Search for all nodes inheriting the sling:VanityPath
-     * mixin
-     */
-    private Map <String, List<String>> loadVanityPaths(boolean createVanityBloomFilter) {
-        // sling:VanityPath (uppercase V) is the mixin name
-        // sling:vanityPath (lowercase) is the property name
-        final Map <String, List<String>> targetPaths = new ConcurrentHashMap <String, List<String>>();
-        final String queryString = "SELECT sling:vanityPath, sling:redirect, sling:redirectStatus FROM sling:VanityPath WHERE sling:vanityPath IS NOT NULL";
-        final Iterator<Resource> i = resolver.findResources(queryString, "sql");
-
-        while (i.hasNext() && (createVanityBloomFilter || isAllVanityPathEntriesCached() || vanityCounter.longValue() < maxCachedVanityPathEntries)) {
-            final Resource resource = i.next();
-            if (isAllVanityPathEntriesCached() || vanityCounter.longValue() < maxCachedVanityPathEntries) {
-                // fill up the cache and the bloom filter
-                loadVanityPath(resource, resolveMapsMap, targetPaths, true,
-                        createVanityBloomFilter);
-            } else {
-                // fill up the bloom filter
-                loadVanityPath(resource, resolveMapsMap, targetPaths, false,
-                        createVanityBloomFilter);
-            }
-
-        }
-
-
-        return targetPaths;
-    }
-
-    /**
-     * Load vanity path given a resource
-     */
-    private void loadVanityPath(final Resource resource, final Map<String, List<MapEntry>> entryMap, final Map <String, List<String>> targetPaths, boolean addToCache, boolean newVanity) {
-        
-        if (!isValidVanityPath(resource)) {            
-            return;
-        }
-        
-        final ValueMap props = resource.adaptTo(ValueMap.class);
-        long vanityOrder = 0;
-        if (props.containsKey(PROP_VANITY_ORDER)) {
-            vanityOrder = props.get(PROP_VANITY_ORDER, Long.class);
-        }   
-
-        // url is ignoring scheme and host.port and the path is
-        // what is stored in the sling:vanityPath property
-        final String[] pVanityPaths = props.get(PROP_VANITY_PATH, new String[0]);
-        for (final String pVanityPath : pVanityPaths) {
-            final String[] result = this.getVanityPathDefinition(pVanityPath);
-            if (result != null) {
-                final String url = result[0] + result[1];
-                // redirect target is the node providing the
-                // sling:vanityPath
-                // property (or its parent if the node is called
-                // jcr:content)
-                final Resource redirectTarget;
-                if (resource.getName().equals("jcr:content")) {
-                    redirectTarget = resource.getParent();
-                } else {
-                    redirectTarget = resource;
-                }
-                final String redirect = redirectTarget.getPath();
-                final String redirectName = redirectTarget.getName();
-
-                // whether the target is attained by a external redirect or
-                // by an internal redirect is defined by the sling:redirect
-                // property
-                final int status = props.get(PROP_REDIRECT_EXTERNAL, false) ? props.get(
-                        PROP_REDIRECT_EXTERNAL_REDIRECT_STATUS, factory.getDefaultVanityPathRedirectStatus())
-                        : -1;
-
-                final String checkPath = result[1];
-
-                boolean addedEntry;
-                if (addToCache) {
-                    if (redirectName.indexOf('.') > -1) {
-                        // 1. entry with exact match
-                        this.addEntry(entryMap, checkPath, getMapEntry(url + "$", status, false, vanityOrder, redirect));
-
-                        final int idx = redirectName.lastIndexOf('.');
-                        final String extension = redirectName.substring(idx + 1);
-
-                        // 2. entry with extension
-                        addedEntry = this.addEntry(entryMap, checkPath, getMapEntry(url + "\\." + extension, status, false, vanityOrder, redirect));
-                    } else {
-                        // 1. entry with exact match
-                        this.addEntry(entryMap, checkPath, getMapEntry(url + "$", status, false, vanityOrder, redirect + ".html"));
-
-                        // 2. entry with match supporting selectors and extension
-                        addedEntry = this.addEntry(entryMap, checkPath, getMapEntry(url + "(\\..*)", status, false, vanityOrder, redirect + "$1"));
-                    }
-                    if (addedEntry) {
-                        // 3. keep the path to return
-                        this.updateTargetPaths(targetPaths, redirect, checkPath); 
-                        //increment only if the instance variable
-                        if (entryMap == resolveMapsMap) {
-                            vanityCounter.addAndGet(2);
-                        }
-
-                        if (newVanity) {
-                            // update bloom filter
-                            BloomFilterUtils.add(vanityBloomFilter, checkPath);
-                        }
-                    }
-                } else {
-                    if (newVanity) {
-                        // update bloom filter
-                        BloomFilterUtils.add(vanityBloomFilter, checkPath);
-                    }
-                }
-            }
-        }
-    }
-    
-    private void updateTargetPaths(final Map<String, List<String>> targetPaths, final String key, final String entry) {
-        if (entry == null) {
-           return;
-        }
-        List<String> entries = targetPaths.get(key);
-        if (entries == null) {
-            entries = new ArrayList<String>();
-            targetPaths.put(key, entries);
-        }
-        entries.add(entry);
-    }
-    
-    /**
-     * Create the vanity path definition. String array containing:
-     * {protocol}/{host}[.port] {absolute path}
-     */
-    private String[] getVanityPathDefinition(final String pVanityPath) {
-        String[] result = null;
-        if (pVanityPath != null) {
-            final String info = pVanityPath.trim();
-            if (info.length() > 0) {
-                String prefix = null;
-                String path = null;
-                // check for url
-                if (info.indexOf(":/") > -1) {
-                    try {
-                        final URL u = new URL(info);
-                        prefix = u.getProtocol() + '/' + u.getHost() + '.' + u.getPort();
-                        path = u.getPath();
-                    } catch (final MalformedURLException e) {
-                        log.warn("Ignoring malformed vanity path {}", pVanityPath);
-                    }
-                } else {
-                    prefix = "^" + ANY_SCHEME_HOST;
-                    if (!info.startsWith("/")) {
-                        path = "/" + info;
-                    } else {
-                        path = info;
-                    }
-                }
-
-                // remove extension
-                if (prefix != null) {
-                    final int lastSlash = path.lastIndexOf('/');
-                    final int firstDot = path.indexOf('.', lastSlash + 1);
-                    if (firstDot != -1) {
-                        path = path.substring(0, firstDot);
-                        log.warn("Removing extension from vanity path {}", pVanityPath);
-                    }
-                    result = new String[] { prefix, path };
-                }
-            }
-        }
-        return result;
-    }
-
-    private void loadConfiguration(final MapConfigurationProvider factory, final List<MapEntry> entries) {
-        // virtual uris
-        final Map<?, ?> virtuals = factory.getVirtualURLMap();
-        if (virtuals != null) {
-            for (final Entry<?, ?> virtualEntry : virtuals.entrySet()) {
-                final String extPath = (String) virtualEntry.getKey();
-                final String intPath = (String) virtualEntry.getValue();
-                if (!extPath.equals(intPath)) {
-                    // this regular expression must match the whole URL !!
-                    final String url = "^" + ANY_SCHEME_HOST + extPath + "$";
-                    final String redirect = intPath;
-                    MapEntry mapEntry = getMapEntry(url, -1, false, redirect);
-                    if (mapEntry!=null){
-                        entries.add(mapEntry);
-                    }
-                }
-            }
-        }
-
-        // URL Mappings
-        final Mapping[] mappings = factory.getMappings();
-        if (mappings != null) {
-            final Map<String, List<String>> map = new HashMap<String, List<String>>();
-            for (final Mapping mapping : mappings) {
-                if (mapping.mapsInbound()) {
-                    final String url = mapping.getTo();
-                    final String alias = mapping.getFrom();
-                    if (url.length() > 0) {
-                        List<String> aliasList = map.get(url);
-                        if (aliasList == null) {
-                            aliasList = new ArrayList<String>();
-                            map.put(url, aliasList);
-                        }
-                        aliasList.add(alias);
-                    }
-                }
-            }
-
-            for (final Entry<String, List<String>> entry : map.entrySet()) {
-                MapEntry mapEntry = getMapEntry(ANY_SCHEME_HOST + entry.getKey(), -1, false, entry.getValue().toArray(new String[0]));
-                if (mapEntry!=null){
-                    entries.add(mapEntry);
-                }
-            }
-        }
-    }
-
-    private void loadMapConfiguration(final MapConfigurationProvider factory, final Map<String, MapEntry> entries) {
-        // URL Mappings
-        final Mapping[] mappings = factory.getMappings();
-        if (mappings != null) {
-            for (int i = mappings.length - 1; i >= 0; i--) {
-                final Mapping mapping = mappings[i];
-                if (mapping.mapsOutbound()) {
-                    final String url = mapping.getTo();
-                    final String alias = mapping.getFrom();
-                    if (!url.equals(alias)) {
-                        addMapEntry(entries, alias, url, -1);
-                    }
-                }
-            }
-        }
-
-        // virtual uris
-        final Map<?, ?> virtuals = factory.getVirtualURLMap();
-        if (virtuals != null) {
-            for (final Entry<?, ?> virtualEntry : virtuals.entrySet()) {
-                final String extPath = (String) virtualEntry.getKey();
-                final String intPath = (String) virtualEntry.getValue();
-                if (!extPath.equals(intPath)) {
-                    // this regular expression must match the whole URL !!
-                    final String path = "^" + intPath + "$";
-                    final String url = extPath;
-                    addMapEntry(entries, path, url, -1);
-                }
-            }
-        }
-    }
-
-    private void addMapEntry(final Map<String, MapEntry> entries, final String path, final String url, final int status) {
-        MapEntry entry = entries.get(path);
-        if (entry == null) {
-            entry = getMapEntry(path, status, false, url);
-        } else {
-            final String[] redir = entry.getRedirect();
-            final String[] newRedir = new String[redir.length + 1];
-            System.arraycopy(redir, 0, newRedir, 0, redir.length);
-            newRedir[redir.length] = url;
-            entry = getMapEntry(entry.getPattern(), entry.getStatus(), false, newRedir);
-        }
-        if (entry!=null){
-            entries.put(path, entry);
-        }
-    }
-
-    /**
-     * Returns a filter which matches if any of the nodeProps (JCR properties
-     * modified) is listed in any of the eventProps (event properties listing
-     * modified JCR properties) this allows to only get events interesting for
-     * updating the internal structure
-     */
-    private static String createFilter(final boolean vanityPathEnabled) {
-        final String[] nodeProps = {
-                        PROP_REDIRECT_EXTERNAL_REDIRECT_STATUS, PROP_REDIRECT_EXTERNAL,
-                        ResourceResolverImpl.PROP_REDIRECT_INTERNAL, PROP_REDIRECT_EXTERNAL_STATUS,
-                        PROP_REG_EXP, ResourceResolverImpl.PROP_ALIAS };
-        final String[] eventProps = { SlingConstants.PROPERTY_ADDED_ATTRIBUTES, SlingConstants.PROPERTY_CHANGED_ATTRIBUTES, SlingConstants.PROPERTY_REMOVED_ATTRIBUTES };
-        final StringBuilder filter = new StringBuilder();
-        filter.append("(|");
-        for (final String eventProp : eventProps) {
-            filter.append("(|");
-            if (  vanityPathEnabled ) {
-                filter.append('(').append(eventProp).append('=').append(PROP_VANITY_PATH).append(')');
-                filter.append('(').append(eventProp).append('=').append(PROP_VANITY_ORDER).append(')');
-            }
-            for (final String nodeProp : nodeProps) {
-                filter.append('(').append(eventProp).append('=').append(nodeProp).append(')');
-            }
-            filter.append(")");
-        }
-        filter.append("(").append(EventConstants.EVENT_TOPIC).append("=").append(SlingConstants.TOPIC_RESOURCE_REMOVED).append(")");
-        filter.append("(").append(EventConstants.EVENT_TOPIC).append("=").append(SlingConstants.TOPIC_RESOURCE_ADDED).append(")");
-        filter.append(")");
-
-        return filter.toString();
-    }
-
-    private final class MapEntryIterator implements Iterator<MapEntry> {
-
-        private final Map<String, List<MapEntry>> resolveMapsMap;
-
-        private String key;
-
-        private MapEntry next;
-
-        private final Iterator<MapEntry> globalListIterator;
-        private MapEntry nextGlobal;
-
-        private Iterator<MapEntry> specialIterator;
-        private MapEntry nextSpecial;
-        
-        private boolean vanityPathPrecedence;
-
-        public MapEntryIterator(final String startKey, final Map<String, List<MapEntry>> resolveMapsMap, final boolean vanityPathPrecedence) {
-            this.key = startKey;
-            this.resolveMapsMap = resolveMapsMap;
-            this.globalListIterator = this.resolveMapsMap.get(GLOBAL_LIST_KEY).iterator();
-            this.vanityPathPrecedence = vanityPathPrecedence;
-            this.seek();
-        }
-
-        /**
-         * @see java.util.Iterator#hasNext()
-         */
-        public boolean hasNext() {
-            return this.next != null;
-        }
-
-        /**
-         * @see java.util.Iterator#next()
-         */
-        public MapEntry next() {
-            if (this.next == null) {
-                throw new NoSuchElementException();
-            }
-            final MapEntry result = this.next;
-            this.seek();
-            return result;
-        }
-
-        /**
-         * @see java.util.Iterator#remove()
-         */
-        public void remove() {
-            throw new UnsupportedOperationException();
-        }
-
-        private void seek() {
-            if (this.nextGlobal == null && this.globalListIterator.hasNext()) {
-                this.nextGlobal = this.globalListIterator.next();
-            }
-            if (this.nextSpecial == null) {
-                if (specialIterator != null && !specialIterator.hasNext()) {
-                    specialIterator = null;
-                }
-                while (specialIterator == null && key != null) {
-                    // remove selectors and extension
-                    final int lastSlashPos = key.lastIndexOf('/');
-                    final int lastDotPos = key.indexOf('.', lastSlashPos);
-                    if (lastDotPos != -1) {
-                        key = key.substring(0, lastDotPos);
-                    }
-                    
-                    final List<MapEntry> special;
-                    if (MapEntries.this.isAllVanityPathEntriesCached()) {
-                        special = this.resolveMapsMap.get(key);
-                    } else {
-                        special = MapEntries.this.getMapEntryList(key)
-;                    }
-                    if (special != null) {
-                        specialIterator = special.iterator();
-                    }
-                    // recurse to the parent
-                    if (key.length() > 1) {
-                        final int lastSlash = key.lastIndexOf("/");
-                        if (lastSlash == 0) {
-                            key = null;
-                        } else {
-                            key = key.substring(0, lastSlash);
-                        }
-                    } else {
-                        key = null;
-                    }
-                }
-                if (this.specialIterator != null && this.specialIterator.hasNext()) {
-                    this.nextSpecial = this.specialIterator.next();
-                }
-            }
-            if (this.nextSpecial == null) {
-                this.next = this.nextGlobal;
-                this.nextGlobal = null;
-            } else if (!this.vanityPathPrecedence){
-                if (this.nextGlobal == null) {
-                    this.next = this.nextSpecial;
-                    this.nextSpecial = null;
-                } else if (this.nextGlobal.getPattern().length() >= this.nextSpecial.getPattern().length()) {
-                    this.next = this.nextGlobal;
-                    this.nextGlobal = null;
-
-                }else {
-                    this.next = this.nextSpecial;
-                    this.nextSpecial = null;
-                }                
-            } else {
-                this.next = this.nextSpecial;
-                this.nextSpecial = null;
-            }
-        }
-    };
-
-    private MapEntry getMapEntry(String url, final int status, final boolean trailingSlash,
-            final String... redirect){
-
-        MapEntry mapEntry = null;
-        try{
-            mapEntry = new MapEntry(url, status, trailingSlash, 0, redirect);
-        }catch (IllegalArgumentException iae){
-            //ignore this entry
-            log.debug("ignored entry due exception ",iae);
-        }
-        return mapEntry;
-    }
-    
-    private MapEntry getMapEntry(String url, final int status, final boolean trailingSlash, long order,
-            final String... redirect){
-
-        MapEntry mapEntry = null;
-        try{
-            mapEntry = new MapEntry(url, status, trailingSlash, order, redirect);
-        }catch (IllegalArgumentException iae){
-            //ignore this entry
-            log.debug("ignored entry due exception ",iae);
-        }
-        return mapEntry;
-    }
-    
-    final class BloomFilterTask extends TimerTask {
-        @Override
-        public void run() {
-            try {
-                if (updateBloomFilterFile) {
-                    persistBloomFilter();
-                    updateBloomFilterFile = false;
-                }
-            } catch (IOException e) {
-                throw new RuntimeException(
-                        "Error while saving bloom filter to disk", e);
-            }
-        }
-    }
-
-}
diff --git a/src/main/java/org/apache/sling/resourceresolver/impl/mapping/MapEntry.java b/src/main/java/org/apache/sling/resourceresolver/impl/mapping/MapEntry.java
deleted file mode 100644
index f5d5d66..0000000
--- a/src/main/java/org/apache/sling/resourceresolver/impl/mapping/MapEntry.java
+++ /dev/null
@@ -1,404 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *   http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-package org.apache.sling.resourceresolver.impl.mapping;
-
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.List;
-import java.util.regex.Matcher;
-import java.util.regex.Pattern;
-
-import org.apache.sling.api.resource.Resource;
-import org.apache.sling.api.resource.ValueMap;
-import org.apache.sling.resourceresolver.impl.ResourceResolverImpl;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-/**
- * The <code>MapEntry</code> class represents a mapping entry in the mapping
- * configuration tree at <code>/etc/map</code>.
- * <p>
- *
- * @see "http://cwiki.apache.org/SLING/flexible-resource-resolution.html"
- */
-public class MapEntry implements Comparable<MapEntry> {
-
-    /** default log */
-    private final Logger log = LoggerFactory.getLogger(getClass());
-
-    private static final Pattern[] URL_WITH_PORT_MATCH = {
-        Pattern.compile("http/([^/]+)(\\.[^\\d/]+)(/.*)?$"),
-        Pattern.compile("https/([^/]+)(\\.[^\\d/]+)(/.*)?$") };
-
-    private static final String[] URL_WITH_PORT_REPLACEMENT = {
-        "http/$1$2.80$3", "https/$1$2.443$3" };
-
-    private static final Pattern[] PATH_TO_URL_MATCH = {
-        Pattern.compile("http/([^/]+)\\.80(/.*)?$"),
-        Pattern.compile("https/([^/]+)\\.443(/.*)?$"),
-        Pattern.compile("([^/]+)/([^/]+)\\.(\\d+)(/.*)?$"),
-        Pattern.compile("([^/]+)/([^/]+)(/.*)?$") };
-
-    private static final String[] PATH_TO_URL_REPLACEMENT = { "http://$1$2",
-        "https://$1$2", "$1://$2:$3$4", "$1://$2$3" };
-
-    private final Pattern urlPattern;
-
-    private final String[] redirect;
-
-    private final int status;
-
-    private long order;
-
-    public static String appendSlash(String path) {
-        if (!path.endsWith("/")) {
-            path = path.concat("/");
-        }
-        return path;
-    }
-
-    /**
-     * Returns a string used for matching map entries against the given request
-     * or URI parts.
-     *
-     * @param scheme
-     *            The URI scheme
-     * @param host
-     *            The host name
-     * @param port
-     *            The port number. If this is negative, the default value used
-     *            is 80 unless the scheme is "https" in which case the default
-     *            value is 443.
-     * @param path
-     *            The (absolute) path
-     * @return The request path string {scheme}://{host}:{port}{path}.
-     */
-    public static String getURI(final String scheme, final String host, final int port,
-                    final String path) {
-
-        final StringBuilder sb = new StringBuilder();
-        sb.append(scheme).append("://").append(host);
-        if (port > 0 && !(port == 80 && "http".equals(scheme))
-                        && !(port == 443 && "https".equals(scheme))) {
-            sb.append(':').append(port);
-        }
-        sb.append(path);
-
-        return sb.toString();
-    }
-
-    public static String fixUriPath(final String uriPath) {
-        for (int i = 0; i < URL_WITH_PORT_MATCH.length; i++) {
-            final Matcher m = URL_WITH_PORT_MATCH[i].matcher(uriPath);
-            if (m.find()) {
-                return m.replaceAll(URL_WITH_PORT_REPLACEMENT[i]);
-            }
-        }
-
-        return uriPath;
-    }
-
-    /**
-     * Converts the resolution path of the form http/host.77/the/path into an
-     * URI of the form http://host:77/the/path where any potential default port
-     * (80 for http and 443 for https) is actually removed. If the path is just
-     * a regular path such as /the/path, this method returns <code>null</code>.
-     */
-    public static String toURI(final String uriPath) {
-        for (int i = 0; i < PATH_TO_URL_MATCH.length; i++) {
-            final Matcher m = PATH_TO_URL_MATCH[i].matcher(uriPath);
-            if (m.find()) {
-                return m.replaceAll(PATH_TO_URL_REPLACEMENT[i]);
-            }
-        }
-
-        return null;
-    }
-
-    public static MapEntry createResolveEntry(String url, final Resource resource,
-                    final boolean trailingSlash) {
-        final ValueMap props = resource.adaptTo(ValueMap.class);
-        if (props != null) {
-
-            // ensure the url contains a port number (if possible)
-            url = fixUriPath(url);
-
-            final String redirect = props.get(
-                            MapEntries.PROP_REDIRECT_EXTERNAL, String.class);
-            if (redirect != null) {
-                final int status = props
-                                .get(MapEntries.PROP_REDIRECT_EXTERNAL_STATUS,
-                                                302);
-                return new MapEntry(url, status, trailingSlash, 0, redirect);
-            }
-
-            final String[] internalRedirectProps = props.get(ResourceResolverImpl.PROP_REDIRECT_INTERNAL,
-                String[].class);
-            final String[] internalRedirect = filterRegExp(internalRedirectProps);
-            if (internalRedirect != null) {
-                return new MapEntry(url, -1, trailingSlash, 0, internalRedirect);
-            }
-        }
-
-        return null;
-    }
-
-    public static List<MapEntry> createMapEntry(String url, final Resource resource,
-                    final boolean trailingSlash) {
-        final ValueMap props = resource.adaptTo(ValueMap.class);
-        if (props != null) {
-            final String redirect = props.get(
-                            MapEntries.PROP_REDIRECT_EXTERNAL, String.class);
-            if (redirect != null) {
-                // ignoring external redirects for mapping
-                LoggerFactory
-                .getLogger(MapEntry.class)
-                .info("createMapEntry: Configuration has external redirect to {}; not creating mapping for configuration in {}",
-                                redirect, resource.getPath());
-                return null;
-            }
-
-            // ignore potential regular expression url
-            if (isRegExp(url)) {
-                LoggerFactory
-                .getLogger(MapEntry.class)
-                .info("createMapEntry: URL {} contains a regular expression; not creating mapping for configuration in {}",
-                                url, resource.getPath());
-
-                return null;
-            }
-
-            // check whether the url is a match hooked to then string end
-            String endHook = "";
-            if (url.endsWith("$")) {
-                endHook = "$";
-                url = url.substring(0, url.length() - 1);
-            }
-
-            // check whether the url is for ANY_SCHEME_HOST
-            if (url.startsWith(MapEntries.ANY_SCHEME_HOST)) {
-                url = url.substring(MapEntries.ANY_SCHEME_HOST.length());
-            }
-
-            final String[] internalRedirect = props
-                            .get(ResourceResolverImpl.PROP_REDIRECT_INTERNAL,
-                                            String[].class);
-            if (internalRedirect != null) {
-
-                // check whether the url is considered external or internal
-                int status = -1;
-                final String pathUri = toURI(url);
-                if (pathUri != null) {
-                    url = pathUri;
-                    status = 302;
-                }
-
-                final List<MapEntry> prepEntries = new ArrayList<MapEntry>(
-                                internalRedirect.length);
-                for (final String redir : internalRedirect) {
-                    if (!redir.contains("$")) {
-                    	MapEntry mapEntry = null;
-                    	try{
-                    		mapEntry = new MapEntry(redir.concat(endHook), status, trailingSlash, 0, url);
-                    	}catch (IllegalArgumentException iae){
-                    		//ignore this entry
-                            LoggerFactory
-                            .getLogger(MapEntry.class)
-                    		.debug("Ignoring mapping due to exception: " + iae.getMessage(), iae);
-                    	}
-                    	if (mapEntry!=null){
-                    		prepEntries.add(mapEntry);
-                    	}
-                    }
-                }
-
-                if (prepEntries.size() > 0) {
-                    return prepEntries;
-                }
-            }
-        }
-
-        return null;
-    }
-
-    public MapEntry(String url, final int status, final boolean trailingSlash,
-                    final long order, final String... redirect) {
-
-        // ensure trailing slashes on redirects if the url
-        // ends with a trailing slash
-        if (trailingSlash) {
-            url = appendSlash(url);
-            for (int i = 0; i < redirect.length; i++) {
-                redirect[i] = appendSlash(redirect[i]);
-            }
-        }
-
-        // ensure pattern is hooked to the start of the string
-        if (!url.startsWith("^")) {
-            url = "^".concat(url);
-        }
-
-        try {
-        	this.urlPattern = Pattern.compile(url);
-        } catch (Exception e){
-        	throw new IllegalArgumentException("Bad url pattern: " + url,e);
-        }
-
-        this.redirect = redirect;
-        this.status = status;
-        this.order = order;
-    }
-
-    // Returns the replacement or null if the value does not match
-    public String[] replace(final String value) {
-        final Matcher m = urlPattern.matcher(value);
-        if (m.find()) {
-            final String[] redirects = getRedirect();
-            final String[] results = new String[redirects.length];
-            for (int i = 0; i < redirects.length; i++) {
-            	try{
-            		 results[i] = m.replaceFirst(redirects[i]);
-            	} catch (final StringIndexOutOfBoundsException siob){
-            		log.debug("Exception while replacing, ignoring entry {} ", redirects[i], siob);
-                } catch (final IllegalArgumentException iae){
-                    log.debug("Exception while replacing, ignoring entry {} ", redirects[i], iae);
-             	}
-            }
-            return results;
-        }
-
-        return null;
-    }
-
-    public String getPattern() {
-        return urlPattern.toString();
-    }
-
-    public String[] getRedirect() {
-        return redirect;
-    }
-
-    public boolean isInternal() {
-        return getStatus() < 0;
-    }
-
-    public int getStatus() {
-        return status;
-    }
-
-    // ---------- Comparable
-
-    public int compareTo(final MapEntry m) {
-        if (this == m) {
-            return 0;
-        }
-
-        final String ownPatternString = urlPattern.toString();
-        final String mPatternString = m.urlPattern.toString();
-
-        final int tlen = ownPatternString.length();
-        final int mlen = mPatternString.length();
-        if (tlen < mlen) {
-            return 1;
-        } else if (tlen > mlen) {
-            return -1;
-        }
-
-        // lengths are equal, but the entries are not
-        // so order based on the pattern
-        int stringComparison = ownPatternString.toString().compareTo(mPatternString);
-        if (stringComparison == 0 && order != m.order) {
-            if (m.order > order) {
-                return 1;
-            } else {
-                return -1;
-            }
-        }
-        return stringComparison;
-    }
-
-    // ---------- Object overwrite
-
-    @Override
-    public String toString() {
-        final StringBuilder buf = new StringBuilder();
-        buf.append("MapEntry: match:").append(urlPattern);
-
-        buf.append(", replacement:");
-        if (getRedirect().length == 1) {
-            buf.append(getRedirect()[0]);
-        } else {
-            buf.append(Arrays.asList(getRedirect()));
-        }
-
-        if (isInternal()) {
-            buf.append(", internal");
-        } else {
-            buf.append(", status:").append(getStatus());
-        }
-        return buf.toString();
-    }
-
-    // ---------- helper
-
-    /**
-     * Returns <code>true</code> if the string contains unescaped regular
-     * expression special characters '+', '*', '?', '|', '(', '), '[', and ']'
-     *
-     * @param string
-     * @return
-     */
-    private static boolean isRegExp(final String string) {
-        for (int i = 0; i < string.length(); i++) {
-            final char c = string.charAt(i);
-            if (c == '\\') {
-                i++; // just skip
-            } else if ("+*?|()[]".indexOf(c) >= 0) {
-                return true; // assume an unescaped pattern character
-            }
-        }
-        return false;
-    }
-
-    /**
-     * Returns an array of strings copied from the given strings where any
-     * regular expressions in the array are removed. If the input is
-     * <code>null</code> or no strings are provided <code>null</code> is
-     * returned. <code>null</code> is also returned if the strings only contain
-     * regular expressions.
-     */
-    private static String[] filterRegExp(final String... strings) {
-        if (strings == null || strings.length == 0) {
-            return null;
-        }
-
-        ArrayList<String> list = new ArrayList<String>(strings.length);
-        for (String string : strings) {
-            if (!isRegExp(string)) {
-                list.add(string);
-            }
-        }
-
-        return list.isEmpty() ? null : (String[]) list.toArray(new String[list.size()]);
-    }
-
-    void setOrder(long order) {
-        this.order = order;
-    }
-}
diff --git a/src/main/java/org/apache/sling/resourceresolver/impl/mapping/Mapping.java b/src/main/java/org/apache/sling/resourceresolver/impl/mapping/Mapping.java
deleted file mode 100644
index 4d4f0d9..0000000
--- a/src/main/java/org/apache/sling/resourceresolver/impl/mapping/Mapping.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.sling.resourceresolver.impl.mapping;
-
-import java.util.regex.Matcher;
-import java.util.regex.Pattern;
-
-/**
- * The <code>Mapping</code> class conveys the mapping configuration used by the
- * {@link org.apache.sling.resourceresolver.impl.ResourceResolverFactoryImpl}.
- */
-public class Mapping {
-
-    /**
-     * defines the 'inbound' direction, that is mapping request path to item
-     * path
-     */
-    public static final int INBOUND = 1;
-
-    /** defined the 'outbound' direction, that is mapping item path to URL path */
-    public static final int OUTBOUND = 2;
-
-    /** defines the 'both' direction */
-    public static final int BOTH = 3;
-
-    /** Simple mapper instance mapping path to URLs 1:1 in both directions */
-    public static final Mapping DIRECT = new Mapping("", "", BOTH) {
-
-        @Override
-        public String mapHandle(String handle) {
-            return handle;
-        }
-
-        @Override
-        public boolean mapsInbound() {
-            return true;
-        }
-
-        @Override
-        public boolean mapsOutbound() {
-            return true;
-        }
-
-        @Override
-        public String mapUri(String uriPath) {
-            return uriPath;
-        }
-    };
-
-    // Regular expression to split mapping configuration strings into three
-    // groups:
-    // 1 - external path prefix
-    // 2 - direction (Outbound (>), Bidirectional (:), Inbound (>))
-    // 3 - internap path prefix
-    private static final Pattern CONFIG_SPLITTER = Pattern
-            .compile("(.+)([:<>])(.+)");
-
-    /** the 'from' (inside, repository) mapping */
-    private final String from;
-
-    /** the 'to' (outside, URL) mapping */
-    private final String to;
-
-    /** the length of the 'from' field */
-    private final int fromLength;
-
-    /** the length of the 'to' field */
-    private final int toLength;
-
-    /** the mapping direction */
-    private final int direction;
-
-    public Mapping(String config) {
-        this(split(config));
-    }
-
-    public Mapping(String[] parts) {
-        this.from = parts[0];
-        this.to = parts[2];
-        this.fromLength = this.from.length();
-        this.toLength = this.to.length();
-
-        this.direction = ">".equals(parts[1]) ? Mapping.INBOUND : ("<"
-                .equals(parts[1]) ? Mapping.OUTBOUND : Mapping.BOTH);
-    }
-
-    @Override
-    public String toString() {
-        return "Mapping (from=" + from + ", to=" + to + ", direction="
-                + direction + ", lengths=" + fromLength + "/" + toLength;
-    }
-
-    /**
-     * Replaces the prefix <em>to</em> by the new prefix <em>from</em>, if and
-     * only if <code>uriPath</code> starts with the <em>to</em> prefix. If
-     * <code>uriPath</code> does not start with the <em>to</em> prefix, or if
-     * this mapping is not defined as a 'inward' mapping, <code>null</code> is
-     * returned.
-     * 
-     * @param uriPath
-     *            The URI path for which to replace the <em>to</em> prefix by
-     *            the <em>from</em> prefix.
-     * @return The string after replacement or <code>null</code> if the
-     *         <code>uriPath</code> does not start with the <em>to</em> prefix,
-     *         or {@link #mapsInbound()} returns <code>false</code>.
-     */
-    public String mapUri(String uriPath) {
-        return (this.mapsInbound() && uriPath.startsWith(this.to)) ? this.from
-                + uriPath.substring(this.toLength) : null;
-    }
-
-    /**
-     * Replaces the prefix <em>from</em> by the new prefix <em>to</em>, if and
-     * only if <code>handle</code> starts with the <em>from</em> prefix. If
-     * <code>uriPath</code> does not start with the <em>from</em> prefix, or if
-     * this mapping is not defined as a 'outward' mapping, <code>null</code> is
-     * returned.
-     * 
-     * @param handle
-     *            The URI path for which to replace the <em>from</em> prefix by
-     *            the <em>to</em> prefix.
-     * @return The string after replacement or <code>null</code> if the
-     *         <code>handle</code> does not start with the <em>from</em> prefix,
-     *         or {@link #mapsOutbound()} returns <code>false</code>.
-     */
-    public String mapHandle(String handle) {
-        return (this.mapsOutbound() && handle.startsWith(this.from)) ? this.to
-                + handle.substring(this.fromLength) : null;
-    }
-
-    // TODO: temporary
-    public String getFrom() {
-        return from;
-    }
-
-    // TODO: temporary
-    public String getTo() {
-        return to;
-    }
-
-    /**
-     * Checks, if this mapping is defined for inbound mapping.
-     * 
-     * @return <code>true</code> if this mapping is defined for inbound mapping;
-     *         <code>false</code> otherwise
-     */
-    public boolean mapsInbound() {
-        return (this.direction & Mapping.INBOUND) > 0;
-    }
-
-    /**
-     * Checks, if this mapping is defined for outbound mapping.
-     * 
-     * @return <code>true</code> if this mapping is defined for outbound
-     *         mapping; <code>false</code> otherwise
-     */
-    public boolean mapsOutbound() {
-        return (this.direction & Mapping.OUTBOUND) > 0;
-    }
-
-    /**
-     * Constructs a new mapping with the given mapping string and the direction
-     */
-    private Mapping(String from, String to, int dir) {
-        this.from = from;
-        this.to = to;
-        this.fromLength = from.length();
-        this.toLength = to.length();
-        this.direction = dir;
-    }
-
-    public static String[] split(String map) {
-
-        // standard case of mapping <path>[<:>]<path>
-        Matcher mapMatch = CONFIG_SPLITTER.matcher(map);
-        if (mapMatch.matches()) {
-            return new String[] { mapMatch.group(1), mapMatch.group(2),
-                    mapMatch.group(3) };
-        }
-
-        // backwards compatibility using "-" instead of ":"
-        int dash = map.indexOf('-');
-        if (dash > 0) {
-            return new String[] { map.substring(0, dash),
-                    map.substring(dash, dash + 1),
-                    map.substring(dash + 1, map.length()) };
-        }
-
-        return new String[] { map, "-", map };
-    }
-
-}
diff --git a/src/main/java/org/apache/sling/resourceresolver/impl/observation/BasicObservationReporter.java b/src/main/java/org/apache/sling/resourceresolver/impl/observation/BasicObservationReporter.java
deleted file mode 100644
index bc155e6..0000000
--- a/src/main/java/org/apache/sling/resourceresolver/impl/observation/BasicObservationReporter.java
+++ /dev/null
@@ -1,217 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *   http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-package org.apache.sling.resourceresolver.impl.observation;
-
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.Collections;
-import java.util.HashMap;
-import java.util.HashSet;
-import java.util.List;
-import java.util.Map;
-import java.util.Set;
-
-import org.apache.sling.api.resource.observation.ResourceChange;
-import org.apache.sling.api.resource.observation.ResourceChange.ChangeType;
-import org.apache.sling.api.resource.path.Path;
-import org.apache.sling.api.resource.path.PathSet;
-import org.apache.sling.spi.resource.provider.ObservationReporter;
-import org.apache.sling.spi.resource.provider.ObserverConfiguration;
-
-/**
- * Implementation of the observation reporter.
- * Each resource provider gets its on instance.
- */
-public class BasicObservationReporter implements ObservationReporter {
-
-
-    private final List<ObserverConfiguration> configs;
-
-    private final Map<ListenerConfig, List<ResourceChangeListenerInfo>> listeners = new HashMap<BasicObservationReporter.ListenerConfig, List<ResourceChangeListenerInfo>>();;
-
-    /**
-     * Create a reporter listening for resource provider changes
-     * @param infos The listeners map
-     */
-    public BasicObservationReporter(final Collection<ResourceChangeListenerInfo> infos) {
-        final Set<String> paths = new HashSet<String>();
-        for(final ResourceChangeListenerInfo info : infos) {
-            if ( !info.getProviderChangeTypes().isEmpty() ) {
-                for(final Path p : info.getPaths()) {
-                    paths.add(p.getPath());
-                }
-                fillListeners(info, info.getResourceChangeTypes());
-            }
-        }
-        final ObserverConfiguration cfg = new BasicObserverConfiguration(PathSet.fromStringCollection(paths));
-        this.configs = Collections.singletonList(cfg);
-    }
-
-    /**
-     * Create a reporter listening for a provider
-     * @param infos The listeners map
-     * @param providerPath The mount point of the provider
-     * @param excludePaths Excluded paths for that provider
-     */
-    public BasicObservationReporter(final Collection<ResourceChangeListenerInfo> infos,
-            final Path providerPath, final PathSet excludePaths) {
-        final Map<String, ObserverConfig> configMap = new HashMap<String, ObserverConfig>();
-        for(final ResourceChangeListenerInfo info : infos) {
-            if ( !info.getResourceChangeTypes().isEmpty() ) {
-                boolean add = false;
-                for(final Path p : info.getPaths()) {
-                    if ( providerPath.matches(p.getPath()) && excludePaths.matches(p.getPath()) == null ) {
-                        ObserverConfig config = configMap.get(p);
-                        if ( config == null ) {
-                            config = new ObserverConfig();
-                            configMap.put(p.getPath(), config);
-                        }
-                        config.types.addAll(info.getResourceChangeTypes());
-                        if ( info.isExternal() ) {
-                            config.isExternal = true;
-                        }
-                        add = true;
-                    }
-                }
-                if ( add ) {
-                    fillListeners(info, info.getResourceChangeTypes());
-                }
-            }
-        }
-        final List<ObserverConfiguration> result = new ArrayList<ObserverConfiguration>();
-        for(final Map.Entry<String, ObserverConfig> entry : configMap.entrySet()) {
-            final ObserverConfiguration cfg = new BasicObserverConfiguration(entry.getKey(), entry.getValue().types,
-                    entry.getValue().isExternal, excludePaths);
-            result.add(cfg);
-        }
-        this.configs = Collections.unmodifiableList(result);
-    }
-
-    private void fillListeners(final ResourceChangeListenerInfo info, final Set<ChangeType> types) {
-        final ListenerConfig cfg = new ListenerConfig(info, types);
-        List<ResourceChangeListenerInfo> list = this.listeners.get(cfg);
-        if ( list == null ) {
-            list = new ArrayList<ResourceChangeListenerInfo>();
-            this.listeners.put(cfg, list);
-        }
-        list.add(info);
-    }
-
-    @Override
-    public List<ObserverConfiguration> getObserverConfigurations() {
-        return configs;
-    }
-
-    @Override
-    public void reportChanges(final Iterable<ResourceChange> changes, final boolean distribute) {
-        for (final Map.Entry<ListenerConfig, List<ResourceChangeListenerInfo>> entry : this.listeners.entrySet()) {
-            final List<ResourceChange> filtered = filterChanges(changes, entry.getKey());
-            if ( !filtered.isEmpty() ) {
-                for(final ResourceChangeListenerInfo info : entry.getValue()) {
-                    info.getListener().onChange(filtered);
-                }
-            }
-        }
-        // TODO implement distribute
-    }
-
-    /**
-     * Filter the change list based on the configuration
-     * @param changes The list of changes
-     * @param config The configuration
-     * @return The filtered list.
-     */
-    private List<ResourceChange> filterChanges(final Iterable<ResourceChange> changes, final ListenerConfig config) {
-        final List<ResourceChange> filtered = new ArrayList<ResourceChange>();
-        for (final ResourceChange c : changes) {
-            if (matches(c, config)) {
-                filtered.add(c);
-            }
-        }
-        return filtered;
-    }
-
-    /**
-     * Match a change against the configuration
-     * @param change The change
-     * @param config The configuration
-     * @return {@code true} whether it matches
-     */
-    private boolean matches(final ResourceChange change, final ListenerConfig config) {
-        if (!config.types.contains(change.getType())) {
-            return false;
-        }
-        if (!config.isExternal && change.isExternal()) {
-            return false;
-        }
-        if (config.paths.matches(change.getPath()) == null ) {
-            return false;
-        }
-        return true;
-    }
-
-    private static final class ObserverConfig {
-        public final Set<ChangeType> types = new HashSet<ChangeType>();
-        public boolean isExternal;
-    }
-
-    private static final class ListenerConfig {
-
-        public final PathSet paths;
-
-        public final boolean isExternal;
-
-        public final Set<ChangeType> types;
-
-        public ListenerConfig(final ResourceChangeListenerInfo info, Set<ChangeType> types) {
-            this.paths = info.getPaths();
-            this.isExternal = info.isExternal();
-            this.types = types;
-        }
-
-        @Override
-        public int hashCode() {
-            final int prime = 31;
-            int result = 1;
-            result = prime * result + (isExternal ? 1231 : 1237);
-            result = prime * result + paths.hashCode();
-            result = prime * result + types.hashCode();
-            return result;
-        }
-
-        @Override
-        public boolean equals(Object obj) {
-            if (this == obj)
-                return true;
-            if (obj == null)
-                return false;
-            if (getClass() != obj.getClass())
-                return false;
-            ListenerConfig other = (ListenerConfig) obj;
-            if (isExternal != other.isExternal)
-                return false;
-            if (!paths.equals(other.paths))
-                return false;
-            if (!types.equals(other.types))
-                return false;
-            return true;
-        }
-
-    }
-}
diff --git a/src/main/java/org/apache/sling/resourceresolver/impl/observation/BasicObserverConfiguration.java b/src/main/java/org/apache/sling/resourceresolver/impl/observation/BasicObserverConfiguration.java
deleted file mode 100644
index e2996c0..0000000
--- a/src/main/java/org/apache/sling/resourceresolver/impl/observation/BasicObserverConfiguration.java
+++ /dev/null
@@ -1,84 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *   http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-package org.apache.sling.resourceresolver.impl.observation;
-
-import java.util.Collections;
-import java.util.HashSet;
-import java.util.Set;
-
-import org.apache.sling.api.resource.observation.ResourceChange.ChangeType;
-import org.apache.sling.api.resource.path.PathSet;
-import org.apache.sling.spi.resource.provider.ObserverConfiguration;
-
-public class BasicObserverConfiguration implements ObserverConfiguration {
-
-    private final boolean includeExternal;
-
-    private final PathSet paths;
-
-    private final PathSet excludedPaths;
-
-    private final Set<ChangeType> changeTypes;
-
-    public BasicObserverConfiguration(final String path, final Set<ChangeType> types,
-            final boolean isExternal, final PathSet excludePaths) {
-        this.includeExternal = isExternal;
-        this.paths = PathSet.fromStrings(path);
-        this.changeTypes = Collections.unmodifiableSet(types);
-        this.excludedPaths = excludePaths.getSubset(path);
-    }
-
-    public BasicObserverConfiguration(final PathSet set) {
-        this.includeExternal = false;
-        this.paths = set;
-        final Set<ChangeType> types = new HashSet<ChangeType>();
-        types.add(ChangeType.PROVIDER_ADDED);
-        types.add(ChangeType.PROVIDER_REMOVED);
-        this.changeTypes = Collections.unmodifiableSet(types);
-        this.excludedPaths = PathSet.EMPTY_SET;
-    }
-
-    @Override
-    public boolean includeExternal() {
-        return includeExternal;
-    }
-
-    @Override
-    public PathSet getPaths() {
-        return paths;
-    }
-
-    @Override
-    public PathSet getExcludedPaths() {
-        return excludedPaths;
-    }
-
-    @Override
-    public Set<ChangeType> getChangeTypes() {
-        return changeTypes;
-    }
-
-    @Override
-    public boolean matches(final String path) {
-        if ( this.paths.matches(path) != null && this.excludedPaths.matches(path) == null ) {
-            return true;
-        }
-        return false;
-    }
-}
diff --git a/src/main/java/org/apache/sling/resourceresolver/impl/observation/OsgiObservationBridge.java b/src/main/java/org/apache/sling/resourceresolver/impl/observation/OsgiObservationBridge.java
deleted file mode 100644
index 80b87b3..0000000
--- a/src/main/java/org/apache/sling/resourceresolver/impl/observation/OsgiObservationBridge.java
+++ /dev/null
@@ -1,181 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *   http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-package org.apache.sling.resourceresolver.impl.observation;
-
-import java.util.Dictionary;
-import java.util.Hashtable;
-import java.util.List;
-import java.util.concurrent.BlockingQueue;
-import java.util.concurrent.Executors;
-import java.util.concurrent.LinkedBlockingQueue;
-import java.util.concurrent.TimeUnit;
-
-import org.apache.felix.scr.annotations.Component;
-import org.apache.felix.scr.annotations.ConfigurationPolicy;
-import org.apache.felix.scr.annotations.Properties;
-import org.apache.felix.scr.annotations.Property;
-import org.apache.felix.scr.annotations.Reference;
-import org.apache.felix.scr.annotations.Service;
-import org.apache.sling.api.SlingConstants;
-import org.apache.sling.api.resource.LoginException;
-import org.apache.sling.api.resource.Resource;
-import org.apache.sling.api.resource.ResourceResolver;
-import org.apache.sling.api.resource.ResourceResolverFactory;
-import org.apache.sling.api.resource.observation.ExternalResourceChangeListener;
-import org.apache.sling.api.resource.observation.ResourceChange;
-import org.apache.sling.api.resource.observation.ResourceChange.ChangeType;
-import org.apache.sling.api.resource.observation.ResourceChangeListener;
-import org.osgi.service.event.Event;
-import org.osgi.service.event.EventAdmin;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-@Component(policy = ConfigurationPolicy.REQUIRE, metatype = true,
-        label="Apache Sling OSGi Observation Bridge", description="Legacy bridge which converts resource change events to OSGi events")
-@Service(ResourceChangeListener.class)
-@Properties({ @Property(name = ResourceChangeListener.CHANGES, value = { "ADDED", "CHANGED", "REMOVED" }),
-        @Property(name = ResourceChangeListener.PATHS, value = "/") })
-public class OsgiObservationBridge implements ResourceChangeListener, ExternalResourceChangeListener {
-
-    private static final Logger logger = LoggerFactory.getLogger(OsgiObservationBridge.class);
-
-    @Reference
-    private EventAdmin eventAdmin;
-
-    @Reference
-    private ResourceResolverFactory resolverFactory;
-
-    private ResourceResolver resolver;
-
-    private BlockingQueue<ResourceChange> changesQueue;
-
-    private EventSendingJob job;
-
-    @SuppressWarnings("deprecation")
-    protected void activate() throws LoginException {
-        resolver = resolverFactory.getAdministrativeResourceResolver(null);
-        changesQueue = new LinkedBlockingQueue<ResourceChange>();
-        job = new EventSendingJob(changesQueue);
-        Executors.newSingleThreadExecutor().submit(job);
-    }
-
-    protected void deactivate() {
-        changesQueue.clear();
-        job.stop();
-        resolver.close();
-    }
-
-    @Override
-    public void onChange(List<ResourceChange> changes) {
-        changesQueue.addAll(changes);
-    }
-
-    @SuppressWarnings("deprecation")
-    private void sendOsgiEvent(ResourceChange change) {
-        Dictionary<String, Object> props = new Hashtable<String, Object>();
-        String topic;
-        switch (change.getType()) {
-        case ADDED:
-            topic = SlingConstants.TOPIC_RESOURCE_ADDED;
-            break;
-
-        case CHANGED:
-            topic = SlingConstants.TOPIC_RESOURCE_CHANGED;
-            break;
-
-        case REMOVED:
-            topic = SlingConstants.TOPIC_RESOURCE_REMOVED;
-            break;
-
-        default:
-            return;
-        }
-
-        props.put(SlingConstants.PROPERTY_PATH, change.getPath());
-        if (change.getUserId() != null) {
-            props.put(SlingConstants.PROPERTY_USERID, change.getUserId());
-        }
-        if (change.getAddedPropertyNames() != null ) {
-            props.put(SlingConstants.PROPERTY_ADDED_ATTRIBUTES, change.getAddedPropertyNames().toArray(new String[change.getAddedPropertyNames().size()]));
-        }
-        if (change.getChangedPropertyNames() != null) {
-            props.put(SlingConstants.PROPERTY_CHANGED_ATTRIBUTES, change.getChangedPropertyNames().toArray(new String[change.getChangedPropertyNames().size()]));
-        }
-        if ( change.getRemovedPropertyNames() != null ) {
-            props.put(SlingConstants.PROPERTY_REMOVED_ATTRIBUTES, change.getRemovedPropertyNames().toArray(new String[change.getRemovedPropertyNames().size()]));
-        }
-        if (change.getType() != ChangeType.REMOVED) {
-            Resource resource = resolver.getResource(change.getPath());
-            if (resource == null) {
-                resolver.refresh();
-                resource = resolver.getResource(change.getPath());
-            }
-            if (resource != null) {
-                if (resource.getResourceType() != null) {
-                    props.put(SlingConstants.PROPERTY_RESOURCE_TYPE, resource.getResourceType());
-                }
-                if (resource.getResourceSuperType() != null) {
-                    props.put(SlingConstants.PROPERTY_RESOURCE_SUPER_TYPE, resource.getResourceSuperType());
-                }
-            }
-        }
-        if (change.isExternal()) {
-            props.put("event.application", "unknown");
-        }
-
-        final Event event = new Event(topic, props);
-        eventAdmin.sendEvent(event);
-    }
-
-    private class EventSendingJob implements Runnable {
-
-        private final BlockingQueue<ResourceChange> changes;
-
-        private volatile boolean stop;
-
-        public EventSendingJob(BlockingQueue<ResourceChange> changes) {
-            this.changes = changes;
-        }
-
-        @Override
-        public void run() {
-            while (!stop) {
-                ResourceChange change = null;
-                try {
-                    change = changes.poll(100, TimeUnit.MILLISECONDS);
-                } catch (InterruptedException e) {
-                    logger.warn("Interrupted the OSGi runnable", e);
-                }
-                if (change == null) {
-                    continue;
-                }
-                try {
-                    sendOsgiEvent(change);
-                } catch (Exception e) {
-                    logger.error("processOsgiEventQueue: Unexpected problem processing resource change {}", change, e);
-                }
-            }
-        }
-
-        public void stop() {
-            stop = true;
-        }
-    }
-
-}
diff --git a/src/main/java/org/apache/sling/resourceresolver/impl/observation/ResourceChangeListenerInfo.java b/src/main/java/org/apache/sling/resourceresolver/impl/observation/ResourceChangeListenerInfo.java
deleted file mode 100644
index d01ad6f..0000000
--- a/src/main/java/org/apache/sling/resourceresolver/impl/observation/ResourceChangeListenerInfo.java
+++ /dev/null
@@ -1,168 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *   http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-package org.apache.sling.resourceresolver.impl.observation;
-
-import static org.apache.sling.api.resource.observation.ResourceChangeListener.CHANGES;
-import static org.apache.sling.api.resource.observation.ResourceChangeListener.PATHS;
-import static org.apache.sling.commons.osgi.PropertiesUtil.toStringArray;
-
-import java.util.Collections;
-import java.util.EnumSet;
-import java.util.HashSet;
-import java.util.Iterator;
-import java.util.Set;
-
-import org.apache.sling.api.resource.ResourceUtil;
-import org.apache.sling.api.resource.observation.ExternalResourceChangeListener;
-import org.apache.sling.api.resource.observation.ResourceChange.ChangeType;
-import org.apache.sling.api.resource.path.PathSet;
-import org.apache.sling.api.resource.observation.ResourceChangeListener;
-import org.osgi.framework.ServiceReference;
-
-/**
- * Information about a resource change listener.
- */
-public class ResourceChangeListenerInfo {
-
-    private static final Set<ChangeType> DEFAULT_CHANGE_RESOURCE_TYPES = EnumSet.of(ChangeType.ADDED, ChangeType.REMOVED, ChangeType.CHANGED);
-
-    private static final Set<ChangeType> DEFAULT_CHANGE_PROVIDER_TYPES = EnumSet.of(ChangeType.PROVIDER_ADDED, ChangeType.PROVIDER_REMOVED);
-
-    private final PathSet paths;
-
-    private final Set<ChangeType> resourceChangeTypes;
-
-    private final Set<ChangeType> providerChangeTypes;
-
-    private final boolean valid;
-
-    private volatile boolean external = false;
-
-    private volatile ResourceChangeListener listener;
-
-    public ResourceChangeListenerInfo(final ServiceReference ref, final String[] searchPaths) {
-        boolean configValid = true;
-        final Set<String> pathsSet = new HashSet<String>();
-        final String paths[] = toStringArray(ref.getProperty(PATHS), null);
-        if ( paths != null ) {
-            for(final String p : paths) {
-                String normalisedPath = ResourceUtil.normalize(p);
-                if (!".".equals(p) && normalisedPath.isEmpty()) {
-                    configValid = false;
-                } else if ( normalisedPath.startsWith("/") ) {
-                    pathsSet.add(normalisedPath);
-                } else {
-                    for(final String sp : searchPaths) {
-                        if ( p.equals(".") ) {
-                            pathsSet.add(sp);
-                        } else {
-                            pathsSet.add(ResourceUtil.normalize(sp + normalisedPath));
-                        }
-                    }
-                }
-            }
-        }
-        if ( pathsSet.isEmpty() ) {
-            configValid = false;
-        } else {
-            // check for sub paths
-            final Iterator<String> iter = pathsSet.iterator();
-            while ( iter.hasNext() ) {
-                final String path = iter.next();
-                boolean remove = false;
-                for(final String p : pathsSet) {
-                    if ( p.length() > path.length() && path.startsWith(p + "/") ) {
-                        remove = true;
-                        break;
-                    }
-                }
-                if ( remove ) {
-                    iter.remove();
-                }
-            }
-        }
-        this.paths = PathSet.fromStringCollection(pathsSet);
-        if (ref.getProperty(CHANGES) != null ) {
-            final Set<ChangeType> rts = new HashSet<ChangeType>();
-            final Set<ChangeType> pts = new HashSet<ChangeType>();
-            for (final String changeName : toStringArray(ref.getProperty(CHANGES))) {
-                try {
-                    final ChangeType ct = ChangeType.valueOf(changeName);
-                    if ( ct.ordinal() < ChangeType.PROVIDER_ADDED.ordinal()) {
-                        rts.add(ct);
-                    } else {
-                        pts.add(ct);
-                    }
-                } catch ( final IllegalArgumentException iae) {
-                    configValid = false;
-                }
-            }
-            if ( rts.isEmpty() ) {
-                this.resourceChangeTypes = Collections.emptySet();
-            } else if ( rts.size() == 3 ) {
-                this.resourceChangeTypes = DEFAULT_CHANGE_RESOURCE_TYPES;
-            } else {
-                this.resourceChangeTypes = Collections.unmodifiableSet(rts);
-            }
-            if ( pts.isEmpty() ) {
-                this.providerChangeTypes = Collections.emptySet();
-            } else if ( pts.size() == 2 ) {
-                this.providerChangeTypes = DEFAULT_CHANGE_PROVIDER_TYPES;
-            } else {
-                this.providerChangeTypes = Collections.unmodifiableSet(pts);
-            }
-        } else {
-            // default is added, changed, removed for resources and
-            // added and removed for providers
-            this.resourceChangeTypes = DEFAULT_CHANGE_RESOURCE_TYPES;
-            this.providerChangeTypes = DEFAULT_CHANGE_PROVIDER_TYPES;
-        }
-
-        this.valid = configValid;
-    }
-
-    public boolean isValid() {
-        return this.valid;
-    }
-
-    public Set<ChangeType> getResourceChangeTypes() {
-        return this.resourceChangeTypes;
-    }
-
-    public Set<ChangeType> getProviderChangeTypes() {
-        return this.providerChangeTypes;
-    }
-
-    public PathSet getPaths() {
-        return this.paths;
-    }
-
-    public boolean isExternal() {
-        return this.external;
-    }
-
-    public ResourceChangeListener getListener() {
-        return listener;
-    }
-
-    public void setListener(final ResourceChangeListener listener) {
-        this.listener = listener;
-        this.external = listener instanceof ExternalResourceChangeListener;
-    }
-}
diff --git a/src/main/java/org/apache/sling/resourceresolver/impl/observation/ResourceChangeListenerWhiteboard.java b/src/main/java/org/apache/sling/resourceresolver/impl/observation/ResourceChangeListenerWhiteboard.java
deleted file mode 100644
index 1a1c959..0000000
--- a/src/main/java/org/apache/sling/resourceresolver/impl/observation/ResourceChangeListenerWhiteboard.java
+++ /dev/null
@@ -1,145 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *   http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-package org.apache.sling.resourceresolver.impl.observation;
-
-import java.util.Collections;
-import java.util.List;
-import java.util.Map;
-import java.util.concurrent.ConcurrentHashMap;
-
-import org.apache.sling.api.resource.observation.ResourceChange;
-import org.apache.sling.api.resource.observation.ResourceChangeListener;
-import org.apache.sling.api.resource.path.Path;
-import org.apache.sling.api.resource.path.PathSet;
-import org.apache.sling.resourceresolver.impl.providers.ResourceProviderTracker;
-import org.apache.sling.resourceresolver.impl.providers.ResourceProviderTracker.ObservationReporterGenerator;
-import org.apache.sling.spi.resource.provider.ObservationReporter;
-import org.apache.sling.spi.resource.provider.ObserverConfiguration;
-import org.osgi.framework.BundleContext;
-import org.osgi.framework.ServiceReference;
-import org.osgi.util.tracker.ServiceTracker;
-import org.osgi.util.tracker.ServiceTrackerCustomizer;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-/**
- * Tracker component for the resource change listeners.
- */
-public class ResourceChangeListenerWhiteboard implements ResourceProviderTracker.ObservationReporterGenerator {
-
-    private final Logger logger = LoggerFactory.getLogger(this.getClass());
-
-    private final Map<ServiceReference, ResourceChangeListenerInfo> listeners = new ConcurrentHashMap<ServiceReference, ResourceChangeListenerInfo>();
-
-    private volatile ResourceProviderTracker resourceProviderTracker;
-
-    private volatile ServiceTracker tracker;
-
-    public void activate(final BundleContext bundleContext,
-            final ResourceProviderTracker resourceProviderTracker,
-            final String[] searchPaths) {
-        this.resourceProviderTracker = resourceProviderTracker;
-        this.resourceProviderTracker.setObservationReporterGenerator(this);
-        this.tracker = new ServiceTracker(bundleContext,
-                ResourceChangeListener.class.getName(),
-                new ServiceTrackerCustomizer() {
-
-            @Override
-            public void removedService(final ServiceReference reference, final Object service) {
-                final ServiceReference ref = (ServiceReference)service;
-                final ResourceChangeListenerInfo info = listeners.remove(ref);
-                if ( info != null ) {
-                    updateProviderTracker();
-                }
-            }
-
-            @Override
-            public void modifiedService(final ServiceReference reference, final Object service) {
-                removedService(reference, service);
-                addingService(reference);
-            }
-
-            @Override
-            public Object addingService(final ServiceReference reference) {
-                final ResourceChangeListenerInfo info = new ResourceChangeListenerInfo(reference, searchPaths);
-                if ( info.isValid() ) {
-                    final ResourceChangeListener listener = (ResourceChangeListener) bundleContext.getService(reference);
-                    if ( listener != null ) {
-                        info.setListener(listener);
-                        listeners.put(reference, info);
-                        updateProviderTracker();
-                    }
-                } else {
-                    logger.warn("Ignoring invalid resource change listenr {}", reference);
-                }
-                return reference;
-            }
-        });
-        this.tracker.open();
-    }
-
-    public void deactivate() {
-        if ( this.tracker != null ) {
-            this.tracker.close();
-            this.tracker = null;
-        }
-        this.resourceProviderTracker.setObservationReporterGenerator(NOP_GENERATOR);
-        this.resourceProviderTracker = null;
-    }
-
-    private void updateProviderTracker() {
-        this.resourceProviderTracker.setObservationReporterGenerator(this);
-    }
-
-    @Override
-    public ObservationReporter create(final Path path, final PathSet excludes) {
-        return new BasicObservationReporter(this.listeners.values(), path, excludes);
-    }
-
-    @Override
-    public ObservationReporter createProviderReporter() {
-        return new BasicObservationReporter(this.listeners.values());
-    }
-
-    private static final ObservationReporter EMPTY_REPORTER = new ObservationReporter() {
-
-        @Override
-        public void reportChanges(Iterable<ResourceChange> changes, boolean distribute) {
-            // ignore
-        }
-
-        @Override
-        public List<ObserverConfiguration> getObserverConfigurations() {
-            return Collections.emptyList();
-        }
-    };
-
-    private static final ObservationReporterGenerator NOP_GENERATOR = new ObservationReporterGenerator() {
-
-        @Override
-        public ObservationReporter create(Path path, PathSet excludes) {
-            return EMPTY_REPORTER;
-        }
-
-        @Override
-        public ObservationReporter createProviderReporter() {
-            return EMPTY_REPORTER;
-        }
-    };
-}
diff --git a/src/main/java/org/apache/sling/resourceresolver/impl/params/ParametersParser.java b/src/main/java/org/apache/sling/resourceresolver/impl/params/ParametersParser.java
deleted file mode 100644
index 3acbd27..0000000
--- a/src/main/java/org/apache/sling/resourceresolver/impl/params/ParametersParser.java
+++ /dev/null
@@ -1,159 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *   http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-
-package org.apache.sling.resourceresolver.impl.params;
-
-import java.util.LinkedHashMap;
-import java.util.Map;
-
-class ParametersParser {
-
-    private enum ParamsState {
-        INIT, NAME, EQUALS, VALUE, QUOTED_VALUE, QUOTE_END
-    }
-
-    private StringBuilder name;
-
-    private StringBuilder value;
-
-    private Map<String, String> parameters = new LinkedHashMap<String, String>();
-
-    private boolean invalid;
-
-    /**
-     * Parses parameters string, eg.: {@code ;x=123;a='1.0'}. The result of the method is available in
-     * {@link #parameters} and {@link #invalid}.
-     * 
-     * @param chars Array containing path with parameters.
-     * @param from Index of the first character of the parameters substring (it must be a semicolon).
-     * @param dotAllowed If true, the dot in parameter value won't stop parsing.
-     * @return Index of the first character not related to parameters.
-     */
-    public int parseParameters(final char[] chars, final int from, final boolean dotAllowed) {
-        resetCurrentParameter();
-        parameters.clear();
-        invalid = false;
-
-        ParamsState state = ParamsState.INIT;
-        for (int i = from; i <= chars.length; i++) {
-            final char c;
-            if (i == chars.length) {
-                c = 0;
-            } else {
-                c = chars[i];
-            }
-            switch (state) {
-                case INIT:
-                    if (c == ';') {
-                        state = ParamsState.NAME;
-                    } else if (c == '.' || c == '/' || c == 0) {
-                        invalid = true;
-                        return i;
-                    }
-                    break;
-
-                case NAME:
-                    if (c == '=') {
-                        state = ParamsState.EQUALS;
-                    } else if (c == '.' || c == '/' || c == 0) {
-                        invalid = true;
-                        return i;
-                    } else if (c == ';') {
-                        resetCurrentParameter();
-                    } else {
-                        name.append(c);
-                    }
-                    break;
-
-                case EQUALS:
-                    if (c == '\'') {
-                        state = ParamsState.QUOTED_VALUE;
-                    } else if (c == '.' || c == '/' || c == 0) {
-                        addParameter(); // empty one
-                        return i;
-                    } else if (c == ';') {
-                        state = ParamsState.NAME; // empty one
-                        addParameter();
-                    } else {
-                        state = ParamsState.VALUE;
-                        value.append(c);
-                    }
-                    break;
-
-                case QUOTED_VALUE:
-                    if (c == '\'') {
-                        state = ParamsState.QUOTE_END;
-                        addParameter();
-                    } else if (c == 0) {
-                        invalid = true;
-                        return i;
-                    } else {
-                        value.append(c);
-                    }
-                    break;
-
-                case VALUE:
-                    if (c == ';') {
-                        state = ParamsState.NAME;
-                        addParameter();
-                    } else if ((c == '.' && !dotAllowed) || c == '/' || c == 0) {
-                        addParameter();
-                        return i;
-                    } else {
-                        value.append(c);
-                    }
-                    break;
-
-                case QUOTE_END:
-                    if (c == ';') {
-                        state = ParamsState.NAME;
-                    } else {
-                        return i;
-                    }
-            }
-        }
-
-        return chars.length;
-    }
-
-    /**
-     * @return Parsed parameters.
-     */
-    public Map<String, String> getParameters() {
-        return parameters;
-    }
-
-    /**
-     * @return True if the {@link #parseParameters(char[], int, boolean)} method failed.
-     */
-    public boolean isInvalid() {
-        return invalid;
-    }
-
-    private void resetCurrentParameter() {
-        name = new StringBuilder();
-        value = new StringBuilder();
-    }
-
-    private void addParameter() {
-        parameters.put(name.toString(), value.toString());
-        name = new StringBuilder();
-        value = new StringBuilder();
-    }
-}
diff --git a/src/main/java/org/apache/sling/resourceresolver/impl/params/ParsedParameters.java b/src/main/java/org/apache/sling/resourceresolver/impl/params/ParsedParameters.java
deleted file mode 100644
index dea21d8..0000000
--- a/src/main/java/org/apache/sling/resourceresolver/impl/params/ParsedParameters.java
+++ /dev/null
@@ -1,75 +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 SF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations under the License.
- */
-
-package org.apache.sling.resourceresolver.impl.params;
-
-import java.util.Collections;
-import java.util.Map;
-
-/**
- * Parses path looking for semicolon-separated parameters. Parameters are extracted and exposed as an
- * immutable map. The path without parameters is available as raw path.
- * 
- * Parameters should be added immedietaly before or after selectors and extension:
- * {@code /content/test;v='1.0'.html} or {@code /content/test.html;v=1.0}. Quotes can be used to escape the
- * parameter value (it is necessary if the value contains dot and parameter is added before extension).
- */
-public class ParsedParameters {
-
-    private final Map<String, String> parameters;
-
-    private final String parametersString;
-
-    private final String path;
-
-    /**
-     * Parse path and create parameters object.
-     * 
-     * @param fullPath Path to parse.
-     */
-    public ParsedParameters(final String fullPath) {
-        final PathParser parser = new PathParser();
-        parser.parse(fullPath);
-
-        parametersString = parser.getParametersString();
-        parameters = Collections.unmodifiableMap(parser.getParameters());
-        path = parser.getPath();
-    }
-
-    /**
-     * @return Path with no parameters.
-     */
-    public String getRawPath() {
-        return path;
-    }
-    
-    /**
-     * @return Path's substring containing parameters
-     */
-    public String getParametersString() {
-        return parametersString;
-    }
-
-    /**
-     * @return Map of the parameters.
-     */
-    public Map<String, String> getParameters() {
-        return parameters;
-    }
-
-}
diff --git a/src/main/java/org/apache/sling/resourceresolver/impl/params/PathParser.java b/src/main/java/org/apache/sling/resourceresolver/impl/params/PathParser.java
deleted file mode 100644
index 96469df..0000000
--- a/src/main/java/org/apache/sling/resourceresolver/impl/params/PathParser.java
+++ /dev/null
@@ -1,171 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *   http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-
-package org.apache.sling.resourceresolver.impl.params;
-
-import java.util.Collections;
-import java.util.Map;
-
-class PathParser {
-
-    /**
-     * List of states. V1 and V2 prefixes means variant 1 and 2. In V1, the parameters are added after
-     * selectors and extension: {@code /content/test.sel.html;v=1.0}. In V2 parameters are added before
-     * selectors and extension: {@code /content/test;v='1.0'.sel.html}
-     */
-    private enum ParserState {
-        INIT, V1_EXTENSION, V1_PARAMS, V2_PARAMS, V2_EXTENSION, SUFFIX, INVALID
-    }
-
-    private String rawPath;
-
-    private String parametersString;
-
-    private Map<String, String> parameters;
-
-    /**
-     * @return Path with no parameters.
-     */
-    public String getPath() {
-        return rawPath;
-    }
-
-    /**
-     * @return Path's substring containing parameters
-     */
-    public String getParametersString() {
-        return parametersString;
-    }
-
-    /**
-     * @return Parsed parameters.
-     */
-    public Map<String, String> getParameters() {
-        return parameters;
-    }
-
-    /**
-     * Parses path containing parameters. Results will be available in {@link #rawPath} and {@link parameters}.
-     * 
-     * @param path
-     */
-    public void parse(String path) {
-        this.rawPath = path;
-        this.parameters = Collections.emptyMap();
-
-        if (path == null) {
-            return;
-        }
-
-        // indexOf shortcut for the most common case
-        final int di = path.indexOf('.');
-        final int si = path.indexOf(';');
-        if (di == -1 && si == -1) {
-            return;
-        }
-
-        final char[] chars = path.toCharArray();
-        final ParametersParser parametersParser = new ParametersParser();
-
-        ParserState state = ParserState.INIT;
-        int paramsStart = -1, paramsEnd = -1;
-
-        int i = (di != -1) ? ((si != -1) ? Math.min(di, si) : di) : si;
-        for (; i <= chars.length; i++) {
-            final char c;
-            if (i == chars.length) {
-                c = 0;
-            } else {
-                c = chars[i];
-            }
-
-            switch (state) {
-                case INIT:
-                    if (c == '.') {
-                        state = ParserState.V1_EXTENSION;
-                    } else if (c == ';') {
-                        paramsStart = i;
-                        i = parametersParser.parseParameters(chars, i, false);
-                        paramsEnd = i--;
-                        state = parametersParser.isInvalid() ? ParserState.INVALID : ParserState.V2_PARAMS;
-                    }
-                    break;
-
-                case V1_EXTENSION:
-                    if (c == '/') {
-                        state = ParserState.SUFFIX;
-                    } else if (c == ';') {
-                        paramsStart = i;
-                        i = parametersParser.parseParameters(chars, i, true);
-                        paramsEnd = i--;
-                        state = parametersParser.isInvalid() ? ParserState.INVALID : ParserState.V1_PARAMS;
-                    }
-                    break;
-
-                case V1_PARAMS:
-                    if (c == '/') {
-                        state = ParserState.SUFFIX;
-                    } else if (c == '.') {
-                        state = ParserState.INVALID; // no dots after params
-                    }
-                    break;
-
-                case V2_PARAMS:
-                    if (c == '/') {
-                        state = ParserState.INVALID; // there was no extension, so no suffix is allowed
-                    } else if (c == '.') {
-                        state = ParserState.V2_EXTENSION;
-                    }
-                    break;
-
-                case V2_EXTENSION:
-                    if (c == '/') {
-                        state = ParserState.SUFFIX;
-                    }
-                    break;
-
-                case SUFFIX:
-                case INVALID:
-                    break;
-            }
-        }
-
-        if (state == ParserState.INVALID) {
-            paramsStart = paramsEnd = -1;
-        } else {
-            cutPath(path, paramsStart, paramsEnd);
-            parameters = parametersParser.getParameters();
-        }
-    }
-
-    private void cutPath(String path, int from, int to) {
-        if (from == -1) {
-            rawPath = path;
-            parametersString = null;
-        } else if (to == -1) {
-            rawPath = path.substring(0, from);
-            parametersString = path.substring(from);
-        } else {
-            rawPath = path.substring(0, from) + path.substring(to);
-            parametersString = path.substring(from, to);
-        }
-    }
-
-
-}
diff --git a/src/main/java/org/apache/sling/resourceresolver/impl/providers/ProviderContextImpl.java b/src/main/java/org/apache/sling/resourceresolver/impl/providers/ProviderContextImpl.java
deleted file mode 100644
index 02dd079..0000000
--- a/src/main/java/org/apache/sling/resourceresolver/impl/providers/ProviderContextImpl.java
+++ /dev/null
@@ -1,48 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *   http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-package org.apache.sling.resourceresolver.impl.providers;
-
-import org.apache.sling.api.resource.path.PathSet;
-import org.apache.sling.spi.resource.provider.ObservationReporter;
-import org.apache.sling.spi.resource.provider.ProviderContext;
-
-/**
- * Provider context implementation
- */
-public class ProviderContextImpl implements ProviderContext {
-
-    private volatile ObservationReporter observationReporter;
-
-    private volatile PathSet excludedPaths;
-
-    public void update(final ObservationReporter observationReporter, PathSet excludedPaths) {
-        this.observationReporter = observationReporter;
-        this.excludedPaths = excludedPaths;
-    }
-
-    @Override
-    public ObservationReporter getObservationReporter() {
-        return observationReporter;
-    }
-
-    @Override
-    public PathSet getExcludedPaths() {
-        return excludedPaths;
-    }
-}
diff --git a/src/main/java/org/apache/sling/resourceresolver/impl/providers/ResourceProviderHandler.java b/src/main/java/org/apache/sling/resourceresolver/impl/providers/ResourceProviderHandler.java
deleted file mode 100644
index 73090f7..0000000
--- a/src/main/java/org/apache/sling/resourceresolver/impl/providers/ResourceProviderHandler.java
+++ /dev/null
@@ -1,173 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *   http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-package org.apache.sling.resourceresolver.impl.providers;
-
-import org.apache.sling.resourceresolver.impl.providers.tree.Pathable;
-import org.apache.sling.spi.resource.provider.ProviderContext;
-import org.apache.sling.spi.resource.provider.ResourceProvider;
-import org.osgi.framework.BundleContext;
-
-/**
- * Holder for a resource provider service.
- */
-public class ResourceProviderHandler implements Comparable<ResourceProviderHandler>, Pathable {
-
-    /** The bundle context to get the provider. */
-    private volatile BundleContext bundleContext;
-
-    /** The provider context. */
-    private volatile ProviderContextImpl context = new ProviderContextImpl();
-
-    /** The resource provider info. */
-    private volatile ResourceProviderInfo info;
-
-    /** The resource provider. Only available if the provider is active. */
-    private volatile ResourceProvider<Object> provider;
-
-    /** Flag to indicate whether the service has been used. */
-    private volatile boolean isUsed = false;
-
-    /**
-     * Create a new handler
-     * @param bc   Bundle context to get the service.
-     * @param info Resource provider info.
-     */
-    public ResourceProviderHandler(final BundleContext bc, final ResourceProviderInfo info) {
-        this.info = info;
-        this.bundleContext = bc;
-    }
-
-    /**
-     * Get the resource provider info
-     * @return The resource provider info or {@code null} if this handler has been deactivated.
-     */
-    public ResourceProviderInfo getInfo() {
-        return this.info;
-    }
-
-    /**
-     * Activate this handler.
-     * Get the resource provider service from the service registry.
-     * @return {@code true} if the provider could be activated, {@code false} otherwise.
-     */
-    @SuppressWarnings("unchecked")
-    public boolean activate() {
-        if ( this.provider == null ) {
-            this.provider = (ResourceProvider<Object>) this.bundleContext.getService(this.info.getServiceReference());
-            if ( this.provider != null ) {
-                this.provider.start(context);
-            }
-            this.isUsed = false;
-        }
-        return this.provider != null;
-    }
-
-    /**
-     * Deactivate this handler.
-     * Unget the provider service.
-     */
-    public void deactivate() {
-        if ( this.provider != null ) {
-            this.provider.stop();
-            this.provider = null;
-            this.context.update(null, null);
-            this.bundleContext.ungetService(this.info.getServiceReference());
-        }
-    }
-
-    /**
-     * Clear all references.
-     */
-    public void dispose() {
-        this.info = null;
-        this.bundleContext = null;
-        this.context = null;
-        this.isUsed = false;
-    }
-
-    /**
-     * Get the resource provider.
-     * @return The resource provider or {@code null} if it is not active.
-     */
-    public ResourceProvider<Object> getResourceProvider() {
-        return this.provider;
-    }
-
-    /**
-     * Get the resource provider and mark it as used.
-     * @return The resource provider or {@code null} if it is not active.
-     */
-    public ResourceProvider<Object> useResourceProvider() {
-        this.isUsed = true;
-        return this.provider;
-    }
-
-    /**
-     * Check whether this provider has been used.
-     * @return
-     */
-    public boolean isUsed() {
-        return this.isUsed;
-    }
-
-    @Override
-    public int compareTo(final ResourceProviderHandler o) {
-        if ( this.getInfo() == null ) {
-            if ( o.getInfo() == null ) {
-                return 0;
-            }
-            return 1;
-        }
-        if ( o.getInfo() == null ) {
-            return -1;
-        }
-        return this.getInfo().compareTo(o.getInfo());
-    }
-
-    /**
-     * Get the path where the provider is mounted.
-     * @return The mount path.
-     */
-    @Override
-    public String getPath() {
-        return this.getInfo().getPath();
-    }
-
-    /**
-     * Update the provider
-     */
-    public void update() {
-        if ( this.provider != null ) {
-            this.provider.update(ProviderContext.EXCLUDED_PATHS_CHANGED + ProviderContext.OBSERVATION_LISTENER_CHANGED);
-        }
-    }
-
-    /**
-     * Get the provider context.
-     * @return The provider context
-     */
-    public ProviderContextImpl getProviderContext() {
-        return this.context;
-    }
-
-    @Override
-    public String toString() {
-        return "[" + getClass().getSimpleName() +"# provider: " + provider + " ]";
-    }
-}
diff --git a/src/main/java/org/apache/sling/resourceresolver/impl/providers/ResourceProviderInfo.java b/src/main/java/org/apache/sling/resourceresolver/impl/providers/ResourceProviderInfo.java
deleted file mode 100644
index 0900e5e..0000000
--- a/src/main/java/org/apache/sling/resourceresolver/impl/providers/ResourceProviderInfo.java
+++ /dev/null
@@ -1,135 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *   http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-package org.apache.sling.resourceresolver.impl.providers;
-
-import org.apache.sling.api.resource.runtime.dto.AuthType;
-import org.apache.sling.commons.osgi.PropertiesUtil;
-import org.apache.sling.spi.resource.provider.ResourceProvider;
-import org.osgi.framework.ServiceReference;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-/**
- * Information about a registered resource provider
- */
-public class ResourceProviderInfo implements Comparable<ResourceProviderInfo> {
-
-    private static final Logger logger = LoggerFactory.getLogger(ResourceProviderInfo.class);
-
-    private final ServiceReference ref;
-
-    private final String path;
-
-    private final String name;
-
-    private final boolean useResourceAccessSecurity;
-
-    private final AuthType authType;
-
-    private final boolean modifiable;
-
-    private final boolean adaptable;
-
-    private final boolean refreshable;
-
-    private final boolean attributable;
-
-    public ResourceProviderInfo(final ServiceReference ref) {
-        this.ref = ref;
-        this.path = PropertiesUtil.toString(ref.getProperty(ResourceProvider.PROPERTY_ROOT), "");
-        this.name = PropertiesUtil.toString(ref.getProperty(ResourceProvider.PROPERTY_NAME), null);
-        this.useResourceAccessSecurity = PropertiesUtil.toBoolean(ref.getProperty(ResourceProvider.PROPERTY_USE_RESOURCE_ACCESS_SECURITY), false);
-        final String authType = PropertiesUtil.toString(ref.getProperty(ResourceProvider.PROPERTY_AUTHENTICATE), AuthType.no.name());
-        AuthType aType = null;
-        try {
-            aType = AuthType.valueOf(authType);
-        } catch ( final IllegalArgumentException iae) {
-            logger.error("Illegal auth type {} for resource provider {}", authType, name);
-        }
-        this.authType = aType;
-        this.modifiable = PropertiesUtil.toBoolean(ref.getProperty(ResourceProvider.PROPERTY_MODIFIABLE), false);
-        this.adaptable = PropertiesUtil.toBoolean(ref.getProperty(ResourceProvider.PROPERTY_ADAPTABLE), false);
-        this.refreshable = PropertiesUtil.toBoolean(ref.getProperty(ResourceProvider.PROPERTY_REFRESHABLE), false);
-        this.attributable = PropertiesUtil.toBoolean(ref.getProperty(ResourceProvider.PROPERTY_ATTRIBUTABLE), false);
-    }
-
-    public boolean isValid() {
-        // TODO - do real path check
-        if ( !path.startsWith("/") ) {
-            logger.debug("ResourceProvider path does not start with /, invalid: {}", path);
-            return false;
-        }
-        if ( this.authType == null ) {
-            logger.debug("ResourceProvider has null authType, invalid");
-            return false;
-        }
-        return true;
-    }
-
-    public ServiceReference getServiceReference() {
-        return this.ref;
-    }
-
-    public String getPath() {
-        return this.path;
-    }
-
-    @Override
-    public int compareTo(final ResourceProviderInfo o) {
-        int result = path.compareTo(o.path);
-        if ( result == 0 ) {
-            result = o.ref.compareTo(ref);
-        }
-        return result;
-    }
-
-    @Override
-    public String toString() {
-        return "ResourceProviderInfo [ref=" + ref + ", path=" + path + ", useResourceAccessSecurity="
-                + useResourceAccessSecurity + ", authType=" + authType + ", modifiable=" + modifiable + "]";
-    }
-
-    public AuthType getAuthType() {
-        return this.authType;
-    }
-
-    public boolean isModifiable() {
-        return this.modifiable;
-    }
-
-    public boolean isAdaptable() {
-        return adaptable;
-    }
-
-    public boolean isRefreshable() {
-        return refreshable;
-    }
-
-    public boolean isAttributable() {
-        return attributable;
-    }
-
-    public String getName() {
-        return this.name;
-    }
-
-    public boolean getUseResourceAccessSecurity() {
-        return this.useResourceAccessSecurity;
-    }
-}
diff --git a/src/main/java/org/apache/sling/resourceresolver/impl/providers/ResourceProviderStorage.java b/src/main/java/org/apache/sling/resourceresolver/impl/providers/ResourceProviderStorage.java
deleted file mode 100644
index dac3616..0000000
--- a/src/main/java/org/apache/sling/resourceresolver/impl/providers/ResourceProviderStorage.java
+++ /dev/null
@@ -1,95 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *   http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-package org.apache.sling.resourceresolver.impl.providers;
-
-import java.util.ArrayList;
-import java.util.List;
-
-import org.apache.sling.api.resource.runtime.dto.AuthType;
-import org.apache.sling.resourceresolver.impl.providers.tree.PathTree;
-import org.apache.sling.spi.resource.provider.ResourceProvider;
-
-/**
- * The resource provider storage contains all available handlers
- * and keeps a list of handlers for specific categories to avoid
- * iterating over all handlers for the different use cases.
- */
-public class ResourceProviderStorage {
-
-    private final List<ResourceProviderHandler> allHandlers;
-
-    private final List<ResourceProviderHandler> authRequiredHandlers;
-
-    private final List<ResourceProviderHandler> adaptableHandlers;
-
-    private final List<ResourceProviderHandler> attributableHandlers;
-
-    private final List<ResourceProviderHandler> languageQueryableHandlers;
-
-    private final PathTree<ResourceProviderHandler> handlersTree;
-
-    public ResourceProviderStorage(List<ResourceProviderHandler> handlers) {
-        this.allHandlers = handlers;
-        this.authRequiredHandlers = new ArrayList<ResourceProviderHandler>();
-        this.adaptableHandlers = new ArrayList<ResourceProviderHandler>();
-        this.attributableHandlers = new ArrayList<ResourceProviderHandler>();
-        this.languageQueryableHandlers = new ArrayList<ResourceProviderHandler>();
-        for (ResourceProviderHandler h : allHandlers) {
-            ResourceProviderInfo info = h.getInfo();
-            if (info.getAuthType() == AuthType.required) {
-                this.authRequiredHandlers.add(h);
-            }
-            if (info.isAdaptable()) {
-                this.adaptableHandlers.add(h);
-            }
-            if (info.isAttributable()) {
-                this.attributableHandlers.add(h);
-            }
-            final ResourceProvider<Object> rp = h.getResourceProvider();
-            if (rp != null && rp.getQueryLanguageProvider() != null) {
-                this.languageQueryableHandlers.add(h);
-            }
-        }
-        this.handlersTree = new PathTree<ResourceProviderHandler>(handlers);
-    }
-
-    public List<ResourceProviderHandler> getAllHandlers() {
-        return allHandlers;
-    }
-
-    public List<ResourceProviderHandler> getAuthRequiredHandlers() {
-        return authRequiredHandlers;
-    }
-
-    public List<ResourceProviderHandler> getAdaptableHandlers() {
-        return adaptableHandlers;
-    }
-
-    public List<ResourceProviderHandler> getAttributableHandlers() {
-        return attributableHandlers;
-    }
-
-    public List<ResourceProviderHandler> getLanguageQueryableHandlers() {
-        return languageQueryableHandlers;
-    }
-
-    public PathTree<ResourceProviderHandler> getTree() {
-        return handlersTree;
-    }
-}
diff --git a/src/main/java/org/apache/sling/resourceresolver/impl/providers/ResourceProviderStorageProvider.java b/src/main/java/org/apache/sling/resourceresolver/impl/providers/ResourceProviderStorageProvider.java
deleted file mode 100644
index 887af12..0000000
--- a/src/main/java/org/apache/sling/resourceresolver/impl/providers/ResourceProviderStorageProvider.java
+++ /dev/null
@@ -1,28 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *   http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-package org.apache.sling.resourceresolver.impl.providers;
-
-/**
- * Interface which allows access to a ResourceProviderStorage object.
- */ 
-public interface ResourceProviderStorageProvider {
-
-    ResourceProviderStorage getResourceProviderStorage();
-
-}
diff --git a/src/main/java/org/apache/sling/resourceresolver/impl/providers/ResourceProviderTracker.java b/src/main/java/org/apache/sling/resourceresolver/impl/providers/ResourceProviderTracker.java
deleted file mode 100644
index 6cf6946..0000000
--- a/src/main/java/org/apache/sling/resourceresolver/impl/providers/ResourceProviderTracker.java
+++ /dev/null
@@ -1,503 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *   http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-package org.apache.sling.resourceresolver.impl.providers;
-
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.Dictionary;
-import java.util.HashMap;
-import java.util.HashSet;
-import java.util.Hashtable;
-import java.util.Iterator;
-import java.util.List;
-import java.util.Map;
-import java.util.Set;
-import java.util.concurrent.ConcurrentHashMap;
-
-import org.apache.sling.api.SlingConstants;
-import org.apache.sling.api.resource.observation.ResourceChange;
-import org.apache.sling.api.resource.observation.ResourceChange.ChangeType;
-import org.apache.sling.api.resource.path.Path;
-import org.apache.sling.api.resource.path.PathSet;
-import org.apache.sling.api.resource.runtime.dto.AuthType;
-import org.apache.sling.api.resource.runtime.dto.FailureReason;
-import org.apache.sling.api.resource.runtime.dto.ResourceProviderDTO;
-import org.apache.sling.api.resource.runtime.dto.ResourceProviderFailureDTO;
-import org.apache.sling.api.resource.runtime.dto.RuntimeDTO;
-import org.apache.sling.resourceresolver.impl.legacy.LegacyResourceProviderWhiteboard;
-import org.apache.sling.spi.resource.provider.ObservationReporter;
-import org.apache.sling.spi.resource.provider.ResourceProvider;
-import org.osgi.framework.BundleContext;
-import org.osgi.framework.Constants;
-import org.osgi.framework.ServiceReference;
-import org.osgi.service.event.Event;
-import org.osgi.service.event.EventAdmin;
-import org.osgi.util.tracker.ServiceTracker;
-import org.osgi.util.tracker.ServiceTrackerCustomizer;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-/**
- * This service keeps track of all resource providers.
- */
-public class ResourceProviderTracker implements ResourceProviderStorageProvider {
-
-    public interface ObservationReporterGenerator {
-
-        ObservationReporter create(final Path path, final PathSet excludes);
-
-        ObservationReporter createProviderReporter();
-    }
-
-    public interface ChangeListener {
-
-        void providerAdded();
-
-        void providerRemoved(String name, String pid, boolean stateful, boolean used);
-    }
-
-    private final Logger logger = LoggerFactory.getLogger(this.getClass());
-
-    private final Map<ServiceReference, ResourceProviderInfo> infos = new ConcurrentHashMap<ServiceReference, ResourceProviderInfo>();
-
-    private volatile BundleContext bundleContext;
-
-    private volatile ServiceTracker tracker;
-
-    private final Map<String, List<ResourceProviderHandler>> handlers = new HashMap<String, List<ResourceProviderHandler>>();
-
-    private final Map<ResourceProviderInfo, FailureReason> invalidProviders = new ConcurrentHashMap<ResourceProviderInfo, FailureReason>();
-
-    private volatile EventAdmin eventAdmin;
-
-    private volatile ObservationReporterGenerator reporterGenerator;
-
-    private volatile ResourceProviderStorage storage;
-
-    private volatile ObservationReporter providerReporter;
-
-    private volatile ChangeListener listener;
-
-    public void activate(final BundleContext bundleContext, final EventAdmin eventAdmin, final ChangeListener listener) {
-        this.bundleContext = bundleContext;
-        this.eventAdmin = eventAdmin;
-        this.listener = listener;
-        this.tracker = new ServiceTracker(bundleContext,
-                ResourceProvider.class.getName(),
-                new ServiceTrackerCustomizer() {
-
-            @Override
-            public void removedService(final ServiceReference reference, final Object service) {
-                final ServiceReference ref = (ServiceReference)service;
-                final ResourceProviderInfo info = infos.remove(ref);
-                if ( info != null ) {
-                    Object pid = ref.getProperty(Constants.SERVICE_PID);
-                    if ( pid != null && !(pid instanceof String) ) {
-                        pid = null;
-                    }
-                    unregister(info, (String)pid);
-                }
-            }
-
-            @Override
-            public void modifiedService(final ServiceReference reference, final Object service) {
-                removedService(reference, service);
-                addingService(reference);
-            }
-
-            @Override
-            public Object addingService(final ServiceReference reference) {
-                final ResourceProviderInfo info = new ResourceProviderInfo(reference);
-                infos.put(reference, info);
-                register(info);
-                return reference;
-            }
-        });
-        this.tracker.open();
-    }
-
-    public void deactivate() {
-        this.listener = null;
-        this.eventAdmin = null;
-        this.providerReporter = null;
-        if ( this.tracker != null ) {
-            this.tracker.close();
-            this.tracker = null;
-        }
-        this.infos.clear();
-        this.handlers.clear();
-        this.invalidProviders.clear();
-    }
-
-    public void setObservationReporterGenerator(final ObservationReporterGenerator generator) {
-        this.providerReporter = generator.createProviderReporter();
-        synchronized ( this.handlers ) {
-            this.reporterGenerator = generator;
-            for (List<ResourceProviderHandler> list : handlers.values()) {
-                final ResourceProviderHandler h  = list.get(0);
-                if (h != null) {
-                    updateProviderContext(h);
-                    h.update();
-                }
-            }
-        }
-    }
-
-    /**
-     * Try to register a new resource provider.
-     * @param info The resource provider info.
-     */
-    private void register(final ResourceProviderInfo info) {
-        if ( info.isValid() ) {
-           logger.debug("Registering new resource provider {}", info);
-           final List<ProviderEvent> events = new ArrayList<ResourceProviderTracker.ProviderEvent>();
-           boolean providerAdded = false;
-           ResourceProviderHandler deactivateHandler = null;
-
-           synchronized ( this.handlers ) {
-               List<ResourceProviderHandler> matchingHandlers = this.handlers.get(info.getPath());
-               if ( matchingHandlers == null ) {
-                   matchingHandlers = new ArrayList<ResourceProviderHandler>();
-                   this.handlers.put(info.getPath(), matchingHandlers);
-               }
-               final ResourceProviderHandler handler = new ResourceProviderHandler(bundleContext, info);
-               matchingHandlers.add(handler);
-               Collections.sort(matchingHandlers);
-               if ( matchingHandlers.get(0) == handler ) {
-                   if ( !this.activate(handler) ) {
-                       matchingHandlers.remove(handler);
-                       if ( matchingHandlers.isEmpty() ) {
-                           this.handlers.remove(info.getPath());
-                       }
-                   } else {
-                       providerAdded = true;
-                       events.add(new ProviderEvent(true, info));
-                       if ( matchingHandlers.size() > 1 ) {
-                           deactivateHandler = matchingHandlers.get(1);
-                       }
-                       storage = null;
-                   }
-               }
-           }
-           final ChangeListener cl = this.listener;
-           if ( providerAdded && cl != null ) {
-               cl.providerAdded();
-           }
-           // we have to check for deactivated handlers
-           if ( deactivateHandler != null ) {
-               final ResourceProviderInfo handlerInfo = deactivateHandler.getInfo();
-               if ( cl != null ) {
-                   Object pid = handlerInfo.getServiceReference().getProperty(Constants.SERVICE_PID);
-                   if ( pid != null && !(pid instanceof String) ) {
-                       pid = null;
-                   }
-                   cl.providerRemoved(handlerInfo.getName(), (String)pid,
-                               handlerInfo.getAuthType() != AuthType.no,
-                                       deactivateHandler.isUsed());
-               }
-               synchronized ( this.handlers ) {
-                   this.deactivate(deactivateHandler);
-                   events.add(new ProviderEvent(false, handlerInfo));
-                   storage = null;
-               }
-           }
-           this.postEvents(events);
-        } else {
-            logger.warn("Ignoring invalid resource provider {}", info);
-            this.invalidProviders.put(info, FailureReason.invalid);
-        }
-    }
-
-    /**
-     * Unregister a resource provider.
-     * @param info The resource provider info.
-     */
-    private void unregister(final ResourceProviderInfo info, final String pid) {
-        final boolean isInvalid;
-        synchronized ( this.invalidProviders ) {
-            isInvalid = this.invalidProviders.remove(info) != null;
-        }
-
-        if ( !isInvalid ) {
-            logger.debug("Unregistering resource provider {}", info);
-            final List<ProviderEvent> events = new ArrayList<ResourceProviderTracker.ProviderEvent>();
-            ResourceProviderHandler deactivateHandler = null;
-            synchronized (this.handlers) {
-                final List<ResourceProviderHandler> matchingHandlers = this.handlers.get(info.getPath());
-                if ( matchingHandlers != null ) {
-                    final ResourceProviderHandler firstHandler = matchingHandlers.get(0);
-                    if ( firstHandler.getInfo() == info ) {
-                        deactivateHandler = firstHandler;
-
-                    }
-                }
-            }
-            if ( deactivateHandler != null ) {
-                final ChangeListener cl = this.listener;
-                if ( cl != null ) {
-                    cl.providerRemoved(info.getName(), pid,
-                            info.getAuthType() != AuthType.no,
-                                    deactivateHandler.isUsed());
-                }
-                boolean providerAdded = false;
-                synchronized ( this.handlers ) {
-                    this.deactivate(deactivateHandler);
-                    storage = null;
-
-                    final List<ResourceProviderHandler> matchingHandlers = this.handlers.get(info.getPath());
-                    if ( matchingHandlers != null && !matchingHandlers.isEmpty() ) {
-                        final ResourceProviderHandler firstHandler = matchingHandlers.get(0);
-                        boolean doActivateNext = firstHandler.getInfo() == info;
-
-                        if (removeHandlerByInfo(info, matchingHandlers)) {
-                            while (doActivateNext && !matchingHandlers.isEmpty()) {
-                                if (this.activate(matchingHandlers.get(0))) {
-                                    doActivateNext = false;
-                                    events.add(new ProviderEvent(true, matchingHandlers.get(0).getInfo()));
-                                    providerAdded = true;
-                                } else {
-                                    matchingHandlers.remove(0);
-                                }
-                            }
-                        }
-                        if (matchingHandlers.isEmpty()) {
-                            this.handlers.remove(info.getPath());
-                        }
-                    }
-                }
-                if ( providerAdded && cl != null ) {
-                    if ( cl != null ) {
-                        cl.providerAdded();
-                    }
-                }
-                events.add(new ProviderEvent(false,info));
-
-            }
-            this.postEvents(events);
-        } else {
-            logger.debug("Unregistering invalid resource provider {}", info);
-        }
-    }
-
-    /**
-     * Search the info in the list of handlers.
-     * @param info The provider info
-     * @param infos The list of handlers
-     * @return {@code true} if the info got removed.
-     */
-    private boolean removeHandlerByInfo(final ResourceProviderInfo info, final List<ResourceProviderHandler> infos) {
-        Iterator<ResourceProviderHandler> it = infos.iterator();
-        boolean removed = false;
-        while (it.hasNext()) {
-            final ResourceProviderHandler h = it.next();
-            if (h.getInfo() == info) {
-                it.remove();
-                h.dispose();
-                removed = true;
-                break;
-            }
-        }
-        return removed;
-    }
-
-    /**
-     * Activate a resource provider
-     * @param handler The provider handler
-     */
-    private boolean activate(final ResourceProviderHandler handler) {
-        updateProviderContext(handler);
-        if ( !handler.activate() ) {
-            logger.warn("Activating resource provider {} failed", handler.getInfo());
-            this.invalidProviders.put(handler.getInfo(), FailureReason.service_not_gettable);
-
-            return false;
-        }
-        logger.debug("Activated resource provider {}", handler.getInfo());
-        return true;
-    }
-
-    /**
-     * Deactivate a resource provider
-     * @param handler The provider handler
-     */
-    private void deactivate(final ResourceProviderHandler handler) {
-        handler.deactivate();
-        logger.debug("Deactivated resource provider {}", handler.getInfo());
-    }
-
-    /**
-     * Post a change event through the event admin
-     * @param event
-     */
-    private void postOSGiEvent(final ProviderEvent event) {
-        final EventAdmin ea = this.eventAdmin;
-        if ( ea != null ) {
-            final Dictionary<String, Object> eventProps = new Hashtable<String, Object>();
-            eventProps.put(SlingConstants.PROPERTY_PATH, event.path);
-            if (event.pid != null) {
-                eventProps.put(Constants.SERVICE_PID, event.pid);
-            }
-            ea.postEvent(new Event(event.isAdd ? SlingConstants.TOPIC_RESOURCE_PROVIDER_ADDED : SlingConstants.TOPIC_RESOURCE_PROVIDER_REMOVED,
-                    eventProps));
-        }
-    }
-
-    /**
-     * Post a change event for a resource provider change
-     * @param type The change type
-     * @param info The resource provider
-     */
-    private void postResourceProviderChange(final ProviderEvent event) {
-        final ObservationReporter or = this.providerReporter;
-        if ( or != null ) {
-            final ResourceChange change = new ResourceChange(event.isAdd ? ChangeType.PROVIDER_ADDED : ChangeType.PROVIDER_REMOVED,
-                    event.path, false, null, null, null);
-            or.reportChanges(Collections.singletonList(change), false);
-        }
-    }
-
-    public void fill(final RuntimeDTO dto) {
-        final List<ResourceProviderDTO> dtos = new ArrayList<ResourceProviderDTO>();
-        final List<ResourceProviderFailureDTO> failures = new ArrayList<ResourceProviderFailureDTO>();
-
-        synchronized ( this.handlers ) {
-            for(final List<ResourceProviderHandler> handlers : this.handlers.values()) {
-                boolean isFirst = true;
-                for(final ResourceProviderHandler h : handlers) {
-                    final ResourceProviderDTO d;
-                    if ( isFirst ) {
-                        d = new ResourceProviderDTO();
-                        dtos.add(d);
-                        isFirst = false;
-                    } else {
-                        d = new ResourceProviderFailureDTO();
-                        ((ResourceProviderFailureDTO)d).reason = FailureReason.shadowed;
-                        failures.add((ResourceProviderFailureDTO)d);
-                    }
-                    fill(d, h);
-                }
-            }
-        }
-        synchronized ( this.invalidProviders ) {
-            for(final Map.Entry<ResourceProviderInfo, FailureReason> entry : this.invalidProviders.entrySet()) {
-                final ResourceProviderFailureDTO d = new ResourceProviderFailureDTO();
-                fill(d, entry.getKey());
-                d.reason = entry.getValue();
-                failures.add(d);
-            }
-        }
-        dto.providers = dtos.toArray(new ResourceProviderDTO[dtos.size()]);
-        dto.failedProviders = failures.toArray(new ResourceProviderFailureDTO[failures.size()]);
-    }
-
-    @Override
-    public ResourceProviderStorage getResourceProviderStorage() {
-        ResourceProviderStorage result = storage;
-        if (result == null) {
-            synchronized (this.handlers) {
-                if (storage == null) {
-                    final List<ResourceProviderHandler> handlerList = new ArrayList<ResourceProviderHandler>();
-                    for (List<ResourceProviderHandler> list : handlers.values()) {
-                        ResourceProviderHandler h  = list.get(0);
-                        if (h != null) {
-                            handlerList.add(h);
-                        }
-                    }
-                    storage = new ResourceProviderStorage(handlerList);
-                }
-                result = storage;
-            }
-        }
-        return result;
-    }
-
-    private void fill(final ResourceProviderDTO d, final ResourceProviderInfo info) {
-        d.adaptable = info.isAdaptable();
-        d.attributable = info.isAttributable();
-        d.authType = info.getAuthType();
-        d.modifiable = info.isModifiable();
-        d.name = info.getName();
-        d.path = info.getPath();
-        d.refreshable = info.isRefreshable();
-        d.serviceId = (Long)info.getServiceReference().getProperty(Constants.SERVICE_ID);
-        d.supportsQueryLanguage = false;
-        d.useResourceAccessSecurity = info.getUseResourceAccessSecurity();
-    }
-
-    private void fill(final ResourceProviderDTO d, final ResourceProviderHandler handler) {
-        fill(d, handler.getInfo());
-        final ResourceProvider<?> provider = handler.getResourceProvider();
-        if ( provider != null ) {
-            d.supportsQueryLanguage = provider.getQueryLanguageProvider() != null;
-        }
-    }
-
-    private void updateProviderContext(final ResourceProviderHandler handler) {
-        final Set<String> excludedPaths = new HashSet<String>();
-        final Path handlerPath = new Path(handler.getPath());
-        for(final String otherPath : handlers.keySet()) {
-            if ( !handler.getPath().equals(otherPath) && handlerPath.matches(otherPath) ) {
-                excludedPaths.add(otherPath);
-            }
-        }
-        final PathSet excludedPathSet = PathSet.fromStringCollection(excludedPaths);
-        handler.getProviderContext().update(
-                reporterGenerator.create(handlerPath, excludedPathSet),
-                excludedPathSet);
-    }
-
-    private void postEvents(final List<ProviderEvent> events) {
-        if ( events.isEmpty() ) {
-            return;
-        }
-        if ( this.listener == null && this.providerReporter == null ) {
-            return;
-        }
-        final Thread t = new Thread(new Runnable() {
-
-            @Override
-            public void run() {
-                for(final ProviderEvent e : events) {
-                    postOSGiEvent(e);
-                    postResourceProviderChange(e);
-                }
-            }
-        });
-        t.setName("Apache Sling Resource Provider Change Notifier");
-        t.setDaemon(true);
-
-        t.start();
-    }
-
-    private static final class ProviderEvent {
-        public final boolean isAdd;
-        public final Object pid;
-        public final String path;
-
-        public ProviderEvent(final boolean isAdd, final ResourceProviderInfo info) {
-            this.isAdd = isAdd;
-            this.path = info.getPath();
-            Object pid = info.getServiceReference().getProperty(Constants.SERVICE_PID);
-            if (pid == null) {
-                pid = info.getServiceReference().getProperty(LegacyResourceProviderWhiteboard.ORIGINAL_SERVICE_PID);
-            }
-            this.pid = pid;
-        }
-    }
-}
diff --git a/src/main/java/org/apache/sling/resourceresolver/impl/providers/RuntimeServiceImpl.java b/src/main/java/org/apache/sling/resourceresolver/impl/providers/RuntimeServiceImpl.java
deleted file mode 100644
index c163100..0000000
--- a/src/main/java/org/apache/sling/resourceresolver/impl/providers/RuntimeServiceImpl.java
+++ /dev/null
@@ -1,38 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *   http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-package org.apache.sling.resourceresolver.impl.providers;
-
-import org.apache.sling.api.resource.runtime.RuntimeService;
-import org.apache.sling.api.resource.runtime.dto.RuntimeDTO;
-
-public class RuntimeServiceImpl implements RuntimeService {
-
-    private final ResourceProviderTracker tracker;
-
-    public RuntimeServiceImpl(final ResourceProviderTracker tracker) {
-        this.tracker = tracker;
-    }
-
-    @Override
-    public RuntimeDTO getRuntimeDTO() {
-        final RuntimeDTO dto = new RuntimeDTO();
-        tracker.fill(dto);
-        return dto;
-    }
-}
diff --git a/src/main/java/org/apache/sling/resourceresolver/impl/providers/stateful/AuthenticatedResourceProvider.java b/src/main/java/org/apache/sling/resourceresolver/impl/providers/stateful/AuthenticatedResourceProvider.java
deleted file mode 100644
index 38d27c4..0000000
--- a/src/main/java/org/apache/sling/resourceresolver/impl/providers/stateful/AuthenticatedResourceProvider.java
+++ /dev/null
@@ -1,444 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *   http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-package org.apache.sling.resourceresolver.impl.providers.stateful;
-
-import java.util.Collection;
-import java.util.Iterator;
-import java.util.Map;
-import java.util.Set;
-
-import javax.annotation.CheckForNull;
-import javax.annotation.Nonnull;
-
-import org.apache.sling.api.resource.PersistenceException;
-import org.apache.sling.api.resource.Resource;
-import org.apache.sling.api.resource.ResourceResolver;
-import org.apache.sling.api.security.AccessSecurityException;
-import org.apache.sling.api.security.ResourceAccessSecurity;
-import org.apache.sling.resourceresolver.impl.ResourceAccessSecurityTracker;
-import org.apache.sling.resourceresolver.impl.ResourceResolverImpl;
-import org.apache.sling.resourceresolver.impl.helper.AbstractIterator;
-import org.apache.sling.resourceresolver.impl.providers.ResourceProviderHandler;
-import org.apache.sling.spi.resource.provider.QueryLanguageProvider;
-import org.apache.sling.spi.resource.provider.ResolveContext;
-import org.apache.sling.spi.resource.provider.ResourceContext;
-import org.apache.sling.spi.resource.provider.ResourceProvider;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-/**
- * This {@link AuthenticatedResourceProvider} implementation keeps a resource
- * provider and the authentication information (through the {@link ResolveContext}.
- *
- * The methods are similar to {@link ResourceProvider}.
- */
-public class AuthenticatedResourceProvider {
-
-    private static final Logger logger = LoggerFactory.getLogger(ResourceResolverImpl.class);
-
-    public static final AuthenticatedResourceProvider UNAUTHENTICATED_PROVIDER = new AuthenticatedResourceProvider(null, false, null, null);
-
-    private final ResourceProviderHandler providerHandler;
-
-    private final ResolveContext<Object> resolveContext;
-
-    private final ResourceAccessSecurityTracker tracker;
-
-    private final boolean useRAS;
-
-    public AuthenticatedResourceProvider(@Nonnull final ResourceProviderHandler providerHandler,
-            final boolean useRAS,
-            @Nonnull final ResolveContext<Object> resolveContext,
-            @Nonnull final ResourceAccessSecurityTracker tracker) {
-        this.providerHandler = providerHandler;
-        this.resolveContext = resolveContext;
-        this.tracker = tracker;
-        this.useRAS = useRAS;
-    }
-
-    /**
-     * Get the resolve context.
-     * @return The resolve context
-     */
-    public @Nonnull ResolveContext<Object> getResolveContext() {
-        return this.resolveContext;
-    }
-
-    /**
-     * #see {@link ResourceProvider#refresh(ResolveContext)}
-     */
-    public void refresh() {
-        final ResourceProvider<Object> rp = this.providerHandler.getResourceProvider();
-        if ( rp != null ) {
-            rp.refresh(this.resolveContext);
-        }
-    }
-
-    /**
-     * #see {@link ResourceProvider#isLive(ResolveContext)}
-     */
-    public boolean isLive() {
-        final ResourceProvider<Object> rp = this.providerHandler.getResourceProvider();
-        if ( rp != null ) {
-            return rp.isLive(this.resolveContext);
-        }
-        return false;
-    }
-
-    /**
-     * #see {@link ResourceProvider#getParent(ResolveContext, Resource)}
-     */
-    public Resource getParent(final Resource child) {
-        final ResourceProvider<Object> rp = this.providerHandler.getResourceProvider();
-        if ( rp != null ) {
-            return wrapResource(rp.getParent(this.resolveContext, child));
-        }
-        return null;
-    }
-
-    /**
-     * #see {@link ResourceProvider#getResource(ResolveContext, String, ResourceContext, Resource)}
-     */
-    public Resource getResource(final String path, final Resource parent, final Map<String, String> parameters) {
-        final ResourceProvider<Object> rp = this.providerHandler.getResourceProvider();
-        if ( rp == null ) {
-            return null;
-        }
-        final ResourceContext resourceContext;
-        if ( parameters != null ) {
-            resourceContext = new ResourceContext() {
-
-                @Override
-                public Map<String, String> getResolveParameters() {
-                    return parameters;
-                }
-            };
-        } else {
-            resourceContext = ResourceContext.EMPTY_CONTEXT;
-        }
-        return wrapResource(rp.getResource(this.resolveContext, path, resourceContext, parent));
-    }
-
-    /**
-     * #see {@link ResourceProvider#listChildren(ResolveContext, Resource)}
-     */
-    public Iterator<Resource> listChildren(final Resource parent) {
-        final ResourceProvider<Object> rp = this.providerHandler.getResourceProvider();
-        if ( rp != null ) {
-            return wrapIterator(rp.listChildren(this.resolveContext, parent));
-        }
-        return null;
-    }
-
-    /**
-     * #see {@link ResourceProvider#getAttributeNames(ResolveContext)}
-     */
-    public void getAttributeNames(final Set<String> attributeNames) {
-        final ResourceProvider<Object> rp = this.providerHandler.getResourceProvider();
-        if ( rp != null ) {
-            Collection<String> rpAttributeNames = rp.getAttributeNames(this.resolveContext);
-            if (rpAttributeNames != null) {
-                attributeNames.addAll(rpAttributeNames);
-            }
-        }
-    }
-
-    /**
-     * #see {@link ResourceProvider#getAttribute(ResolveContext, String)}
-     */
-    public Object getAttribute(final String name) {
-        final ResourceProvider<Object> rp = this.providerHandler.getResourceProvider();
-        if ( rp != null ) {
-            return rp.getAttribute(this.resolveContext, name);
-        }
-        return null;
-    }
-
-    /**
-     * #see {@link ResourceProvider#create(ResolveContext, String, Map)}
-     */
-    public Resource create(final ResourceResolver resolver,
-            final String path,
-            final Map<String, Object> properties)
-    throws PersistenceException {
-        final ResourceProvider<Object> rp = this.providerHandler.getResourceProvider();
-        if ( rp != null && this.canCreate(resolver, path) ) {
-            return rp.create(this.resolveContext, path, properties);
-        }
-        return null;
-    }
-
-    /**
-     * #see {@link ResourceProvider#delete(ResolveContext, Resource)}
-     */
-    public void delete(final Resource resource) throws PersistenceException {
-        final ResourceProvider<Object> rp = this.providerHandler.getResourceProvider();
-        if ( rp != null && this.canDelete(resource) ) {
-            rp.delete(this.resolveContext, resource);
-        } else {
-            throw new PersistenceException("Unable to delete resource " + resource.getPath());
-        }
-    }
-
-    /**
-     * #see {@link ResourceProvider#revert(ResolveContext)}
-     */
-    public void revert() {
-        final ResourceProvider<Object> rp = this.providerHandler.getResourceProvider();
-        if ( rp != null ) {
-            rp.revert(this.resolveContext);
-        }
-    }
-
-    /**
-     * #see {@link ResourceProvider#commit(ResolveContext)}
-     */
-    public void commit() throws PersistenceException {
-        final ResourceProvider<Object> rp = this.providerHandler.getResourceProvider();
-        if ( rp != null ) {
-            rp.commit(this.resolveContext);
-        }
-    }
-
-    /**
-     * #see {@link ResourceProvider#hasChanges(ResolveContext)}
-     */
-    public boolean hasChanges() {
-        final ResourceProvider<Object> rp = this.providerHandler.getResourceProvider();
-        if ( rp != null ) {
-            return rp.hasChanges(this.resolveContext);
-        }
-        return false;
-    }
-
-    /**
-     * #see {@link ResourceProvider#getQueryLanguageProvider()}
-     */
-    private QueryLanguageProvider<Object> getQueryLanguageProvider() {
-        final ResourceProvider<Object> rp = this.providerHandler.getResourceProvider();
-        if ( rp != null ) {
-            return rp.getQueryLanguageProvider();
-        }
-        return null;
-    }
-
-    /**
-     * #see {@link QueryLanguageProvider#getSupportedLanguages(ResolveContext)}
-     */
-    public String[] getSupportedLanguages() {
-        final QueryLanguageProvider<Object> jcrQueryProvider = getQueryLanguageProvider();
-        if (jcrQueryProvider == null) {
-            return null;
-        }
-        return jcrQueryProvider.getSupportedLanguages(this.resolveContext);
-    }
-
-    /**
-     * #see {@link QueryLanguageProvider}{@link #findResources(String, String)}
-     */
-    public Iterator<Resource> findResources(final String query, final String language) {
-        final QueryLanguageProvider<Object> jcrQueryProvider = getQueryLanguageProvider();
-        if (jcrQueryProvider == null) {
-            return null;
-        }
-        return wrapIterator(jcrQueryProvider.findResources(this.resolveContext, transformQuery(query, language), language));
-    }
-
-    /**
-     * #see {@link QueryLanguageProvider#queryResources(ResolveContext, String, String)}
-     */
-    @SuppressWarnings({ "unchecked", "rawtypes" })
-    public Iterator<Map<String, Object>> queryResources(final String query, final String language) {
-        final QueryLanguageProvider<Object> jcrQueryProvider = getQueryLanguageProvider();
-        if (jcrQueryProvider == null) {
-            return null;
-        }
-        return (Iterator) jcrQueryProvider.queryResources(this.resolveContext, transformQuery(query, language), language);
-    }
-
-    /**
-     * #see {@link ResourceProvider#adaptTo(ResolveContext, Class)}
-     */
-    public <AdapterType> AdapterType adaptTo(final Class<AdapterType> type) {
-        final ResourceProvider<Object> rp = this.providerHandler.getResourceProvider();
-        if ( rp != null ) {
-            return rp.adaptTo(this.resolveContext, type);
-        }
-        return null;
-    }
-
-    /**
-     * #see {@link ResourceProvider#copy(ResolveContext, String, String)}
-     */
-    public boolean copy(final String srcAbsPath, final String destAbsPath) throws PersistenceException {
-        final ResourceProvider<Object> rp = this.providerHandler.getResourceProvider();
-        if ( rp != null ) {
-            return rp.copy(this.resolveContext, srcAbsPath, destAbsPath);
-        }
-        return false;
-    }
-
-    /**
-     * #see {@link ResourceProvider#move(ResolveContext, String, String)}
-     */
-    public boolean move(final String srcAbsPath, final String destAbsPath) throws PersistenceException {
-        final ResourceProvider<Object> rp = this.providerHandler.getResourceProvider();
-        if ( rp != null ) {
-            return rp.move(this.resolveContext, srcAbsPath, destAbsPath);
-        }
-        return false;
-    }
-
-    private boolean canCreate(final ResourceResolver resolver, final String path) {
-        boolean allowed = true;
-        if ( this.useRAS ) {
-            final ResourceAccessSecurity security = tracker.getProviderResourceAccessSecurity();
-            if ( security != null ) {
-                allowed = security.canCreate(path, resolver);
-            } else {
-                allowed = false;
-            }
-        }
-
-        if ( allowed ) {
-            final ResourceAccessSecurity security = tracker.getApplicationResourceAccessSecurity();
-            if (security != null) {
-                allowed = security.canCreate(path, resolver);
-            }
-        }
-        return allowed;
-    }
-
-    private boolean canDelete(final Resource resource) {
-        boolean allowed = true;
-        if ( this.useRAS ) {
-            final ResourceAccessSecurity security = tracker.getProviderResourceAccessSecurity();
-            if ( security != null ) {
-                allowed = security.canDelete(resource);
-            } else {
-                allowed = false;
-            }
-        }
-
-        if ( allowed ) {
-            final ResourceAccessSecurity security = tracker.getApplicationResourceAccessSecurity();
-            if (security != null) {
-                allowed = security.canDelete(resource);
-            }
-        }
-        return allowed;
-    }
-
-    /**
-     * applies resource access security if configured
-     */
-    private String transformQuery ( final String query, final String language ) {
-        String returnValue = query;
-
-        if (this.useRAS) {
-            final ResourceAccessSecurity resourceAccessSecurity = tracker
-                    .getProviderResourceAccessSecurity();
-            if (resourceAccessSecurity != null) {
-                try {
-                    returnValue = resourceAccessSecurity.transformQuery(
-                            returnValue, language, this.resolveContext.getResourceResolver());
-                } catch (AccessSecurityException e) {
-                    logger.error(
-                            "AccessSecurityException occurred while trying to transform the query {} (language {}).",
-                            new Object[] { query, language }, e);
-                }
-            }
-        }
-
-        final ResourceAccessSecurity resourceAccessSecurity = tracker
-                .getApplicationResourceAccessSecurity();
-        if (resourceAccessSecurity != null) {
-            try {
-                returnValue = resourceAccessSecurity.transformQuery(
-                        returnValue, language, this.resolveContext.getResourceResolver());
-            } catch (AccessSecurityException e) {
-                logger.error(
-                        "AccessSecurityException occurred while trying to transform the query {} (language {}).",
-                        new Object[] { query, language }, e);
-            }
-        }
-
-        return returnValue;
-    }
-
-    /**
-     * Wrap a resource with additional resource access security
-     * @param rsrc The resource or {@code null}.
-     * @return The wrapped resource or {@code null}
-     */
-    private @CheckForNull Resource wrapResource(@CheckForNull Resource rsrc) {
-        Resource returnValue = null;
-
-        if (useRAS && rsrc != null) {
-            final ResourceAccessSecurity resourceAccessSecurity = tracker.getProviderResourceAccessSecurity();
-            if (resourceAccessSecurity != null) {
-                returnValue = resourceAccessSecurity.getReadableResource(rsrc);
-            }
-        } else {
-            returnValue = rsrc;
-        }
-
-        if ( returnValue != null ) {
-            final ResourceAccessSecurity resourceAccessSecurity = tracker.getApplicationResourceAccessSecurity();
-            if (resourceAccessSecurity != null) {
-                returnValue = resourceAccessSecurity.getReadableResource(returnValue);
-            }
-        }
-
-        return returnValue;
-    }
-
-    private Iterator<Resource> wrapIterator(Iterator<Resource> iterator) {
-        if (iterator == null) {
-            return iterator;
-        } else {
-            return new SecureIterator(iterator);
-        }
-    }
-
-    private class SecureIterator extends AbstractIterator<Resource> {
-
-        private final Iterator<Resource> iterator;
-
-        public SecureIterator(Iterator<Resource> iterator) {
-            this.iterator = iterator;
-        }
-
-        @Override
-        protected Resource seek() {
-            while (iterator.hasNext()) {
-                final Resource resource = wrapResource(iterator.next());
-                if (resource != null) {
-                    return resource;
-                }
-            }
-            return null;
-        }
-    }
-
-    @Override
-    public String toString() {
-        return "[" + getClass().getSimpleName() + "# rp: " + this.providerHandler.getResourceProvider() + "]";
-    }
-}
diff --git a/src/main/java/org/apache/sling/resourceresolver/impl/providers/stateful/BasicResolveContext.java b/src/main/java/org/apache/sling/resourceresolver/impl/providers/stateful/BasicResolveContext.java
deleted file mode 100644
index 6b0335e..0000000
--- a/src/main/java/org/apache/sling/resourceresolver/impl/providers/stateful/BasicResolveContext.java
+++ /dev/null
@@ -1,112 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *   http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-package org.apache.sling.resourceresolver.impl.providers.stateful;
-
-import javax.annotation.CheckForNull;
-import javax.annotation.Nonnull;
-
-import org.apache.sling.api.resource.LoginException;
-import org.apache.sling.api.resource.ResourceResolver;
-import org.apache.sling.api.resource.ResourceUtil;
-import org.apache.sling.resourceresolver.impl.helper.ResourceResolverControl;
-import org.apache.sling.resourceresolver.impl.providers.ResourceProviderHandler;
-import org.apache.sling.resourceresolver.impl.providers.tree.Node;
-import org.apache.sling.spi.resource.provider.ResolveContext;
-import org.apache.sling.spi.resource.provider.ResourceProvider;
-
-/**
- * Resolve context implementation for a resource provider.
- *
- * This class is not thread safe (same as the resource resolver).
- */
-public class BasicResolveContext<T> implements ResolveContext<T> {
-
-    private final ResourceResolver resolver;
-
-    private final ProviderManager resolveContextManager;
-
-    private final ResourceResolverControl control;
-
-    private final T providerState;
-
-    private final String parentPath;
-
-    public BasicResolveContext(@Nonnull final ResourceResolver resolver,
-            @Nonnull final ProviderManager resolveContextManager,
-            @Nonnull final ResourceResolverControl control,
-            @CheckForNull final T providerState,
-            @Nonnull final String parentPath) {
-        this.resolver = resolver;
-        this.resolveContextManager = resolveContextManager;
-        this.parentPath = parentPath;
-        this.providerState = providerState;
-        this.control = control;
-    }
-
-    @Override
-    public ResourceResolver getResourceResolver() {
-        return this.resolver;
-    }
-
-    @Override
-    public T getProviderState() {
-        return providerState;
-    }
-
-    @Override
-    public ResolveContext<?> getParentResolveContext() {
-        final Object[] providerAndContext = getParentProviderAndContext();
-        return (ResolveContext<?>) (providerAndContext != null ? providerAndContext[1] : null);
-    }
-
-    @Override
-    public ResourceProvider<?> getParentResourceProvider() {
-        final Object[] providerAndContext = getParentProviderAndContext();
-        return (ResourceProvider<?>) (providerAndContext != null ? providerAndContext[0] : null);
-    }
-
-    private Object[] getParentProviderAndContext() {
-        ResourceProvider<?> parentProvider = null;
-        ResolveContext<?> parentResolveContext = null;
-        if ( this.parentPath != null ) {
-            String path = this.parentPath;
-            while ( path != null && parentProvider == null ) {
-                final Node<ResourceProviderHandler> node = this.control.getResourceProviderStorage().getTree().getBestMatchingNode(path);
-                if ( node != null ) {
-                    final ResourceProviderHandler handler = node.getValue();
-                    try {
-                       parentResolveContext = this.resolveContextManager.getOrCreateResolveContext(handler, this.control);
-                       if ( parentResolveContext != null ) {
-                           parentProvider = handler.getResourceProvider();
-                        }
-                    } catch ( final LoginException se) {
-                        // skip this, try next
-                    }
-                    if ( parentProvider == null ) {
-                        parentResolveContext = null;
-                        path = ResourceUtil.getParent(path);
-                    }
-                } else {
-                    path = null;
-                }
-            }
-        }
-        return parentProvider != null ? new Object[] {parentProvider, parentResolveContext} : null;
-    }
-}
diff --git a/src/main/java/org/apache/sling/resourceresolver/impl/providers/stateful/ProviderManager.java b/src/main/java/org/apache/sling/resourceresolver/impl/providers/stateful/ProviderManager.java
deleted file mode 100644
index 4dfcda2..0000000
--- a/src/main/java/org/apache/sling/resourceresolver/impl/providers/stateful/ProviderManager.java
+++ /dev/null
@@ -1,229 +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 SF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations under the License.
- */
-package org.apache.sling.resourceresolver.impl.providers.stateful;
-
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.IdentityHashMap;
-import java.util.Iterator;
-import java.util.List;
-import java.util.Map;
-
-import javax.annotation.CheckForNull;
-import javax.annotation.Nonnull;
-
-import org.apache.sling.api.resource.LoginException;
-import org.apache.sling.api.resource.ResourceResolver;
-import org.apache.sling.api.resource.ResourceUtil;
-import org.apache.sling.api.resource.runtime.dto.AuthType;
-import org.apache.sling.resourceresolver.impl.ResourceAccessSecurityTracker;
-import org.apache.sling.resourceresolver.impl.helper.AbstractIterator;
-import org.apache.sling.resourceresolver.impl.helper.ResourceResolverControl;
-import org.apache.sling.resourceresolver.impl.providers.ResourceProviderHandler;
-import org.apache.sling.spi.resource.provider.ResolveContext;
-import org.apache.sling.spi.resource.provider.ResourceProvider;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-/**
- * Manages resolve contexts for each resource provider including
- * authentication.
- *
- * This class is not thread safe (same as the resource resolver).
- */
-public class ProviderManager {
-
-    private static final Logger logger = LoggerFactory.getLogger(ProviderManager.class);
-
-    private final ResourceResolver resolver;
-
-    private final Map<ResourceProviderHandler, AuthenticatedResourceProvider> contextMap;
-
-    /** Set of authenticated resource providers. */
-    private final List<AuthenticatedResourceProvider> authenticated = new ArrayList<AuthenticatedResourceProvider>();
-
-    /** Set of modifiable resource providers. */
-    private final List<AuthenticatedResourceProvider> modifiable = new ArrayList<AuthenticatedResourceProvider>();
-
-    /** Set of refreshable resource providers. */
-    private final List<AuthenticatedResourceProvider> refreshable = new ArrayList<AuthenticatedResourceProvider>();
-
-    private final ResourceAccessSecurityTracker tracker;
-
-    public ProviderManager(@Nonnull final ResourceResolver resolver, @Nonnull final ResourceAccessSecurityTracker tracker) {
-        this.contextMap = new IdentityHashMap<ResourceProviderHandler, AuthenticatedResourceProvider>();
-        this.resolver = resolver;
-        this.tracker = tracker;
-    }
-
-    /**
-     * Get the context
-     * @param handler The resource handler
-     * @return The resource context or {@code null} if authentication failed previously.
-     */
-    public @CheckForNull AuthenticatedResourceProvider getOrCreateProvider(@Nonnull final ResourceProviderHandler handler,
-            @Nonnull final ResourceResolverControl control)
-    throws LoginException {
-        AuthenticatedResourceProvider provider = this.contextMap.get(handler);
-        if (provider == null) {
-            final ResourceProvider<Object> resourceProvider = handler.useResourceProvider();
-            if ( resourceProvider != null ) {
-                try {
-                    provider = authenticate(handler, resourceProvider, control);
-                    this.contextMap.put(handler, provider);
-                    if ( handler.getInfo().getAuthType() == AuthType.lazy || handler.getInfo().getAuthType() == AuthType.required ) {
-                        control.registerAuthenticatedProvider(handler, provider.getResolveContext().getProviderState());
-                    }
-                } catch ( final LoginException le) {
-                    logger.debug("Authentication to resource provider " + resourceProvider + " failed: " + le.getMessage(), le);
-                    this.contextMap.put(handler, AuthenticatedResourceProvider.UNAUTHENTICATED_PROVIDER);
-
-                    throw le;
-                }
-            } else {
-                this.contextMap.put(handler, AuthenticatedResourceProvider.UNAUTHENTICATED_PROVIDER);
-            }
-        }
-
-        return provider == AuthenticatedResourceProvider.UNAUTHENTICATED_PROVIDER ? null : provider;
-    }
-
-    /**
-     * Get the context
-     * @param handler The resource handler
-     * @return The resource context or {@code null}.
-     */
-    public @CheckForNull ResolveContext<Object> getOrCreateResolveContext(@Nonnull final ResourceProviderHandler handler,
-            @Nonnull final ResourceResolverControl control)
-    throws LoginException {
-        AuthenticatedResourceProvider provider = this.getOrCreateProvider(handler, control);
-        return provider == null ? null : provider.getResolveContext();
-    }
-
-    /**
-     * Authenticate all handlers
-     * @param handlers List of handlers
-     * @param control the resource resolver control
-     * @throws LoginException If authentication fails to one provider
-     */
-    public void authenticateAll(@Nonnull final List<ResourceProviderHandler> handlers,
-            @Nonnull final ResourceResolverControl control)
-    throws LoginException {
-        for (final ResourceProviderHandler h : handlers) {
-            try {
-                this.getOrCreateProvider(h, control);
-            } catch ( final LoginException le ) {
-                // authentication failed, logout from all successful handlers
-                for(final Map.Entry<ResourceProviderHandler, AuthenticatedResourceProvider> entry : this.contextMap.entrySet()) {
-                    if ( entry.getValue() != AuthenticatedResourceProvider.UNAUTHENTICATED_PROVIDER ) {
-                        final ResourceProvider<Object> provider = entry.getKey().getResourceProvider();
-                        if ( provider != null ) {
-                            provider.logout(entry.getValue().getResolveContext().getProviderState());
-                        }
-                    }
-                }
-                this.contextMap.clear();
-                control.clearAuthenticatedProviders();
-                throw le;
-            }
-        }
-    }
-
-    /**
-     * Authenticate a single resource provider (handler)
-     * @param handler The resource provider handler
-     * @param control The resource control
-     * @return The resolve context
-     * @throws LoginException If authentication fails
-     */
-    private @Nonnull AuthenticatedResourceProvider authenticate(@Nonnull final ResourceProviderHandler handler,
-            @Nonnull final ResourceProvider<Object> provider,
-            @Nonnull final ResourceResolverControl control) throws LoginException {
-        boolean isAuthenticated = false;
-        Object contextData = null;
-        if ( (handler.getInfo().getAuthType() == AuthType.required || handler.getInfo().getAuthType() == AuthType.lazy) ) {
-            try {
-                contextData = provider.authenticate(control.getAuthenticationInfo());
-                isAuthenticated = true;
-            } catch ( final LoginException le ) {
-                logger.debug("Unable to login into resource provider " + provider, le);
-                throw le;
-            }
-        }
-
-        final ResolveContext<Object> context = new BasicResolveContext<Object>(this.resolver,
-                this,
-                control,
-                contextData,
-                ResourceUtil.getParent(handler.getInfo().getPath()));
-        final AuthenticatedResourceProvider rp = new AuthenticatedResourceProvider(handler,
-                handler.getInfo().getUseResourceAccessSecurity(),
-                context,
-                this.tracker);
-        if ( isAuthenticated ) {
-            this.authenticated.add(rp);
-        }
-        if ( handler.getInfo().isModifiable() ) {
-            this.modifiable.add(rp);
-        }
-        if ( handler.getInfo().isRefreshable() ) {
-            this.refreshable.add(rp);
-        }
-
-        return rp;
-    }
-
-    public Collection<AuthenticatedResourceProvider> getAllAuthenticated() {
-        return new ArrayList<AuthenticatedResourceProvider>(this.authenticated);
-    }
-
-    public Collection<AuthenticatedResourceProvider> getAllUsedModifiable() {
-        return new ArrayList<AuthenticatedResourceProvider>(modifiable);
-    }
-
-    public Collection<AuthenticatedResourceProvider> getAllUsedRefreshable() {
-        return new ArrayList<AuthenticatedResourceProvider>(refreshable);
-    }
-
-    public Iterable<AuthenticatedResourceProvider> getAllBestEffort(@Nonnull final List<ResourceProviderHandler> handlers,
-            @Nonnull final ResourceResolverControl control) {
-        final Iterator<ResourceProviderHandler> handlerIter = handlers.iterator();
-        return new Iterable<AuthenticatedResourceProvider>() {
-
-            @Override
-            public Iterator<AuthenticatedResourceProvider> iterator() {
-                return new AbstractIterator<AuthenticatedResourceProvider>() {
-
-                    @Override
-                    protected AuthenticatedResourceProvider seek() {
-                        AuthenticatedResourceProvider result = null;
-                        while ( result == null && handlerIter.hasNext() ) {
-                            final ResourceProviderHandler h = handlerIter.next();
-                            try {
-                                result = getOrCreateProvider(h, control);
-                            } catch ( final LoginException le) {
-                                // ignore
-                            }
-                        }
-                        return result;
-                    }
-                };
-            }
-        };
-    }
-}
diff --git a/src/main/java/org/apache/sling/resourceresolver/impl/providers/tree/Node.java b/src/main/java/org/apache/sling/resourceresolver/impl/providers/tree/Node.java
deleted file mode 100644
index d5a834a..0000000
--- a/src/main/java/org/apache/sling/resourceresolver/impl/providers/tree/Node.java
+++ /dev/null
@@ -1,72 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *   http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-package org.apache.sling.resourceresolver.impl.providers.tree;
-
-import java.util.Collections;
-import java.util.HashMap;
-import java.util.Map;
-
-public class Node<T> {
-
-    private T value;
-
-    private Map<String, Node<T>> children;
-
-    public boolean hasChild(String name) {
-        return children != null && children.containsKey(name);
-    }
-
-    public Node<T> getChild(String name) {
-        if (children != null) {
-            return children.get(name);
-        } else {
-            return null;
-        }
-    }
-
-    Node<T> addChild(String name) {
-        if (children == null) {
-            children = new HashMap<String, Node<T>>();
-        }
-        Node<T> newNode = new Node<T>();
-        children.put(name, newNode);
-        return newNode;
-    }
-
-    void setValue(T value) {
-        this.value = value;
-    }
-
-    public T getValue() {
-        return value;
-    }
-
-    public Map<String, Node<T>> getChildren() {
-        if (children == null) {
-            return Collections.emptyMap();
-        } else {
-            return children;
-        }
-    }
-    
-    @Override
-    public String toString() {
-        return "[" + getClass().getSimpleName() + "# value: " + value +" ]";
-    }
-}
\ No newline at end of file
diff --git a/src/main/java/org/apache/sling/resourceresolver/impl/providers/tree/PathSegmentIterator.java b/src/main/java/org/apache/sling/resourceresolver/impl/providers/tree/PathSegmentIterator.java
deleted file mode 100644
index bf91dc1..0000000
--- a/src/main/java/org/apache/sling/resourceresolver/impl/providers/tree/PathSegmentIterator.java
+++ /dev/null
@@ -1,58 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *   http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-package org.apache.sling.resourceresolver.impl.providers.tree;
-
-import java.util.Iterator;
-import java.util.NoSuchElementException;
-
-public class PathSegmentIterator implements Iterator<String> {
-
-    private final String path;
-
-    private int index = 0;
-
-    public PathSegmentIterator(String path, int index) {
-        this.path = path;
-        this.index = index;
-    }
-
-    @Override
-    public boolean hasNext() {
-        return index < path.length();
-    }
-
-    @Override
-    public String next() {
-        if (!hasNext()) {
-            throw new NoSuchElementException();
-        }
-        int nextIndex = path.indexOf('/', index);
-        if (nextIndex == -1) {
-            nextIndex = path.length();
-        }
-        String result = path.substring(index, nextIndex);
-        index = nextIndex + 1;
-        return result;
-    }
-
-    @Override
-    public void remove() {
-        throw new UnsupportedOperationException();
-    }
-}
diff --git a/src/main/java/org/apache/sling/resourceresolver/impl/providers/tree/PathTree.java b/src/main/java/org/apache/sling/resourceresolver/impl/providers/tree/PathTree.java
deleted file mode 100644
index 532bf74..0000000
--- a/src/main/java/org/apache/sling/resourceresolver/impl/providers/tree/PathTree.java
+++ /dev/null
@@ -1,87 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *   http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-package org.apache.sling.resourceresolver.impl.providers.tree;
-
-import static org.apache.commons.lang.StringUtils.split;
-
-import java.util.Iterator;
-import java.util.List;
-
-public class PathTree<T extends Pathable> {
-
-    private Node<T> root;
-
-    public PathTree(List<T> values) {
-        this.root = new Node<T>();
-        for (T v : values) {
-            addNewValue(v);
-        }
-    }
-
-    private void addNewValue(T value) {
-        Node<T> node = root;
-        for (String segment : split(value.getPath(), '/')) {
-            if (node.hasChild(segment)) {
-                node = node.getChild(segment);
-            } else {
-                node = node.addChild(segment);
-            }
-        }
-        node.setValue(value);
-    }
-
-    public Node<T> getBestMatchingNode(final String path) {
-        if (path == null || path.isEmpty() || path.charAt(0) != '/') {
-            return null;
-        }
-
-        Node<T> result = root.getValue() != null ? root : null;
-
-        Node<T> node = root;
-        Iterator<String> it = new PathSegmentIterator(path, 1);
-        while (it.hasNext()) {
-            String segment = it.next();
-            node = node.getChild(segment);
-            if (node == null) {
-                break;
-            } else {
-                if (node.getValue() != null) {
-                    result = node;
-                }
-            }
-        }
-        return result;
-    }
-
-    public Node<T> getNode(String path) {
-        if (path == null || path.isEmpty() || path.charAt(0) != '/') {
-            return null;
-        }
-        Node<T> node = root;
-        Iterator<String> it = new PathSegmentIterator(path, 1);
-        while (it.hasNext()) {
-            String segment = it.next();
-            node = node.getChild(segment);
-            if (node == null) {
-                return null;
-            }
-        }
-        return node;
-    }
-}
diff --git a/src/main/java/org/apache/sling/resourceresolver/impl/providers/tree/Pathable.java b/src/main/java/org/apache/sling/resourceresolver/impl/providers/tree/Pathable.java
deleted file mode 100644
index 8c7a90d..0000000
--- a/src/main/java/org/apache/sling/resourceresolver/impl/providers/tree/Pathable.java
+++ /dev/null
@@ -1,25 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *   http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-package org.apache.sling.resourceresolver.impl.providers.tree;
-
-public interface Pathable {
-
-    String getPath();
-
-}
diff --git a/src/main/resources/META-INF/m2e/lifecycle-mapping-metadata.xml b/src/main/resources/META-INF/m2e/lifecycle-mapping-metadata.xml
new file mode 100644
index 0000000..a99b99f
--- /dev/null
+++ b/src/main/resources/META-INF/m2e/lifecycle-mapping-metadata.xml
@@ -0,0 +1,33 @@
+<!--~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+  ~ 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.
+  ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~-->
+<lifecycleMappingMetadata>
+  <pluginExecutions>
+    <pluginExecution>
+      <pluginExecutionFilter>
+        <goals>
+          <goal>validate</goal>
+        </goals>
+      </pluginExecutionFilter>
+      <action>
+        <execute>
+          <runOnIncremental>true</runOnIncremental>
+          <runOnConfiguration>false</runOnConfiguration>
+        </execute>
+      </action>
+    </pluginExecution>
+  </pluginExecutions>
+</lifecycleMappingMetadata>
\ No newline at end of file
diff --git a/src/main/resources/res/ui/resourceresolver.css b/src/main/resources/res/ui/resourceresolver.css
deleted file mode 100644
index 789d578..0000000
--- a/src/main/resources/res/ui/resourceresolver.css
+++ /dev/null
@@ -1,21 +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.
- */
- 
-tr.content.duplicate td.content {
-    color: grey;
-    text-decoration: line-through;
-}
\ No newline at end of file
diff --git a/src/test/java/org/apache/sling/maven/htl/ProjectStub.java b/src/test/java/org/apache/sling/maven/htl/ProjectStub.java
new file mode 100644
index 0000000..aebef35
--- /dev/null
+++ b/src/test/java/org/apache/sling/maven/htl/ProjectStub.java
@@ -0,0 +1,34 @@
+/*******************************************************************************
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ ******************************************************************************/
+package org.apache.sling.maven.htl;
+
+import java.io.File;
+
+import org.apache.maven.model.Model;
+import org.apache.maven.plugin.testing.stubs.MavenProjectStub;
+
+public class ProjectStub extends MavenProjectStub {
+
+    public ProjectStub(File pomFile) {
+        readModel(pomFile);
+        setPomFile(pomFile);
+        Model model = getModel();
+        setGroupId(model.getGroupId());
+        setArtifactId(model.getArtifactId());
+        setVersion(model.getVersion());
+    }
+}
diff --git a/src/test/java/org/apache/sling/maven/htl/ValidateMojoTest.java b/src/test/java/org/apache/sling/maven/htl/ValidateMojoTest.java
new file mode 100644
index 0000000..86d14eb
--- /dev/null
+++ b/src/test/java/org/apache/sling/maven/htl/ValidateMojoTest.java
@@ -0,0 +1,118 @@
+/*******************************************************************************
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ ******************************************************************************/
+package org.apache.sling.maven.htl;
+
+import java.io.File;
+import java.util.List;
+
+import org.apache.maven.plugin.MojoFailureException;
+import org.apache.maven.plugin.testing.MojoRule;
+import org.apache.maven.plugin.testing.SilentLog;
+import org.apache.maven.project.MavenProject;
+import org.junit.Rule;
+import org.junit.Test;
+import org.sonatype.plexus.build.incremental.DefaultBuildContext;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertTrue;
+
+public class ValidateMojoTest {
+
+    public static final String ERROR_SLY = "src/main/resources/apps/projects/error.sly";
+    public static final String WARNING_SLY = "src/main/resources/apps/projects/warning.sly";
+    public static final String SCRIPT_HTML = "src/main/resources/apps/projects/script.html";
+    public static final String TEST_PROJECT = "test-project";
+    public static final String EXPLICIT_INCLUDES_POM = "explicit-includes.pom.xml";
+    public static final String EXPLICIT_EXCLUDES_POM = "explicit-excludes.pom.xml";
+    public static final String FAIL_ON_WARNINGS_POM = "fail-on-warnings.pom.xml";
+
+    @Rule
+    public MojoRule mojoRule = new MojoRule() {
+        @Override
+        protected void before() throws Throwable {
+            super.before();
+            /**
+             * Make sure the base directory is initialised properly for this test
+             */
+            System.setProperty("basedir", new File("src" + File.separator + "test" + File.separator + "resources" + File
+                    .separator + TEST_PROJECT).getAbsolutePath());
+        }
+    };
+
+    @Test
+    public void testExplicitIncludes() throws Exception {
+        File baseDir = new File(System.getProperty("basedir"));
+        ValidateMojo validateMojo = getMojo(baseDir, EXPLICIT_INCLUDES_POM);
+        try {
+            validateMojo.execute();
+        } catch (MojoFailureException e) {
+            List<File> processedFiles = validateMojo.getProcessedFiles();
+            assertEquals("Expected 2 files to process.", 2, processedFiles.size());
+            assertTrue("Expected error.sly to be one of the processed files.", processedFiles.contains(new File(baseDir, ERROR_SLY)));
+            assertTrue("Expected warning.sly to be one of the processed files.", processedFiles.contains(new File(baseDir, WARNING_SLY)));
+            assertEquals("Expected compilation errors.", true, validateMojo.hasErrors());
+            assertEquals("Expected compilation warnings.", true, validateMojo.hasWarnings());
+        }
+    }
+
+    @Test
+    public void testExplicitExcludes() throws Exception {
+        File baseDir = new File(System.getProperty("basedir"));
+        ValidateMojo validateMojo = getMojo(baseDir, EXPLICIT_EXCLUDES_POM);
+        validateMojo.execute();
+        List<File> processedFiles = validateMojo.getProcessedFiles();
+        assertEquals("Expected 1 file to process.", 1, processedFiles.size());
+        assertTrue("Expected script.html to be the only processed file.", processedFiles.contains(new File(baseDir, SCRIPT_HTML)));
+        assertEquals("Did not expect compilation errors.", false, validateMojo.hasErrors());
+        assertEquals("Did not expect compilation warnings.", false, validateMojo.hasWarnings());
+    }
+
+    @Test
+    public void testFailOnWarnings() throws Exception {
+        File baseDir = new File(System.getProperty("basedir"));
+        ValidateMojo validateMojo = getMojo(baseDir, FAIL_ON_WARNINGS_POM);
+        Exception exception = null;
+        try {
+            validateMojo.execute();
+        } catch (MojoFailureException e) {
+            exception = e;
+        }
+        List<File> processedFiles = validateMojo.getProcessedFiles();
+        assertNotNull("Expected a MojoFailureException.", exception);
+        assertEquals("Expected 1 file to process.", 1, processedFiles.size());
+        assertTrue("Expected warning.sly to be one of the processed files.", processedFiles.contains(new File(baseDir, WARNING_SLY)));
+        assertEquals("Expected compilation warnings.", true, validateMojo.hasWarnings());
+    }
+
+    private ValidateMojo getMojo(File baseDir, String pomFile) throws Exception {
+        SilentLog log = new SilentLog();
+        DefaultBuildContext buildContext = new DefaultBuildContext();
+
+        File pom = new File(baseDir, pomFile);
+        ValidateMojo validateMojo = new ValidateMojo();
+        mojoRule.configureMojo(validateMojo, mojoRule.extractPluginConfiguration("htl-maven-plugin", pom));
+        MavenProject mavenProject = new ProjectStub(pom);
+        mojoRule.setVariableValueToObject(validateMojo, "project", mavenProject);
+        validateMojo.setLog(log);
+        buildContext.enableLogging(log);
+        validateMojo.setBuildContext(buildContext);
+        return validateMojo;
+    }
+
+
+}
diff --git a/src/test/java/org/apache/sling/resourceresolver/impl/FactoryPreconditionsTest.java b/src/test/java/org/apache/sling/resourceresolver/impl/FactoryPreconditionsTest.java
deleted file mode 100644
index 7d0d275..0000000
--- a/src/test/java/org/apache/sling/resourceresolver/impl/FactoryPreconditionsTest.java
+++ /dev/null
@@ -1,161 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *   http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-package org.apache.sling.resourceresolver.impl;
-
-import static org.junit.Assert.assertFalse;
-import static org.junit.Assert.assertTrue;
-
-import java.util.ArrayList;
-import java.util.List;
-
-import org.apache.sling.resourceresolver.impl.providers.ResourceProviderHandler;
-import org.apache.sling.resourceresolver.impl.providers.ResourceProviderInfo;
-import org.apache.sling.resourceresolver.impl.providers.ResourceProviderStorage;
-import org.apache.sling.resourceresolver.impl.providers.ResourceProviderTracker;
-import org.junit.Test;
-import org.mockito.Mockito;
-import org.osgi.framework.Constants;
-import org.osgi.framework.ServiceReference;
-
-public class FactoryPreconditionsTest {
-
-    @Test public void testNoRequiredProviders() {
-        final ResourceProviderTracker tracker = Mockito.mock(ResourceProviderTracker.class);
-        final ResourceProviderStorage storage = Mockito.mock(ResourceProviderStorage.class);
-        Mockito.when(tracker.getResourceProviderStorage()).thenReturn(storage);
-
-        FactoryPreconditions conditions = new FactoryPreconditions();
-        conditions.activate(null, null, null, tracker);
-
-        assertTrue(conditions.checkPreconditions(null, null));
-
-        conditions = new FactoryPreconditions();
-        conditions.activate(null, new String[0], new String[0], tracker);
-
-        assertTrue(conditions.checkPreconditions(null, null));
-    }
-
-    @Test public void testDeactivated() {
-        final ResourceProviderTracker tracker = Mockito.mock(ResourceProviderTracker.class);
-        final ResourceProviderStorage storage = Mockito.mock(ResourceProviderStorage.class);
-        Mockito.when(tracker.getResourceProviderStorage()).thenReturn(storage);
-
-        FactoryPreconditions conditions = new FactoryPreconditions();
-        conditions.activate(null, null, null, tracker);
-
-        assertTrue(conditions.checkPreconditions(null, null));
-
-        conditions.deactivate();
-
-        assertFalse(conditions.checkPreconditions(null, null));
-    }
-
-    private List<ResourceProviderHandler> getResourceProviderHandlers(String[] pids) {
-        final List<ResourceProviderHandler> result = new ArrayList<ResourceProviderHandler>();
-
-        for(final String p : pids) {
-            final ResourceProviderHandler handler = Mockito.mock(ResourceProviderHandler.class);
-            final ResourceProviderInfo info = Mockito.mock(ResourceProviderInfo.class);
-            final ServiceReference ref = Mockito.mock(ServiceReference.class);
-
-            Mockito.when(handler.getInfo()).thenReturn(info);
-            Mockito.when(info.getServiceReference()).thenReturn(ref);
-            Mockito.when(ref.getProperty(Constants.SERVICE_PID)).thenReturn(p);
-
-            result.add(handler);
-        }
-        return result;
-    }
-
-    private List<ResourceProviderHandler> getResourceProviderHandlersWithNames(String[] names) {
-        final List<ResourceProviderHandler> result = new ArrayList<ResourceProviderHandler>();
-
-        for(final String n : names) {
-            final ResourceProviderHandler handler = Mockito.mock(ResourceProviderHandler.class);
-            final ResourceProviderInfo info = Mockito.mock(ResourceProviderInfo.class);
-            Mockito.when(info.getName()).thenReturn(n);
-            final ServiceReference ref = Mockito.mock(ServiceReference.class);
-
-            Mockito.when(handler.getInfo()).thenReturn(info);
-            Mockito.when(info.getServiceReference()).thenReturn(ref);
-
-            result.add(handler);
-        }
-        return result;
-    }
-
-    @Test public void testPIDs() {
-        final ResourceProviderTracker tracker = Mockito.mock(ResourceProviderTracker.class);
-        final ResourceProviderStorage storage = Mockito.mock(ResourceProviderStorage.class);
-        Mockito.when(tracker.getResourceProviderStorage()).thenReturn(storage);
-
-        FactoryPreconditions conditions = new FactoryPreconditions();
-        conditions.activate(null, new String[] {"pid1", "pid3"}, null, tracker);
-
-        final List<ResourceProviderHandler> handlers1 = getResourceProviderHandlers(new String[] {"pid2"});
-        Mockito.when(storage.getAllHandlers()).thenReturn(handlers1);
-        assertFalse(conditions.checkPreconditions(null, null));
-
-        final List<ResourceProviderHandler> handlers2 = getResourceProviderHandlers(new String[] {"pid1", "pid2", "pid3"});
-        Mockito.when(storage.getAllHandlers()).thenReturn(handlers2);
-        assertTrue(conditions.checkPreconditions(null, null));
-
-        final List<ResourceProviderHandler> handlers3 = getResourceProviderHandlers(new String[] {"pid1"});
-        Mockito.when(storage.getAllHandlers()).thenReturn(handlers3);
-        assertFalse(conditions.checkPreconditions(null, null));
-    }
-
-    @Test public void testNames() {
-        final ResourceProviderTracker tracker = Mockito.mock(ResourceProviderTracker.class);
-        final ResourceProviderStorage storage = Mockito.mock(ResourceProviderStorage.class);
-        Mockito.when(tracker.getResourceProviderStorage()).thenReturn(storage);
-
-        FactoryPreconditions conditions = new FactoryPreconditions();
-        conditions.activate(null, null, new String[] {"n1", "n2"}, tracker);
-
-        final List<ResourceProviderHandler> handlers1 = getResourceProviderHandlersWithNames(new String[] {"n2"});
-        Mockito.when(storage.getAllHandlers()).thenReturn(handlers1);
-        assertFalse(conditions.checkPreconditions(null, null));
-
-        final List<ResourceProviderHandler> handlers2 = getResourceProviderHandlersWithNames(new String[] {"n1", "n2", "n3"});
-        Mockito.when(storage.getAllHandlers()).thenReturn(handlers2);
-        assertTrue(conditions.checkPreconditions(null, null));
-
-        final List<ResourceProviderHandler> handlers3 = getResourceProviderHandlersWithNames(new String[] {"n1"});
-        Mockito.when(storage.getAllHandlers()).thenReturn(handlers3);
-        assertFalse(conditions.checkPreconditions(null, null));
-    }
-
-    @Test public void testUnregisteringService() {
-        final ResourceProviderTracker tracker = Mockito.mock(ResourceProviderTracker.class);
-        final ResourceProviderStorage storage = Mockito.mock(ResourceProviderStorage.class);
-        Mockito.when(tracker.getResourceProviderStorage()).thenReturn(storage);
-
-        FactoryPreconditions conditions = new FactoryPreconditions();
-        conditions.activate(null, new String[] {"pid1", "pid3"}, null, tracker);
-
-        final List<ResourceProviderHandler> handlers2 = getResourceProviderHandlers(new String[] {"pid1", "pid2", "pid3"});
-        Mockito.when(storage.getAllHandlers()).thenReturn(handlers2);
-        assertTrue(conditions.checkPreconditions(null, null));
-
-        assertTrue(conditions.checkPreconditions(null, "pid2"));
-
-        assertFalse(conditions.checkPreconditions(null, "pid1"));
-    }
-}
diff --git a/src/test/java/org/apache/sling/resourceresolver/impl/Fixture.java b/src/test/java/org/apache/sling/resourceresolver/impl/Fixture.java
deleted file mode 100644
index d73563d..0000000
--- a/src/test/java/org/apache/sling/resourceresolver/impl/Fixture.java
+++ /dev/null
@@ -1,74 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *   http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-package org.apache.sling.resourceresolver.impl;
-
-import java.util.Dictionary;
-import java.util.HashMap;
-import java.util.Hashtable;
-import java.util.Map;
-
-import org.apache.sling.api.resource.runtime.dto.AuthType;
-import org.apache.sling.resourceresolver.impl.providers.ResourceProviderInfo;
-import org.apache.sling.spi.resource.provider.ResourceProvider;
-import org.osgi.framework.BundleContext;
-import org.osgi.framework.InvalidSyntaxException;
-import org.osgi.framework.ServiceReference;
-import org.osgi.framework.ServiceRegistration;
-
-/**
- * The <tt>Fixture</tt> holds reusable, shared, test setup code
- */
-public class Fixture { 
-
-    private final BundleContext bc;
-    private final Map<ResourceProviderInfo, ServiceRegistration> providerRegistrations = new HashMap<ResourceProviderInfo, ServiceRegistration>();
-    
-    public Fixture(BundleContext bc) {
-        this.bc = bc;
-    }
-
-    public ResourceProviderInfo registerResourceProvider(ResourceProvider<?> rp, String root, AuthType authType) throws InvalidSyntaxException {
-        
-        Dictionary<String, String> props = new Hashtable<String, String>();
-        props.put(ResourceProvider.PROPERTY_ROOT, root);
-        props.put(ResourceProvider.PROPERTY_AUTHENTICATE, authType.name());
-        props.put(ResourceProvider.PROPERTY_MODIFIABLE, Boolean.TRUE.toString());
-        
-        ServiceRegistration registration = bc.registerService(ResourceProvider.class.getName(), rp, props);
-        
-        ServiceReference sr = bc.getServiceReferences(ResourceProvider.class.getName(),
-                "(" + ResourceProvider.PROPERTY_ROOT + "=" + root + ")")[0];
-        
-        ResourceProviderInfo providerInfo = new ResourceProviderInfo(sr);
-
-        providerRegistrations.put(providerInfo, registration);
-        
-        return providerInfo;
-    }
-    
-    public void unregisterResourceProvider(ResourceProviderInfo info) {
-        
-        ServiceRegistration registration = providerRegistrations.remove(info);
-        if ( registration == null ) {
-            throw new IllegalArgumentException("No " + ServiceRegistration.class.getSimpleName() + " found for " + info);
-        }
-        
-        registration.unregister();
-    }
-}
\ No newline at end of file
diff --git a/src/test/java/org/apache/sling/resourceresolver/impl/MockedResourceResolverImplTest.java b/src/test/java/org/apache/sling/resourceresolver/impl/MockedResourceResolverImplTest.java
deleted file mode 100644
index bd4ad1a..0000000
--- a/src/test/java/org/apache/sling/resourceresolver/impl/MockedResourceResolverImplTest.java
+++ /dev/null
@@ -1,591 +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 SF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations under the License.
- */
-package org.apache.sling.resourceresolver.impl;
-
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertNotNull;
-import static org.junit.Assert.assertTrue;
-
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.Dictionary;
-import java.util.HashMap;
-import java.util.HashSet;
-import java.util.Hashtable;
-import java.util.Iterator;
-import java.util.List;
-import java.util.Map;
-import java.util.Random;
-import java.util.Set;
-
-import javax.servlet.http.HttpServletRequest;
-
-import org.apache.sling.api.resource.LoginException;
-import org.apache.sling.api.resource.Resource;
-import org.apache.sling.api.resource.ResourceMetadata;
-import org.apache.sling.api.resource.ResourceResolver;
-import org.apache.sling.api.resource.ResourceResolverFactory;
-import org.apache.sling.api.resource.ValueMap;
-import org.apache.sling.api.wrappers.ValueMapDecorator;
-import org.apache.sling.resourceresolver.impl.observation.ResourceChangeListenerWhiteboard;
-import org.apache.sling.resourceresolver.impl.providers.ResourceProviderHandler;
-import org.apache.sling.resourceresolver.impl.providers.ResourceProviderInfo;
-import org.apache.sling.resourceresolver.impl.providers.ResourceProviderStorage;
-import org.apache.sling.resourceresolver.impl.providers.ResourceProviderTracker;
-import org.apache.sling.spi.resource.provider.QueryLanguageProvider;
-import org.apache.sling.spi.resource.provider.ResolveContext;
-import org.apache.sling.spi.resource.provider.ResourceContext;
-import org.apache.sling.spi.resource.provider.ResourceProvider;
-import org.junit.After;
-import org.junit.Assert;
-import org.junit.Before;
-import org.junit.Test;
-import org.mockito.ArgumentCaptor;
-import org.mockito.Mock;
-import org.mockito.Mockito;
-import org.mockito.MockitoAnnotations;
-import org.osgi.framework.Bundle;
-import org.osgi.framework.BundleContext;
-import org.osgi.framework.Constants;
-import org.osgi.framework.ServiceFactory;
-import org.osgi.framework.ServiceReference;
-import org.osgi.service.component.ComponentContext;
-
-/**
- * This tests the ResourceResolver using mocks. The Unit test is in addition to
- * ResourceResolverImplTest which covers API conformance more than it covers all
- * code paths.
- */
-// TODO: Configure mapping to react correctly.
-// TODO: test external redirect.
-// TODO: Map to URI
-// TODO: Statresource
-public class MockedResourceResolverImplTest {
-
-    private static final List<Resource> EMPTY_RESOURCE_LIST = new ArrayList<Resource>();
-    private static final String FAKE_QUERY_LANGUAGE = "fake";
-    private static final String PATH = "path";
-
-    private ResourceResolverFactoryActivator activator;
-
-    private List<ResourceProviderHandler> handlers = new ArrayList<ResourceProviderHandler>();
-
-    @Mock
-    private ComponentContext componentContext;
-
-    @Mock
-    private BundleContext bundleContext;
-
-    @Mock
-    private Bundle usingBundle;
-
-    @Mock
-    private BundleContext usingBundleContext;
-
-    @Mock
-    private ResourceProviderTracker resourceProviderTracker;
-
-    @Mock
-    private ResourceChangeListenerWhiteboard resourceChangeListenerWhiteboard;
-
-    @SuppressWarnings("rawtypes")
-    @Mock
-    private QueryLanguageProvider queryProvider;
-
-    private Map<String, Object> services = new HashMap<String, Object>();
-
-    private Map<String, Object> serviceProperties = new HashMap<String, Object>();
-
-    private ResourceResolverFactoryImpl resourceResolverFactory;
-
-    @Mock
-    private ResourceProvider<?> resourceProvider;
-
-    /**
-     * deals with /etc resolution.
-     */
-    @Mock
-    private ResourceProvider<?> mappingResourceProvider;
-
-    /**
-     * deals with /apps and /libs resolution.
-     */
-    @Mock
-    private ResourceProvider<?> appsResourceProvider;
-
-    /**
-     * QueriableResourceProviders
-     */
-    @Mock
-    private ResourceProvider<?> queriableResourceProviderA;
-
-
-    public MockedResourceResolverImplTest() {
-        MockitoAnnotations.initMocks(this);
-    }
-
-    @SuppressWarnings("unchecked")
-    @Before
-    public void before() throws LoginException {
-        activator = new ResourceResolverFactoryActivator();
-
-        Mockito.when(componentContext.getProperties()).thenReturn(buildBundleProperties());
-        Mockito.when(componentContext.getBundleContext()).thenReturn(
-            bundleContext);
-
-        activator.resourceAccessSecurityTracker = new ResourceAccessSecurityTracker();
-        activator.resourceProviderTracker = resourceProviderTracker;
-        activator.changeListenerWhiteboard = resourceChangeListenerWhiteboard;
-
-        handlers.add(createRPHandler(resourceProvider, "org.apache.sling.resourceresolver.impl.DummyTestProvider", 10L, "/single"));
-
-        // setup mapping resources at /etc/map to exercise vanity etc.
-        // hmm, can't provide the resolver since its not up and ready.
-        // mapping almost certainly work properly until this can be setup correctly.
-        buildMappingResource("/etc/map", mappingResourceProvider, null);
-
-        handlers.add(createRPHandler(mappingResourceProvider, "org.apache.sling.resourceresolver.impl.MapProvider", 11L, "/etc"));
-        handlers.add(createRPHandler(appsResourceProvider, "org.apache.sling.resourceresolver.impl.AppsProvider", 12L, "/libs"));
-        handlers.add(createRPHandler(appsResourceProvider, "org.apache.sling.resourceresolver.impl.AppsProvider", 13L, "/apps"));
-        handlers.add(createRPHandler(queriableResourceProviderA, "org.apache.sling.resourceresolver.impl.QueriableResourceProviderA", 14L, "/searchA"));
-        Mockito.when(queriableResourceProviderA.getQueryLanguageProvider()).thenReturn(queryProvider);
-
-        ResourceProviderStorage storage = new ResourceProviderStorage(handlers);
-
-        Mockito.when(resourceProviderTracker.getResourceProviderStorage()).thenReturn(storage);
-
-        // activate the components.
-        activator.activate(componentContext);
-
-        // configure using Bundle
-        Mockito.when(usingBundle.getBundleContext()).thenReturn(usingBundleContext);
-        Mockito.when(usingBundleContext.getBundle()).thenReturn(usingBundle);
-
-        // extract any services that were registered into a map.
-        ArgumentCaptor<String> classesCaptor = ArgumentCaptor.forClass(String.class);
-        ArgumentCaptor<Object> serviceCaptor = ArgumentCaptor.forClass(Object.class);
-        @SuppressWarnings("rawtypes")
-        ArgumentCaptor<Dictionary> propertiesCaptor = ArgumentCaptor.forClass(Dictionary.class);
-        Mockito.verify(bundleContext, Mockito.atLeastOnce()).registerService(
-            classesCaptor.capture(), serviceCaptor.capture(),
-            propertiesCaptor.capture());
-
-        int si = 0;
-        List<Object> serviceList = serviceCaptor.getAllValues();
-        @SuppressWarnings({ "unused", "rawtypes" })
-        List<Dictionary> servicePropertiesList = propertiesCaptor.getAllValues();
-        for (String serviceName : classesCaptor.getAllValues()) {
-            services.put(serviceName, serviceList.get(si));
-            serviceProperties.put(serviceName, serviceProperties.get(si));
-            si++;
-        }
-        // verify that a ResourceResolverFactoryImpl was created and registered.
-        Assert.assertNotNull(services.get(ResourceResolverFactory.class.getName()));
-        Object rrf = services.get(ResourceResolverFactory.class.getName());
-        if (rrf instanceof ServiceFactory) {
-            rrf = ((ServiceFactory) rrf).getService(usingBundle, null);
-        }
-        Assert.assertTrue(rrf instanceof ResourceResolverFactoryImpl);
-        resourceResolverFactory = (ResourceResolverFactoryImpl) rrf;
-    }
-
-    public static ResourceProviderHandler createRPHandler(ResourceProvider<?> rp, String pid, long ranking,
-            String path) {
-        ServiceReference ref = Mockito.mock(ServiceReference.class);
-        BundleContext bc = Mockito.mock(BundleContext.class);
-        Mockito.when(bc.getService(Mockito.eq(ref))).thenReturn(rp);
-        Mockito.when(ref.getProperty(Mockito.eq(Constants.SERVICE_ID))).thenReturn(new Random().nextLong());
-        Mockito.when(ref.getProperty(Mockito.eq(Constants.SERVICE_PID))).thenReturn(pid);
-        Mockito.when(ref.getProperty(Mockito.eq(Constants.SERVICE_RANKING))).thenReturn(ranking);
-        Mockito.when(ref.getProperty(Mockito.eq(ResourceProvider.PROPERTY_ROOT))).thenReturn(path);
-        Mockito.when(ref.getProperty(Mockito.eq(ResourceProvider.PROPERTY_MODIFIABLE))).thenReturn(true);
-        Mockito.when(ref.getProperty(Mockito.eq(ResourceProvider.PROPERTY_ATTRIBUTABLE))).thenReturn(true);
-        Mockito.when(ref.getProperty(Mockito.eq(ResourceProvider.PROPERTY_ADAPTABLE))).thenReturn(true);
-
-        ResourceProviderInfo info = new ResourceProviderInfo(ref);
-        final ResourceProviderHandler handler = new ResourceProviderHandler(bc, info);
-        handler.activate();
-        return handler;
-    }
-
-    @SuppressWarnings("unchecked")
-    private Resource buildMappingResource(String path,
-            ResourceProvider<?> provider, ResourceResolver resourceResolver) {
-        List<Resource> localHostAnyList = new ArrayList<Resource>();
-        localHostAnyList.add(buildResource(path+"/http/example.com.80/cgi-bin", EMPTY_RESOURCE_LIST, resourceResolver, provider, "sling:internalRedirect", "/scripts" ));
-        localHostAnyList.add(buildResource(path+"/http/example.com.80/gateway", EMPTY_RESOURCE_LIST, resourceResolver, provider,"sling:internalRedirect", "http://gbiv.com"));
-        localHostAnyList.add(buildResource(path+"/http/example.com.80/stories", EMPTY_RESOURCE_LIST, resourceResolver, provider,"sling:internalRedirect", "/anecdotes/$1"));
-
-        List<Resource> mappingChildren = new ArrayList<Resource>();
-        mappingChildren.add(buildResource(path+"/http/example.com.80", EMPTY_RESOURCE_LIST, resourceResolver, provider,"sling:redirect", "http://www.example.com/"));
-        mappingChildren.add(buildResource(path+"/http/www.example.com.80", EMPTY_RESOURCE_LIST, resourceResolver, provider,"sling:internalRedirect", "/example"));
-        mappingChildren.add(buildResource(path+"/http/any_example.com.80", EMPTY_RESOURCE_LIST, resourceResolver, provider,"sling:match", ".+\\.example\\.com\\.80", "sling:redirect", "http://www.example.com/"));
-        mappingChildren.add(buildResource(path+"/http/localhost_any", localHostAnyList, resourceResolver, provider,"sling:match", "localhost\\.\\d*", "sling:internalRedirect", "/content"));
-
-        Resource etcMapResource = buildResource(path+"/http", mappingChildren);
-        Mockito.when(provider.getResource(Mockito.any(ResolveContext.class), Mockito.eq(path), Mockito.any(ResourceContext.class), Mockito.any(Resource.class))).thenReturn(etcMapResource);
-        return etcMapResource;
-    }
-
-    @After
-    public void after() {
-        handlers.clear();
-    }
-
-    /**
-     * build child resources as an iterable of resources.
-     * @param parent
-     * @return
-     */
-    private Iterable<Resource> buildChildResources(String parent) {
-        List<Resource> mappingResources = new ArrayList<Resource>();
-        for ( int i = 0; i < 5; i++ ) {
-            mappingResources.add(buildResource(parent+"/m"+i, EMPTY_RESOURCE_LIST));
-        }
-        return mappingResources;
-    }
-    /**
-     * Build a resource based on path and children.
-     * @param fullpath
-     * @param children
-     * @return
-     */
-    private Resource buildResource(String fullpath, Iterable<Resource> children) {
-        return buildResource(fullpath, children, null, null, new String[0]);
-    }
-
-    /** Build a List of ValueMap */
-    private List<ValueMap> buildValueMapCollection(int howMany, String pathPrefix) {
-        final List<ValueMap> result = new ArrayList<ValueMap>();
-        for(int i=0;  i < howMany; i++) {
-            final Map<String, Object> m = new HashMap<String, Object>();
-            m.put(PATH, pathPrefix + i);
-            result.add(new ValueMapDecorator(m));
-        }
-        return result;
-    }
-
-    /**
-     * Build a resource with path, children and resource resolver.
-     * @param fullpath
-     * @param children
-     * @param resourceResolver
-     * @return
-     */
-    @SuppressWarnings("unchecked")
-    private Resource buildResource(String fullpath, Iterable<Resource> children, ResourceResolver resourceResolver, ResourceProvider<?> provider, String ... properties) {
-        Resource resource = Mockito.mock(Resource.class);
-        Mockito.when(resource.getName()).thenReturn(getName(fullpath));
-        Mockito.when(resource.getPath()).thenReturn(fullpath);
-        ResourceMetadata resourceMetadata = new ResourceMetadata();
-        Mockito.when(resource.getResourceMetadata()).thenReturn(resourceMetadata);
-        Mockito.when(resource.listChildren()).thenReturn(children.iterator());
-        Mockito.when(resource.getResourceResolver()).thenReturn(resourceResolver);
-
-        // register the resource with the provider
-        if ( provider != null ) {
-            Mockito.when(provider.listChildren(Mockito.any(ResolveContext.class), Mockito.eq(resource))).thenReturn(children.iterator());
-            Mockito.when(provider.getResource(Mockito.any(ResolveContext.class), Mockito.eq(fullpath), Mockito.any(ResourceContext.class), Mockito.any(Resource.class))).thenReturn(resource);
-        }
-        if ( properties != null ) {
-            ValueMap vm = new SimpleValueMapImpl();
-            for ( int i=0; i < properties.length; i+=2) {
-                resourceMetadata.put(properties[i], properties[i+1]);
-                vm.put(properties[i], properties[i+1]);
-            }
-            Mockito.when(resource.getValueMap()).thenReturn(vm);
-            Mockito.when(resource.adaptTo(Mockito.eq(ValueMap.class))).thenReturn(vm);
-        } else {
-            Mockito.when(resource.getValueMap()).thenReturn(ValueMapDecorator.EMPTY);
-            Mockito.when(resource.adaptTo(Mockito.eq(ValueMap.class))).thenReturn(ValueMapDecorator.EMPTY);
-        }
-
-        return resource;
-    }
-
-
-    /**
-     * extract the name from a path.
-     * @param fullpath
-     * @return
-     */
-    private String getName(String fullpath) {
-        int n = fullpath.lastIndexOf("/");
-        return fullpath.substring(n+1);
-    }
-
-    /**
-     * build a properties for a resource resolver bundle.
-     * @return
-     */
-    private Dictionary<String, Object> buildBundleProperties() {
-        Dictionary<String, Object> properties = new Hashtable<String, Object>();
-        properties.put("resource.resolver.virtual", new String[] { "/:/" });
-        properties.put("resource.resolver.mapping", new String[] { "/:/",
-            "/content/:/", "/system/docroot/:/", "/content.html-/$" });
-        properties.put("resource.resolver.allowDirect", true);
-        properties.put("resource.resolver.searchpath", new String[] { "/apps",
-            "/libs" });
-        properties.put("resource.resolver.manglenamespaces", true);
-        properties.put("resource.resolver.map.location", "/etc/map");
-        properties.put("resource.resolver.default.vanity.redirect.status", 302);
-        properties.put(
-            "resource.resolver.required.providers",
-            new String[] { "org.apache.sling.resourceresolver.impl.DummyTestProvider" });
-        properties.put(Constants.SERVICE_VENDOR, "Apache");
-        properties.put(Constants.SERVICE_DESCRIPTION, "Testing");
-        return properties;
-    }
-
-    /**
-     * Test getting a resolver.
-     * @throws LoginException
-     */
-    @Test
-    public void testGetResolver() throws LoginException {
-        ResourceResolver resourceResolver = resourceResolverFactory.getResourceResolver(null);
-        Assert.assertNotNull(resourceResolver);
-        Map<String, Object> authenticationInfo = new HashMap<String, Object>();
-        resourceResolver = resourceResolverFactory.getAdministrativeResourceResolver(authenticationInfo);
-        Assert.assertNotNull(resourceResolver);
-    }
-
-    /**
-     * Misceleneous coverage.
-     * @throws LoginException
-     */
-    @Test
-    public void testResolverMisc() throws LoginException {
-        ResourceResolver resourceResolver = resourceResolverFactory.getResourceResolver(null);
-        try {
-            resourceResolver.getAttribute(null);
-            Assert.fail("Should have thrown a NPE");
-        } catch ( NullPointerException e) {
-            // this is expected.
-        }
-        Assert.assertArrayEquals(new String[]{"/apps/","/libs/"}, resourceResolver.getSearchPath());
-    }
-
-    /**
-     * Test various administrative resource resolvers.
-     * @throws LoginException
-     */
-    @Test
-    public void testGetAuthenticatedResolve() throws LoginException {
-        ResourceResolver resourceResolver = resourceResolverFactory.getAdministrativeResourceResolver(null);
-        Assert.assertNotNull(resourceResolver);
-        Map<String, Object> authenticationInfo = new HashMap<String, Object>();
-
-        resourceResolver = resourceResolverFactory.getAdministrativeResourceResolver(authenticationInfo);
-        Assert.assertNotNull(resourceResolver);
-    }
-
-    /**
-     * Test getResource for a resource provided by a resource provider.
-     * @throws LoginException
-     */
-    @Test
-    public void testGetResource() throws LoginException {
-        ResourceResolver resourceResolver = resourceResolverFactory.getResourceResolver(null);
-        Assert.assertNotNull(resourceResolver);
-        Resource singleResource = buildResource("/single/test", EMPTY_RESOURCE_LIST, resourceResolver, resourceProvider);
-        Resource resource = resourceResolver.getResource("/single/test");
-        Assert.assertEquals(singleResource, resource);
-    }
-
-    /**
-     * Test getResource where path contains intermediate . verifying fix for SLING-864
-     * @throws LoginException
-     */
-    @Test
-    public void testGetResourceSLING864() throws LoginException {
-        ResourceResolver resourceResolver = resourceResolverFactory.getResourceResolver(null);
-        Assert.assertNotNull(resourceResolver);
-        Resource singleResource = buildResource("/single/test.with/extra.dots/inthepath", EMPTY_RESOURCE_LIST,resourceResolver, resourceProvider);
-        Resource resource = resourceResolver.getResource("/single/test.with/extra.dots/inthepath");
-        Assert.assertEquals(singleResource, resource);
-    }
-
-
-    /**
-     * Test search paths
-     * @throws LoginException
-     */
-    @Test
-    public void testRelativeResource() throws LoginException {
-        ResourceResolver resourceResolver = resourceResolverFactory.getResourceResolver(null);
-        Assert.assertNotNull(resourceResolver);
-        Resource appResource = buildResource("/apps/store/inventory", EMPTY_RESOURCE_LIST, resourceResolver, appsResourceProvider);
-        Resource libResource = buildResource("/libs/store/catalog", EMPTY_RESOURCE_LIST, resourceResolver, appsResourceProvider);
-        Resource testResource = resourceResolver.getResource("store/inventory");
-        Assert.assertEquals(appResource, testResource);
-        testResource = resourceResolver.getResource("store/catalog");
-        Assert.assertEquals(libResource, testResource);
-    }
-
-    /**
-     * Basic test of mapping functionality, at the moment needs more
-     * configuration in the virtual /etc/map.
-     *
-     * @throws LoginException
-     */
-    @Test
-    public void testMapping() throws LoginException {
-        ResourceResolver resourceResolver = resourceResolverFactory.getResourceResolver(null);
-        buildResource("/single/test", EMPTY_RESOURCE_LIST, resourceResolver, resourceProvider);
-        HttpServletRequest request = Mockito.mock(HttpServletRequest.class);
-        Mockito.when(request.getScheme()).thenReturn("http");
-        Mockito.when(request.getServerPort()).thenReturn(80);
-        Mockito.when(request.getServerName()).thenReturn("localhost");
-        String path = resourceResolver.map(request,"/single/test?q=123123");
-        Assert.assertEquals("/single/test?q=123123", path);
-        path = resourceResolver.map(request,"/single/test");
-        Assert.assertEquals("/single/test", path);
-
-        // test path mapping without a request.
-        path = resourceResolver.map("/single/test");
-        Assert.assertEquals("/single/test", path);
-
-        buildResource("/content", EMPTY_RESOURCE_LIST, resourceResolver, resourceProvider);
-        path = resourceResolver.map("/content.html");
-        Assert.assertEquals("/content.html", path);
-
-    }
-
-
-    /**
-     * Tests list children via the resource (NB, this doesn't really test the
-     * resource resolver at all, but validates this unit test.)
-     *
-     * @throws LoginException
-     */
-    @Test
-    public void testListChildren() throws LoginException {
-        ResourceResolver resourceResolver = resourceResolverFactory.getResourceResolver(null);
-        buildResource("/single/test/withchildren", buildChildResources("/single/test/withchildren"), resourceResolver, resourceProvider );
-
-
-        Resource resource = resourceResolver.getResource("/single/test/withchildren");
-        Assert.assertNotNull(resource);
-
-        // test via the resource list children itself, this really just tests this test case.
-        Iterator<Resource> resourceIterator = resource.listChildren();
-        Assert.assertNotNull(resourceResolver);
-        int i = 0;
-        while(resourceIterator.hasNext()) {
-            Assert.assertEquals("m"+i, resourceIterator.next().getName());
-            i++;
-        }
-        Assert.assertEquals(5, i);
-    }
-
-    /**
-     * Test listing children via the resource resolver listChildren call.
-     * @throws LoginException
-     */
-    @Test
-    public void testResourceResolverListChildren() throws LoginException {
-        ResourceResolver resourceResolver = resourceResolverFactory.getResourceResolver(null);
-        buildResource("/single/test/withchildren", buildChildResources("/single/test/withchildren"), resourceResolver, resourceProvider);
-
-
-        Resource resource = resourceResolver.getResource("/single/test/withchildren");
-        Assert.assertNotNull(resource);
-
-        // test via the resource list children itself, this really just tests this test case.
-        Iterator<Resource> resourceIterator = resourceResolver.listChildren(resource);
-        Assert.assertNotNull(resourceResolver);
-        int i = 0;
-        while(resourceIterator.hasNext()) {
-            Assert.assertEquals("m"+i, resourceIterator.next().getName());
-            i++;
-        }
-        Assert.assertEquals(5,i);
-    }
-
-    /**
-     * Tests listing children via the resource resolver getChildren call.
-     * @throws LoginException
-     */
-    @Test
-    public void testResourceResolverGetChildren() throws LoginException {
-        ResourceResolver resourceResolver = resourceResolverFactory.getResourceResolver(null);
-        buildResource("/single/test/withchildren", buildChildResources("/single/test/withchildren"), resourceResolver, resourceProvider);
-
-
-        Resource resource = resourceResolver.getResource("/single/test/withchildren");
-        Assert.assertNotNull(resource);
-
-        // test via the resource list children itself, this really just tests this test case.
-        Iterable<Resource> resourceIterator = resourceResolver.getChildren(resource);
-        Assert.assertNotNull(resourceResolver);
-        int i = 0;
-        for(Resource r : resourceIterator) {
-            Assert.assertEquals("m"+i, r.getName());
-            i++;
-        }
-        Assert.assertEquals(5,i);
-    }
-
-    @SuppressWarnings("unchecked")
-    @Test
-    public void testQueryResources() throws LoginException {
-        final int n = 3;
-        String[] languages = new String[] {FAKE_QUERY_LANGUAGE};
-        Mockito.when(queryProvider.getSupportedLanguages(Mockito.any(ResolveContext.class))).thenReturn(languages);
-        Mockito.when(queryProvider.queryResources(Mockito.any(ResolveContext.class), Mockito.any(String.class), Mockito.any(String.class)))
-        .thenReturn(buildValueMapCollection(n, "A_").iterator());
-
-        final ResourceResolver rr = resourceResolverFactory.getResourceResolver(null);
-        buildResource("/search/test/withchildren", buildChildResources("/search/test/withchildren"), rr, resourceProvider);
-        final Iterator<Map<String, Object>> it = rr.queryResources("/search", FAKE_QUERY_LANGUAGE);
-        final Set<String> toFind = new HashSet<String>();
-        for(int i=0; i < n; i++) {
-            toFind.add("A_" + i);
-        }
-
-        assertTrue("Expecting non-empty result (" + n + ")", it.hasNext());
-        while(it.hasNext()) {
-            final Map<String, Object> m = it.next();
-            toFind.remove(m.get(PATH));
-        }
-        assertTrue("Expecting no leftovers (" + n + ") in" + toFind, toFind.isEmpty());
-    }
-
-    @Test public void test_versions() throws LoginException {
-        ResourceResolver resourceResolver = resourceResolverFactory.getResourceResolver(null);
-
-        Resource resource = resourceResolver.resolve("/content/test.html;v=1.0");
-        Map<String, String> parameters = resource.getResourceMetadata().getParameterMap();
-        assertEquals("/content/test.html", resource.getPath());
-        assertEquals("test.html", resource.getName());
-        assertEquals(Collections.singletonMap("v", "1.0"), parameters);
-
-        resource = resourceResolver.resolve("/content/test;v='1.0'.html");
-        parameters = resource.getResourceMetadata().getParameterMap();
-        assertEquals("/content/test.html", resource.getPath());
-        assertEquals("test.html", resource.getName());
-        assertEquals(Collections.singletonMap("v", "1.0"), parameters);
-
-        buildResource("/single/test/withchildren", buildChildResources("/single/test/withchildren"), resourceResolver, resourceProvider);
-        resource = resourceResolver.getResource("/single/test/withchildren;v='1.0'");
-        assertNotNull(resource);
-        assertEquals("/single/test/withchildren", resource.getPath());
-        assertEquals("withchildren", resource.getName());
-    }
-}
diff --git a/src/test/java/org/apache/sling/resourceresolver/impl/ProviderHandlerTest.java b/src/test/java/org/apache/sling/resourceresolver/impl/ProviderHandlerTest.java
deleted file mode 100644
index d9592c4..0000000
--- a/src/test/java/org/apache/sling/resourceresolver/impl/ProviderHandlerTest.java
+++ /dev/null
@@ -1,87 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *   http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-package org.apache.sling.resourceresolver.impl;
-
-import static org.apache.sling.resourceresolver.impl.MockedResourceResolverImplTest.createRPHandler;
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertNotNull;
-import static org.junit.Assert.assertTrue;
-
-import java.util.Arrays;
-
-import org.apache.sling.api.resource.LoginException;
-import org.apache.sling.api.resource.NonExistingResource;
-import org.apache.sling.api.resource.Resource;
-import org.apache.sling.api.resource.ResourceMetadata;
-import org.apache.sling.api.resource.ResourceResolver;
-import org.apache.sling.api.resource.ResourceUtil;
-import org.apache.sling.resourceresolver.impl.providers.ResourceProviderHandler;
-import org.apache.sling.resourceresolver.impl.providers.ResourceProviderStorage;
-import org.apache.sling.resourceresolver.impl.providers.ResourceProviderStorageProvider;
-import org.apache.sling.spi.resource.provider.ResolveContext;
-import org.apache.sling.spi.resource.provider.ResourceContext;
-import org.apache.sling.spi.resource.provider.ResourceProvider;
-import org.junit.Test;
-import org.mockito.Mockito;
-import org.mockito.invocation.InvocationOnMock;
-import org.mockito.stubbing.Answer;
-
-public class ProviderHandlerTest {
-
-    @SuppressWarnings("unchecked")
-    @Test public void testServletRegistrationAndSyntheticResources() throws LoginException {
-        final String servletpath = "/libs/a/b/GET.servlet";
-        final Resource servletResource = Mockito.mock(Resource.class);
-        Mockito.when(servletResource.getResourceMetadata()).then(new Answer<ResourceMetadata>() {
-            @Override
-            public ResourceMetadata answer(InvocationOnMock invocation) throws Throwable {
-                return new ResourceMetadata();
-            }
-        });
-
-        final ResourceProvider<?> leaveProvider = Mockito.mock(ResourceProvider.class);
-        Mockito.when(leaveProvider.getResource(Mockito.any(ResolveContext.class), Mockito.eq(servletpath), Mockito.any(ResourceContext.class), Mockito.any(Resource.class))).thenReturn(servletResource);
-        final ResourceProviderHandler h = createRPHandler(leaveProvider, "my-pid", 0, servletpath);
-        ResourceResolverFactoryActivator activator = new ResourceResolverFactoryActivator();
-        activator.resourceAccessSecurityTracker = new ResourceAccessSecurityTracker();
-        ResourceResolver resolver = new ResourceResolverImpl(new CommonResourceResolverFactoryImpl(activator), false, null, new ResourceProviderStorageProvider() {
-                
-                @Override
-                public ResourceProviderStorage getResourceProviderStorage() {
-                    return new ResourceProviderStorage(Arrays.asList(h));
-                }
-            });
-
-        final Resource parent = resolver.getResource(ResourceUtil.getParent(servletpath));
-        assertNotNull("Parent must be available", parent);
-        assertTrue("Resource should be synthetic", ResourceUtil.isSyntheticResource(parent));
-
-        final Resource servlet = resolver.getResource(servletpath);
-        assertNotNull("Servlet resource must not be null", servlet);
-        assertEquals(servletResource, servlet);
-
-        assertNotNull(resolver.getResource("/libs"));
-
-        // now check when doing a resolve()
-        assertTrue(resolver.resolve("/libs") instanceof NonExistingResource);
-        assertTrue(resolver.resolve(ResourceUtil.getParent(servletpath)) instanceof NonExistingResource);
-        assertNotNull(resolver.resolve(servletpath));
-        resolver.close();
-    }
-}
diff --git a/src/test/java/org/apache/sling/resourceresolver/impl/ResourceDecorationTest.java b/src/test/java/org/apache/sling/resourceresolver/impl/ResourceDecorationTest.java
deleted file mode 100644
index 7d45741..0000000
--- a/src/test/java/org/apache/sling/resourceresolver/impl/ResourceDecorationTest.java
+++ /dev/null
@@ -1,113 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *   http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-package org.apache.sling.resourceresolver.impl;
-
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertNotNull;
-import static org.junit.Assert.assertNull;
-import static org.junit.Assert.assertTrue;
-
-import java.util.Iterator;
-
-import org.apache.sling.api.resource.Resource;
-import org.apache.sling.api.resource.ResourceWrapper;
-import org.junit.Test;
-
-/** Test ResourceDecorator handling in ResourceResolverImpl */
-public class ResourceDecorationTest extends ResourceDecoratorTestBase {
-
-    private static final String DECORATED_NAME = "decorated";
-    
-    /** Wrap any resource so that its name is DECORATED_NAME */
-    protected Resource wrapResourceForTest(Resource resource) {
-        return new ResourceWrapper(resource) {
-            @Override
-            public String getName() {
-                return DECORATED_NAME;
-            }
-        };
-    }
-    
-    private void assertDecorated(Resource r) {
-        assertEquals("Expecting " + r + " to be decorated", DECORATED_NAME, r.getName());
-    }
-    
-    private void assertDecorated(Iterator<Resource> it, int expectedCount) {
-        assertNotNull(it);
-        assertTrue("Expecting non-empty Iterator", it.hasNext());
-        int count = 0;
-        while(it.hasNext()) {
-            count++;
-            assertDecorated(it.next());
-        }
-        assertEquals("Expecting " + expectedCount + " items in Iterator", expectedCount, count);
-    }
-    
-    @Test
-    public void resolveRootIsDecorated() {
-        final Resource r = resolver.resolve((String)null); 
-        assertDecorated(r);
-        assertExistent(r, true);
-    }
-    
-    @Test
-    public void getRootIsDecorated() {
-        final Resource r = resolver.getResource("/"); 
-        assertDecorated(r);
-        assertExistent(r, true);
-    }
-    
-    @Test
-    public void getNonExistingIsNull() {
-        assertNull(resolver.getResource("/non-existing/something")); 
-    }
-    
-    @Test
-    public void existentIsDecorated() {
-        final Resource r = resolver.resolve("/tmp/C");
-        assertDecorated(r);
-        assertExistent(r, true);
-    }
-    
-    @Test
-    public void NonExistentIsDecorated() {
-        final Resource r = resolver.resolve("/foo");
-        assertDecorated(r);
-        assertExistent(r, false);
-    }
-    
-    @Test
-    public void childrenAreDecorated() {
-        final Resource root = resolver.resolve((String)null);
-        final Iterator<Resource> it = resolver.listChildren(root);
-        assertTrue("Expecting root to have children", it.hasNext());
-        assertDecorated(it, 2);
-    }
-    
-    @Test
-    public void listChildrenDecorates() {
-        final Resource testVar = resolver.resolve("/var");
-        assertDecorated(resolver.listChildren(testVar), 3);
-    }
-    
-    @Test
-    public void findDecorates() {
-        assertDecorated(resolver.findResources("foo", QUERY_LANGUAGE), 4);
-    }
-}
\ No newline at end of file
diff --git a/src/test/java/org/apache/sling/resourceresolver/impl/ResourceDecoratorReturnsNullTest.java b/src/test/java/org/apache/sling/resourceresolver/impl/ResourceDecoratorReturnsNullTest.java
deleted file mode 100644
index dadd520..0000000
--- a/src/test/java/org/apache/sling/resourceresolver/impl/ResourceDecoratorReturnsNullTest.java
+++ /dev/null
@@ -1,113 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *   http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-package org.apache.sling.resourceresolver.impl;
-
-import static org.junit.Assert.assertNotNull;
-import static org.junit.Assert.assertTrue;
-import static org.junit.Assert.fail;
-
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.HashSet;
-import java.util.Iterator;
-import java.util.List;
-import java.util.Set;
-
-import org.apache.sling.api.resource.LoginException;
-import org.apache.sling.api.resource.Resource;
-import org.junit.Before;
-import org.junit.Test;
-
-/** Verify what happens when ResourceDecorator returns null */
-public class ResourceDecoratorReturnsNullTest extends ResourceDecoratorTestBase {
-
-    private Set<String> pathsThatReturnNull = new HashSet<String>();
-    
-    /** Return null for resources that have a path in pathsThatReturnNull.
-     *  Will cause our test ResourceDecorator to return null for these resources
-     */
-    protected Resource wrapResourceForTest(Resource r) {
-        return isReturnNull(r) ? null : r;
-    }
-    
-    private boolean isReturnNull(Resource r) {
-        return pathsThatReturnNull.contains(r.getPath());
-    }
-    
-    private void assertResources(Iterator<Resource> it, String ...paths) {
-        assertNotNull("Expecting non-null Iterator", it);
-        final List<String> actual = new ArrayList<String>();
-        while(it.hasNext()) {
-            final Resource r = it.next();
-            assertNotNull("Expecting no null Resources in iterator", r);
-            actual.add(r.getPath());
-        }
-        for(String path : paths) {
-            assertTrue("Expecting path " + path + " in " + actual, actual.contains(path));
-        }
-        if(actual.size() != paths.length) {
-            fail("Expecting the same number of items in " + Arrays.asList(paths) + " and " + actual);
-        }
-    }
-    
-    @Before
-    public void setup() throws LoginException {
-        super.setup();
-        pathsThatReturnNull.add("/tmp/D");
-        pathsThatReturnNull.add("/var/two");
-    }
-    
-    @Test
-    public void testResolveNotNull() {
-        assertExistent(resolver.resolve("/tmp/A"), true);
-    }
-    
-    public void testGetNotNull() {
-        assertExistent(resolver.getResource("/tmp/A"), true);
-    }
-    
-    @Test
-    public void testGetNull() {
-        assertExistent(resolver.getResource("/tmp/D"), true);
-    }
-    
-    @Test
-    public void testResolveNull() {
-        assertExistent(resolver.resolve("/tmp/D"), true);
-    }
-    
-    @Test
-    public void testRootChildren() {
-        final Resource root = resolver.resolve("/");
-        assertNotNull(root);
-        assertResources(resolver.listChildren(root), "/tmp", "/var");
-    }
-    
-    @Test
-    public void testVarChildren() {
-        final Resource var = resolver.resolve("/var");
-        assertNotNull(var);
-        assertResources(resolver.listChildren(var), "/var/one", "/var/two", "/var/three");
-    }
-    
-    @Test
-    public void testFind() {
-        assertResources(resolver.findResources("foo", QUERY_LANGUAGE), "/tmp/C", "/tmp/D", "/var/one", "/var/two");
-    }
-}
\ No newline at end of file
diff --git a/src/test/java/org/apache/sling/resourceresolver/impl/ResourceDecoratorTestBase.java b/src/test/java/org/apache/sling/resourceresolver/impl/ResourceDecoratorTestBase.java
deleted file mode 100644
index e2b1d80..0000000
--- a/src/test/java/org/apache/sling/resourceresolver/impl/ResourceDecoratorTestBase.java
+++ /dev/null
@@ -1,171 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *   http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-package org.apache.sling.resourceresolver.impl;
-
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertNotNull;
-
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.Iterator;
-import java.util.List;
-
-import javax.servlet.http.HttpServletRequest;
-
-import org.apache.sling.api.resource.LoginException;
-import org.apache.sling.api.resource.NonExistingResource;
-import org.apache.sling.api.resource.Resource;
-import org.apache.sling.api.resource.ResourceDecorator;
-import org.apache.sling.api.resource.ResourceMetadata;
-import org.apache.sling.api.resource.ResourceResolver;
-import org.apache.sling.api.resource.ResourceUtil;
-import org.apache.sling.api.resource.ValueMap;
-import org.apache.sling.resourceresolver.impl.helper.ResourceDecoratorTracker;
-import org.apache.sling.resourceresolver.impl.providers.ResourceProviderHandler;
-import org.apache.sling.resourceresolver.impl.providers.ResourceProviderStorage;
-import org.apache.sling.resourceresolver.impl.providers.ResourceProviderStorageProvider;
-import org.apache.sling.spi.resource.provider.QueryLanguageProvider;
-import org.apache.sling.spi.resource.provider.ResolveContext;
-import org.apache.sling.spi.resource.provider.ResourceContext;
-import org.apache.sling.spi.resource.provider.ResourceProvider;
-import org.junit.Before;
-import org.mockito.Mockito;
-
-/** Base class for tests that involve ResourceDecorators */
-public abstract class ResourceDecoratorTestBase {
-
-    protected ResourceResolver resolver;
-    protected static final String QUERY_LANGUAGE = "some.funnny.language";
-
-    protected abstract Resource wrapResourceForTest(Resource resource);
-
-    @Before
-    public void setup() throws LoginException {
-        final ResourceDecorator d = new ResourceDecorator() {
-            @Override
-            public Resource decorate(Resource resource) {
-                return ResourceDecoratorTestBase.this.wrapResourceForTest(resource);
-            }
-
-            @Override
-            public Resource decorate(Resource resource, HttpServletRequest request) {
-                throw new UnsupportedOperationException("Not supposed to be used in these tests");
-            }
-
-        };
-
-        final ResourceDecoratorTracker t = new ResourceDecoratorTracker();
-        t.bindResourceDecorator(d, null);
-
-        final ResourceProvider<?> provider = new ResourceProvider<Object>() {
-
-            @Override
-            public QueryLanguageProvider<Object> getQueryLanguageProvider() {
-                return new QueryLanguageProvider<Object>() {
-
-                    @Override
-                    public String[] getSupportedLanguages(ResolveContext<Object> ctx) {
-                        return new String[] { QUERY_LANGUAGE };
-                    }
-
-                    @Override
-                    public Iterator<Resource> findResources(ResolveContext<Object> ctx, String query, String language) {
-                        final List<Resource> found = new ArrayList<Resource>();
-                        found.add(mockResource("/tmp/C"));
-                        found.add(mockResource("/tmp/D"));
-                        found.add(mockResource("/var/one"));
-                        found.add(mockResource("/var/two"));
-                        return found.iterator();
-                    }
-
-                    @Override
-                    public Iterator<ValueMap> queryResources(ResolveContext<Object> ctx, String query, String language) {
-                        return null;
-                    }
-                };
-            }
-
-            @Override
-            public Resource getResource(ResolveContext<Object> ctx, String path, final ResourceContext rCtx, Resource parent) {
-                if(path.equals("/") || path.startsWith("/tmp") || path.startsWith("/var")) {
-                    return mockResource(path);
-                }
-                return null;
-            }
-
-            @Override
-            public Iterator<Resource> listChildren(ResolveContext<Object> ctx, Resource parent) {
-                final List<Resource> children = new ArrayList<Resource>();
-                if("/".equals(parent.getPath())) {
-                    children.add(mockResource("/tmp"));
-                    children.add(mockResource("/var"));
-                } else if("/var".equals(parent.getPath())) {
-                    children.add(mockResource("/var/one"));
-                    children.add(mockResource("/var/two"));
-                    children.add(mockResource("/var/three"));
-                } else if("/tmp".equals(parent.getPath())) {
-                    children.add(mockResource("/tmp/A"));
-                    children.add(mockResource("/tmp/B"));
-                    children.add(mockResource("/tmp/C"));
-                    children.add(mockResource("/tmp/D"));
-                }
-                return children.iterator();
-            }
-
-        };
-
-        ResourceResolverFactoryActivator activator = new ResourceResolverFactoryActivator();
-        final CommonResourceResolverFactoryImpl crf = new CommonResourceResolverFactoryImpl(activator) {
-            @Override
-            public ResourceDecoratorTracker getResourceDecoratorTracker() {
-                return t;
-            }
-
-            @Override
-            public ResourceAccessSecurityTracker getResourceAccessSecurityTracker() {
-                return new ResourceAccessSecurityTracker();
-            }
-        };
-
-        final List<ResourceProviderHandler> list = Arrays.asList(MockedResourceResolverImplTest.createRPHandler(provider, "A-provider", 0L, "/"));
-        resolver = new ResourceResolverImpl(crf, false, null, new ResourceProviderStorageProvider() {
-
-            @Override
-            public ResourceProviderStorage getResourceProviderStorage() {
-                return new ResourceProviderStorage(list);
-            }
-        });
-    }
-
-    protected void assertExistent(Resource r, boolean existent) {
-        assertNotNull("Expecting non-null Resource", r);
-        assertEquals("Expecting " + (existent ? "existent" : "non-existent") + " resource",
-                existent,
-                !NonExistingResource.RESOURCE_TYPE_NON_EXISTING.equals(r.getResourceType()));
-    }
-
-    protected Resource mockResource(String path) {
-        final Resource result = Mockito.mock(Resource.class);
-        Mockito.when(result.getPath()).thenReturn(path);
-        Mockito.when(result.getName()).thenReturn(ResourceUtil.getName(path));
-        final ResourceMetadata m = new ResourceMetadata();
-        Mockito.when(result.getResourceMetadata()).thenReturn(m);
-        return result;
-    }
-}
\ No newline at end of file
diff --git a/src/test/java/org/apache/sling/resourceresolver/impl/ResourceProviderEntryTest.java b/src/test/java/org/apache/sling/resourceresolver/impl/ResourceProviderEntryTest.java
deleted file mode 100644
index 3e74a62..0000000
--- a/src/test/java/org/apache/sling/resourceresolver/impl/ResourceProviderEntryTest.java
+++ /dev/null
@@ -1,303 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *   http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-package org.apache.sling.resourceresolver.impl;
-
-import static org.apache.sling.resourceresolver.impl.MockedResourceResolverImplTest.createRPHandler;
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertFalse;
-import static org.junit.Assert.assertNull;
-import static org.junit.Assert.fail;
-
-import java.util.ArrayList;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-
-import org.apache.sling.api.resource.AbstractResource;
-import org.apache.sling.api.resource.LoginException;
-import org.apache.sling.api.resource.Resource;
-import org.apache.sling.api.resource.ResourceMetadata;
-import org.apache.sling.api.resource.ResourceResolver;
-import org.apache.sling.api.resource.SyntheticResource;
-import org.apache.sling.resourceresolver.impl.providers.ResourceProviderHandler;
-import org.apache.sling.resourceresolver.impl.providers.ResourceProviderStorage;
-import org.apache.sling.resourceresolver.impl.providers.ResourceProviderStorageProvider;
-import org.apache.sling.spi.resource.provider.ResolveContext;
-import org.apache.sling.spi.resource.provider.ResourceContext;
-import org.apache.sling.spi.resource.provider.ResourceProvider;
-import org.junit.Before;
-import org.junit.Test;
-import org.mockito.Mockito;
-import org.osgi.framework.Constants;
-
-@SuppressWarnings("unchecked")
-public class ResourceProviderEntryTest {
-
-    private List<ResourceProviderHandler> providers = new ArrayList<ResourceProviderHandler>();
-
-    private ResourceResolver providersBasedResolver;
-
-    private ResourceResolver mockedRootResolver;
-
-    @Before public void setUp() throws Exception {
-        this.mockedRootResolver = Mockito.mock(ResourceResolver.class);
-        this.providersBasedResolver = null;
-        this.providers.clear();
-        final ResourceProvider<?> rootProvider = Mockito.mock(ResourceProvider.class);
-        Mockito.when(rootProvider.getResource(Mockito.any(ResolveContext.class), Mockito.anyString(), Mockito.any(ResourceContext.class), Mockito.any(Resource.class))).thenReturn(new TestResource(this.mockedRootResolver));
-        providers.add(createRPHandler(rootProvider, "rp0", 0, "/"));
-    }
-
-    @Test public void testRootProvider() throws LoginException {
-        assertNull(getResource("relpath"));
-        assertEqualsResolver(this.mockedRootResolver, getResource("/"));
-        assertEqualsResolver(this.mockedRootResolver, getResource("/rootel"));
-        assertEqualsResolver(this.mockedRootResolver, getResource("/rootel/child"));
-        assertEqualsResolver(this.mockedRootResolver, getResource("/apps/sling/sample/html.js"));
-        assertEqualsResolver(this.mockedRootResolver, getResource("/apps/sling/microsling/html.js"));
-    }
-
-    @Test public void testAdd1Provider() throws LoginException {
-        String firstPath = "/rootel";
-        final ResourceResolver resolver = Mockito.mock(ResourceResolver.class);
-        final ResourceProvider<?> first = Mockito.mock(ResourceProvider.class);
-        Mockito.when(first.getResource(Mockito.any(ResolveContext.class), Mockito.startsWith(firstPath), Mockito.any(ResourceContext.class), Mockito.any(Resource.class))).thenReturn(new TestResource(resolver));
-
-        providers.add(createRPHandler(first, "rp1", 1, "/rootel"));
-        this.providersBasedResolver = null;
-
-        assertEqualsResolver(this.mockedRootResolver, getResource("/"));
-        assertEqualsResolver(resolver, getResource("/rootel"));
-        assertEqualsResolver(resolver, getResource("/rootel/html.js"));
-        assertEqualsResolver(resolver, getResource("/rootel/child"));
-        assertEqualsResolver(resolver, getResource("/rootel/child/html.js"));
-        assertEqualsResolver(this.mockedRootResolver, getResource("/apps/sling/sample/html.js"));
-        assertEqualsResolver(this.mockedRootResolver, getResource("/apps/sling/microsling/html.js"));
-    }
-
-    @Test public void testAdd3Providers() throws LoginException {
-        String firstPath = "/rootel";
-        String secondPath = firstPath + "/child";
-        String thirdPath = "/apps/sling/sample";
-
-        final ResourceResolver firstResolver = Mockito.mock(ResourceResolver.class);
-        final ResourceProvider<?> first = Mockito.mock(ResourceProvider.class);
-        Mockito.when(first.getResource(Mockito.any(ResolveContext.class), Mockito.startsWith(firstPath), Mockito.any(ResourceContext.class), Mockito.any(Resource.class))).thenReturn(new TestResource(firstResolver));
-        final ResourceResolver secondResolver = Mockito.mock(ResourceResolver.class);
-        final ResourceProvider<?> second = Mockito.mock(ResourceProvider.class);
-        Mockito.when(second.getResource(Mockito.any(ResolveContext.class), Mockito.startsWith(secondPath), Mockito.any(ResourceContext.class), Mockito.any(Resource.class))).thenReturn(new TestResource(secondResolver));
-        final ResourceResolver thirdResolver = Mockito.mock(ResourceResolver.class);
-        final ResourceProvider<?> third = Mockito.mock(ResourceProvider.class);
-        Mockito.when(third.getResource(Mockito.any(ResolveContext.class), Mockito.startsWith(thirdPath), Mockito.any(ResourceContext.class), Mockito.any(Resource.class))).thenReturn(new TestResource(thirdResolver));
-
-        providers.add(createRPHandler(first, "rp1", 1, firstPath));
-        providers.add(createRPHandler(second, "rp2", 2, secondPath));
-        providers.add(createRPHandler(third, "rp3", 3, thirdPath));
-        this.providersBasedResolver = null;
-
-        assertEqualsResolver(this.mockedRootResolver, getResource("/"));
-        assertEqualsResolver(firstResolver, getResource("/rootel"));
-        assertEqualsResolver(firstResolver, getResource("/rootel/html.js"));
-        assertEqualsResolver(secondResolver, getResource("/rootel/child"));
-        assertEqualsResolver(secondResolver, getResource("/rootel/child/html.js"));
-        assertEqualsResolver(thirdResolver, getResource("/apps/sling/sample/html.js"));
-        assertEqualsResolver(this.mockedRootResolver, getResource("/apps/sling/microsling/html.js"));
-    }
-
-    @Test public void testAdd3ProvidersReverse() throws LoginException {
-        String firstPath = "/rootel";
-        String secondPath = firstPath + "/child";
-        String thirdPath = "/apps/sling/sample";
-
-        final ResourceResolver firstResolver = Mockito.mock(ResourceResolver.class);
-        final ResourceProvider<?> first = Mockito.mock(ResourceProvider.class);
-        Mockito.when(first.getResource(Mockito.any(ResolveContext.class), Mockito.startsWith(firstPath), Mockito.any(ResourceContext.class), Mockito.any(Resource.class))).thenReturn(new TestResource(firstResolver));
-        final ResourceResolver secondResolver = Mockito.mock(ResourceResolver.class);
-        final ResourceProvider<?> second = Mockito.mock(ResourceProvider.class);
-        Mockito.when(second.getResource(Mockito.any(ResolveContext.class), Mockito.startsWith(secondPath), Mockito.any(ResourceContext.class), Mockito.any(Resource.class))).thenReturn(new TestResource(secondResolver));
-        final ResourceResolver thirdResolver = Mockito.mock(ResourceResolver.class);
-        final ResourceProvider<?> third = Mockito.mock(ResourceProvider.class);
-        Mockito.when(third.getResource(Mockito.any(ResolveContext.class), Mockito.startsWith(thirdPath), Mockito.any(ResourceContext.class), Mockito.any(Resource.class))).thenReturn(new TestResource(thirdResolver));
-
-        providers.add(createRPHandler(first, "rp1", 1, firstPath));
-        providers.add(createRPHandler(second, "rp2", 2, secondPath));
-        providers.add(createRPHandler(third, "rp3", 3, thirdPath));
-        this.providersBasedResolver = null;
-
-        assertEqualsResolver(this.mockedRootResolver, getResource("/"));
-        assertEqualsResolver(firstResolver, getResource("/rootel"));
-        assertEqualsResolver(firstResolver, getResource("/rootel/html.js"));
-        assertEqualsResolver(secondResolver, getResource("/rootel/child"));
-        assertEqualsResolver(secondResolver, getResource("/rootel/child/html.js"));
-        assertEqualsResolver(thirdResolver, getResource("/apps/sling/sample/html.js"));
-        assertEqualsResolver(this.mockedRootResolver, getResource("/apps/sling/microsling/html.js"));
-    }
-
-    @Test public void testRemoveProviders() throws LoginException {
-        String firstPath = "/rootel";
-        String thirdPath = "/apps/sling/sample";
-        String secondPath = firstPath + "/child";
-
-        final ResourceResolver firstResolver = Mockito.mock(ResourceResolver.class);
-        final ResourceProvider<?> first = Mockito.mock(ResourceProvider.class);
-        Mockito.when(first.getResource(Mockito.any(ResolveContext.class), Mockito.startsWith(firstPath), Mockito.any(ResourceContext.class), Mockito.any(Resource.class))).thenReturn(new TestResource(firstResolver));
-        final ResourceResolver secondResolver = Mockito.mock(ResourceResolver.class);
-        final ResourceProvider<?> second = Mockito.mock(ResourceProvider.class);
-        Mockito.when(second.getResource(Mockito.any(ResolveContext.class), Mockito.startsWith(secondPath), Mockito.any(ResourceContext.class), Mockito.any(Resource.class))).thenReturn(new TestResource(secondResolver));
-        final ResourceResolver thirdResolver = Mockito.mock(ResourceResolver.class);
-        final ResourceProvider<?> third = Mockito.mock(ResourceProvider.class);
-        Mockito.when(third.getResource(Mockito.any(ResolveContext.class), Mockito.startsWith(thirdPath), Mockito.any(ResourceContext.class), Mockito.any(Resource.class))).thenReturn(new TestResource(thirdResolver));
-
-        final Map<String, Object> firstProps = new HashMap<String, Object>();
-        firstProps.put(Constants.SERVICE_ID, (long)1);
-        final Map<String, Object> secondProps = new HashMap<String, Object>();
-        secondProps.put(Constants.SERVICE_ID, (long)2);
-        final Map<String, Object> thirdProps = new HashMap<String, Object>();
-        thirdProps.put(Constants.SERVICE_ID, (long)3);
-
-        ResourceProviderHandler firstH = createRPHandler(first, "rp1", 1, firstPath);
-        providers.add(firstH);
-        providers.add(createRPHandler(second, "rp2", 2, secondPath));
-        providers.add(createRPHandler(third, "rp3", 3, thirdPath));
-        this.providersBasedResolver = null;
-
-        assertEqualsResolver(this.mockedRootResolver, getResource("/"));
-        assertEqualsResolver(firstResolver, getResource("/rootel/html.js"));
-        assertEqualsResolver(secondResolver, getResource("/rootel/child/html.js"));
-
-        providers.remove(firstH);
-        this.providersBasedResolver = null;
-
-        assertEqualsResolver(this.mockedRootResolver, getResource("/"));
-        assertEqualsResolver(this.mockedRootResolver, getResource("/rootel/sddsf/sdfsdf/html.js"));
-        assertEqualsResolver(this.mockedRootResolver, getResource("/rootel/html.js"));
-        assertEqualsResolver(secondResolver, getResource("/rootel/child/html.js"));
-
-        providers.add(firstH);
-        this.providersBasedResolver = null;
-
-        assertEqualsResolver(this.mockedRootResolver, getResource("/"));
-        assertEqualsResolver(firstResolver, getResource("/rootel/html.js"));
-        assertEqualsResolver(secondResolver, getResource("/rootel/child/html.js"));
-    }
-
-    @Test public void testRemoveTheOnlyProvider() throws LoginException {
-        long counter = 1;
-
-        providers.clear();
-        for(String path : new String[] { "/foo", "/", "/foo/bar" }) {
-            final ResourceResolver resolver = Mockito.mock(ResourceResolver.class);
-            final ResourceProvider<?> p = Mockito.mock(ResourceProvider.class);
-            Mockito.when(p.getResource(Mockito.any(ResolveContext.class), Mockito.startsWith(path), Mockito.any(ResourceContext.class), Mockito.any(Resource.class))).thenReturn(new TestResource(resolver));
-
-            ++counter;
-
-            ResourceProviderHandler h = createRPHandler(p, "rp"+counter, counter, path);
-            providers.add(h);
-            this.providersBasedResolver = null;
-            {
-                final Resource r = getResource(path);
-                assertEqualsResolver(resolver, r);
-                assertFalse(r instanceof SyntheticResource);
-            }
-
-            providers.remove(h);
-            this.providersBasedResolver = null;
-            {
-                final Resource r = getResource(path);
-                // If our provider is indeed gone, we should get one of the following conditions
-                if(r == null) {
-                    //fine
-                } else if(!p.equals(r.getResourceResolver())) {
-                    //fine
-                } else {
-                    fail("Expecting inactive provider after removing it for " + path);
-                }
-            }
-        }
-    }
-
-    private void assertEqualsResolver(final ResourceResolver resolver, final Resource res) {
-        assertEquals(resolver, res.getResourceResolver());
-    }
-
-    private Resource getResource(String path) throws LoginException {
-        return getResolver().getResource(path);
-    }
-
-    private ResourceResolver getResolver() throws LoginException {
-        if (providersBasedResolver == null) {
-            final ResourceResolverFactoryActivator activator = new ResourceResolverFactoryActivator();
-            activator.resourceAccessSecurityTracker = new ResourceAccessSecurityTracker();
-            providersBasedResolver = new ResourceResolverImpl(new CommonResourceResolverFactoryImpl(activator), false, null,
-                    new ResourceProviderStorageProvider() {
-
-                        @Override
-                        public ResourceProviderStorage getResourceProviderStorage() {
-                            return new ResourceProviderStorage(providers);
-                        }
-                    });
-        }
-        return providersBasedResolver;
-    }
-
-    private static class TestResource extends AbstractResource {
-
-        private final ResourceResolver resourceResolver;
-
-        public TestResource(ResourceResolver resourceResolver) {
-            this.resourceResolver = resourceResolver;
-        }
-
-        @Override
-        public String getPath() {
-            return null;
-        }
-
-        @Override
-        public ResourceMetadata getResourceMetadata() {
-            return new ResourceMetadata();
-        }
-
-        @Override
-        public ResourceResolver getResourceResolver() {
-            return resourceResolver;
-        }
-
-        @Override
-        public String getResourceType() {
-            return null;
-        }
-
-        @Override
-        public String getResourceSuperType() {
-            return null;
-        }
-
-        @Override
-        public <AdapterType> AdapterType adaptTo(Class<AdapterType> type) {
-            return null;
-        }
-
-		@Override
-        public boolean hasChildren() {
-			return false;
-		}
-    }
-}
diff --git a/src/test/java/org/apache/sling/resourceresolver/impl/ResourceResolverFactoryTest.java b/src/test/java/org/apache/sling/resourceresolver/impl/ResourceResolverFactoryTest.java
deleted file mode 100644
index 57234f0..0000000
--- a/src/test/java/org/apache/sling/resourceresolver/impl/ResourceResolverFactoryTest.java
+++ /dev/null
@@ -1,102 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *   http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-package org.apache.sling.resourceresolver.impl;
-
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertNotNull;
-import static org.junit.Assert.assertNull;
-
-import org.apache.sling.api.resource.ResourceResolver;
-import org.apache.sling.resourceresolver.impl.providers.ResourceProviderTracker;
-import org.junit.Before;
-import org.junit.Test;
-
-public class ResourceResolverFactoryTest {
-
-    private CommonResourceResolverFactoryImpl commonFactory;
-
-    @Before public void setup() {
-        ResourceResolverFactoryActivator activator = new ResourceResolverFactoryActivator();
-        activator.resourceProviderTracker = new ResourceProviderTracker();
-        commonFactory = new CommonResourceResolverFactoryImpl(activator);
-    }
-
-    @Test public void testSingleThreadLocal() throws Exception {
-        assertNull(this.commonFactory.getThreadResourceResolver());
-        // create first resolver
-        final ResourceResolver rr1 = this.commonFactory.getResourceResolver(null);
-        assertNotNull(rr1);
-        assertEquals(rr1, this.commonFactory.getThreadResourceResolver());
-        rr1.close();
-
-        assertNull(this.commonFactory.getThreadResourceResolver());
-    }
-
-    @Test public void testNestedThreadLocal() throws Exception {
-        assertNull(this.commonFactory.getThreadResourceResolver());
-        // create first resolver
-        final ResourceResolver rr1 = this.commonFactory.getResourceResolver(null);
-        assertNotNull(rr1);
-        assertEquals(rr1, this.commonFactory.getThreadResourceResolver());
-
-        // create second resolver
-        final ResourceResolver rr2 = this.commonFactory.getResourceResolver(null);
-        assertNotNull(rr2);
-        assertEquals(rr2, this.commonFactory.getThreadResourceResolver());
-
-        rr2.close();
-        assertEquals(rr1, this.commonFactory.getThreadResourceResolver());
-
-        rr1.close();
-        assertNull(this.commonFactory.getThreadResourceResolver());
-    }
-
-    @Test public void testNestedUnorderedCloseThreadLocal() throws Exception {
-        assertNull(this.commonFactory.getThreadResourceResolver());
-        // create three resolver
-        final ResourceResolver rr1 = this.commonFactory.getResourceResolver(null);
-        final ResourceResolver rr2 = this.commonFactory.getResourceResolver(null);
-        final ResourceResolver rr3 = this.commonFactory.getResourceResolver(null);
-
-        assertEquals(rr3, this.commonFactory.getThreadResourceResolver());
-
-        rr2.close();
-        assertEquals(rr3, this.commonFactory.getThreadResourceResolver());
-
-        rr3.close();
-        assertEquals(rr1, this.commonFactory.getThreadResourceResolver());
-
-        rr1.close();
-        assertNull(this.commonFactory.getThreadResourceResolver());
-    }
-
-    @Test public void testThreadLocalWithAdmin() throws Exception {
-        assertNull(this.commonFactory.getThreadResourceResolver());
-        final ResourceResolver rr1 = this.commonFactory.getResourceResolver(null);
-        final ResourceResolver admin = this.commonFactory.getAdministrativeResourceResolver(null);
-
-        assertEquals(rr1, this.commonFactory.getThreadResourceResolver());
-
-        rr1.close();
-        assertNull(this.commonFactory.getThreadResourceResolver());
-
-        admin.close();
-        assertNull(this.commonFactory.getThreadResourceResolver());
-    }
-}
diff --git a/src/test/java/org/apache/sling/resourceresolver/impl/ResourceResolverImplTest.java b/src/test/java/org/apache/sling/resourceresolver/impl/ResourceResolverImplTest.java
deleted file mode 100644
index dfa79e9..0000000
--- a/src/test/java/org/apache/sling/resourceresolver/impl/ResourceResolverImplTest.java
+++ /dev/null
@@ -1,662 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *   http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-package org.apache.sling.resourceresolver.impl;
-
-import static java.util.Arrays.asList;
-import static org.apache.sling.resourceresolver.impl.MockedResourceResolverImplTest.createRPHandler;
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertFalse;
-import static org.junit.Assert.assertNotNull;
-import static org.junit.Assert.assertNull;
-import static org.junit.Assert.assertTrue;
-import static org.junit.Assert.fail;
-import static org.mockito.Mockito.mock;
-import static org.mockito.Mockito.spy;
-import static org.mockito.Mockito.when;
-
-import java.util.ArrayList;
-import java.util.HashMap;
-import java.util.HashSet;
-import java.util.Iterator;
-import java.util.List;
-import java.util.Map;
-
-import javax.jcr.Session;
-import javax.servlet.http.HttpServletRequest;
-
-import org.apache.sling.api.SlingException;
-import org.apache.sling.api.resource.LoginException;
-import org.apache.sling.api.resource.NonExistingResource;
-import org.apache.sling.api.resource.PersistenceException;
-import org.apache.sling.api.resource.Resource;
-import org.apache.sling.api.resource.ResourceResolver;
-import org.apache.sling.api.resource.ResourceResolverFactory;
-import org.apache.sling.api.resource.SyntheticResource;
-import org.apache.sling.resourceresolver.impl.providers.ResourceProviderHandler;
-import org.apache.sling.resourceresolver.impl.providers.ResourceProviderStorage;
-import org.apache.sling.resourceresolver.impl.providers.ResourceProviderTracker;
-import org.apache.sling.spi.resource.provider.ResolveContext;
-import org.apache.sling.spi.resource.provider.ResourceContext;
-import org.apache.sling.spi.resource.provider.ResourceProvider;
-import org.junit.Before;
-import org.junit.Test;
-import org.mockito.internal.util.reflection.Whitebox;
-
-public class ResourceResolverImplTest {
-
-    private CommonResourceResolverFactoryImpl commonFactory;
-
-    private ResourceResolver resResolver;
-
-    private ResourceResolverFactoryImpl resFac;
-
-    private ResourceProviderTracker resourceProviderTracker;
-
-    @Before public void setup() throws LoginException {
-        ResourceProvider<?> rp = new ResourceProvider<Object>() {
-
-            @Override
-            public Resource getResource(ResolveContext<Object> ctx, String path, ResourceContext rCtx, Resource parent) {
-                return null;
-            }
-
-            @Override
-            public Iterator<Resource> listChildren(ResolveContext<Object> ctx, Resource parent) {
-                return null;
-            }
-        };
-
-        List<ResourceProviderHandler> handlers = asList(createRPHandler(rp, "rp1", 0, "/"));
-        resourceProviderTracker = mock(ResourceProviderTracker.class);
-        ResourceProviderStorage storage = new ResourceProviderStorage(handlers);
-        when(resourceProviderTracker.getResourceProviderStorage()).thenReturn(storage);
-        ResourceResolverFactoryActivator activator = new ResourceResolverFactoryActivator();
-        activator.resourceProviderTracker = resourceProviderTracker;
-        activator.resourceAccessSecurityTracker = new ResourceAccessSecurityTracker();
-        commonFactory = new CommonResourceResolverFactoryImpl(activator);
-        resFac = new ResourceResolverFactoryImpl(commonFactory, /* TODO: using Bundle */ null, null);
-        resResolver = resFac.getAdministrativeResourceResolver(null);
-    }
-
-    @SuppressWarnings("deprecation")
-    @Test public void testClose() throws Exception {
-        final ResourceResolver rr = new ResourceResolverImpl(commonFactory, false, null, resourceProviderTracker);
-        assertTrue(rr.isLive());
-        rr.close();
-        assertFalse(rr.isLive());
-        // close is always allowed to be called
-        rr.close();
-        assertFalse(rr.isLive());
-        // now check all public method - they should all throw!
-        try {
-            rr.adaptTo(Session.class);
-            fail();
-        } catch (final IllegalStateException ise) {
-            // expected
-        }
-        try {
-            rr.clone(null);
-            fail();
-        } catch (final IllegalStateException ise) {
-            // expected
-        }
-        try {
-            rr.findResources("a", "b");
-            fail();
-        } catch (final IllegalStateException ise) {
-            // expected
-        }
-        try {
-            rr.getAttribute("a");
-            fail();
-        } catch (final IllegalStateException ise) {
-            // expected
-        }
-        try {
-            rr.getAttributeNames();
-            fail();
-        } catch (final IllegalStateException ise) {
-            // expected
-        }
-        try {
-            rr.getResource(null);
-            fail();
-        } catch (final IllegalStateException ise) {
-            // expected
-        }
-        try {
-            rr.getResource(null, "/a");
-            fail();
-        } catch (final IllegalStateException ise) {
-            // expected
-        }
-        try {
-            rr.getSearchPath();
-            fail();
-        } catch (final IllegalStateException ise) {
-            // expected
-        }
-        try {
-            rr.getUserID();
-            fail();
-        } catch (final IllegalStateException ise) {
-            // expected
-        }
-        try {
-            rr.listChildren(null);
-            fail();
-        } catch (final IllegalStateException ise) {
-            // expected
-        }
-        try {
-            rr.map("/somepath");
-            fail();
-        } catch (final IllegalStateException ise) {
-            // expected
-        }
-        try {
-            rr.map(null, "/somepath");
-            fail();
-        } catch (final IllegalStateException ise) {
-            // expected
-        }
-        try {
-            rr.queryResources("a", "b");
-            fail();
-        } catch (final IllegalStateException ise) {
-            // expected
-        }
-        try {
-            rr.resolve((HttpServletRequest)null);
-            fail();
-        } catch (final IllegalStateException ise) {
-            // expected
-        }
-        try {
-            rr.resolve("/path");
-            fail();
-        } catch (final IllegalStateException ise) {
-            // expected
-        }
-        try {
-            rr.resolve(null, "/path");
-            fail();
-        } catch (final IllegalStateException ise) {
-            // expected
-        }
-    }
-
-    @SuppressWarnings("deprecation")
-    @Test
-    public void testCloseWithStackTraceLogging() throws Exception {
-        ResourceResolverFactoryActivator rrfa = spy(new ResourceResolverFactoryActivator());
-        Whitebox.setInternalState(rrfa, "logResourceResolverClosing", true);
-        CommonResourceResolverFactoryImpl crrfi = new CommonResourceResolverFactoryImpl(rrfa);
-        final ResourceResolver rr = new ResourceResolverImpl(crrfi, false, null, resourceProviderTracker);
-        assertTrue(rr.isLive());
-        rr.close();
-        assertFalse(rr.isLive());
-        // close is always allowed to be called
-        rr.close();
-        assertFalse(rr.isLive());
-        // now check all public method - they should all throw!
-        try {
-            rr.adaptTo(Session.class);
-            fail();
-        } catch (final IllegalStateException ise) {
-            // expected
-        }
-        try {
-            rr.clone(null);
-            fail();
-        } catch (final IllegalStateException ise) {
-            // expected
-        }
-        try {
-            rr.findResources("a", "b");
-            fail();
-        } catch (final IllegalStateException ise) {
-            // expected
-        }
-        try {
-            rr.getAttribute("a");
-            fail();
-        } catch (final IllegalStateException ise) {
-            // expected
-        }
-        try {
-            rr.getAttributeNames();
-            fail();
-        } catch (final IllegalStateException ise) {
-            // expected
-        }
-        try {
-            rr.getResource(null);
-            fail();
-        } catch (final IllegalStateException ise) {
-            // expected
-        }
-        try {
-            rr.getResource(null, "/a");
-            fail();
-        } catch (final IllegalStateException ise) {
-            // expected
-        }
-        try {
-            rr.getSearchPath();
-            fail();
-        } catch (final IllegalStateException ise) {
-            // expected
-        }
-        try {
-            rr.getUserID();
-            fail();
-        } catch (final IllegalStateException ise) {
-            // expected
-        }
-        try {
-            rr.listChildren(null);
-            fail();
-        } catch (final IllegalStateException ise) {
-            // expected
-        }
-        try {
-            rr.map("/somepath");
-            fail();
-        } catch (final IllegalStateException ise) {
-            // expected
-        }
-        try {
-            rr.map(null, "/somepath");
-            fail();
-        } catch (final IllegalStateException ise) {
-            // expected
-        }
-        try {
-            rr.queryResources("a", "b");
-            fail();
-        } catch (final IllegalStateException ise) {
-            // expected
-        }
-        try {
-            rr.resolve((HttpServletRequest)null);
-            fail();
-        } catch (final IllegalStateException ise) {
-            // expected
-        }
-        try {
-            rr.resolve("/path");
-            fail();
-        } catch (final IllegalStateException ise) {
-            // expected
-        }
-        try {
-            rr.resolve(null, "/path");
-            fail();
-        } catch (final IllegalStateException ise) {
-            // expected
-        }
-    }
-
-    @SuppressWarnings("deprecation")
-    @Test public void testBasicAPIAssumptions() throws Exception {
-
-        // null resource is accessing /, which exists of course
-        final Resource res00 = resResolver.resolve((String) null);
-        assertNotNull(res00);
-        assertTrue("Resource must be NonExistingResource",
-                res00 instanceof NonExistingResource);
-        assertEquals("Null path is expected to return root", "/",
-                res00.getPath());
-
-        // relative paths are treated as if absolute
-        final String path01 = "relPath/relPath";
-        final Resource res01 = resResolver.resolve(path01);
-        assertNotNull(res01);
-        assertEquals("Expecting absolute path for relative path", "/" + path01,
-                res01.getPath());
-        assertTrue("Resource must be NonExistingResource",
-                res01 instanceof NonExistingResource);
-
-        final String no_resource_path = "/no_resource/at/this/location";
-        final Resource res02 = resResolver.resolve(no_resource_path);
-        assertNotNull(res02);
-        assertEquals("Expecting absolute path for relative path",
-                no_resource_path, res02.getPath());
-        assertTrue("Resource must be NonExistingResource",
-                res01 instanceof NonExistingResource);
-
-        try {
-            resResolver.resolve((HttpServletRequest) null);
-            fail("Expected NullPointerException trying to resolve null request");
-        } catch (NullPointerException npe) {
-            // expected
-        }
-
-        final Resource res0 = resResolver.resolve(null, no_resource_path);
-        assertNotNull("Expecting resource if resolution fails", res0);
-        assertTrue("Resource must be NonExistingResource",
-                res0 instanceof NonExistingResource);
-        assertEquals("Path must be the original path", no_resource_path,
-                res0.getPath());
-
-        final HttpServletRequest req1 = mock(HttpServletRequest.class);
-        when(req1.getProtocol()).thenReturn("http");
-        when(req1.getServerName()).thenReturn("localhost");
-        when(req1.getPathInfo()).thenReturn(no_resource_path);
-
-        final Resource res1 = resResolver.resolve(req1);
-        assertNotNull("Expecting resource if resolution fails", res1);
-        assertTrue("Resource must be NonExistingResource",
-                res1 instanceof NonExistingResource);
-        assertEquals("Path must be the original path", no_resource_path,
-                res1.getPath());
-
-        final HttpServletRequest req2 = mock(HttpServletRequest.class);
-        when(req2.getProtocol()).thenReturn("http");
-        when(req2.getServerName()).thenReturn("localhost");
-        when(req2.getPathInfo()).thenReturn(null);
-        final Resource res2 = resResolver.resolve(req2);
-        assertNotNull("Expecting resource if resolution fails", res2);
-        assertTrue("Resource must be NonExistingResource",
-                res2 instanceof NonExistingResource);
-        assertEquals("Path must be the the root path", "/", res2.getPath());
-
-        final Resource res3 = resResolver.getResource(null);
-        assertNull("Expected null resource for null path", res3);
-
-        final Resource res4 = resResolver.getResource(null, null);
-        assertNull("Expected null resource for null path", res4);
-
-        final Resource res5 = resResolver.getResource(res01, null);
-        assertNull("Expected null resource for null path", res5);
-    }
-
-    @Test public void test_clone_based_on_anonymous() throws Exception {
-        final ResourceResolver anon0 = resFac.getResourceResolver((Map<String, Object>) null);
-        // no session
-        final Session anon0Session = anon0.adaptTo(Session.class);
-        assertNull("Session should not be available", anon0Session);
-        // no user information, so user id is null
-        assertEquals(null, anon0.getUserID());
-
-        // same user and workspace
-        final ResourceResolver anon1 = anon0.clone(null);
-        final Session anon1Session = anon1.adaptTo(Session.class);
-        assertEquals(anon0.getUserID(), anon1.getUserID());
-        assertNull("Session should not be available", anon1Session);
-        anon1.close();
-
-        // same workspace but admin user
-        final Map<String, Object> admin0Cred = new HashMap<String, Object>();
-        admin0Cred.put(ResourceResolverFactory.USER, "admin");
-        admin0Cred.put(ResourceResolverFactory.PASSWORD, "admin".toCharArray());
-        final ResourceResolver admin0 = anon0.clone(admin0Cred);
-        assertEquals("admin", admin0.getUserID());
-        admin0.close();
-
-        anon0.close();
-    }
-
-    @Test public void test_clone_based_on_admin() throws Exception {
-        final ResourceResolver admin0 = resFac.getAdministrativeResourceResolver((Map<String, Object>) null);
-        // no user information, so user id is null
-        assertEquals(null, admin0.getUserID());
-
-        // same user and workspace
-        final ResourceResolver admin1 = admin0.clone(null);
-        assertEquals(admin0.getUserID(), admin1.getUserID());
-        admin1.close();
-
-        // same workspace but anonymous user
-        final Map<String, Object> anon0Cred = new HashMap<String, Object>();
-        anon0Cred.put(ResourceResolverFactory.USER, "anonymous");
-        final ResourceResolver anon0 = admin0.clone(anon0Cred);
-        assertEquals("anonymous", anon0.getUserID());
-        anon0.close();
-
-        admin0.close();
-    }
-
-    @Test public void test_attributes_from_authInfo() throws Exception {
-        final Map<String, Object> authInfo = new HashMap<String, Object>();
-        authInfo.put(ResourceResolverFactory.USER, "admin");
-        authInfo.put(ResourceResolverFactory.PASSWORD, "admin".toCharArray());
-        authInfo.put("testAttributeString", "AStringValue");
-        authInfo.put("testAttributeNumber", 999);
-        final ResourceResolver rr = resFac.getResourceResolver(authInfo);
-
-        assertEquals("AStringValue", rr.getAttribute("testAttributeString"));
-        assertEquals(999, rr.getAttribute("testAttributeNumber"));
-        assertEquals("admin", rr.getAttribute(ResourceResolverFactory.USER));
-        assertNull(rr.getAttribute(ResourceResolverFactory.PASSWORD));
-
-        final HashSet<String> validNames = new HashSet<String>();
-        validNames.add(ResourceResolverFactory.USER);
-        validNames.add("testAttributeString");
-        validNames.add("testAttributeNumber");
-        final Iterator<String> names = rr.getAttributeNames();
-        assertTrue(validNames.remove(names.next()));
-        assertTrue(validNames.remove(names.next()));
-        assertTrue(validNames.remove(names.next()));
-        assertFalse("Expect no more names", names.hasNext());
-        assertTrue("Expect validNames set to be empty now",
-                validNames.isEmpty());
-
-        rr.close();
-    }
-
-    @Test public void testBasicCrud() throws Exception {
-        final Resource r = mock(Resource.class);
-        when(r.getPath()).thenReturn("/some");
-        try {
-            this.resResolver.create(null, "a", null);
-            fail("Null parent resource should throw NPE");
-        } catch (final NullPointerException npe) {
-            // correct
-        }
-        try {
-            this.resResolver.create(r, null, null);
-            fail("Null name should throw NPE");
-        } catch (final NullPointerException npe) {
-            // correct
-        }
-        try {
-            this.resResolver.create(r, "a/b", null);
-            fail("Slash in name should throw illegal argument exception");
-        } catch (final IllegalArgumentException pe) {
-            // correct
-        }
-        try {
-            this.resResolver.create(r, "a", null);
-            fail("This should be unsupported.");
-        } catch (final PersistenceException uoe) {
-            // correct
-        }
-    }
-
-    @Test public void test_getResourceSuperType() {
-        final PathBasedResourceResolverImpl resolver = getPathBasedResourceResolver();
-
-        // the resources to test
-        final Resource r = resolver.add(new SyntheticResource(resolver, "/a", "a:b"));
-        final Resource r2 = resolver.add(new SyntheticResource(resolver, "/a2", "a:c"));
-        resolver.add(new SyntheticResourceWithSupertype(resolver, "/a/b", "x:y", "t:c"));
-
-        assertEquals("t:c", resolver.getParentResourceType(r.getResourceType()));
-        assertNull(resolver.getParentResourceType(r2.getResourceType()));
-    }
-
-    @Test public void testIsResourceType() {
-        final PathBasedResourceResolverImpl resolver = getPathBasedResourceResolver();
-
-        final Resource r = resolver.add(new SyntheticResourceWithSupertype(resolver, "/a", "a:b", "d:e"));
-        resolver.add(new SyntheticResourceWithSupertype(resolver, "/d/e", "x:y", "t:c"));
-
-        assertTrue(resolver.isResourceType(r, "a:b"));
-        assertTrue(resolver.isResourceType(r, "d:e"));
-        assertFalse(resolver.isResourceType(r, "x:y"));
-        assertTrue(resolver.isResourceType(r, "t:c"));
-        assertFalse(resolver.isResourceType(r, "h:p"));
-    }
-
-    @Test public void testIsResourceTypeWithPaths() {
-        final PathBasedResourceResolverImpl resolver = getPathBasedResourceResolver();
-
-        /**
-         * prepare resource type hierarchy
-         * /types/1
-         *  +- /types/2
-         *    +- /types/3
-         */
-        resolver.add(new SyntheticResourceWithSupertype(resolver, "/types/1", "/types/component", "/types/2"));
-        resolver.add(new SyntheticResourceWithSupertype(resolver, "/types/2", "/types/component", "/types/3"));
-        resolver.add(new SyntheticResource(resolver, "/types/3", "/types/component"));
-
-        Resource resourceT1 = resolver.add(new SyntheticResource(resolver, "/resourceT1", "/types/1"));
-        Resource resourceT2 = resolver.add(new SyntheticResource(resolver, "/resourceT2", "/types/2"));
-        Resource resourceT3 = resolver.add(new SyntheticResource(resolver, "/resourceT3", "/types/3"));
-
-        assertTrue(resolver.isResourceType(resourceT1, "/types/1"));
-        assertTrue(resolver.isResourceType(resourceT1, "/types/2"));
-        assertTrue(resolver.isResourceType(resourceT1, "/types/3"));
-        assertFalse(resolver.isResourceType(resourceT1, "/types/component"));
-        assertFalse(resolver.isResourceType(resourceT1, "/types/unknown"));
-
-        assertFalse(resolver.isResourceType(resourceT2, "/types/1"));
-        assertTrue(resolver.isResourceType(resourceT2, "/types/2"));
-        assertTrue(resolver.isResourceType(resourceT2, "/types/3"));
-        assertFalse(resolver.isResourceType(resourceT2, "/types/component"));
-        assertFalse(resolver.isResourceType(resourceT2, "/types/unknown"));
-
-        assertFalse(resolver.isResourceType(resourceT3, "/types/1"));
-        assertFalse(resolver.isResourceType(resourceT3, "/types/2"));
-        assertTrue(resolver.isResourceType(resourceT3, "/types/3"));
-        assertFalse(resolver.isResourceType(resourceT3, "/types/component"));
-        assertFalse(resolver.isResourceType(resourceT3, "/types/unknown"));
-    }
-
-    @Test(expected=SlingException.class)  public void testIsResourceCyclicHierarchyDirect() {
-        final PathBasedResourceResolverImpl resolver = getPathBasedResourceResolver();
-
-        /**
-         * prepare resource type hierarchy
-         * /types/1  <---+
-         *  +- /types/2 -+
-         */
-        resolver.add(new SyntheticResourceWithSupertype(resolver, "/types/1", "/types/component", "/types/2"));
-        resolver.add(new SyntheticResourceWithSupertype(resolver, "/types/2", "/types/component", "/types/1"));
-
-        Resource resource = resolver.add(new SyntheticResource(resolver, "/resourceT1", "/types/1"));
-
-        assertTrue(resolver.isResourceType(resource, "/types/1"));
-        assertTrue(resolver.isResourceType(resource, "/types/2"));
-
-        // this should throw a SlingException when detecting the cyclic hierarchy
-        resolver.isResourceType(resource, "/types/unknown");
-    }
-
-    @Test(expected=SlingException.class) public void testIsResourceCyclicHierarchyIndirect() {
-        final PathBasedResourceResolverImpl resolver = getPathBasedResourceResolver();
-
-        /**
-         * prepare resource type hierarchy
-         * /types/1   <----+
-         *  +- /types/2    |
-         *    +- /types/3 -+
-         */
-        resolver.add(new SyntheticResourceWithSupertype(resolver, "/types/1", "/types/component", "/types/2"));
-        resolver.add(new SyntheticResourceWithSupertype(resolver, "/types/2", "/types/component", "/types/3"));
-        resolver.add(new SyntheticResourceWithSupertype(resolver, "/types/3", "/types/component", "/types/1"));
-
-        Resource resource = resolver.add(new SyntheticResource(resolver, "/resourceT1", "/types/1"));
-
-        assertTrue(resolver.isResourceType(resource, "/types/1"));
-        assertTrue(resolver.isResourceType(resource, "/types/2"));
-        assertTrue(resolver.isResourceType(resource, "/types/3"));
-
-        // this should throw a SlingException when detecting the cyclic hierarchy
-        resolver.isResourceType(resource, "/types/unknown");
-    }
-
-    private PathBasedResourceResolverImpl getPathBasedResourceResolver() {
-        try {
-            final List<ResourceResolver> resolvers = new ArrayList<ResourceResolver>();
-            final PathBasedResourceResolverImpl resolver = new PathBasedResourceResolverImpl(resolvers, resourceProviderTracker);
-            resolvers.add(resolver);
-            return resolver;
-        }
-        catch (LoginException ex) {
-            throw new RuntimeException(ex);
-        }
-    }
-
-    private static class PathBasedResourceResolverImpl extends ResourceResolverImpl {
-
-        private final Map<String, Resource> resources = new HashMap<String, Resource>();
-
-        public PathBasedResourceResolverImpl(final List<ResourceResolver> resolvers, final ResourceProviderTracker resourceProviderTracker) throws LoginException {
-            this(new CommonResourceResolverFactoryImpl(new ResourceResolverFactoryActivator()) {
-                @Override
-                public ResourceResolver getAdministrativeResourceResolver(
-                        Map<String, Object> authenticationInfo) throws LoginException {
-                    return resolvers.get(0);
-                }
-            }, resourceProviderTracker);
-        }
-
-        public PathBasedResourceResolverImpl(CommonResourceResolverFactoryImpl factory, ResourceProviderTracker resourceProviderTracker) throws LoginException {
-            super(factory, false, null, resourceProviderTracker);
-        }
-
-        public Resource add(final Resource r) {
-            this.resources.put(r.getPath(), r);
-            return r;
-        }
-
-        @Override
-        public String[] getSearchPath() {
-            return new String[] {""};
-        }
-
-        @Override
-        public Resource getResource(final String path) {
-            final String p = (path.startsWith("/") ? path : "/" + path);
-            return this.resources.get(p);
-        }
-    }
-
-    private static class SyntheticResourceWithSupertype extends SyntheticResource {
-
-        private final String resourceSuperType;
-
-        public SyntheticResourceWithSupertype(ResourceResolver resourceResolver, String path,
-                String resourceType, String resourceSuperType) {
-            super(resourceResolver, path, resourceType);
-            this.resourceSuperType = resourceSuperType;
-        }
-
-        @Override
-        public String getResourceSuperType() {
-            return this.resourceSuperType;
-        }
-
-    }
-
-}
diff --git a/src/test/java/org/apache/sling/resourceresolver/impl/ResourceResolverMangleNamespacesTest.java b/src/test/java/org/apache/sling/resourceresolver/impl/ResourceResolverMangleNamespacesTest.java
deleted file mode 100644
index f994979..0000000
--- a/src/test/java/org/apache/sling/resourceresolver/impl/ResourceResolverMangleNamespacesTest.java
+++ /dev/null
@@ -1,163 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *   http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-package org.apache.sling.resourceresolver.impl;
-
-import static org.junit.Assert.assertEquals;
-
-import java.util.Arrays;
-import java.util.Iterator;
-
-import javax.annotation.CheckForNull;
-import javax.annotation.Nonnull;
-import javax.jcr.RepositoryException;
-import javax.jcr.Session;
-
-import org.apache.commons.collections.IteratorUtils;
-import org.apache.sling.api.resource.LoginException;
-import org.apache.sling.api.resource.Resource;
-import org.apache.sling.resourceresolver.impl.providers.ResourceProviderStorage;
-import org.apache.sling.resourceresolver.impl.providers.ResourceProviderStorageProvider;
-import org.apache.sling.spi.resource.provider.ResolveContext;
-import org.apache.sling.spi.resource.provider.ResourceContext;
-import org.apache.sling.spi.resource.provider.ResourceProvider;
-import org.junit.Before;
-import org.junit.Test;
-import org.mockito.Mock;
-import org.mockito.Mockito;
-import org.mockito.MockitoAnnotations;
-
-/** Test ResourceResolverImpl.mangleNamespaces methods */
-public class ResourceResolverMangleNamespacesTest {
-    private ResourceResolverImpl rr;
-
-    @Mock
-    private Session mockedSession;
-
-    private Session activeSession;
-
-    public static final String NS_PREFIX = "testNS";
-    public static final String NS_URL = "http://example.com/namespaces/testNS";
-
-    @Before
-    public void setup() throws RepositoryException, LoginException {
-        MockitoAnnotations.initMocks(this);
-        activeSession = mockedSession;
-
-        // Setup a ResourceResolverImpl with namespace mangling and unmangling
-        final ResourceResolverFactoryActivator act = new ResourceResolverFactoryActivator() {
-            @Override
-            public boolean isMangleNamespacePrefixes() {
-                return true;
-            }
-        };
-
-        Mockito.when(mockedSession.getNamespacePrefix(NS_PREFIX)).thenReturn(NS_URL);
-
-        final ResourceProvider<?> rp = new ResourceProvider<Object>() {
-
-            @SuppressWarnings("unchecked")
-            @Override
-            public @CheckForNull <AdapterType> AdapterType adaptTo(final  @Nonnull ResolveContext<Object> ctx,
-                    final @Nonnull Class<AdapterType> type) {
-                if (type.equals(Session.class)) {
-                    return (AdapterType) activeSession;
-                } else {
-                    return null;
-                }
-            }
-
-            @Override
-            public Resource getResource(ResolveContext<Object> ctx, String path, ResourceContext rCtx, Resource parent) {
-                return null;
-            }
-
-            @SuppressWarnings("unchecked")
-            @Override
-            public Iterator<Resource> listChildren(ResolveContext<Object> ctx, Resource parent) {
-                return IteratorUtils.emptyIterator();
-            }
-        };
-
-        final CommonResourceResolverFactoryImpl fac = new CommonResourceResolverFactoryImpl(act);
-
-        rr = new ResourceResolverImpl(fac, false, null, new ResourceProviderStorageProvider() {
-            
-            @Override
-            public ResourceProviderStorage getResourceProviderStorage() {
-                return new ResourceProviderStorage(Arrays.asList(MockedResourceResolverImplTest.createRPHandler(rp, "rp1", 0, "/")));
-            }
-        });
-    }
-
-    @Test
-    public void testUrlWithPath() {
-        assertEquals("http://example.com/some/path", rr.map("http://example.com/some/path"));
-    }
-
-    @Test
-    public void testMangleHttp() {
-        assertEquals("http://example.com/path/_with_colon", rr.map("http://example.com/path/with:colon"));
-    }
-
-    @Test
-    public void testUnmangleHttp() {
-        final Resource r = rr.resolve(null, "http://example.com/path/_with_mangling");
-        assertEquals("/http://example.com/path/with:mangling", r.getPath());
-    }
-
-    @Test
-    public void testUnmangleNoSession() {
-        activeSession = null;
-        final Resource r = rr.resolve(null, "http://example.com/path/_with_mangling");
-        assertEquals("/http://example.com/path/_with_mangling", r.getPath());
-    }
-
-    @Test
-    public void testManglePath() {
-        assertEquals("/example.com/path/_with_colon", rr.map("/example.com/path/with:colon"));
-    }
-
-    @Test
-    public void testUnmanglePath() {
-        final Resource r = rr.resolve(null, "/example.com/path/_with_mangling");
-        assertEquals("/example.com/path/with:mangling", r.getPath());
-    }
-
-    @Test
-    public void testUrlNoPath() {
-        assertEquals("http://withSlash.com/", rr.map("http://withSlash.com/"));
-        assertEquals("http://noSlash.com", rr.map("http://noSlash.com"));
-        assertEquals("http://nosuffix", rr.map("http://nosuffix"));
-    }
-
-    @Test
-    public void testWeirdCases() {
-        assertEquals("http://foo", rr.map("http://foo"));
-        assertEquals("http://", rr.map("http://"));
-        assertEquals("http:/", rr.map("http:/"));
-        assertEquals("http:", rr.map("http:"));
-        assertEquals("http", rr.map("http"));
-
-        assertEquals("gopher://foo", rr.map("gopher://foo"));
-        assertEquals("gopher://", rr.map("gopher://"));
-        assertEquals("gopher:/", rr.map("gopher:/"));
-        assertEquals("gopher:", rr.map("gopher:"));
-        assertEquals("gopher", rr.map("gopher"));
-    }
-}
diff --git a/src/test/java/org/apache/sling/resourceresolver/impl/SimpleValueMapImpl.java b/src/test/java/org/apache/sling/resourceresolver/impl/SimpleValueMapImpl.java
deleted file mode 100644
index f1ed9c1..0000000
--- a/src/test/java/org/apache/sling/resourceresolver/impl/SimpleValueMapImpl.java
+++ /dev/null
@@ -1,100 +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 SF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations under the License.
- */
-package org.apache.sling.resourceresolver.impl;
-
-import java.util.Collection;
-import java.util.HashMap;
-import java.util.Map;
-import java.util.Set;
-
-import org.apache.sling.api.resource.ValueMap;
-
-public class SimpleValueMapImpl implements ValueMap {
-
-    private Map<String, Object> delegate;
-
-    public SimpleValueMapImpl() {
-        delegate = new HashMap<String, Object>();
-    }
-
-    public void clear() {
-        delegate.clear();
-    }
-
-    public boolean containsKey(Object key) {
-        return delegate.containsKey(key);
-    }
-
-    public boolean containsValue(Object value) {
-        return delegate.containsValue(value);
-    }
-
-    public Set<java.util.Map.Entry<String, Object>> entrySet() {
-        return delegate.entrySet();
-    }
-
-    public Object get(Object key) {
-        return delegate.get(key);
-    }
-
-    public boolean isEmpty() {
-        return delegate.isEmpty();
-    }
-
-    public Set<String> keySet() {
-        return delegate.keySet();
-    }
-
-    public Object put(String key, Object value) {
-        return delegate.put(key, value);
-    }
-
-    public void putAll(Map<? extends String, ? extends Object> m) {
-        delegate.putAll(m);
-    }
-
-    public Object remove(Object key) {
-        return delegate.remove(key);
-    }
-
-    public int size() {
-        return delegate.size();
-    }
-
-    public Collection<Object> values() {
-        return delegate.values();
-    }
-
-    @SuppressWarnings("unchecked")
-    public <T> T get(String name, Class<T> type) {
-        Object o = delegate.get(name);
-        if ( type.equals(String[].class) && ! ( o instanceof String[])) {
-            o = new String[] { String.valueOf(o) };
-        }
-        return (T) o;
-    }
-
-    @SuppressWarnings("unchecked")
-    public <T> T get(String name, T defaultValue) {
-        if ( delegate.containsKey(name)) {
-            return (T) delegate.get(name);
-        } 
-        return defaultValue;
-    }
-
-}
diff --git a/src/test/java/org/apache/sling/resourceresolver/impl/helper/RedirectResourceTest.java b/src/test/java/org/apache/sling/resourceresolver/impl/helper/RedirectResourceTest.java
deleted file mode 100644
index 2c6292d..0000000
--- a/src/test/java/org/apache/sling/resourceresolver/impl/helper/RedirectResourceTest.java
+++ /dev/null
@@ -1,60 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *   http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-package org.apache.sling.resourceresolver.impl.helper;
-
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertNotNull;
-import static org.junit.Assert.assertNull;
-
-import java.util.Map;
-
-import org.apache.sling.api.resource.PersistableValueMap;
-import org.apache.sling.api.resource.ValueMap;
-import org.junit.Test;
-
-@SuppressWarnings("deprecation")
-public class RedirectResourceTest {
-
-    @Test public void testRedirectResource() {
-
-        final String path = "/redir/path";
-        final String target = "/redir/target";
-        final int status = 999;
-        final RedirectResource res = new RedirectResource(null, path, target,
-            status);
-
-        assertEquals(path, res.getPath());
-        assertEquals(RedirectResource.RT_SLING_REDIRECT, res.getResourceType());
-
-        final Map<?, ?> map = res.adaptTo(Map.class);
-        assertNotNull("Expected Map adapter", map);
-        assertEquals(target, map.get(RedirectResource.PROP_SLING_TARGET));
-        assertEquals(status, ((Integer) map.get(RedirectResource.PROP_SLING_STATUS)).intValue());
-
-        final ValueMap valueMap = res.adaptTo(ValueMap.class);
-        assertNotNull("Expected ValueMap adapter", valueMap);
-        assertEquals(target, valueMap.get(RedirectResource.PROP_SLING_TARGET));
-        assertEquals(status, ((Integer) valueMap.get(RedirectResource.PROP_SLING_STATUS)).intValue());
-        assertEquals(status, valueMap.get(RedirectResource.PROP_SLING_STATUS, Integer.class).intValue());
-
-        final PersistableValueMap persistableValueMap = res.adaptTo(PersistableValueMap.class);
-        assertNull("Unexpected PersistableValueMap adapter",
-            persistableValueMap);
-    }
-}
diff --git a/src/test/java/org/apache/sling/resourceresolver/impl/helper/ResourcePathIteratorTest.java b/src/test/java/org/apache/sling/resourceresolver/impl/helper/ResourcePathIteratorTest.java
deleted file mode 100644
index d70ffd7..0000000
--- a/src/test/java/org/apache/sling/resourceresolver/impl/helper/ResourcePathIteratorTest.java
+++ /dev/null
@@ -1,155 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *   http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-package org.apache.sling.resourceresolver.impl.helper;
-
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertFalse;
-import static org.junit.Assert.assertTrue;
-import static org.junit.Assert.fail;
-
-import java.util.Iterator;
-import java.util.NoSuchElementException;
-
-import org.junit.Test;
-
-public class ResourcePathIteratorTest {
-
-    @Test public void testNull() {
-        ResourcePathIterator rpi = new ResourcePathIterator(null);
-        assertFinished(rpi);
-    }
-
-    @Test public void testEmpty() {
-        ResourcePathIterator rpi = new ResourcePathIterator("");
-        assertFinished(rpi);
-    }
-
-    @Test public void testRoot() {
-        ResourcePathIterator rpi = new ResourcePathIterator("/");
-        assertNext("/", rpi);
-        assertFinished(rpi);
-    }
-
-    @Test public void testSlashed() {
-        ResourcePathIterator rpi = new ResourcePathIterator("/root/child");
-        assertNext("/root/child", rpi);
-        assertFinished(rpi);
-    }
-
-    @Test public void testSlashedTrailingSlash1() {
-        ResourcePathIterator rpi = new ResourcePathIterator("/root/child/");
-        assertNext("/root/child", rpi);
-        assertFinished(rpi);
-    }
-
-    @Test public void testSlashedTrailingSlash2() {
-        ResourcePathIterator rpi = new ResourcePathIterator("/root/child//");
-        assertNext("/root/child", rpi);
-        assertFinished(rpi);
-    }
-
-    @Test public void testDotted() {
-        ResourcePathIterator rpi = new ResourcePathIterator("/root.child");
-        assertNext("/root.child", rpi);
-        assertNext("/root", rpi);
-        assertFinished(rpi);
-    }
-
-    @Test public void testMixed() {
-        ResourcePathIterator rpi = new ResourcePathIterator(
-            "/root/child.print.a4.html/with/suffix");
-        assertNext("/root/child.print.a4.html/with/suffix", rpi);
-        assertNext("/root/child.print.a4", rpi);
-        assertNext("/root/child.print", rpi);
-        assertNext("/root/child", rpi);
-        assertFinished(rpi);
-    }
-
-    @Test public void testNoSeparators() {
-        final Iterator<String> rpi = new ResourcePathIterator(
-            "MickeyMouseWasHere");
-        assertNext("MickeyMouseWasHere", rpi);
-        assertFinished(rpi);
-    }
-
-    @Test public void testGetA() {
-        final Iterator<String> rpi = new ResourcePathIterator(
-            "/some/stuff/more.a4.html");
-        assertNext("/some/stuff/more.a4.html", rpi);
-        assertNext("/some/stuff/more.a4", rpi);
-        assertNext("/some/stuff/more", rpi);
-        assertFinished(rpi);
-    }
-
-    @Test public void testGetB() {
-        final Iterator<String> rpi = new ResourcePathIterator(
-            "/some/stuff/more.html");
-        assertNext("/some/stuff/more.html", rpi);
-        assertNext("/some/stuff/more", rpi);
-        assertFinished(rpi);
-    }
-
-    @Test public void testHeadB() {
-        final Iterator<String> rpi = new ResourcePathIterator(
-            "/some/stuff/more.html");
-        assertNext("/some/stuff/more.html", rpi);
-        assertNext("/some/stuff/more", rpi);
-        assertFinished(rpi);
-    }
-
-    @Test public void testGetC() {
-        final Iterator<String> it = new ResourcePathIterator("/some/stuff/more");
-        assertNext("/some/stuff/more", it);
-        assertFinished(it);
-    }
-
-    @Test public void testGetD() {
-        final Iterator<String> it = new ResourcePathIterator(
-            "/some/stuff.print/more.html");
-        assertNext("/some/stuff.print/more.html", it);
-        assertNext("/some/stuff.print/more", it);
-        assertNext("/some/stuff", it);
-        assertFinished(it);
-    }
-
-    @Test public void testRelativePathGet() {
-        final Iterator<String> it = new ResourcePathIterator("some/stuff.print");
-        assertNext("some/stuff.print", it);
-        assertNext("some/stuff", it);
-        assertFinished(it);
-    }
-
-    private void assertNext(String expected, Iterator<String> iterator) {
-        assertTrue("Iterator must have next", iterator.hasNext());
-        assertEquals("Incorrect next value", expected, iterator.next());
-    }
-
-    private void assertFinished(Iterator<String> iterator) {
-
-        assertFalse("Iterator must not have next", iterator.hasNext());
-
-        try {
-            iterator.next();
-            fail("Iterator should throw NoSuchElementException");
-        } catch (NoSuchElementException nsee) {
-            // expected
-        }
-
-    }
-}
\ No newline at end of file
diff --git a/src/test/java/org/apache/sling/resourceresolver/impl/helper/ResourceResolverControlTest.java b/src/test/java/org/apache/sling/resourceresolver/impl/helper/ResourceResolverControlTest.java
deleted file mode 100644
index 40dc392..0000000
--- a/src/test/java/org/apache/sling/resourceresolver/impl/helper/ResourceResolverControlTest.java
+++ /dev/null
@@ -1,456 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *   http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-package org.apache.sling.resourceresolver.impl.helper;
-
-import static org.hamcrest.Matchers.arrayContainingInAnyOrder;
-import static org.hamcrest.Matchers.equalTo;
-import static org.hamcrest.Matchers.hasEntry;
-import static org.hamcrest.Matchers.not;
-import static org.hamcrest.Matchers.notNullValue;
-import static org.hamcrest.Matchers.nullValue;
-import static org.junit.Assert.assertNotNull;
-import static org.junit.Assert.assertThat;
-import static org.junit.Assert.assertTrue;
-import static org.mockito.Mockito.mock;
-import static org.mockito.Mockito.verify;
-import static org.mockito.Mockito.when;
-
-import java.util.Arrays;
-import java.util.Collections;
-import java.util.HashMap;
-import java.util.Iterator;
-import java.util.List;
-import java.util.Map;
-
-import org.apache.sling.api.resource.LoginException;
-import org.apache.sling.api.resource.PersistenceException;
-import org.apache.sling.api.resource.Resource;
-import org.apache.sling.api.resource.ResourceMetadata;
-import org.apache.sling.api.resource.ResourceResolver;
-import org.apache.sling.api.resource.ResourceUtil;
-import org.apache.sling.api.resource.ValueMap;
-import org.apache.sling.api.resource.runtime.dto.AuthType;
-import org.apache.sling.resourceresolver.impl.Fixture;
-import org.apache.sling.resourceresolver.impl.ResourceAccessSecurityTracker;
-import org.apache.sling.resourceresolver.impl.SimpleValueMapImpl;
-import org.apache.sling.resourceresolver.impl.providers.ResourceProviderHandler;
-import org.apache.sling.resourceresolver.impl.providers.ResourceProviderInfo;
-import org.apache.sling.resourceresolver.impl.providers.ResourceProviderStorage;
-import org.apache.sling.resourceresolver.impl.providers.ResourceProviderStorageProvider;
-import org.apache.sling.spi.resource.provider.QueryLanguageProvider;
-import org.apache.sling.spi.resource.provider.ResolveContext;
-import org.apache.sling.spi.resource.provider.ResourceContext;
-import org.apache.sling.spi.resource.provider.ResourceProvider;
-import org.apache.sling.testing.mock.osgi.MockOsgi;
-import org.hamcrest.Matchers;
-import org.junit.Before;
-import org.junit.Test;
-import org.mockito.Mockito;
-import org.osgi.framework.BundleContext;
-
-@SuppressWarnings("unchecked")
-public class ResourceResolverControlTest {
-
-    // query language names
-    private static final String QL_MOCK = "MockQueryLanguage";
-    private static final String QL_ANOTHER_MOCK = "AnotherMockQueryLanguage";
-    private static final String QL_NOOP = "NoopQueryLanguage";
-
-    // query definitions
-    private static final String QUERY_MOCK_FIND_ALL = "FIND ALL";
-
-    private ResourceResolverControl crp;
-    private List<ResourceProviderHandler> handlers;
-    private ResourceProvider<Object> subProvider;
-    private Map<String, Object> authInfo;
-    private ResourceProvider<Object> rootProvider;
-    private Resource subProviderResource;
-    private Resource somethingResource;
-    private ResourceResolverContext context;
-
-    @Before
-    public void prepare() throws Exception {
-
-        BundleContext bc = MockOsgi.newBundleContext();
-
-        Fixture fixture = new Fixture(bc);
-
-        // sub-provider
-        subProvider = Mockito.mock(ResourceProvider.class);
-        ResourceProviderInfo info = fixture.registerResourceProvider(subProvider, "/some/path", AuthType.required);
-        ResourceProviderHandler handler = new ResourceProviderHandler(bc, info);
-        when(subProvider.getQueryLanguageProvider()).thenReturn(new SimpleQueryLanguageProvider(QL_MOCK, QL_ANOTHER_MOCK) {
-            @Override
-            public Iterator<ValueMap> queryResources(ResolveContext<Object> ctx, String query, String language) {
-                if ( query.equals(QUERY_MOCK_FIND_ALL) && language.equals(QL_MOCK)) {
-                    SimpleValueMapImpl valueMap = new SimpleValueMapImpl();
-                    valueMap.put("key", "value");
-                    return Collections.<ValueMap> singletonList(valueMap).iterator();
-                }
-
-                throw new UnsupportedOperationException();
-            }
-
-            @Override
-            public Iterator<Resource> findResources(ResolveContext<Object> ctx, String query, String language) {
-
-                if ( query.equals(QUERY_MOCK_FIND_ALL) && language.equals(QL_MOCK)) {
-                    return Collections.<Resource> singletonList(newMockResource("/some/path/object")).iterator();
-                }
-
-                throw new UnsupportedOperationException();
-
-            }
-        });
-        handler.activate();
-
-        rootProvider = mock(ResourceProvider.class);
-        ResourceProviderInfo rootInfo = fixture.registerResourceProvider(rootProvider, "/", AuthType.required);
-        ResourceProviderHandler rootHandler = new ResourceProviderHandler(bc, rootInfo);
-        when(rootProvider.getQueryLanguageProvider()).thenReturn(new SimpleQueryLanguageProvider(QL_NOOP));
-        rootHandler.activate();
-
-        // configure mock resources
-        Resource root = configureResourceAt(rootProvider, "/");
-        somethingResource = configureResourceAt(rootProvider, "/something");
-        subProviderResource = configureResourceAt(subProvider, "/some/path/object");
-
-        // configure query at '/'
-        when(rootProvider.listChildren((ResolveContext<Object>) Mockito.anyObject(), Mockito.eq(root))).thenReturn(Collections.singleton(somethingResource).iterator());
-
-        ResourceResolver rr = mock(ResourceResolver.class);
-        ResourceAccessSecurityTracker securityTracker = Mockito.mock(ResourceAccessSecurityTracker.class);
-        authInfo = Collections.emptyMap();
-
-        handlers = Arrays.asList(rootHandler, handler);
-        final ResourceProviderStorage storage = new ResourceProviderStorage(handlers);
-
-        crp = new ResourceResolverControl(false, authInfo, new ResourceProviderStorageProvider() {
-            
-            @Override
-            public ResourceProviderStorage getResourceProviderStorage() {
-                return storage;
-            }
-        });
-        context = new ResourceResolverContext(rr, securityTracker);
-    }
-
-    /**
-     * Configures the provider to return a mock resource for the specified path
-     * @return
-     */
-    private <T> Resource configureResourceAt(ResourceProvider<T> provider, String path) {
-
-        Resource mockResource = newMockResource(path);
-
-        when(provider.getResource((ResolveContext<T>) Mockito.any(), Mockito.eq(path), (ResourceContext) Mockito.any(), (Resource) Mockito.any()))
-            .thenReturn(mockResource);
-
-        return mockResource;
-    }
-
-    private Resource newMockResource(String path) {
-
-        Resource mockResource = mock(Resource.class);
-        when(mockResource.getPath()).thenReturn(path);
-        when(mockResource.getName()).thenReturn(ResourceUtil.getName(path));
-        when(mockResource.getResourceMetadata()).thenReturn(mock(ResourceMetadata.class));
-        when(mockResource.getChildren()).thenReturn(Collections.<Resource> emptyList());
-
-        return mockResource;
-    }
-
-    /**
-     * Verifies that login and logout calls are invoked as expected on
-     * ResourceProviders with authType = {@link AuthType#required}
-     */
-    @Test
-    public void loginLogout() throws LoginException {
-
-        context.getProviderManager().authenticateAll(handlers, crp);
-
-        verify(subProvider).authenticate(authInfo);
-
-        crp.close();
-
-        verify(subProvider).logout(mockContext());
-    }
-
-    private ResolveContext<Object> mockContext() {
-        return (ResolveContext<Object>) Mockito.any();
-    }
-
-    /**
-     * Verifies that a synthetic resource is returned for a path which holds no
-     * actual resource but is an ancestor of another resource provider
-     */
-    @Test
-    public void getResource_synthetic() {
-
-        Resource resource = crp.getResource(context, "/some", null, null, false);
-
-        assertTrue("Not a syntethic resource : " + resource, ResourceUtil.isSyntheticResource(resource));
-    }
-
-    /**
-     * Verifies that a getResource call for a missing resource returns null
-     */
-    @Test
-    public void getResource_missing() {
-        assertThat(crp.getResource(context, "/nothing", null, null, false), nullValue());
-    }
-
-    /**
-     * Verifies that a resource is returned when it should be
-     */
-    @Test
-    public void getResource_found() {
-        assertThat(crp.getResource(context, "/something", null, null, false), not(nullValue()));
-        assertThat(crp.getResource(context, "/some/path/object", null, null, false), not(nullValue()));
-    }
-
-
-    /**
-     * Verifies that the existing parent of a resource is found
-     */
-    @Test
-    public void getParent_found() {
-        Resource parent = crp.getParent(context, ResourceUtil.getParent(somethingResource.getPath()), somethingResource);
-        assertThat(parent, notNullValue());
-        assertThat("parent.path", parent.getPath(), equalTo("/"));
-    }
-
-
-
-    /**
-     * Verifies that a synthetic parent is returned for a resource without an actual parent
-     */
-    @Test
-    public void getParent_synthetic() {
-        Resource parent = crp.getParent(context, ResourceUtil.getParent(subProviderResource.getPath()), subProviderResource);
-        assertThat(parent, notNullValue());
-        assertTrue("parent is a synthetic resource", ResourceUtil.isSyntheticResource(parent));
-    }
-
-    /**
-     * Test parent from a different provider
-     */
-    @Test
-    public void getParent_differentProviders() {
-        final Resource childResource = mock(Resource.class);
-        when(childResource.getPath()).thenReturn("/some/path");
-        when(subProvider.getResource((ResolveContext<Object>) Mockito.anyObject(), Mockito.eq("/some/path"), (ResourceContext) Mockito.anyObject(), (Resource)Mockito.eq(null))).thenReturn(childResource);
-
-        final Resource parentResource = mock(Resource.class);
-        when(parentResource.getPath()).thenReturn("/some");
-        when(rootProvider.getResource((ResolveContext<Object>) Mockito.anyObject(), Mockito.eq("/some"), (ResourceContext) Mockito.anyObject(), (Resource)Mockito.eq(null))).thenReturn(parentResource);
-
-        Resource child = crp.getResource(context, "/some/path", null, null, false);
-        assertNotNull(child);
-        assertTrue(childResource == child);
-
-        Resource parent = crp.getParent(context, ResourceUtil.getParent(child.getPath()), child);
-        assertNotNull(parent);
-        assertTrue(parentResource == parent);
-    }
-
-    /**
-     * Verifies that listing the children at root lists both the synthetic and the 'real' children
-     */
-    @Test
-    public void listChildren_root() {
-        Resource root = crp.getResource(context, "/", null, null, false);
-        Iterator<Resource> children = crp.listChildren(context, root);
-
-        Map<String, Resource> all = new HashMap<String, Resource>();
-        while ( children.hasNext() ) {
-            Resource child = children.next();
-            all.put(child.getPath(), child);
-        }
-
-        assertThat(all.entrySet(), Matchers.hasSize(2));
-        assertThat("Resource at /something", all.get("/something"), not(nullValue()));
-        assertThat("Resource at /some", all.get("/some"), not(nullValue()));
-    }
-
-    /**
-     * Verifies listing the children at a level below the root
-     */
-    @Test
-    public void listChildren_lowerLevel() {
-
-        Resource root = crp.getResource(context, "/some", null, null, false);
-        Iterator<Resource> children = crp.listChildren(context, root);
-        Map<String, Resource> all = new HashMap<String, Resource>();
-
-        while ( children.hasNext() ) {
-            Resource child = children.next();
-            all.put(child.getPath(), child);
-        }
-
-        assertThat(all.entrySet(), Matchers.hasSize(1));
-        assertThat("Resource at /some/path", all.get("/some/path"), not(nullValue()));
-
-    }
-
-    /**
-     * Verifies copying resources between the same ResourceProvider
-     *
-     * @throws PersistenceException persistence exception
-     */
-    @Test
-    public void copy_sameProvider() throws PersistenceException {
-
-        when(subProvider.copy(mockContext(), Mockito.eq("/some/path/object"), Mockito.eq("/some/path/new")))
-            .thenReturn(true);
-        configureResourceAt(subProvider, "/some/path/new/object");
-        configureResourceAt(subProvider, "/some/path/new");
-
-        Resource resource = crp.copy(context, "/some/path/object", "/some/path/new");
-
-
-        assertThat(resource, not(nullValue()));
-    }
-
-    /**
-     * Verifies copying resources between different ResourceProviders
-     *
-     * @throws PersistenceException persistence exception
-     */
-    @Test
-    public void copy_differentProvider() throws PersistenceException {
-
-        Resource newRes = newMockResource("/object");
-        when(rootProvider.create(mockContext(), Mockito.eq("/object"), Mockito.anyMap()))
-            .thenReturn(newRes);
-
-        Resource resource = crp.copy(context, "/some/path/object", "/");
-
-        assertThat(resource, not(nullValue()));
-    }
-
-    /**
-     * Verifies moving resources between the same ResourceProvider
-     *
-     * @throws PersistenceException persistence exception
-     */
-    @Test
-    public void move_sameProvider() throws PersistenceException {
-
-        when(subProvider.move(mockContext(), Mockito.eq("/some/path/object"), Mockito.eq("/some/path/new")))
-                .thenReturn(true);
-        configureResourceAt(subProvider, "/some/path/new/object");
-        configureResourceAt(subProvider, "/some/path/new");
-
-        Resource resource = crp.move(context, "/some/path/object", "/some/path/new");
-
-        assertThat(resource, not(nullValue()));
-    }
-
-    /**
-     * Verifies moving resources between different ResourceProviders
-     *
-     * @throws PersistenceException persistence exception
-     */
-    @Test
-    public void move_differentProvider() throws PersistenceException {
-
-        Resource newRes = newMockResource("/object");
-        when(rootProvider.create(mockContext(), Mockito.eq("/object"), Mockito.anyMap())).thenReturn(newRes);
-
-        Resource resource = crp.move(context, "/some/path/object", "/");
-
-        assertThat(resource, not(nullValue()));
-
-        verify(subProvider).delete(mockContext(), Mockito.eq(subProviderResource));
-    }
-
-    /**
-     * Verifies listing the query languages
-     */
-    @Test
-    public void queryLanguages() throws PersistenceException {
-
-        assertThat(crp.getSupportedLanguages(context), arrayContainingInAnyOrder(QL_NOOP, QL_MOCK, QL_ANOTHER_MOCK));
-    }
-
-    /**
-     * Verifies running a query
-     */
-    @Test
-    public void queryResources() throws PersistenceException {
-
-        Iterator<Map<String, Object>> queryResources = crp.queryResources(context, QUERY_MOCK_FIND_ALL, QL_MOCK);
-
-        int count = 0;
-
-        while ( queryResources.hasNext() ) {
-            assertThat("ValueMap returned from query", queryResources.next(), hasEntry("key", (Object) "value"));
-            count++;
-        }
-
-        assertThat("query result count", count, Matchers.equalTo(1));
-    }
-
-    /**
-     * Verifies finding resources
-     */
-    @Test
-    public void findResource() throws PersistenceException {
-
-        Iterator<Resource> resources = crp.findResources(context, QUERY_MOCK_FIND_ALL, QL_MOCK);
-
-        int count = 0;
-
-        while ( resources.hasNext() ) {
-            assertThat("resources[0].path", resources.next().getPath(), equalTo("/some/path/object"));
-            count++;
-        }
-
-        assertThat("query result count", count, Matchers.equalTo(1));
-    }
-
-    /**
-     * Simple test-only QueryLanguageProvider
-     *
-     */
-    private static class SimpleQueryLanguageProvider implements QueryLanguageProvider<Object> {
-
-        private final String[] queryLanguages;
-
-        public SimpleQueryLanguageProvider(String... queryLanguages) {
-            this.queryLanguages = queryLanguages;
-        }
-
-        @Override
-        public String[] getSupportedLanguages(ResolveContext<Object> ctx) {
-            return queryLanguages;
-        }
-
-        @Override
-        public Iterator<ValueMap> queryResources(ResolveContext<Object> ctx, String query, String language) {
-            throw new UnsupportedOperationException();
-        }
-
-        @Override
-        public Iterator<Resource> findResources(ResolveContext<Object> ctx, String query, String language) {
-            throw new UnsupportedOperationException();
-        }
-    }
-}
diff --git a/src/test/java/org/apache/sling/resourceresolver/impl/helper/StarResourceTest.java b/src/test/java/org/apache/sling/resourceresolver/impl/helper/StarResourceTest.java
deleted file mode 100644
index 72c2689..0000000
--- a/src/test/java/org/apache/sling/resourceresolver/impl/helper/StarResourceTest.java
+++ /dev/null
@@ -1,50 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *   http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-package org.apache.sling.resourceresolver.impl.helper;
-
-import static org.junit.Assert.assertEquals;
-
-import org.apache.sling.api.resource.ResourceMetadata;
-import org.junit.Test;
-
-/** Test the StarResource */
-public class StarResourceTest {
-
-	private void assertSplit(String requestPath, String path, String pathInfo) {
-		final ResourceMetadata rm = StarResource.getResourceMetadata(requestPath);
-		assertEquals("For requestPath=" + requestPath + ", path matches", path, rm.getResolutionPath());
-		assertEquals("For requestPath=" + requestPath + ", pathInfo matches", pathInfo, rm.getResolutionPathInfo());
-	}
-
-	@Test public void testSimplePath() {
-		assertSplit("/foo/*.html", "/foo/*", ".html");
-	}
-
-	@Test public void testNoExtension() {
-		assertSplit("/foo/*", "/foo/*", "");
-	}
-
-	@Test public void testNoStar() {
-		assertSplit("/foo/bar.html", "/foo/bar.html", null);
-	}
-
-	@Test public void testTwoStars() {
-		assertSplit("/foo/*.html/*.txt", "/foo/*", ".html/*.txt");
-	}
-}
diff --git a/src/test/java/org/apache/sling/resourceresolver/impl/helper/URI2Test.java b/src/test/java/org/apache/sling/resourceresolver/impl/helper/URI2Test.java
deleted file mode 100644
index 432feae..0000000
--- a/src/test/java/org/apache/sling/resourceresolver/impl/helper/URI2Test.java
+++ /dev/null
@@ -1,49 +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 SF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations under the License.
- */
-package org.apache.sling.resourceresolver.impl.helper;
-
-import org.junit.Assert;
-import org.junit.Test;
-
-/**
- * Unit test to cover areas not already covered by the URI test from HttpClient.
- */
-public class URI2Test {
-    
-    @Test
-    public void testCreate() {
-        URI u = new URI("http","//localhost:8080/to/a/resource", "fragment");
-        Assert.assertEquals("http://localhost:8080/to/a/resource", u.toString());   
-        u = new URI("http://localhost:8080/to/a/r%20e%20s%20o%20u%20r%20c%20e", true, "UTF-8");
-        Assert.assertEquals("http://localhost:8080/to/a/r%20e%20s%20o%20u%20r%20c%20e", u.toString());   
-        u = new URI("http://localhost:8080/to/a/r e s o u r c e", false, "UTF-8");
-        Assert.assertEquals("http://localhost:8080/to/a/r%20e%20s%20o%20u%20r%20c%20e", u.toString());       
-        Assert.assertEquals("r%20e%20s%20o%20u%20r%20c%20e", new String(u.getRawName()));       
-        Assert.assertEquals("/to/a/r%20e%20s%20o%20u%20r%20c%20e", new String(u.getRawPathQuery()));
-
-    }
-    
-    @Test
-    public void testClone() throws CloneNotSupportedException {
-        URI url = new URI("http://jakarta.apache.org", false);
-        URI uriClone = (URI) url.clone();
-        Assert.assertEquals(url,uriClone);
-        Assert.assertEquals(url.hashCode(),uriClone.hashCode());
-    }
-
-}
diff --git a/src/test/java/org/apache/sling/resourceresolver/impl/helper/URITest.java b/src/test/java/org/apache/sling/resourceresolver/impl/helper/URITest.java
deleted file mode 100644
index e94e358..0000000
--- a/src/test/java/org/apache/sling/resourceresolver/impl/helper/URITest.java
+++ /dev/null
@@ -1,251 +0,0 @@
-/*
- * $HeadURL$
- * $Revision$
- * $Date$
- *
- * ====================================================================
- *
- *  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.
- * ====================================================================
- *
- * This software consists of voluntary contributions made by many
- * individuals on behalf of the Apache Software Foundation.  For more
- * information on the Apache Software Foundation, please see
- * <http://www.apache.org/>.
- *
- */
-/*
- * This class was taken from the ASF repo at http://svn.apache.org/viewvc/httpcomponents/oac.hc3x/tags/HTTPCLIENT_3_1/src/test/org/apache/commons/httpclient/TestURI.java?revision=567248&view=co
- * to provide coverage for the URI class from the same source that is embedded in this bundle. 
- * 
- * It has minor modifications to eliminate dependencies on other parts of the HttpClient 3.1 package.
- */
-package org.apache.sling.resourceresolver.impl.helper;
-
-
-
-import junit.framework.Test;
-import junit.framework.TestCase;
-import junit.framework.TestSuite;
-
-/**
- * Simple tests for the URI class.
- * 
- * @author Michael Becke
- */
-public class URITest extends TestCase {
-
-    /**
-     * Constructor for TestURI.
-     * @param testName
-     */
-    public URITest(String testName) {
-        super(testName);
-    }
-    
-    public static Test suite() {
-        return new TestSuite(URITest.class);
-    }
-    
-    public void testIPv4Address() throws URIException {
-
-        URI base = new URI("http://10.0.1.10:8830", false);
-        
-        URI uri = base;        
-        assertTrue("Should be an IPv4 address", uri.isIPv4address());
-            
-        uri = new URI(base, "/04-1.html", false);
-        assertTrue("Should be an IPv4 address", uri.isIPv4address());
-
-        uri = new URI("/04-1.html", false);
-        assertFalse("Should NOT be an IPv4 address", uri.isIPv4address());
-
-        uri = new URI(base, "http://10.0.1.10:8830/04-1.html", false);
-        assertTrue("Should be an IPv4 address", uri.isIPv4address());
-
-        uri = new URI("http://10.0.1.10:8830/04-1.html", false);
-        assertTrue("Should be an IPv4 address", uri.isIPv4address());
-
-        uri = new URI(base, "http://host.org/04-1.html", false);
-        assertFalse("Should NOT be an IPv4 address", uri.isIPv4address());
-
-        uri = new URI("http://host.org/04-1.html", false);
-        assertFalse("Should NOT be an IPv4 address", uri.isIPv4address());
-        
-    }
-    
-    public void testUrl() throws URIException {
-        URI url = new URI("http://jakarta.apache.org", false);
-        assertEquals(-1, url.getPort()); // URI itself has no knowledge of default ports.
-        assertEquals("http", url.getScheme());
-        
-        url = new URI("https://jakarta.apache.org", false);
-        assertEquals(-1, url.getPort()); // URI itself has no knowledge of default ports.
-        assertEquals("https", url.getScheme());
-    }
-    
-    /**
-     * Tests the URI(URI, String) constructor.  This tests URIs ability to
-     * resolve relative URIs.
-     */
-    public void testRelativeURIConstructor() {
-        
-        URI baseURI = null;
-        
-        try {
-            baseURI = new URI("http://a/b/c/d;p?q", false);
-        } catch ( URIException e ) {
-            fail( "unable to create base URI: " + e );
-        }
-        
-        // the following is an array of arrays in the following order
-        // relative URI, scheme, host(authority), path, query, fragment, abs. URI
-        //
-        // these examples were taken from rfc 2396
-        String[][] testRelativeURIs = {
-            { "g:h", "g", null, "h", null, null, "g:h" },
-            { "g", "http", "a", "/b/c/g", null, null, "http://a/b/c/g" },
-            { "./g", "http", "a", "/b/c/g", null, null, "http://a/b/c/g" },
-            { "g/", "http", "a", "/b/c/g/", null, null, "http://a/b/c/g/" },
-            { "/g", "http", "a", "/g", null, null, "http://a/g" },
-            { "//g", "http", "g", null, null, null, "http://g" },
-            { "?y", "http", "a", "/b/c/d;p", "y", null, "http://a/b/c/d;p?y" },
-            { "g?y", "http", "a", "/b/c/g", "y", null, "http://a/b/c/g?y" },
-            { "#s", "http", "a", "/b/c/d;p", "q", "s", "http://a/b/c/d;p?q#s" },
-            { "#", "http", "a", "/b/c/d;p", "q", "", "http://a/b/c/d;p?q#" },
-            { "", "http", "a", "/b/c/d;p", "q", null, "http://a/b/c/d;p?q" },
-            { "g#s", "http", "a", "/b/c/g", null, "s", "http://a/b/c/g#s" },
-            { "g?y#s","http", "a", "/b/c/g", "y", "s", "http://a/b/c/g?y#s" },
-            { ";x", "http", "a", "/b/c/;x", null, null, "http://a/b/c/;x" },
-            { "g;x", "http", "a", "/b/c/g;x", null, null, "http://a/b/c/g;x" },
-            { "g;x?y#s", "http", "a", "/b/c/g;x", "y", "s", "http://a/b/c/g;x?y#s" },
-            { ".", "http", "a", "/b/c/", null, null, "http://a/b/c/" },
-            { "./", "http", "a", "/b/c/", null, null, "http://a/b/c/" },
-            { "..", "http", "a", "/b/", null, null, "http://a/b/" },
-            { "../", "http", "a", "/b/", null, null, "http://a/b/" },
-            { "../g", "http", "a", "/b/g", null, null, "http://a/b/g" },
-            { "../..", "http", "a", "/", null, null, "http://a/" },
-            { "../../", "http", "a", "/", null, null, "http://a/" },
-            { "../../g", "http", "a", "/g", null, null, "http://a/g" },
-            { "../../../g", "http", "a", "/g", null, null, "http://a/g" },
-            { "../../../../g", "http", "a", "/g", null, null, "http://a/g" },
-            { "/./g", "http", "a", "/g", null, null, "http://a/g" },
-            { "/../g", "http", "a", "/g", null, null, "http://a/g" },
-            { "g.", "http", "a", "/b/c/g.", null, null, "http://a/b/c/g." },
-            { ".g", "http", "a", "/b/c/.g", null, null, "http://a/b/c/.g" },
-            { "g..", "http", "a", "/b/c/g..", null, null, "http://a/b/c/g.." },
-            { "..g", "http", "a", "/b/c/..g", null, null, "http://a/b/c/..g" },
-            { "./../g", "http", "a", "/b/g", null, null, "http://a/b/g" },
-            { "./g/.", "http", "a", "/b/c/g/", null, null, "http://a/b/c/g/" },
-            { "g/./h", "http", "a", "/b/c/g/h", null, null, "http://a/b/c/g/h" },
-            { "g/../h", "http", "a", "/b/c/h", null, null, "http://a/b/c/h" },
-            { "g;x=1/./y", "http", "a", "/b/c/g;x=1/y", null, null, "http://a/b/c/g;x=1/y" },
-            { "g;x=1/../y", "http", "a", "/b/c/y", null, null, "http://a/b/c/y" },
-            { "g?y/./x", "http", "a", "/b/c/g", "y/./x", null, "http://a/b/c/g?y/./x" },
-            { "g?y/../x", "http", "a", "/b/c/g", "y/../x", null, "http://a/b/c/g?y/../x" },
-            { "g#s/./x", "http", "a", "/b/c/g", null, "s/./x", "http://a/b/c/g#s/./x" },
-            { "g#s/../x", "http", "a", "/b/c/g", null, "s/../x", "http://a/b/c/g#s/../x" },
-            { ":g", "http", "a", "/b/c/:g", null, null, "http://a/b/c/:g" }, // see issue #35148
-            { "//a/b/c", "http", "a", "/b/c", null, null, "http://a/b/c" } // see HTTPCLIENT-580 
-        };
-        for (int i = 0; i < testRelativeURIs.length; i++) {
-            URI testURI = null;
-            
-            try {
-                testURI = new URI( baseURI, testRelativeURIs[i][0], false );
-            } catch ( URIException e ) {
-                e.printStackTrace();
-                fail( 
-                    "unable to create URI with relative value(" 
-                    + testRelativeURIs[i][0] + "): " + e 
-                );   
-            }
-            
-            try {
-                assertEquals("array index "+i, testRelativeURIs[i][1], testURI.getScheme());
-                assertEquals("array index "+i, testRelativeURIs[i][2], testURI.getAuthority());
-                assertEquals("array index "+i, testRelativeURIs[i][3], testURI.getPath());
-                assertEquals("array index "+i, testRelativeURIs[i][4], testURI.getQuery());
-                assertEquals("array index "+i, testRelativeURIs[i][5], testURI.getFragment());
-                assertEquals("array index "+i, testRelativeURIs[i][6], testURI.getURIReference());
-            } catch ( URIException e ) {
-                fail( "error getting URI property: " + e );
-            }            
-        }
-        
-    }
-
-    public void testTestURIAuthorityString() throws Exception {
-        URI url = new URI("ftp", "user:password", "localhost", -1, "/");
-        assertEquals("ftp://user:password@localhost/", url.toString());
-        assertEquals("user:password@localhost", url.getAuthority());
-    }
-    
-    
-
-    
-    public void testVariousCharacters() throws Exception {
-        verifyInvalidURI("http://authority:123/path/path?query&name=val ue");
-        verifyInvalidURI("http://authority:123/path/path?query&na me=value");
-        verifyInvalidURI("http://authority:123/path/path?qu ery&name=value");
-        verifyInvalidURI("http://authority:123/path/pa th?query&name=value");
-        verifyInvalidURI("http://authority:123/pa th/path?query&name=value");
-        verifyInvalidURI("http://authority:12 3/path/path?query&name=value");
-        verifyInvalidURI("http://autho rity:123/path/path?query&name=value");
-        verifyInvalidURI("htt p://authority:123/path/path?query&name=value");
-    }
-    
-    private void verifyInvalidURI(String uri) {
-        try {
-            new URI(uri, true);
-            fail("should have thrown URIException");
-        } catch(URIException e) {
-            /* expected */
-        }
-    }    
-    
-    /**
-     * Verify proper handling of relative URIs which have a scheme. 
-     * See bug http://issues.apache.org/jira/browse/HTTPCLIENT-587
-     * 
-     * @throws Exception
-     */
-    public void testRelativeWithScheme() throws Exception {
-        URI base = new URI("http://www.example.com/some/path", true);
-        URI rel1 = new URI("http:", true);
-        URI rel2 = new URI("http:foo", true);
-        URI rel3 = new URI("http:../../bar", true);
-        URI derel1 = new URI(base, rel1);
-        assertEquals("http://www.example.com/some/path",derel1.toString());
-        URI derel2 = new URI(base, rel2);
-        assertEquals("http://www.example.com/some/foo",derel2.toString());
-        URI derel3 = new URI(base,rel3);
-        assertEquals("http://www.example.com/bar",derel3.toString());
-    }
-    
-    /**
-     * Verify proper handling of relative URIs with embedded double-slashes,
-     * like "foo//bar//baz". 
-     * See bug http://issues.apache.org/jira/browse/HTTPCLIENT-588
-     * 
-     * @throws Exception
-     */
-    public void testRelativeWithDoubleSlash() throws Exception {
-        URI rel = new URI("foo//bar//baz",true);
-        assertEquals("foo//bar//baz",rel.toString());
-    }
-    
-}
\ No newline at end of file
diff --git a/src/test/java/org/apache/sling/resourceresolver/impl/mapping/BloomFilterUtilsTest.java b/src/test/java/org/apache/sling/resourceresolver/impl/mapping/BloomFilterUtilsTest.java
deleted file mode 100644
index 69bf67a..0000000
--- a/src/test/java/org/apache/sling/resourceresolver/impl/mapping/BloomFilterUtilsTest.java
+++ /dev/null
@@ -1,206 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements.  See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License.  You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.apache.sling.resourceresolver.impl.mapping;
-
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertTrue;
-import java.math.BigInteger;
-import java.util.HashSet;
-import java.util.Random;
-import org.junit.Test;
-
-/**
- * Test the bloom filter utility class.
- */
-public class BloomFilterUtilsTest {
-
-    /**
-     * Program to calculate the best shift and multiply constants.
-     */
-    public static void main(String... args) {
-        Random random = new Random(1);
-        HashSet<String> inSet = new HashSet<String>();
-        while (inSet.size() < 100) {
-            inSet.add(randomString(random));
-        }
-        Object[] in = inSet.toArray();
-        HashSet<String> notSet = new HashSet<String>();
-        while (notSet.size() < 10000) {
-            String k = randomString(random);
-            if (!inSet.contains(k)) {
-                notSet.add(k);
-            }
-        }
-        Object[] not = notSet.toArray();
-        int best = Integer.MAX_VALUE;
-        for (int mul = 1; mul < 100000; mul += 2) {
-            if (!BigInteger.valueOf(mul).isProbablePrime(10)) {
-                continue;
-            }
-            for (int shift = 0; shift < 32; shift++) {
-                byte[] bloom = BloomFilterUtils.createFilter(100, 64);
-                for (Object k : in) {
-                    int h1 = hash(k.hashCode(), mul, shift), h2 = hash(h1, mul, shift);
-                    add(bloom, h1, h2);
-                }
-                int falsePositives = 0;
-                for (Object k : not) {
-                    int h1 = hash(k.hashCode(), mul, shift), h2 = hash(h1, mul, shift);
-                    if (probablyContains(bloom, h1, h2)) {
-                        falsePositives++;
-                        // short false positives are bad
-                        if (k.toString().length() < 4) {
-                            falsePositives += 5;
-                        }
-                        if (falsePositives > best) {
-                            break;
-                        }
-                    }
-                }
-                if (falsePositives < best) {
-                    best = falsePositives;
-                    System.out.println("mul: " + mul + " shift: "
-                            + shift + " falsePositives: " + best);
-                }
-            }
-        }
-    }
-
-    private static String randomString(Random r) {
-        if (r.nextInt(5) == 0) {
-            return randomName(r);
-        }
-        int length = 1 + Math.abs((int) r.nextGaussian() * 5);
-        if (r.nextBoolean()) {
-            length += r.nextInt(10);
-        }
-        char[] chars = new char[length];
-        for (int i = 0; i < length; i++) {
-            chars[i] = randomChar(r);
-        }
-        return new String(chars);
-    }
-
-    private static char randomChar(Random r) {
-        switch (r.nextInt(101) / 100) {
-        case 0:
-        case 1:
-            // 20% ascii
-            return (char) (32 + r.nextInt(127 - 32));
-        case 2:
-        case 3:
-        case 4:
-        case 5:
-            // 40% a-z
-            return (char) ('a' + r.nextInt('z' - 'a'));
-        case 6:
-            // 10% A-Z
-            return (char) ('A' + r.nextInt('Z' - 'A'));
-        case 7:
-        case 8:
-            // 20% 0-9
-            return (char) ('0' + r.nextInt('9' - '0'));
-        case 9:
-            // 10% aeiou
-            return "aeiou".charAt(r.nextInt("aeiou".length()));
-        }
-        // 1% unicode
-        return (char) r.nextInt(65535);
-    }
-
-    private static String randomName(Random r) {
-        int i = r.nextInt(1000);
-        // like TPC-C lastName, but lowercase
-        String[] n = {
-                "bar", "ought", "able", "pri", "pres", "ese", "anti",
-                "cally", "ation", "eing" };
-        StringBuilder buff = new StringBuilder();
-        buff.append(n[i / 100]);
-        buff.append(n[(i / 10) % 10]);
-        buff.append(n[i % 10]);
-        return buff.toString();
-    }
-
-
-    private static int hash(int oldHash, int mul, int shift) {
-        return oldHash ^ ((oldHash * mul) >> shift);
-    }
-
-    private static void add(byte[] bloom, int h1, int h2) {
-        int len = bloom.length;
-        if (len > 0) {
-            bloom[(h1 >>> 3) % len] |= 1 << (h1 & 7);
-            bloom[(h2 >>> 3) % len] |= 1 << (h2 & 7);
-        }
-    }
-
-    private static boolean probablyContains(byte[] bloom, int h1, int h2) {
-        int len = bloom.length;
-        if (len == 0) {
-            return true;
-        }
-        int x = bloom[(h1 >>> 3) % len] & (1 << (h1 & 7));
-        if (x != 0) {
-            x = bloom[(h2 >>> 3) % len] & (1 << (h2 & 7));
-        }
-        return x != 0;
-    }
-
-    @Test
-    public void size() {
-        byte[] bloom = BloomFilterUtils.createFilter(100, 64);
-        assertEquals(64, bloom.length);
-        bloom = BloomFilterUtils.createFilter(10, 64);
-        assertEquals(11, bloom.length);
-        bloom = BloomFilterUtils.createFilter(0, 64);
-        assertEquals(0, bloom.length);
-        bloom = BloomFilterUtils.createFilter(1, 64);
-        assertEquals(1, bloom.length);
-    }
-
-    @Test
-    public void probability() {
-        byte[] bloom = BloomFilterUtils.createFilter(20, 64);
-        System.out.println(bloom.length);
-        Random random = new Random(1);
-        random.setSeed(1);
-        for (int i = 0; i < 20; i++) {
-            BloomFilterUtils.add(bloom, random.nextInt());
-        }
-        random.setSeed(1);
-        for (int i = 0; i < 20; i++) {
-            assertTrue(BloomFilterUtils.probablyContains(bloom, random.nextInt()));
-        }
-        int falsePositives = 0;
-        for (int i = 20; i < 100000; i++) {
-            if (BloomFilterUtils.probablyContains(bloom, random.nextInt())) {
-                falsePositives++;
-            }
-        }
-        assertEquals(4594, falsePositives);
-    }
-    @Test
-    public void negativeHashCode() {
-        BloomFilterUtils.add(new byte[0], new Object() {
-            @Override
-            public int hashCode() {
-                return -1;
-            }
-        });
-    }
-
-}
diff --git a/src/test/java/org/apache/sling/resourceresolver/impl/mapping/MapEntriesTest.java b/src/test/java/org/apache/sling/resourceresolver/impl/mapping/MapEntriesTest.java
deleted file mode 100644
index 54af3be..0000000
--- a/src/test/java/org/apache/sling/resourceresolver/impl/mapping/MapEntriesTest.java
+++ /dev/null
@@ -1,1885 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with this
- * work for additional information regarding copyright ownership. The ASF
- * licenses this file to You under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
- * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
- * License for the specific language governing permissions and limitations under
- * the License.
- */
-package org.apache.sling.resourceresolver.impl.mapping;
-
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertFalse;
-import static org.junit.Assert.assertNotNull;
-import static org.junit.Assert.assertNull;
-import static org.junit.Assert.assertTrue;
-import static org.mockito.Matchers.anyString;
-import static org.mockito.Matchers.eq;
-import static org.mockito.Mockito.mock;
-import static org.mockito.Mockito.when;
-
-import java.io.File;
-import java.io.IOException;
-import java.lang.reflect.Field;
-import java.lang.reflect.Method;
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.Collections;
-import java.util.HashMap;
-import java.util.HashSet;
-import java.util.Iterator;
-import java.util.List;
-import java.util.Map;
-import java.util.Set;
-import java.util.concurrent.Callable;
-import java.util.concurrent.ExecutorService;
-import java.util.concurrent.Executors;
-import java.util.concurrent.Future;
-import java.util.concurrent.atomic.AtomicLong;
-
-import org.apache.sling.api.resource.Resource;
-import org.apache.sling.api.resource.ResourceResolver;
-import org.apache.sling.api.resource.ResourceUtil;
-import org.apache.sling.api.resource.ValueMap;
-import org.apache.sling.api.wrappers.ValueMapDecorator;
-import org.apache.sling.resourceresolver.impl.mapping.MapConfigurationProvider.VanityPathConfig;
-import org.junit.After;
-import org.junit.Before;
-import org.junit.Test;
-import org.mockito.Mock;
-import org.mockito.MockitoAnnotations;
-import org.mockito.invocation.InvocationOnMock;
-import org.mockito.stubbing.Answer;
-import org.osgi.framework.BundleContext;
-import org.osgi.service.event.EventAdmin;
-
-public class MapEntriesTest {
-
-    private MapEntries mapEntries;
-    
-    File vanityBloomFilterFile;
-
-    @Mock
-    private MapConfigurationProvider resourceResolverFactory;
-
-    @Mock
-    private BundleContext bundleContext;
-
-    @Mock
-    private ResourceResolver resourceResolver;
-
-    @Mock
-    private EventAdmin eventAdmin;
-
-    @SuppressWarnings("deprecation")
-    @Before
-    public void setup() throws Exception {
-        MockitoAnnotations.initMocks(this);
-
-        final List<VanityPathConfig> configs = new ArrayList<MapConfigurationProvider.VanityPathConfig>();
-        configs.add(new VanityPathConfig("/libs/", false));
-        configs.add(new VanityPathConfig("/libs/denied", true));
-        configs.add(new VanityPathConfig("/foo/", false));
-        configs.add(new VanityPathConfig("/baa/", false));
-        configs.add(new VanityPathConfig("/justVanityPath", false));
-        configs.add(new VanityPathConfig("/justVanityPath2", false));
-        configs.add(new VanityPathConfig("/badVanityPath", false));
-        configs.add(new VanityPathConfig("/redirectingVanityPath", false));
-        configs.add(new VanityPathConfig("/redirectingVanityPath301", false));
-        configs.add(new VanityPathConfig("/vanityPathOnJcrContent", false));
-
-        Collections.sort(configs);
-        vanityBloomFilterFile = new File("src/main/resourcesvanityBloomFilter.txt");
-        when(bundleContext.getDataFile("vanityBloomFilter.txt")).thenReturn(vanityBloomFilterFile);
-        when(resourceResolverFactory.getAdministrativeResourceResolver(null)).thenReturn(resourceResolver);
-        when(resourceResolverFactory.isVanityPathEnabled()).thenReturn(true);
-        when(resourceResolverFactory.getVanityPathConfig()).thenReturn(configs);
-        when(resourceResolverFactory.isOptimizeAliasResolutionEnabled()).thenReturn(true);
-        when(resourceResolver.findResources(anyString(), eq("sql"))).thenReturn(
-                Collections.<Resource> emptySet().iterator());
-
-        mapEntries = new MapEntries(resourceResolverFactory, bundleContext, eventAdmin);
-        Field field0 = MapEntries.class.getDeclaredField("mapRoot");
-        field0.setAccessible(true);  
-        field0.set(mapEntries, MapEntries.DEFAULT_MAP_ROOT);
-        
-        Field field1 = MapEntries.class.getDeclaredField("maxCachedVanityPathEntries");
-        field1.setAccessible(true);  
-        field1.set(mapEntries, -1);
-        
-        Field field2 = MapEntries.class.getDeclaredField("maxCachedVanityPathEntriesStartup");
-        field2.setAccessible(true);  
-        field2.set(mapEntries, true);
-        
-    }
-    
-    @After
-    public void tearDown() throws Exception {
-        vanityBloomFilterFile.delete();
-    }
-
-    @Test
-    public void test_simple_alias_support() {
-        Resource parent = mock(Resource.class);
-        when(parent.getPath()).thenReturn("/parent");
-
-        final Resource result = mock(Resource.class);
-        when(result.getParent()).thenReturn(parent);
-        when(result.getPath()).thenReturn("/parent/child");
-        when(result.getName()).thenReturn("child");
-        when(result.adaptTo(ValueMap.class)).thenReturn(buildValueMap("sling:alias", "alias"));
-
-        when(resourceResolver.findResources(anyString(), eq("sql"))).thenAnswer(new Answer<Iterator<Resource>>() {
-
-            public Iterator<Resource> answer(InvocationOnMock invocation) throws Throwable {
-                if (invocation.getArguments()[0].toString().contains("sling:alias")) {
-                    return Collections.singleton(result).iterator();
-                } else {
-                    return Collections.<Resource> emptySet().iterator();
-                }
-            }
-        });
-
-        mapEntries.doInit();
-
-        Map<String, String> aliasMap = mapEntries.getAliasMap("/parent");
-        assertNotNull(aliasMap);
-        assertTrue(aliasMap.containsKey("alias"));
-        assertEquals("child", aliasMap.get("alias"));
-    }
-
-    @Test
-    public void test_that_duplicate_alias_doesnt_replace_first_alias() {
-        Resource parent = mock(Resource.class);
-        when(parent.getPath()).thenReturn("/parent");
-
-        final Resource result = mock(Resource.class);
-        when(result.getParent()).thenReturn(parent);
-        when(result.getPath()).thenReturn("/parent/child");
-        when(result.getName()).thenReturn("child");
-        when(result.adaptTo(ValueMap.class)).thenReturn(buildValueMap("sling:alias", "alias"));
-
-        final Resource secondResult = mock(Resource.class);
-        when(secondResult.getParent()).thenReturn(parent);
-        when(secondResult.getPath()).thenReturn("/parent/child2");
-        when(secondResult.getName()).thenReturn("child2");
-        when(secondResult.adaptTo(ValueMap.class)).thenReturn(buildValueMap("sling:alias", "alias"));
-
-        when(resourceResolver.findResources(anyString(), eq("sql"))).thenAnswer(new Answer<Iterator<Resource>>() {
-
-            public Iterator<Resource> answer(InvocationOnMock invocation) throws Throwable {
-                if (invocation.getArguments()[0].toString().contains("sling:alias")) {
-                    return Arrays.asList(result, secondResult).iterator();
-                } else {
-                    return Collections.<Resource> emptySet().iterator();
-                }
-            }
-        });
-
-        mapEntries.doInit();
-
-        Map<String, String> aliasMap = mapEntries.getAliasMap("/parent");
-        assertNotNull(aliasMap);
-        assertTrue(aliasMap.containsKey("alias"));
-        assertEquals("child", aliasMap.get("alias"));
-    }
-
-    @Test
-    public void test_vanity_path_registration() throws Exception {
-        // specifically making this a weird value because we want to verify that
-        // the configuration value is being used
-        int DEFAULT_VANITY_STATUS = 333333;
-
-        when(resourceResolverFactory.getDefaultVanityPathRedirectStatus()).thenReturn(DEFAULT_VANITY_STATUS);
-
-        final List<Resource> resources = new ArrayList<Resource>();
-
-        Resource justVanityPath = mock(Resource.class, "justVanityPath");
-        when(justVanityPath.getPath()).thenReturn("/justVanityPath");
-        when(justVanityPath.getName()).thenReturn("justVanityPath");
-        when(justVanityPath.adaptTo(ValueMap.class)).thenReturn(buildValueMap("sling:vanityPath", "/target/justVanityPath"));
-        resources.add(justVanityPath);
-
-        Resource badVanityPath = mock(Resource.class, "badVanityPath");
-        when(badVanityPath.getPath()).thenReturn("/badVanityPath");
-        when(badVanityPath.getName()).thenReturn("badVanityPath");
-        when(badVanityPath.adaptTo(ValueMap.class)).thenReturn(buildValueMap("sling:vanityPath", "/content/mypage/en-us-{132"));
-        resources.add(badVanityPath);
-
-
-        Resource redirectingVanityPath = mock(Resource.class, "redirectingVanityPath");
-        when(redirectingVanityPath.getPath()).thenReturn("/redirectingVanityPath");
-        when(redirectingVanityPath.getName()).thenReturn("redirectingVanityPath");
-        when(redirectingVanityPath.adaptTo(ValueMap.class)).thenReturn(buildValueMap("sling:vanityPath", "/target/redirectingVanityPath", "sling:redirect", true));
-        resources.add(redirectingVanityPath);
-
-        Resource redirectingVanityPath301 = mock(Resource.class, "redirectingVanityPath301");
-        when(redirectingVanityPath301.getPath()).thenReturn("/redirectingVanityPath301");
-        when(redirectingVanityPath301.getName()).thenReturn("redirectingVanityPath301");
-        when(redirectingVanityPath301.adaptTo(ValueMap.class)).thenReturn(buildValueMap("sling:vanityPath", "/target/redirectingVanityPath301", "sling:redirect", true, "sling:redirectStatus", 301));
-        resources.add(redirectingVanityPath301);
-
-        Resource vanityPathOnJcrContentParent = mock(Resource.class, "vanityPathOnJcrContentParent");
-        when(vanityPathOnJcrContentParent.getPath()).thenReturn("/vanityPathOnJcrContent");
-        when(vanityPathOnJcrContentParent.getName()).thenReturn("vanityPathOnJcrContent");
-
-        Resource vanityPathOnJcrContent = mock(Resource.class, "vanityPathOnJcrContent");
-        when(vanityPathOnJcrContent.getPath()).thenReturn("/vanityPathOnJcrContent/jcr:content");
-        when(vanityPathOnJcrContent.getName()).thenReturn("jcr:content");
-        when(vanityPathOnJcrContent.getParent()).thenReturn(vanityPathOnJcrContentParent);
-        when(vanityPathOnJcrContent.adaptTo(ValueMap.class)).thenReturn(buildValueMap("sling:vanityPath", "/target/vanityPathOnJcrContent"));
-        resources.add(vanityPathOnJcrContent);
-
-        when(resourceResolver.findResources(anyString(), eq("sql"))).thenAnswer(new Answer<Iterator<Resource>>() {
-
-            public Iterator<Resource> answer(InvocationOnMock invocation) throws Throwable {
-                if (invocation.getArguments()[0].toString().contains("sling:vanityPath")) {
-                    return resources.iterator();
-                } else {
-                    return Collections.<Resource> emptySet().iterator();
-                }
-            }
-        });
-
-        mapEntries.doInit();
-        mapEntries.initializeVanityPaths();
-
-        List<MapEntry> entries = mapEntries.getResolveMaps();
-        assertEquals(8, entries.size());
-        for (MapEntry entry : entries) {
-            if (entry.getPattern().contains("/target/redirectingVanityPath301")) {
-                assertEquals(301, entry.getStatus());
-                assertFalse(entry.isInternal());
-            } else if (entry.getPattern().contains("/target/redirectingVanityPath")) {
-                assertEquals(DEFAULT_VANITY_STATUS, entry.getStatus());
-                assertFalse(entry.isInternal());
-            } else if (entry.getPattern().contains("/target/justVanityPath")) {
-                assertTrue(entry.isInternal());
-            } else if (entry.getPattern().contains("/target/vanityPathOnJcrContent")) {
-                for (String redirect : entry.getRedirect()) {
-                    assertFalse(redirect.contains("jcr:content"));
-                }
-            }
-        }
-        
-        Field field = MapEntries.class.getDeclaredField("vanityTargets");
-        field.setAccessible(true);
-        @SuppressWarnings("unchecked")
-        Map<String, List<String>> vanityTargets = (Map<String, List<String>>) field.get(mapEntries);
-        assertEquals(4, vanityTargets.size());
-        
-    }
-
-    private ValueMap buildValueMap(Object... string) {
-        final Map<String, Object> data = new HashMap<String, Object>();
-        for (int i = 0; i < string.length; i = i + 2) {
-            data.put((String) string[i], string[i+1]);
-        }
-        return new ValueMapDecorator(data);
-    }
-
-    private Resource getVanityPathResource(final String path) {
-        Resource rsrc = mock(Resource.class);
-        when(rsrc.getPath()).thenReturn(path);
-        when(rsrc.getName()).thenReturn(ResourceUtil.getName(path));
-        when(rsrc.adaptTo(ValueMap.class)).thenReturn(buildValueMap("sling:vanityPath", "/vanity" + path));
-        return rsrc;
-    }
-
-    @Test
-    public void test_vanity_path_registration_include_exclude() throws IOException {
-        final String[] validPaths = {"/libs/somewhere", "/libs/a/b", "/foo/a", "/baa/a"};
-        final String[] invalidPaths = {"/libs/denied/a", "/libs/denied/b/c", "/nowhere"};
-
-        final List<Resource> resources = new ArrayList<Resource>();
-        for(final String val : validPaths) {
-            resources.add(getVanityPathResource(val));
-        }
-        for(final String val : invalidPaths) {
-            resources.add(getVanityPathResource(val));
-        }
-
-
-        when(resourceResolver.findResources(anyString(), eq("sql"))).thenAnswer(new Answer<Iterator<Resource>>() {
-
-            public Iterator<Resource> answer(InvocationOnMock invocation) throws Throwable {
-                if (invocation.getArguments()[0].toString().contains("sling:vanityPath")) {
-                    return resources.iterator();
-                } else {
-                    return Collections.<Resource> emptySet().iterator();
-                }
-            }
-        });
-
-        mapEntries.doInit();
-        mapEntries.initializeVanityPaths();
-
-        List<MapEntry> entries = mapEntries.getResolveMaps();
-        // each valid resource results in 2 entries
-        assertEquals(validPaths.length * 2, entries.size());
-
-        final Set<String> resultSet = new HashSet<String>();
-        for(final String p : validPaths) {
-            resultSet.add(p + "$1");
-            resultSet.add(p + ".html");
-        }
-        for (final MapEntry entry : entries) {
-            assertTrue(resultSet.remove(entry.getRedirect()[0]));
-        }
-    }
-    
-    @Test
-    public void test_getActualContentPath() throws Exception {
-
-        Method method = MapEntries.class.getDeclaredMethod("getActualContentPath", String.class);
-        method.setAccessible(true);
-        
-        String actualContent = (String) method.invoke(mapEntries, "/content");
-        assertEquals("/content", actualContent);
-        
-        actualContent = (String) method.invoke(mapEntries, "/content/jcr:content");
-        assertEquals("/content", actualContent);
-    }
-    
-    @Test
-    public void test_getMapEntryRedirect() throws Exception {
-
-        Method method = MapEntries.class.getDeclaredMethod("getMapEntryRedirect", MapEntry.class);
-        method.setAccessible(true);
-        
-        MapEntry mapEntry = new MapEntry("/content", -1, false, 0, "/content");     
-        String actualContent = (String) method.invoke(mapEntries, mapEntry);
-        assertEquals("/content", actualContent);
-        
-        mapEntry = new MapEntry("/content", -1, false, 0, "/content$1");     
-        actualContent = (String) method.invoke(mapEntries, mapEntry);
-        assertEquals("/content", actualContent);
-        
-        mapEntry = new MapEntry("/content", -1, false, 0, "/content.html");     
-        actualContent = (String) method.invoke(mapEntries, mapEntry);
-        assertEquals("/content", actualContent);
-    }
-    
-    @SuppressWarnings("unchecked")
-    @Test
-    public void test_doAddVanity() throws Exception {
-        List<MapEntry> entries = mapEntries.getResolveMaps();
-        assertEquals(0, entries.size());
-        Field field = MapEntries.class.getDeclaredField("vanityTargets");
-        field.setAccessible(true);
-        Map<String, List<String>> vanityTargets = (Map<String, List<String>>) field.get(mapEntries);
-        assertEquals(0, vanityTargets.size());
-        
-        Method method = MapEntries.class.getDeclaredMethod("doAddVanity", String.class);
-        method.setAccessible(true);
-        
-        Resource justVanityPath = mock(Resource.class, "justVanityPath");
-        when(resourceResolver.getResource("/justVanityPath")).thenReturn(justVanityPath);
-        when(justVanityPath.getPath()).thenReturn("/justVanityPath");                 
-        when(justVanityPath.getName()).thenReturn("justVanityPath");
-        when(justVanityPath.adaptTo(ValueMap.class)).thenReturn(buildValueMap("sling:vanityPath", "/target/justVanityPath"));
-        
-        method.invoke(mapEntries, "/justVanityPath");
-
-        entries = mapEntries.getResolveMaps();
-        assertEquals(2, entries.size());
-        
-        Field vanityCounter = MapEntries.class.getDeclaredField("vanityCounter");
-        vanityCounter.setAccessible(true);  
-        AtomicLong counter = (AtomicLong) vanityCounter.get(mapEntries);
-        assertEquals(2, counter.longValue());        
-        
-        //bad vanity
-        Resource badVanityPath = mock(Resource.class, "badVanityPath");
-        when(resourceResolver.getResource("/badVanityPath")).thenReturn(badVanityPath);
-        when(badVanityPath.getPath()).thenReturn("/badVanityPath");
-        when(badVanityPath.getName()).thenReturn("badVanityPath");        
-        when(badVanityPath.adaptTo(ValueMap.class)).thenReturn(buildValueMap("sling:vanityPath", "/content/mypage/en-us-{132"));
-        
-        method.invoke(mapEntries, "/badVanityPath");
-        
-
-        assertEquals(2, entries.size());
-
-        vanityTargets = (Map<String, List<String>>) field.get(mapEntries);
-        assertEquals(1, vanityTargets.size());
-        
-        //vanity under jcr:content
-        Resource vanityPathOnJcrContentParent = mock(Resource.class, "vanityPathOnJcrContentParent");
-        when(vanityPathOnJcrContentParent.getPath()).thenReturn("/vanityPathOnJcrContent");
-        when(vanityPathOnJcrContentParent.getName()).thenReturn("vanityPathOnJcrContent");
-
-        Resource vanityPathOnJcrContent = mock(Resource.class, "vanityPathOnJcrContent");
-        when(resourceResolver.getResource("/vanityPathOnJcrContent/jcr:content")).thenReturn(vanityPathOnJcrContent);
-        when(vanityPathOnJcrContent.getPath()).thenReturn("/vanityPathOnJcrContent/jcr:content");
-        when(vanityPathOnJcrContent.getName()).thenReturn("jcr:content");
-        when(vanityPathOnJcrContent.getParent()).thenReturn(vanityPathOnJcrContentParent);
-        when(vanityPathOnJcrContent.adaptTo(ValueMap.class)).thenReturn(buildValueMap("sling:vanityPath", "/target/vanityPathOnJcrContent"));
-        
-        method.invoke(mapEntries, "/vanityPathOnJcrContent/jcr:content");
-        
-        entries = mapEntries.getResolveMaps();
-        assertEquals(4, entries.size());
-        
-        counter = (AtomicLong) vanityCounter.get(mapEntries);
-        assertEquals(4, counter.longValue());        
-
-        vanityTargets = (Map<String, List<String>>) field.get(mapEntries);
-        assertEquals(2, vanityTargets.size());
-        
-        assertNull(vanityTargets.get("/vanityPathOnJcrContent/jcr:content"));
-        assertNotNull(vanityTargets.get("/vanityPathOnJcrContent"));
-    }
-    
-    @SuppressWarnings("unchecked")
-    @Test
-    public void test_doAddVanity_1() throws Exception {
-        Field field1 = MapEntries.class.getDeclaredField("maxCachedVanityPathEntries");
-        field1.setAccessible(true);  
-        field1.set(mapEntries, 10);
-        
-        List<MapEntry> entries = mapEntries.getResolveMaps();
-        assertEquals(0, entries.size());
-        Field field = MapEntries.class.getDeclaredField("vanityTargets");
-        field.setAccessible(true);
-        Map<String, List<String>> vanityTargets = (Map<String, List<String>>) field.get(mapEntries);
-        assertEquals(0, vanityTargets.size());
-        
-        Method method = MapEntries.class.getDeclaredMethod("doAddVanity", String.class);
-        method.setAccessible(true);
-        
-        Resource justVanityPath = mock(Resource.class, "justVanityPath");
-        when(resourceResolver.getResource("/justVanityPath")).thenReturn(justVanityPath);
-        when(justVanityPath.getPath()).thenReturn("/justVanityPath");                 
-        when(justVanityPath.getName()).thenReturn("justVanityPath");
-        when(justVanityPath.adaptTo(ValueMap.class)).thenReturn(buildValueMap("sling:vanityPath", "/target/justVanityPath"));
-        
-        method.invoke(mapEntries, "/justVanityPath");
-
-        entries = mapEntries.getResolveMaps();
-        assertEquals(2, entries.size());
-        
-        Field vanityCounter = MapEntries.class.getDeclaredField("vanityCounter");
-        vanityCounter.setAccessible(true);  
-        AtomicLong counter = (AtomicLong) vanityCounter.get(mapEntries);
-        assertEquals(2, counter.longValue());        
-        
-        //bad vanity
-        Resource badVanityPath = mock(Resource.class, "badVanityPath");
-        when(resourceResolver.getResource("/badVanityPath")).thenReturn(badVanityPath);
-        when(badVanityPath.getPath()).thenReturn("/badVanityPath");
-        when(badVanityPath.getName()).thenReturn("badVanityPath");        
-        when(badVanityPath.adaptTo(ValueMap.class)).thenReturn(buildValueMap("sling:vanityPath", "/content/mypage/en-us-{132"));
-        
-        method.invoke(mapEntries, "/badVanityPath");
-        
-
-        assertEquals(2, entries.size());
-
-        vanityTargets = (Map<String, List<String>>) field.get(mapEntries);
-        assertEquals(1, vanityTargets.size());
-        
-        //vanity under jcr:content
-        Resource vanityPathOnJcrContentParent = mock(Resource.class, "vanityPathOnJcrContentParent");
-        when(vanityPathOnJcrContentParent.getPath()).thenReturn("/vanityPathOnJcrContent");
-        when(vanityPathOnJcrContentParent.getName()).thenReturn("vanityPathOnJcrContent");
-
-        Resource vanityPathOnJcrContent = mock(Resource.class, "vanityPathOnJcrContent");
-        when(resourceResolver.getResource("/vanityPathOnJcrContent/jcr:content")).thenReturn(vanityPathOnJcrContent);
-        when(vanityPathOnJcrContent.getPath()).thenReturn("/vanityPathOnJcrContent/jcr:content");
-        when(vanityPathOnJcrContent.getName()).thenReturn("jcr:content");
-        when(vanityPathOnJcrContent.getParent()).thenReturn(vanityPathOnJcrContentParent);
-        when(vanityPathOnJcrContent.adaptTo(ValueMap.class)).thenReturn(buildValueMap("sling:vanityPath", "/target/vanityPathOnJcrContent"));
-        
-        method.invoke(mapEntries, "/vanityPathOnJcrContent/jcr:content");
-        
-        entries = mapEntries.getResolveMaps();
-        assertEquals(4, entries.size());
-        
-        counter = (AtomicLong) vanityCounter.get(mapEntries);
-        assertEquals(4, counter.longValue());
-
-        vanityTargets = (Map<String, List<String>>) field.get(mapEntries);
-        assertEquals(2, vanityTargets.size());
-        
-        assertNull(vanityTargets.get("/vanityPathOnJcrContent/jcr:content"));
-        assertNotNull(vanityTargets.get("/vanityPathOnJcrContent"));
-    }
-    
-    
-    @SuppressWarnings("unchecked")
-    @Test
-    public void test_doUpdateVanity() throws Exception {
-        Field field0 = MapEntries.class.getDeclaredField("resolveMapsMap");
-        field0.setAccessible(true);   
-        Map<String, List<MapEntry>> resolveMapsMap = (Map<String, List<MapEntry>>) field0.get(mapEntries);
-        assertEquals(1, resolveMapsMap.size());
-        
-        Field field = MapEntries.class.getDeclaredField("vanityTargets");
-        field.setAccessible(true);
-        Map<String, List<String>> vanityTargets = (Map<String, List<String>>) field.get(mapEntries);
-        assertEquals(0, vanityTargets.size());
-        
-        Method method = MapEntries.class.getDeclaredMethod("doAddVanity", String.class);
-        method.setAccessible(true);
-        
-        Method method1 = MapEntries.class.getDeclaredMethod("doUpdateVanity", String.class);
-        method1.setAccessible(true);
-        
-        Resource justVanityPath = mock(Resource.class, "justVanityPath");
-        when(resourceResolver.getResource("/justVanityPath")).thenReturn(justVanityPath);
-        when(justVanityPath.getPath()).thenReturn("/justVanityPath");                 
-        when(justVanityPath.getName()).thenReturn("justVanityPath");
-        when(justVanityPath.adaptTo(ValueMap.class)).thenReturn(buildValueMap("sling:vanityPath", "/target/justVanityPath"));
-        
-        method.invoke(mapEntries, "/justVanityPath");
- 
-        assertEquals(2, resolveMapsMap.size());
-        assertEquals(1, vanityTargets.size());
-        assertNotNull(resolveMapsMap.get("/target/justVanityPath"));
-        assertNull(resolveMapsMap.get("/target/justVanityPathUpdated"));
-        assertEquals(1, vanityTargets.get("/justVanityPath").size());
-        assertEquals("/target/justVanityPath", vanityTargets.get("/justVanityPath").get(0));
-        
-        //update vanity path
-        when(justVanityPath.adaptTo(ValueMap.class)).thenReturn(buildValueMap("sling:vanityPath", "/target/justVanityPathUpdated"));
-        method1.invoke(mapEntries, "/justVanityPath");
-               
-        assertEquals(2, resolveMapsMap.size());
-        assertEquals(1, vanityTargets.size());
-        assertNull(resolveMapsMap.get("/target/justVanityPath"));
-        assertNotNull(resolveMapsMap.get("/target/justVanityPathUpdated"));
-        assertEquals(1, vanityTargets.get("/justVanityPath").size());
-        assertEquals("/target/justVanityPathUpdated", vanityTargets.get("/justVanityPath").get(0));
-        
-        //vanity under jcr:content
-        Resource vanityPathOnJcrContentParent = mock(Resource.class, "vanityPathOnJcrContentParent");
-        when(vanityPathOnJcrContentParent.getPath()).thenReturn("/vanityPathOnJcrContent");
-        when(vanityPathOnJcrContentParent.getName()).thenReturn("vanityPathOnJcrContent");
-
-        Resource vanityPathOnJcrContent = mock(Resource.class, "vanityPathOnJcrContent");
-        when(resourceResolver.getResource("/vanityPathOnJcrContent/jcr:content")).thenReturn(vanityPathOnJcrContent);
-        when(vanityPathOnJcrContent.getPath()).thenReturn("/vanityPathOnJcrContent/jcr:content");
-        when(vanityPathOnJcrContent.getName()).thenReturn("jcr:content");
-        when(vanityPathOnJcrContent.getParent()).thenReturn(vanityPathOnJcrContentParent);
-        when(vanityPathOnJcrContent.adaptTo(ValueMap.class)).thenReturn(buildValueMap("sling:vanityPath", "/target/vanityPathOnJcrContent"));
-        
-        method.invoke(mapEntries, "/vanityPathOnJcrContent/jcr:content");
-        
-        assertEquals(3, resolveMapsMap.size());
-        assertEquals(2, vanityTargets.size());
-        assertNotNull(resolveMapsMap.get("/target/vanityPathOnJcrContent"));
-        assertNull(resolveMapsMap.get("/target/vanityPathOnJcrContentUpdated"));
-        assertEquals(1, vanityTargets.get("/vanityPathOnJcrContent").size());
-        assertEquals("/target/vanityPathOnJcrContent", vanityTargets.get("/vanityPathOnJcrContent").get(0));
-        
-        //update vanity path
-        when(vanityPathOnJcrContent.adaptTo(ValueMap.class)).thenReturn(buildValueMap("sling:vanityPath", "/target/vanityPathOnJcrContentUpdated"));     
-        method1.invoke(mapEntries, "/vanityPathOnJcrContent/jcr:content");
-        
-        assertEquals(3, resolveMapsMap.size());
-        assertEquals(2, vanityTargets.size());
-        assertNull(resolveMapsMap.get("/target/vanityPathOnJcrContent"));
-        assertNotNull(resolveMapsMap.get("/target/vanityPathOnJcrContentUpdated"));
-        assertEquals(1, vanityTargets.get("/vanityPathOnJcrContent").size());
-        assertEquals("/target/vanityPathOnJcrContentUpdated", vanityTargets.get("/vanityPathOnJcrContent").get(0));
-    }
-    
-    @SuppressWarnings("unchecked")
-    @Test
-    public void test_doRemoveVanity() throws Exception {
-        Field field0 = MapEntries.class.getDeclaredField("resolveMapsMap");
-        field0.setAccessible(true);   
-        Map<String, List<MapEntry>> resolveMapsMap = (Map<String, List<MapEntry>>) field0.get(mapEntries);
-        assertEquals(1, resolveMapsMap.size());
-        
-        Field field = MapEntries.class.getDeclaredField("vanityTargets");
-        field.setAccessible(true);
-        Map<String, List<String>> vanityTargets = (Map<String, List<String>>) field.get(mapEntries);
-        assertEquals(0, vanityTargets.size());
-        
-        Method method = MapEntries.class.getDeclaredMethod("doAddVanity", String.class);
-        method.setAccessible(true);
-        
-        Method method1 = MapEntries.class.getDeclaredMethod("doRemoveVanity", String.class);
-        method1.setAccessible(true);
-        
-        Resource justVanityPath = mock(Resource.class, "justVanityPath");
-        when(resourceResolver.getResource("/justVanityPath")).thenReturn(justVanityPath);
-        when(justVanityPath.getPath()).thenReturn("/justVanityPath");                 
-        when(justVanityPath.getName()).thenReturn("justVanityPath");
-        when(justVanityPath.adaptTo(ValueMap.class)).thenReturn(buildValueMap("sling:vanityPath", "/target/justVanityPath"));
-        
-        method.invoke(mapEntries, "/justVanityPath");
-        
-        Field vanityCounter = MapEntries.class.getDeclaredField("vanityCounter");
-        vanityCounter.setAccessible(true);  
-        AtomicLong counter = (AtomicLong) vanityCounter.get(mapEntries);
-        assertEquals(2, counter.longValue());  
-        assertEquals(2, resolveMapsMap.size());
-        assertEquals(1, vanityTargets.size());
-        assertNotNull(resolveMapsMap.get("/target/justVanityPath"));
-        assertEquals(1, vanityTargets.get("/justVanityPath").size());
-        assertEquals("/target/justVanityPath", vanityTargets.get("/justVanityPath").get(0));
-        
-        //remove vanity path
-        method1.invoke(mapEntries, "/justVanityPath");
-        
-        counter = (AtomicLong) vanityCounter.get(mapEntries);
-        assertEquals(0, counter.longValue());  
-        
-        assertEquals(1, resolveMapsMap.size());
-        assertEquals(0, vanityTargets.size());      
-        assertNull(resolveMapsMap.get("/target/justVanityPath"));
-        
-        //vanity under jcr:content
-        Resource vanityPathOnJcrContentParent = mock(Resource.class, "vanityPathOnJcrContentParent");
-        when(vanityPathOnJcrContentParent.getPath()).thenReturn("/vanityPathOnJcrContent");
-        when(vanityPathOnJcrContentParent.getName()).thenReturn("vanityPathOnJcrContent");
-
-        Resource vanityPathOnJcrContent = mock(Resource.class, "vanityPathOnJcrContent");
-        when(resourceResolver.getResource("/vanityPathOnJcrContent/jcr:content")).thenReturn(vanityPathOnJcrContent);
-        when(vanityPathOnJcrContent.getPath()).thenReturn("/vanityPathOnJcrContent/jcr:content");
-        when(vanityPathOnJcrContent.getName()).thenReturn("jcr:content");
-        when(vanityPathOnJcrContent.getParent()).thenReturn(vanityPathOnJcrContentParent);
-        when(vanityPathOnJcrContent.adaptTo(ValueMap.class)).thenReturn(buildValueMap("sling:vanityPath", "/target/vanityPathOnJcrContent"));
-        
-        method.invoke(mapEntries, "/vanityPathOnJcrContent/jcr:content");
-        
-        assertEquals(2, resolveMapsMap.size());
-        assertEquals(1, vanityTargets.size());
-        assertNotNull(resolveMapsMap.get("/target/vanityPathOnJcrContent"));
-        assertEquals(1,vanityTargets.get("/vanityPathOnJcrContent").size());
-        assertEquals("/target/vanityPathOnJcrContent", vanityTargets.get("/vanityPathOnJcrContent").get(0));
-        
-        //remove vanity path
-        method1.invoke(mapEntries, "/vanityPathOnJcrContent/jcr:content");
-        
-        assertEquals(1, resolveMapsMap.size());
-        assertEquals(0, vanityTargets.size());      
-        assertNull(resolveMapsMap.get("/target/vanityPathOnJcrContent"));
-        
-    }
-    
-    @SuppressWarnings("unchecked")
-    @Test
-    public void test_doUpdateVanityOrder() throws Exception {
-        Field field0 = MapEntries.class.getDeclaredField("resolveMapsMap");
-        field0.setAccessible(true);   
-        Map<String, List<MapEntry>> resolveMapsMap = (Map<String, List<MapEntry>>) field0.get(mapEntries);
-        assertEquals(1, resolveMapsMap.size());
-        
-        Field field = MapEntries.class.getDeclaredField("vanityTargets");
-        field.setAccessible(true);
-        Map<String, List<String>> vanityTargets = (Map<String, List<String>>) field.get(mapEntries);
-        assertEquals(0, vanityTargets.size());
-        
-        Method method = MapEntries.class.getDeclaredMethod("doAddVanity", String.class);
-        method.setAccessible(true);
-        
-        Method method1 = MapEntries.class.getDeclaredMethod("doUpdateVanityOrder", String.class, boolean.class);
-        method1.setAccessible(true);
-        
-        Resource justVanityPath = mock(Resource.class, "justVanityPath");
-        when(resourceResolver.getResource("/justVanityPath")).thenReturn(justVanityPath);
-        when(justVanityPath.getPath()).thenReturn("/justVanityPath");                 
-        when(justVanityPath.getName()).thenReturn("justVanityPath");
-        when(justVanityPath.adaptTo(ValueMap.class)).thenReturn(buildValueMap("sling:vanityPath", "/target/justVanityPath"));
-        
-        method.invoke(mapEntries, "/justVanityPath");
-        
-        Resource justVanityPath2 = mock(Resource.class, "justVanityPath2");
-        when(resourceResolver.getResource("/justVanityPath2")).thenReturn(justVanityPath2);
-        when(justVanityPath2.getPath()).thenReturn("/justVanityPath2");                 
-        when(justVanityPath2.getName()).thenReturn("justVanityPath2");
-        when(justVanityPath2.adaptTo(ValueMap.class)).thenReturn(buildValueMap("sling:vanityPath", "/target/justVanityPath","sling:vanityOrder", 100));
-        
-        method.invoke(mapEntries, "/justVanityPath2");
-              
-        assertEquals(2, resolveMapsMap.size());
-        assertEquals(2, vanityTargets.size());    
-        assertNotNull(resolveMapsMap.get("/target/justVanityPath"));
-        
-        Iterator <MapEntry> iterator = resolveMapsMap.get("/target/justVanityPath").iterator();
-        assertEquals("/justVanityPath2$1", iterator.next().getRedirect()[0]);
-        assertEquals("/justVanityPath$1", iterator.next().getRedirect()[0]);
-        assertEquals("/justVanityPath2.html", iterator.next().getRedirect()[0]);
-        assertEquals("/justVanityPath.html", iterator.next().getRedirect()[0]);    
-        assertFalse(iterator.hasNext());
-        
-        when(justVanityPath.adaptTo(ValueMap.class)).thenReturn(buildValueMap("sling:vanityPath", "/target/justVanityPath","sling:vanityOrder", 1000));
-        method1.invoke(mapEntries, "/justVanityPath",false);
-        
-        iterator = resolveMapsMap.get("/target/justVanityPath").iterator();
-        assertEquals("/justVanityPath$1", iterator.next().getRedirect()[0]);
-        assertEquals("/justVanityPath2$1", iterator.next().getRedirect()[0]);
-        assertEquals("/justVanityPath.html", iterator.next().getRedirect()[0]);
-        assertEquals("/justVanityPath2.html", iterator.next().getRedirect()[0]);    
-        assertFalse(iterator.hasNext());
-        
-        when(justVanityPath.adaptTo(ValueMap.class)).thenReturn(buildValueMap("sling:vanityPath", "/target/justVanityPath"));
-        method1.invoke(mapEntries, "/justVanityPath",true);
-        
-        iterator = resolveMapsMap.get("/target/justVanityPath").iterator();
-        assertEquals("/justVanityPath2$1", iterator.next().getRedirect()[0]);
-        assertEquals("/justVanityPath$1", iterator.next().getRedirect()[0]);
-        assertEquals("/justVanityPath2.html", iterator.next().getRedirect()[0]);
-        assertEquals("/justVanityPath.html", iterator.next().getRedirect()[0]);    
-        assertFalse(iterator.hasNext());
-    }
-    
-    //SLING-3727
-    @Test
-    public void test_doAddAliasAttributesWithDisableAliasOptimization() throws Exception {
-        Method method = MapEntries.class.getDeclaredMethod("doAddAttributes", String.class, String[].class, boolean.class);
-        method.setAccessible(true);
-        
-        when(resourceResolverFactory.isOptimizeAliasResolutionEnabled()).thenReturn(false);
-        mapEntries = new MapEntries(resourceResolverFactory, bundleContext, eventAdmin);
-        Field field0 = MapEntries.class.getDeclaredField("mapRoot");
-        field0.setAccessible(true);  
-        field0.set(mapEntries, MapEntries.DEFAULT_MAP_ROOT);
-        
-        Resource parent = mock(Resource.class);
-        when(parent.getPath()).thenReturn("/parent");
-
-        final Resource result = mock(Resource.class);
-        when(resourceResolver.getResource("/parent/child")).thenReturn(result);
-        when(result.getParent()).thenReturn(parent);
-        when(result.getPath()).thenReturn("/parent/child");
-        when(result.getName()).thenReturn("child");
-        when(result.adaptTo(ValueMap.class)).thenReturn(buildValueMap("sling:alias", "alias"));
-        
-        method.invoke(mapEntries, "/parent/child",
-                new String[] { "sling:alias" }, false);
-        
-        Map<String, String> aliasMap = mapEntries.getAliasMap("/parent");
-        assertNull(aliasMap);
-    }
-    
-    //SLING-3727
-    @Test
-    public void test_doUpdateAttributesWithDisableAliasOptimization() throws Exception {
-        Method method = MapEntries.class.getDeclaredMethod("doUpdateAttributes", String.class, String[].class, boolean.class);
-        method.setAccessible(true);
-        
-        when(resourceResolverFactory.isOptimizeAliasResolutionEnabled()).thenReturn(false);
-        mapEntries = new MapEntries(resourceResolverFactory, bundleContext, eventAdmin);
-        Field field0 = MapEntries.class.getDeclaredField("mapRoot");
-        field0.setAccessible(true);  
-        field0.set(mapEntries, MapEntries.DEFAULT_MAP_ROOT);
-        
-        Resource parent = mock(Resource.class);
-        when(parent.getPath()).thenReturn("/parent");
-
-        final Resource result = mock(Resource.class);
-        when(resourceResolver.getResource("/parent/child")).thenReturn(result);
-        when(result.getParent()).thenReturn(parent);
-        when(result.getPath()).thenReturn("/parent/child");
-        when(result.getName()).thenReturn("child");
-        when(result.adaptTo(ValueMap.class)).thenReturn(buildValueMap("sling:alias", "alias"));
-        
-        method.invoke(mapEntries, "/parent/child",
-                new String[] { "sling:alias" }, false);
-        
-        Map<String, String> aliasMap = mapEntries.getAliasMap("/parent");
-        assertNull(aliasMap);
-    }
-    
-    //SLING-3727
-    @Test
-    public void test_doRemoveAttributessWithDisableAliasOptimization() throws Exception {
-        Method method = MapEntries.class.getDeclaredMethod("doRemoveAttributes", String.class, String[].class, boolean.class, boolean.class);
-        method.setAccessible(true);
-        
-        when(resourceResolverFactory.isOptimizeAliasResolutionEnabled()).thenReturn(false);
-        mapEntries = new MapEntries(resourceResolverFactory, bundleContext, eventAdmin);
-        Field field0 = MapEntries.class.getDeclaredField("mapRoot");
-        field0.setAccessible(true);  
-        field0.set(mapEntries, MapEntries.DEFAULT_MAP_ROOT);
-        
-        Resource parent = mock(Resource.class);
-        when(parent.getPath()).thenReturn("/parent");
-
-        final Resource result = mock(Resource.class);
-        when(resourceResolver.getResource("/parent/child")).thenReturn(result);
-        when(result.getParent()).thenReturn(parent);
-        when(result.getPath()).thenReturn("/parent/child");
-        when(result.getName()).thenReturn("child");
-        when(result.adaptTo(ValueMap.class)).thenReturn(buildValueMap("sling:alias", "alias"));
-        
-        method.invoke(mapEntries, "/parent/child",
-                new String[] { "sling:alias" }, false, false);
-        
-        Map<String, String> aliasMap = mapEntries.getAliasMap("/parent");
-        assertNull(aliasMap);
-    }    
-    
-    @SuppressWarnings("unchecked")
-    @Test
-    public void test_doAddAlias() throws Exception {
-        Method method = MapEntries.class.getDeclaredMethod("doAddAlias", String.class);
-        method.setAccessible(true);
-        
-        Field field0 = MapEntries.class.getDeclaredField("aliasMap");
-        field0.setAccessible(true);   
-        
-        Map<String, Map<String, String>> aliasMap = ( Map<String, Map<String, String>>) field0.get(mapEntries);
-        assertEquals(0, aliasMap.size());        
-        
-        Resource parent = mock(Resource.class);
-        when(parent.getPath()).thenReturn("/parent");
-        
-        final Resource result = mock(Resource.class);
-        when(resourceResolver.getResource("/parent/child")).thenReturn(result);
-        when(result.getParent()).thenReturn(parent);
-        when(result.getPath()).thenReturn("/parent/child");
-        when(result.getName()).thenReturn("child");
-        when(result.adaptTo(ValueMap.class)).thenReturn(buildValueMap("sling:alias", "alias"));
-        
-        method.invoke(mapEntries, "/parent/child");
-        
-        Map<String, String> aliasMapEntry = mapEntries.getAliasMap("/parent");
-        assertNotNull(aliasMapEntry);
-        assertTrue(aliasMapEntry.containsKey("alias"));
-        assertEquals("child", aliasMapEntry.get("alias"));
-        
-        assertEquals(1, aliasMap.size()); 
-        
-        //test_that_duplicate_alias_doesnt_replace_first_alias
-        final Resource secondResult = mock(Resource.class);
-        when(resourceResolver.getResource("/parent/child2")).thenReturn(secondResult);
-        when(secondResult.getParent()).thenReturn(parent);
-        when(secondResult.getPath()).thenReturn("/parent/child2");
-        when(secondResult.getName()).thenReturn("child2");
-        when(secondResult.adaptTo(ValueMap.class)).thenReturn(buildValueMap("sling:alias", "alias"));
-        
-        method.invoke(mapEntries, "/parent/child2");
-        
-        aliasMapEntry = mapEntries.getAliasMap("/parent");
-        assertNotNull(aliasMapEntry);
-        assertTrue(aliasMapEntry.containsKey("alias"));
-        assertEquals("child", aliasMapEntry.get("alias"));
-        
-        assertEquals(1, aliasMap.size()); 
-        
-        //testing jcr:content node
-        final Resource jcrContentResult = mock(Resource.class);
-        when(resourceResolver.getResource("/parent/child/jcr:content")).thenReturn(jcrContentResult);
-        when(jcrContentResult.getParent()).thenReturn(result);
-        when(jcrContentResult.getPath()).thenReturn("/parent/child/jcr:content");
-        when(jcrContentResult.getName()).thenReturn("jcr:content");
-        when(jcrContentResult.adaptTo(ValueMap.class)).thenReturn(buildValueMap("sling:alias", "aliasJcrContent"));
-        
-        method.invoke(mapEntries, "/parent/child/jcr:content");
-        
-        aliasMapEntry = mapEntries.getAliasMap("/parent");
-        assertNotNull(aliasMapEntry);
-        assertEquals(2, aliasMapEntry.size()); 
-        assertTrue(aliasMapEntry.containsKey("aliasJcrContent"));
-        assertEquals("child", aliasMapEntry.get("aliasJcrContent"));
-        
-        assertEquals(1, aliasMap.size()); 
-    }
-    
-    @SuppressWarnings("unchecked")
-    @Test
-    public void test_doAddAlias2() throws Exception {
-        Method method = MapEntries.class.getDeclaredMethod("doAddAlias", String.class);
-        method.setAccessible(true);
-        
-        Field field0 = MapEntries.class.getDeclaredField("aliasMap");
-        field0.setAccessible(true);   
-        
-        Map<String, Map<String, String>> aliasMap = ( Map<String, Map<String, String>>) field0.get(mapEntries);
-        assertEquals(0, aliasMap.size());        
-        
-        Resource parent = mock(Resource.class);
-        when(parent.getPath()).thenReturn("/");
-        
-        final Resource result = mock(Resource.class);
-        when(resourceResolver.getResource("/parent")).thenReturn(result);
-        when(result.getParent()).thenReturn(parent);
-        when(result.getPath()).thenReturn("/parent");
-        when(result.getName()).thenReturn("parent");
-        when(result.adaptTo(ValueMap.class)).thenReturn(buildValueMap("sling:alias", "alias"));
-        
-        method.invoke(mapEntries, "/parent");
-        
-        Map<String, String> aliasMapEntry = mapEntries.getAliasMap("/");
-        assertNotNull(aliasMapEntry);
-        assertTrue(aliasMapEntry.containsKey("alias"));
-        assertEquals("parent", aliasMapEntry.get("alias"));
-        
-        assertEquals(1, aliasMap.size()); 
-        
-        //test_that_duplicate_alias_doesnt_replace_first_alias
-        final Resource secondResult = mock(Resource.class);
-        when(resourceResolver.getResource("/parent2")).thenReturn(secondResult);
-        when(secondResult.getParent()).thenReturn(parent);
-        when(secondResult.getPath()).thenReturn("/parent2");
-        when(secondResult.getName()).thenReturn("parent2");
-        when(secondResult.adaptTo(ValueMap.class)).thenReturn(buildValueMap("sling:alias", "alias"));
-        
-        method.invoke(mapEntries, "/parent2");
-        
-        aliasMapEntry = mapEntries.getAliasMap("/");
-        assertNotNull(aliasMapEntry);
-        assertTrue(aliasMapEntry.containsKey("alias"));
-        assertEquals("parent", aliasMapEntry.get("alias"));
-        
-        assertEquals(1, aliasMap.size()); 
-        
-        //testing jcr:content node
-        final Resource jcrContentResult = mock(Resource.class);
-        when(resourceResolver.getResource("/parent/jcr:content")).thenReturn(jcrContentResult);
-        when(jcrContentResult.getParent()).thenReturn(result);
-        when(jcrContentResult.getPath()).thenReturn("/parent/jcr:content");
-        when(jcrContentResult.getName()).thenReturn("jcr:content");
-        when(jcrContentResult.adaptTo(ValueMap.class)).thenReturn(buildValueMap("sling:alias", "aliasJcrContent"));
-        
-        method.invoke(mapEntries, "/parent/jcr:content");
-        
-        aliasMapEntry = mapEntries.getAliasMap("/");
-        assertNotNull(aliasMapEntry);
-        assertEquals(2, aliasMapEntry.size()); 
-        assertTrue(aliasMapEntry.containsKey("aliasJcrContent"));
-        assertEquals("parent", aliasMapEntry.get("aliasJcrContent"));
-        
-        assertEquals(1, aliasMap.size()); 
-    }
-    
-    
-    @SuppressWarnings("unchecked")
-    @Test
-    public void test_doUpdateAlias() throws Exception {
-        Method method = MapEntries.class.getDeclaredMethod("doAddAlias", String.class);
-        method.setAccessible(true);
-        
-        Method method1 = MapEntries.class.getDeclaredMethod("doUpdateAttributes", String.class , String[].class, boolean.class);
-        method1.setAccessible(true);
-        
-        Field field0 = MapEntries.class.getDeclaredField("aliasMap");
-        field0.setAccessible(true);   
-        
-        Map<String, Map<String, String>> aliasMap = ( Map<String, Map<String, String>>) field0.get(mapEntries);
-        assertEquals(0, aliasMap.size());        
-        
-        Resource parent = mock(Resource.class);
-        when(parent.getPath()).thenReturn("/parent");
-        
-        final Resource result = mock(Resource.class);
-        when(resourceResolver.getResource("/parent/child")).thenReturn(result);
-        when(result.getParent()).thenReturn(parent);
-        when(result.getPath()).thenReturn("/parent/child");
-        when(result.getName()).thenReturn("child");
-        when(result.adaptTo(ValueMap.class)).thenReturn(buildValueMap("sling:alias", "alias"));
-        
-        method.invoke(mapEntries, "/parent/child");
-        
-        Map<String, String> aliasMapEntry = mapEntries.getAliasMap("/parent");
-        assertNotNull(aliasMapEntry);
-        assertTrue(aliasMapEntry.containsKey("alias"));
-        assertFalse(aliasMapEntry.containsKey("aliasUpdated"));
-        assertEquals("child", aliasMapEntry.get("alias"));
-        
-        assertEquals(1, aliasMap.size()); 
-        
-        when(result.adaptTo(ValueMap.class)).thenReturn(buildValueMap("sling:alias", "aliasUpdated"));
-        
-        method1.invoke(mapEntries, "/parent/child", new String[] { "sling:alias" }, false);
-        
-        aliasMapEntry = mapEntries.getAliasMap("/parent");
-        assertNotNull(aliasMapEntry);
-        assertFalse(aliasMapEntry.containsKey("alias"));
-        assertTrue(aliasMapEntry.containsKey("aliasUpdated"));
-        assertEquals("child", aliasMapEntry.get("aliasUpdated"));
-        
-        assertEquals(1, aliasMap.size()); 
-        
-        //testing jcr:content node update
-        final Resource jcrContentResult = mock(Resource.class);
-        when(resourceResolver.getResource("/parent/child/jcr:content")).thenReturn(jcrContentResult);
-        when(jcrContentResult.getParent()).thenReturn(result);
-        when(jcrContentResult.getPath()).thenReturn("/parent/child/jcr:content");
-        when(jcrContentResult.getName()).thenReturn("jcr:content");
-        when(jcrContentResult.adaptTo(ValueMap.class)).thenReturn(buildValueMap("sling:alias", "aliasJcrContent"));
-        when(result.getChild("jcr:content")).thenReturn(jcrContentResult);
-        
-        method.invoke(mapEntries, "/parent/child/jcr:content");
-        
-        aliasMapEntry = mapEntries.getAliasMap("/parent");
-        assertNotNull(aliasMapEntry);
-        assertEquals(2, aliasMapEntry.size()); 
-        assertTrue(aliasMapEntry.containsKey("aliasJcrContent"));
-        assertFalse(aliasMapEntry.containsKey("aliasJcrContentUpdated"));
-        assertEquals("child", aliasMapEntry.get("aliasJcrContent"));
-        
-        assertEquals(1, aliasMap.size()); 
-        
-        when(jcrContentResult.adaptTo(ValueMap.class)).thenReturn(buildValueMap("sling:alias", "aliasJcrContentUpdated"));
-        method1.invoke(mapEntries, "/parent/child/jcr:content",  new String[] { "sling:alias" }, false);
-        
-        aliasMapEntry = mapEntries.getAliasMap("/parent");
-        assertNotNull(aliasMapEntry);
-        assertEquals(2, aliasMapEntry.size()); 
-        assertFalse(aliasMapEntry.containsKey("aliasJcrContent"));
-        assertTrue(aliasMapEntry.containsKey("aliasJcrContentUpdated"));
-        assertEquals("child", aliasMapEntry.get("aliasJcrContentUpdated"));
-        
-        assertEquals(1, aliasMap.size()); 
-        
-        //re-update alias
-        method1.invoke(mapEntries, "/parent/child",  new String[] { "sling:alias" }, false);
-        
-        aliasMapEntry = mapEntries.getAliasMap("/parent");
-        assertNotNull(aliasMapEntry);
-        assertEquals(2, aliasMapEntry.size());
-        assertFalse(aliasMapEntry.containsKey("alias"));
-        assertTrue(aliasMapEntry.containsKey("aliasUpdated"));
-        assertEquals("child", aliasMapEntry.get("aliasUpdated"));
-        
-        //add another node with different alias and check that the update doesn't break anything (see also SLING-3728)
-        final Resource secondResult = mock(Resource.class);
-        when(resourceResolver.getResource("/parent/child2")).thenReturn(secondResult);
-        when(secondResult.getParent()).thenReturn(parent);
-        when(secondResult.getPath()).thenReturn("/parent/child2");
-        when(secondResult.getName()).thenReturn("child2");
-        when(secondResult.adaptTo(ValueMap.class)).thenReturn(buildValueMap("sling:alias", "alias2"));
-               
-        method.invoke(mapEntries, "/parent/child2");
-        assertEquals(1, aliasMap.size()); 
-        
-        aliasMapEntry = mapEntries.getAliasMap("/parent");
-        assertNotNull(aliasMapEntry);
-        assertEquals(3, aliasMapEntry.size());
-        
-        when(jcrContentResult.adaptTo(ValueMap.class)).thenReturn(buildValueMap("sling:alias", "aliasJcrContentUpdated"));
-        method1.invoke(mapEntries, "/parent/child/jcr:content",  new String[] { "sling:alias" }, false);
-        
-        aliasMapEntry = mapEntries.getAliasMap("/parent");
-        assertNotNull(aliasMapEntry);
-        assertEquals(3, aliasMapEntry.size()); 
-        assertFalse(aliasMapEntry.containsKey("aliasJcrContent"));
-        assertTrue(aliasMapEntry.containsKey("aliasJcrContentUpdated"));
-        assertEquals("child", aliasMapEntry.get("aliasJcrContentUpdated"));
-        
-        assertEquals(1, aliasMap.size()); 
- 
-        
-        when(result.adaptTo(ValueMap.class)).thenReturn(buildValueMap("sling:alias", null));
-        when(jcrContentResult.adaptTo(ValueMap.class)).thenReturn(buildValueMap("sling:alias", "aliasJcrContentUpdated"));
-        method1.invoke(mapEntries, "/parent/child/jcr:content",  new String[] { "sling:alias" }, false);
-        
-        aliasMapEntry = mapEntries.getAliasMap("/parent");
-        assertNotNull(aliasMapEntry);
-        assertEquals(2, aliasMapEntry.size()); 
-        assertFalse(aliasMapEntry.containsKey("aliasJcrContent"));
-        assertTrue(aliasMapEntry.containsKey("aliasJcrContentUpdated"));
-        assertEquals("child", aliasMapEntry.get("aliasJcrContentUpdated"));
-        
-        assertEquals(1, aliasMap.size()); 
- 
-    }
-    
-    @SuppressWarnings("unchecked")
-    @Test
-    public void test_doRemoveAlias() throws Exception {       
-        Method method = MapEntries.class.getDeclaredMethod("doAddAlias", String.class);
-        method.setAccessible(true);
-        
-        Method method1 = MapEntries.class.getDeclaredMethod("doRemoveAttributes", String.class, String[].class, boolean.class, boolean.class);
-        method1.setAccessible(true);
-        
-        Field field0 = MapEntries.class.getDeclaredField("aliasMap");
-        field0.setAccessible(true);   
-        
-        Map<String, Map<String, String>> aliasMap = ( Map<String, Map<String, String>>) field0.get(mapEntries);
-        assertEquals(0, aliasMap.size()); 
-        
-        Resource parent = mock(Resource.class);
-        when(parent.getPath()).thenReturn("/parent");
-        
-        final Resource result = mock(Resource.class);
-        when(resourceResolver.getResource("/parent/child")).thenReturn(result);
-        when(result.getParent()).thenReturn(parent);
-        when(result.getPath()).thenReturn("/parent/child");
-        when(result.getName()).thenReturn("child");
-        when(result.adaptTo(ValueMap.class)).thenReturn(buildValueMap("sling:alias", "alias"));
-        
-        method.invoke(mapEntries, "/parent/child");
-        
-        Map<String, String> aliasMapEntry = mapEntries.getAliasMap("/parent");
-        assertNotNull(aliasMapEntry);
-        assertTrue(aliasMapEntry.containsKey("alias"));
-        assertEquals("child", aliasMapEntry.get("alias"));
-        
-        assertEquals(1, aliasMap.size()); 
-        
-        method1.invoke(mapEntries, "/parent/child", new String[] { "sling:alias" }, false, false);
-        
-        aliasMapEntry = mapEntries.getAliasMap("/parent");
-        assertNull(aliasMapEntry);
-        
-        assertEquals(0, aliasMap.size()); 
-        
-        //re-add node and test nodeDeletion true
-        method.invoke(mapEntries, "/parent/child");
-        
-        aliasMapEntry = mapEntries.getAliasMap("/parent");
-        assertNotNull(aliasMapEntry);
-        assertTrue(aliasMapEntry.containsKey("alias"));
-        assertEquals("child", aliasMapEntry.get("alias"));
-        
-        assertEquals(1, aliasMap.size()); 
-        
-        when(resourceResolver.getResource("/parent/child")).thenReturn(null);
-        method1.invoke(mapEntries, "/parent/child", new String[] { "sling:alias" }, true, false);
-        
-        aliasMapEntry = mapEntries.getAliasMap("/parent");
-        assertNull(aliasMapEntry);
-        
-        assertEquals(0, aliasMap.size()); 
-    } 
-
-    @SuppressWarnings("unchecked")
-    @Test
-    public void test_doRemoveAlias2() throws Exception { 
-        Method method = MapEntries.class.getDeclaredMethod("doAddAlias", String.class);
-        method.setAccessible(true);
-        
-        Method method1 = MapEntries.class.getDeclaredMethod("doRemoveAttributes", String.class, String[].class, boolean.class, boolean.class);
-        method1.setAccessible(true);
-        
-        Field field0 = MapEntries.class.getDeclaredField("aliasMap");
-        field0.setAccessible(true);   
-        
-        Map<String, Map<String, String>> aliasMap = ( Map<String, Map<String, String>>) field0.get(mapEntries);
-        assertEquals(0, aliasMap.size()); 
-        
-        Resource parent = mock(Resource.class);
-        when(parent.getPath()).thenReturn("/parent");
-        
-        final Resource result = mock(Resource.class);
-        when(resourceResolver.getResource("/parent/child")).thenReturn(result);
-        when(result.getParent()).thenReturn(parent);
-        when(result.getPath()).thenReturn("/parent/child");
-        when(result.getName()).thenReturn("child");
-        when(result.adaptTo(ValueMap.class)).thenReturn(buildValueMap());
-        
-        //testing jcr:content node removal
-        final Resource jcrContentResult = mock(Resource.class);
-        when(resourceResolver.getResource("/parent/child/jcr:content")).thenReturn(jcrContentResult);
-        when(jcrContentResult.getParent()).thenReturn(result);
-        when(jcrContentResult.getPath()).thenReturn("/parent/child/jcr:content");
-        when(jcrContentResult.getName()).thenReturn("jcr:content");
-        when(jcrContentResult.adaptTo(ValueMap.class)).thenReturn(buildValueMap("sling:alias", "aliasJcrContent"));
-        when(result.getChild("jcr:content")).thenReturn(jcrContentResult);
-        
-        method.invoke(mapEntries, "/parent/child/jcr:content");
-        
-        Map<String, String> aliasMapEntry = mapEntries.getAliasMap("/parent");
-        assertNotNull(aliasMapEntry);
-        assertTrue(aliasMapEntry.containsKey("aliasJcrContent"));
-        assertEquals("child", aliasMapEntry.get("aliasJcrContent"));
-        
-        assertEquals(1, aliasMap.size());        
-        
-        method1.invoke(mapEntries, "/parent/child/jcr:content", new String[] { "sling:alias" }, false, false);
-        
-        aliasMapEntry = mapEntries.getAliasMap("/parent");
-        assertNull(aliasMapEntry);
-        
-        assertEquals(0, aliasMap.size()); 
-        
-        //re-add node and test nodeDeletion true       
-        method.invoke(mapEntries, "/parent/child/jcr:content");
-        
-        aliasMapEntry = mapEntries.getAliasMap("/parent");
-        assertNotNull(aliasMapEntry);
-        assertTrue(aliasMapEntry.containsKey("aliasJcrContent"));
-        assertEquals("child", aliasMapEntry.get("aliasJcrContent"));
-        
-        assertEquals(1, aliasMap.size());        
-        when(resourceResolver.getResource("/parent/child/jcr:content")).thenReturn(null);
-        when(result.getChild("jcr:content")).thenReturn(null);
-        method1.invoke(mapEntries, "/parent/child/jcr:content", new String[] { "sling:alias" }, true, false);
-        
-        aliasMapEntry = mapEntries.getAliasMap("/parent");
-        assertNull(aliasMapEntry);
-        
-        assertEquals(0, aliasMap.size());
-    }
-    
-    @SuppressWarnings("unchecked")
-    @Test
-    public void test_doRemoveAlias3() throws Exception { 
-        Method method = MapEntries.class.getDeclaredMethod("doAddAlias", String.class);
-        method.setAccessible(true);
-        
-        Method method1 = MapEntries.class.getDeclaredMethod("doRemoveAttributes", String.class, String[].class, boolean.class, boolean.class);
-        method1.setAccessible(true);
-        
-        Field field0 = MapEntries.class.getDeclaredField("aliasMap");
-        field0.setAccessible(true);   
-        
-        Map<String, Map<String, String>> aliasMap = ( Map<String, Map<String, String>>) field0.get(mapEntries);
-        assertEquals(0, aliasMap.size()); 
-        
-        Resource parent = mock(Resource.class);
-        when(parent.getPath()).thenReturn("/parent");
-        
-        final Resource result = mock(Resource.class);
-        when(resourceResolver.getResource("/parent/child")).thenReturn(result);
-        when(result.getParent()).thenReturn(parent);
-        when(result.getPath()).thenReturn("/parent/child");
-        when(result.getName()).thenReturn("child");
-        when(result.adaptTo(ValueMap.class)).thenReturn(buildValueMap("sling:alias", "alias"));
-        
-        method.invoke(mapEntries, "/parent/child");
-        
-        final Resource jcrContentResult = mock(Resource.class);
-        when(resourceResolver.getResource("/parent/child/jcr:content")).thenReturn(jcrContentResult);
-        when(jcrContentResult.getParent()).thenReturn(result);
-        when(jcrContentResult.getPath()).thenReturn("/parent/child/jcr:content");
-        when(jcrContentResult.getName()).thenReturn("jcr:content");
-        when(jcrContentResult.adaptTo(ValueMap.class)).thenReturn(buildValueMap("sling:alias", "aliasJcrContent"));
-        when(result.getChild("jcr:content")).thenReturn(jcrContentResult);
-        
-        method.invoke(mapEntries, "/parent/child/jcr:content");
-        
-        Map<String, String> aliasMapEntry = mapEntries.getAliasMap("/parent");
-        assertNotNull(aliasMapEntry);
-        assertTrue(aliasMapEntry.containsKey("aliasJcrContent"));
-        assertEquals("child", aliasMapEntry.get("aliasJcrContent"));
-  
-        //test with two nodes 
-        assertEquals(1, aliasMap.size()); 
-        aliasMapEntry = mapEntries.getAliasMap("/parent");
-        assertNotNull(aliasMapEntry);
-        assertEquals(2, aliasMapEntry.size()); 
-        
-        method1.invoke(mapEntries, "/parent/child/jcr:content", new String[] { "sling:alias" }, false, false);
-        
-        assertEquals(1, aliasMap.size()); 
-        aliasMapEntry = mapEntries.getAliasMap("/parent");
-        assertNotNull(aliasMapEntry);
-        assertEquals(1, aliasMapEntry.size());  
-        
-        // re-add the node and test /parent/child
-        method.invoke(mapEntries, "/parent/child/jcr:content");
-        
-        aliasMapEntry = mapEntries.getAliasMap("/parent");
-        assertNotNull(aliasMapEntry);
-        assertTrue(aliasMapEntry.containsKey("aliasJcrContent"));
-        assertEquals("child", aliasMapEntry.get("aliasJcrContent"));
-        assertEquals(2, aliasMapEntry.size()); 
-        
-        method1.invoke(mapEntries, "/parent/child", new String[] { "sling:alias" }, false, false);
-        
-        assertEquals(1, aliasMap.size()); 
-        aliasMapEntry = mapEntries.getAliasMap("/parent");
-        assertNotNull(aliasMapEntry);
-        assertEquals(1, aliasMapEntry.size());  
-        
-        // re-add the node and test node removal
-        method.invoke(mapEntries, "/parent/child");
-        
-        aliasMapEntry = mapEntries.getAliasMap("/parent");
-        assertNotNull(aliasMapEntry);
-        assertTrue(aliasMapEntry.containsKey("aliasJcrContent"));
-        assertEquals("child", aliasMapEntry.get("aliasJcrContent"));
-        assertEquals(2, aliasMapEntry.size()); 
-        
-        when(resourceResolver.getResource("/parent/child/jcr:content")).thenReturn(null);
-        when(result.getChild("jcr:content")).thenReturn(null);
-        method1.invoke(mapEntries, "/parent/child/jcr:content", new String[] { "sling:alias" }, true, false);
-        
-        assertEquals(1, aliasMap.size()); 
-        aliasMapEntry = mapEntries.getAliasMap("/parent");
-        assertNotNull(aliasMapEntry);
-        assertEquals(1, aliasMapEntry.size());  
-        
-        // re-add the node and test node removal for  /parent/child
-        when(resourceResolver.getResource("/parent/child/jcr:content")).thenReturn(jcrContentResult);
-        when(result.getChild("jcr:content")).thenReturn(jcrContentResult);
-        method.invoke(mapEntries, "/parent/child/jcr:content");
-        
-        
-        aliasMapEntry = mapEntries.getAliasMap("/parent");
-        assertNotNull(aliasMapEntry);
-        assertTrue(aliasMapEntry.containsKey("aliasJcrContent"));
-        assertEquals("child", aliasMapEntry.get("aliasJcrContent"));
-        assertEquals(2, aliasMapEntry.size()); 
-        
-        method1.invoke(mapEntries, "/parent/child", new String[] { "sling:alias" }, true, false);
-        
-        assertEquals(0, aliasMap.size()); 
-        aliasMapEntry = mapEntries.getAliasMap("/parent");
-        assertNull(aliasMapEntry);
-    }
-    
-    @SuppressWarnings("unchecked")
-    @Test
-    public void test_doRemoveAlias4() throws Exception {       
-        Method method = MapEntries.class.getDeclaredMethod("doAddAlias", String.class);
-        method.setAccessible(true);
-        
-        Method method1 = MapEntries.class.getDeclaredMethod("doRemoveAttributes", String.class, String[].class, boolean.class, boolean.class);
-        method1.setAccessible(true);
-        
-        Field field0 = MapEntries.class.getDeclaredField("aliasMap");
-        field0.setAccessible(true);   
-        
-        Map<String, Map<String, String>> aliasMap = ( Map<String, Map<String, String>>) field0.get(mapEntries);
-        assertEquals(0, aliasMap.size()); 
-        
-        Resource parent = mock(Resource.class);
-        when(parent.getPath()).thenReturn("/");
-        
-        final Resource result = mock(Resource.class);
-        when(resourceResolver.getResource("/parent")).thenReturn(result);
-        when(result.getParent()).thenReturn(parent);
-        when(result.getPath()).thenReturn("/parent");
-        when(result.getName()).thenReturn("parent");
-        when(result.adaptTo(ValueMap.class)).thenReturn(buildValueMap("sling:alias", "alias"));
-        
-        method.invoke(mapEntries, "/parent");
-        
-        Map<String, String> aliasMapEntry = mapEntries.getAliasMap("/");
-        assertNotNull(aliasMapEntry);
-        assertTrue(aliasMapEntry.containsKey("alias"));
-        assertEquals("parent", aliasMapEntry.get("alias"));
-        
-        assertEquals(1, aliasMap.size()); 
-        
-        method1.invoke(mapEntries, "/parent", new String[] { "sling:alias" }, false, false);
-        
-        aliasMapEntry = mapEntries.getAliasMap("/");
-        assertNull(aliasMapEntry);
-        
-        assertEquals(0, aliasMap.size()); 
-        
-        //re-add node and test nodeDeletion true
-        method.invoke(mapEntries, "/parent");
-        
-        aliasMapEntry = mapEntries.getAliasMap("/");
-        assertNotNull(aliasMapEntry);
-        assertTrue(aliasMapEntry.containsKey("alias"));
-        assertEquals("parent", aliasMapEntry.get("alias"));
-        
-        assertEquals(1, aliasMap.size()); 
-        
-        when(resourceResolver.getResource("/parent")).thenReturn(null);
-        method1.invoke(mapEntries, "/parent", new String[] { "sling:alias" }, true, false);
-        
-        aliasMapEntry = mapEntries.getAliasMap("/");
-        assertNull(aliasMapEntry);
-        
-        assertEquals(0, aliasMap.size()); 
-    } 
-       
-    @SuppressWarnings("unchecked")
-    @Test
-    public void test_doRemoveAlias5() throws Exception { 
-        Method method = MapEntries.class.getDeclaredMethod("doAddAlias", String.class);
-        method.setAccessible(true);
-        
-        Method method1 = MapEntries.class.getDeclaredMethod("doRemoveAttributes", String.class, String[].class, boolean.class, boolean.class);
-        method1.setAccessible(true);
-        
-        Field field0 = MapEntries.class.getDeclaredField("aliasMap");
-        field0.setAccessible(true);   
-        
-        Map<String, Map<String, String>> aliasMap = ( Map<String, Map<String, String>>) field0.get(mapEntries);
-        assertEquals(0, aliasMap.size()); 
-        
-        Resource parent = mock(Resource.class);
-        when(parent.getPath()).thenReturn("/");
-        
-        final Resource result = mock(Resource.class);
-        when(resourceResolver.getResource("/parent")).thenReturn(result);
-        when(result.getParent()).thenReturn(parent);
-        when(result.getPath()).thenReturn("/parent");
-        when(result.getName()).thenReturn("parent");
-        when(result.adaptTo(ValueMap.class)).thenReturn(buildValueMap());
-        
-        //testing jcr:content node removal
-        final Resource jcrContentResult = mock(Resource.class);
-        when(resourceResolver.getResource("/parent/jcr:content")).thenReturn(jcrContentResult);
-        when(jcrContentResult.getParent()).thenReturn(result);
-        when(jcrContentResult.getPath()).thenReturn("/parent/jcr:content");
-        when(jcrContentResult.getName()).thenReturn("jcr:content");
-        when(jcrContentResult.adaptTo(ValueMap.class)).thenReturn(buildValueMap("sling:alias", "aliasJcrContent"));
-        when(result.getChild("jcr:content")).thenReturn(jcrContentResult);
-        
-        method.invoke(mapEntries, "/parent/jcr:content");
-        
-        Map<String, String> aliasMapEntry = mapEntries.getAliasMap("/");
-        assertNotNull(aliasMapEntry);
-        assertTrue(aliasMapEntry.containsKey("aliasJcrContent"));
-        assertEquals("parent", aliasMapEntry.get("aliasJcrContent"));
-        
-        assertEquals(1, aliasMap.size());        
-        
-        method1.invoke(mapEntries, "/parent/jcr:content", new String[] { "sling:alias" }, false, false);
-        
-        aliasMapEntry = mapEntries.getAliasMap("/");
-        assertNull(aliasMapEntry);
-        
-        assertEquals(0, aliasMap.size()); 
-        
-        //re-add node and test nodeDeletion true       
-        method.invoke(mapEntries, "/parent/jcr:content");
-        
-        aliasMapEntry = mapEntries.getAliasMap("/");
-        assertNotNull(aliasMapEntry);
-        assertTrue(aliasMapEntry.containsKey("aliasJcrContent"));
-        assertEquals("parent", aliasMapEntry.get("aliasJcrContent"));
-        
-        assertEquals(1, aliasMap.size());        
-        when(resourceResolver.getResource("/parent/jcr:content")).thenReturn(null);
-        when(result.getChild("jcr:content")).thenReturn(null);
-        method1.invoke(mapEntries, "/parent/jcr:content", new String[] { "sling:alias" }, true, false);
-        
-        aliasMapEntry = mapEntries.getAliasMap("/");
-        assertNull(aliasMapEntry);
-        
-        assertEquals(0, aliasMap.size());
-    }
-    
-    @Test
-    public void test_isValidVanityPath() throws Exception {
-        Method method = MapEntries.class.getDeclaredMethod("isValidVanityPath", Resource.class);
-        method.setAccessible(true);
-        
-        final Resource resource = mock(Resource.class);
-        when(resource.getPath()).thenReturn("/jcr:system/node");
-        
-        assertFalse((Boolean)method.invoke(mapEntries, resource));
-        
-        when(resource.getPath()).thenReturn("/justVanityPath");
-        assertFalse((Boolean)method.invoke(mapEntries, resource));
-        
-        when(resource.adaptTo(ValueMap.class)).thenReturn(mock(ValueMap.class));
-        assertTrue((Boolean)method.invoke(mapEntries, resource));
-    }
-    
-    @Test
-    //SLING-4847
-    public void test_doNodeAdded1() throws Exception { 
-        Method method = MapEntries.class.getDeclaredMethod("doNodeAdded", String.class, boolean.class);
-        method.setAccessible(true);
-        Boolean resfreshed = (Boolean ) method.invoke(mapEntries, "/node", true);
-        assertTrue(resfreshed.booleanValue());
-    }
-    
-    @Test
-    //SLING-4891
-    public void test_getVanityPaths_1() throws Exception {
-        
-        Field field1 = MapEntries.class.getDeclaredField("maxCachedVanityPathEntries");
-        field1.setAccessible(true);  
-        field1.set(mapEntries, 0);
-        
-        Method method = MapEntries.class.getDeclaredMethod("getVanityPaths", String.class);
-        method.setAccessible(true);
-        method.invoke(mapEntries, "/notExisting");   
-        
-        Field vanityCounter = MapEntries.class.getDeclaredField("vanityCounter");
-        vanityCounter.setAccessible(true);  
-        AtomicLong counter = (AtomicLong) vanityCounter.get(mapEntries);
-        assertEquals(0, counter.longValue());        
-    }
-    
-    @Test
-    //SLING-4891
-    public void test_getVanityPaths_2() throws Exception { 
-        
-        final Resource justVanityPath = mock(Resource.class, "justVanityPath");
-        when(resourceResolver.getResource("/justVanityPath")).thenReturn(justVanityPath);
-        when(justVanityPath.getPath()).thenReturn("/justVanityPath");                 
-        when(justVanityPath.getName()).thenReturn("justVanityPath");
-        when(justVanityPath.adaptTo(ValueMap.class)).thenReturn(buildValueMap("sling:vanityPath", "/target/justVanityPath"));
-        
-        
-        when(resourceResolver.findResources(anyString(), eq("sql"))).thenAnswer(new Answer<Iterator<Resource>>() {
-
-            public Iterator<Resource> answer(InvocationOnMock invocation) throws Throwable {
-                if (invocation.getArguments()[0].toString().contains("sling:vanityPath")) {
-                    return Collections.singleton(justVanityPath).iterator();
-                } else {
-                    return Collections.<Resource> emptySet().iterator();
-                }
-            }
-        });
-        
-        Field field1 = MapEntries.class.getDeclaredField("maxCachedVanityPathEntries");
-        field1.setAccessible(true);  
-        field1.set(mapEntries, 0);
-        
-        Method method = MapEntries.class.getDeclaredMethod("getVanityPaths", String.class);
-        method.setAccessible(true);
-        method.invoke(mapEntries, "/target/justVanityPath");   
-        
-        Field vanityCounter = MapEntries.class.getDeclaredField("vanityCounter");
-        vanityCounter.setAccessible(true);  
-        AtomicLong counter = (AtomicLong) vanityCounter.get(mapEntries);
-        assertEquals(2, counter.longValue());        
-        
-        final Resource justVanityPath2 = mock(Resource.class, "justVanityPath2");
-        when(resourceResolver.getResource("/justVanityPath2")).thenReturn(justVanityPath2);
-        when(justVanityPath2.getPath()).thenReturn("/justVanityPath2");                 
-        when(justVanityPath2.getName()).thenReturn("justVanityPath2");
-        when(justVanityPath2.adaptTo(ValueMap.class)).thenReturn(buildValueMap("sling:vanityPath", "/target/justVanityPath","sling:vanityOrder", 100));
-        
-        when(resourceResolver.findResources(anyString(), eq("sql"))).thenAnswer(new Answer<Iterator<Resource>>() {
-
-            public Iterator<Resource> answer(InvocationOnMock invocation) throws Throwable {
-                if (invocation.getArguments()[0].toString().contains("sling:vanityPath")) {
-                    return Collections.singleton(justVanityPath).iterator();
-                } else {
-                    return Collections.<Resource> emptySet().iterator();
-                }
-            }
-        });
-        
-        method.invoke(mapEntries, "/target/justVanityPath");
-  
-        counter = (AtomicLong) vanityCounter.get(mapEntries);
-        assertEquals(4, counter.longValue());  
-    }
-    
-    @Test
-    //SLING-4891
-    public void test_getVanityPaths_3() throws Exception { 
-        
-        final Resource justVanityPath = mock(Resource.class, "justVanityPath");
-        when(resourceResolver.getResource("/justVanityPath")).thenReturn(justVanityPath);
-        when(justVanityPath.getPath()).thenReturn("/justVanityPath");                 
-        when(justVanityPath.getName()).thenReturn("justVanityPath");
-        when(justVanityPath.adaptTo(ValueMap.class)).thenReturn(buildValueMap("sling:vanityPath", "/target/justVanityPath"));
-        
-        
-        when(resourceResolver.findResources(anyString(), eq("sql"))).thenAnswer(new Answer<Iterator<Resource>>() {
-
-            public Iterator<Resource> answer(InvocationOnMock invocation) throws Throwable {
-                if (invocation.getArguments()[0].toString().contains("sling:vanityPath")) {
-                    return Collections.singleton(justVanityPath).iterator();
-                } else {
-                    return Collections.<Resource> emptySet().iterator();
-                }
-            }
-        });
-        
-        Field field1 = MapEntries.class.getDeclaredField("maxCachedVanityPathEntries");
-        field1.setAccessible(true);  
-        field1.set(mapEntries, 0);
-        
-        Field field2 = MapEntries.class.getDeclaredField("maxCachedVanityPathEntriesStartup");
-        field2.setAccessible(true);  
-        field2.set(mapEntries, false);
-        
-        Method method = MapEntries.class.getDeclaredMethod("getVanityPaths", String.class);
-        method.setAccessible(true);
-        method.invoke(mapEntries, "/target/justVanityPath");   
-        
-        Field vanityCounter = MapEntries.class.getDeclaredField("vanityCounter");
-        vanityCounter.setAccessible(true);  
-        AtomicLong counter = (AtomicLong) vanityCounter.get(mapEntries);
-        assertEquals(0, counter.longValue());        
-    }
-    
-    @Test
-    //SLING-4891
-    public void test_getVanityPaths_4() throws Exception { 
-        
-        final Resource badVanityPath = mock(Resource.class, "badVanityPath");
-        when(badVanityPath.getPath()).thenReturn("/badVanityPath");
-        when(badVanityPath.getName()).thenReturn("badVanityPath");
-        when(badVanityPath.adaptTo(ValueMap.class)).thenReturn(buildValueMap("sling:vanityPath", "/content/mypage/en-us-{132"));
-        
-        
-        when(resourceResolver.findResources(anyString(), eq("sql"))).thenAnswer(new Answer<Iterator<Resource>>() {
-
-            public Iterator<Resource> answer(InvocationOnMock invocation) throws Throwable {
-                if (invocation.getArguments()[0].toString().contains("sling:vanityPath")) {
-                    return Collections.singleton(badVanityPath).iterator();
-                } else {
-                    return Collections.<Resource> emptySet().iterator();
-                }
-            }
-        });
-        
-        Field field1 = MapEntries.class.getDeclaredField("maxCachedVanityPathEntries");
-        field1.setAccessible(true);  
-        field1.set(mapEntries, 0);
-        
-        Field field2 = MapEntries.class.getDeclaredField("maxCachedVanityPathEntriesStartup");
-        field2.setAccessible(true);  
-        field2.set(mapEntries, true);
-        
-        Method method = MapEntries.class.getDeclaredMethod("getVanityPaths", String.class);
-        method.setAccessible(true);
-        method.invoke(mapEntries, "/content/mypage/en-us-{132");   
-        
-        Field vanityCounter = MapEntries.class.getDeclaredField("vanityCounter");
-        vanityCounter.setAccessible(true);  
-        AtomicLong counter = (AtomicLong) vanityCounter.get(mapEntries);
-        assertEquals(0, counter.longValue());        
-    }
-    
-    @Test
-    //SLING-4891
-    public void test_getVanityPaths_5() throws Exception { 
-        
-        final Resource justVanityPath = mock(Resource.class, "justVanityPath");
-        when(resourceResolver.getResource("/justVanityPath")).thenReturn(justVanityPath);
-        when(justVanityPath.getPath()).thenReturn("/justVanityPath");                 
-        when(justVanityPath.getName()).thenReturn("justVanityPath");
-        when(justVanityPath.adaptTo(ValueMap.class)).thenReturn(buildValueMap("sling:vanityPath", "/target/justVanityPath"));       
-        
-        when(resourceResolver.findResources(anyString(), eq("sql"))).thenAnswer(new Answer<Iterator<Resource>>() {
-
-            public Iterator<Resource> answer(InvocationOnMock invocation) throws Throwable {
-                if (invocation.getArguments()[0].toString().contains("sling:vanityPath")) {
-                    return Collections.singleton(justVanityPath).iterator();
-                } else {
-                    return Collections.<Resource> emptySet().iterator();
-                }
-            }
-        });
-        
-        Field field1 = MapEntries.class.getDeclaredField("maxCachedVanityPathEntries");
-        field1.setAccessible(true);  
-        field1.set(mapEntries, 2);
-        
-        Field field2 = MapEntries.class.getDeclaredField("maxCachedVanityPathEntriesStartup");
-        field2.setAccessible(true);  
-        field2.set(mapEntries, false);
-        
-        Method method = MapEntries.class.getDeclaredMethod("getVanityPaths", String.class);
-        method.setAccessible(true);
-        method.invoke(mapEntries, "/target/justVanityPath");   
-        
-        Field vanityCounter = MapEntries.class.getDeclaredField("vanityCounter");
-        vanityCounter.setAccessible(true);  
-        AtomicLong counter = (AtomicLong) vanityCounter.get(mapEntries);
-        assertEquals(2, counter.longValue());        
-        
-        final Resource justVanityPath2 = mock(Resource.class, "justVanityPath2");
-        when(resourceResolver.getResource("/justVanityPath2")).thenReturn(justVanityPath2);
-        when(justVanityPath2.getPath()).thenReturn("/justVanityPath2");                 
-        when(justVanityPath2.getName()).thenReturn("justVanityPath2");
-        when(justVanityPath2.adaptTo(ValueMap.class)).thenReturn(buildValueMap("sling:vanityPath", "/target/justVanityPath","sling:vanityOrder", 100));
-        
-        when(resourceResolver.findResources(anyString(), eq("sql"))).thenAnswer(new Answer<Iterator<Resource>>() {
-
-            public Iterator<Resource> answer(InvocationOnMock invocation) throws Throwable {
-                if (invocation.getArguments()[0].toString().contains("sling:vanityPath")) {
-                    return Collections.singleton(justVanityPath).iterator();
-                } else {
-                    return Collections.<Resource> emptySet().iterator();
-                }
-            }
-        });
-        
-        method.invoke(mapEntries, "/target/justVanityPath");
-  
-        counter = (AtomicLong) vanityCounter.get(mapEntries);
-        assertEquals(2, counter.longValue());  
-    }
-    
-    @Test
-    //SLING-4891
-    public void test_loadVanityPaths() throws Exception {
-        Field field1 = MapEntries.class.getDeclaredField("maxCachedVanityPathEntries");
-        field1.setAccessible(true);  
-        field1.set(mapEntries, 2);
-        
-        final Resource justVanityPath = mock(Resource.class, "justVanityPath");
-        when(resourceResolver.getResource("/justVanityPath")).thenReturn(justVanityPath);
-        when(justVanityPath.getPath()).thenReturn("/justVanityPath");                 
-        when(justVanityPath.getName()).thenReturn("justVanityPath");
-        when(justVanityPath.adaptTo(ValueMap.class)).thenReturn(buildValueMap("sling:vanityPath", "/target/justVanityPath"));       
-        
-        when(resourceResolver.findResources(anyString(), eq("sql"))).thenAnswer(new Answer<Iterator<Resource>>() {
-
-            public Iterator<Resource> answer(InvocationOnMock invocation) throws Throwable {
-                if (invocation.getArguments()[0].toString().contains("sling:vanityPath")) {
-                    return Collections.singleton(justVanityPath).iterator();
-                } else {
-                    return Collections.<Resource> emptySet().iterator();
-                }
-            }
-        });        
-        
-        Method method = MapEntries.class.getDeclaredMethod("loadVanityPaths", boolean.class);
-        method.setAccessible(true);
-        method.invoke(mapEntries, false);   
-        
-        Field vanityCounter = MapEntries.class.getDeclaredField("vanityCounter");
-        vanityCounter.setAccessible(true);  
-        AtomicLong counter = (AtomicLong) vanityCounter.get(mapEntries);
-        assertEquals(2, counter.longValue()); 
-    }
-    
-    @Test
-    //SLING-4891
-    public void test_loadVanityPaths_1() throws Exception {
-        
-        final Resource justVanityPath = mock(Resource.class, "justVanityPath");
-        when(resourceResolver.getResource("/justVanityPath")).thenReturn(justVanityPath);
-        when(justVanityPath.getPath()).thenReturn("/justVanityPath");                 
-        when(justVanityPath.getName()).thenReturn("justVanityPath");
-        when(justVanityPath.adaptTo(ValueMap.class)).thenReturn(buildValueMap("sling:vanityPath", "/target/justVanityPath"));       
-        
-        when(resourceResolver.findResources(anyString(), eq("sql"))).thenAnswer(new Answer<Iterator<Resource>>() {
-
-            public Iterator<Resource> answer(InvocationOnMock invocation) throws Throwable {
-                if (invocation.getArguments()[0].toString().contains("sling:vanityPath")) {
-                    return Collections.singleton(justVanityPath).iterator();
-                } else {
-                    return Collections.<Resource> emptySet().iterator();
-                }
-            }
-        });        
-        
-        Method method = MapEntries.class.getDeclaredMethod("loadVanityPaths", boolean.class);
-        method.setAccessible(true);
-        method.invoke(mapEntries, false);   
-        
-        Field vanityCounter = MapEntries.class.getDeclaredField("vanityCounter");
-        vanityCounter.setAccessible(true);  
-        AtomicLong counter = (AtomicLong) vanityCounter.get(mapEntries);
-        assertEquals(2, counter.longValue()); 
-    }
-    
-    @Test
-    //SLING-4891
-    public void test_getMapEntryList() throws Exception {
-
-        List<MapEntry> entries = mapEntries.getResolveMaps();
-        assertEquals(0, entries.size());
-
-
-        final Resource justVanityPath = mock(Resource.class,
-                "justVanityPath");
-
-        when(resourceResolver.getResource("/justVanityPath")).thenReturn(justVanityPath);
-
-        when(justVanityPath.getPath()).thenReturn("/justVanityPath");
-
-        when(justVanityPath.getName()).thenReturn("justVanityPath");
-
-        when(justVanityPath.adaptTo(ValueMap.class)).thenReturn(buildValueMap("sling:vanityPath",
-                "/target/justVanityPath"));
-
-        when(resourceResolver.findResources(anyString(),
-                eq("sql"))).thenAnswer(new Answer<Iterator<Resource>>() {
-
-                    public Iterator<Resource> answer(InvocationOnMock invocation)
-                            throws Throwable {
-                        if
-                        (invocation.getArguments()[0].toString().contains("sling:vanityPath")) {
-                            return Collections.singleton(justVanityPath).iterator();
-                        } else {
-                            return Collections.<Resource> emptySet().iterator();
-                        }
-                    }
-                });
-
-        Method method =
-                MapEntries.class.getDeclaredMethod("getMapEntryList",String.class);
-        method.setAccessible(true);
-        method.invoke(mapEntries, "/target/justVanityPath");
-
-        entries = mapEntries.getResolveMaps();
-        assertEquals(2, entries.size());
-
-        Field vanityCounter =
-                MapEntries.class.getDeclaredField("vanityCounter");
-        vanityCounter.setAccessible(true);
-        AtomicLong counter = (AtomicLong) vanityCounter.get(mapEntries);
-        assertEquals(2, counter.longValue());
-
-        method.invoke(mapEntries, "/target/justVanityPath");
-
-        entries = mapEntries.getResolveMaps();
-        assertEquals(2, entries.size());
-
-        counter = (AtomicLong) vanityCounter.get(mapEntries);
-        assertEquals(2, counter.longValue());
-    }
-    
-    @Test
-    //SLING-4883
-    public void test_concutrrent_getResolveMapsIterator() throws Exception {
-        ExecutorService pool = Executors.newFixedThreadPool(10);
-        
-        final Resource justVanityPath = mock(Resource.class, "justVanityPath");
-        when(resourceResolver.getResource("/justVanityPath")).thenReturn(justVanityPath);
-        when(justVanityPath.getPath()).thenReturn("/justVanityPath");                 
-        when(justVanityPath.getName()).thenReturn("justVanityPath");
-        when(justVanityPath.adaptTo(ValueMap.class)).thenReturn(buildValueMap("sling:vanityPath", "/target/justVanityPath"));
-        
-        
-        when(resourceResolver.findResources(anyString(), eq("sql"))).thenAnswer(new Answer<Iterator<Resource>>() {
-
-            public Iterator<Resource> answer(InvocationOnMock invocation) throws Throwable {
-                if (invocation.getArguments()[0].toString().contains("sling:vanityPath")) {
-                    return Collections.singleton(justVanityPath).iterator();
-                } else {
-                    return Collections.<Resource> emptySet().iterator();
-                }
-            }
-        });
-        
-        
-        Field field1 = MapEntries.class.getDeclaredField("maxCachedVanityPathEntries");
-        field1.setAccessible(true);  
-        field1.set(mapEntries, 2);
-        
-        ArrayList<DataFuture> list = new ArrayList<DataFuture>();
-        for (int i =0;i<10;i++) {
-            list.add(createDataFuture(pool, mapEntries));
- 
-        }
- 
-       for (DataFuture df : list) {
-           df.future.get();           
-        }
-  
-    }
-    
-    // -------------------------- private methods ----------
-    private DataFuture createDataFuture(ExecutorService pool, final MapEntries mapEntries) {
-
-        Future<Iterator<?>> future = pool.submit(new Callable<Iterator<?>>() {
-            @Override
-            public Iterator<MapEntry> call() throws Exception {
-                return mapEntries.getResolveMapsIterator("http/localhost.8080/target/justVanityPath");                     
-            }
-        });
-        return new DataFuture(future);
-    }    
-    
-    // -------------------------- inner classes ------------
-
-    private static class DataFuture {
-        public Future<Iterator<?>> future;
-
-        public DataFuture(Future<Iterator<?>> future) {
-            super();
-            this.future = future;
-        }
-    }    
-}
diff --git a/src/test/java/org/apache/sling/resourceresolver/impl/mapping/MapEntryTest.java b/src/test/java/org/apache/sling/resourceresolver/impl/mapping/MapEntryTest.java
deleted file mode 100644
index d45fcf0..0000000
--- a/src/test/java/org/apache/sling/resourceresolver/impl/mapping/MapEntryTest.java
+++ /dev/null
@@ -1,226 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *   http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-package org.apache.sling.resourceresolver.impl.mapping;
-
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertNotNull;
-import static org.junit.Assert.assertTrue;
-import static org.junit.Assert.fail;
-
-import java.lang.reflect.Method;
-
-import junit.framework.TestCase;
-
-import org.junit.Test;
-
-public class MapEntryTest {
-
-    @Test public void test_to_url_http_80() {
-        assertEqualUri("http://sling.apache.org", "http/sling.apache.org.80");
-        assertEqualUri("http://sling.apache.org/", "http/sling.apache.org.80/");
-        assertEqualUri("http://sling.apache.org/site/index.html",
-            "http/sling.apache.org.80/site/index.html");
-    }
-
-    @Test public void test_to_url_https_443() {
-        assertEqualUri("https://sling.apache.org", "https/sling.apache.org.443");
-        assertEqualUri("https://sling.apache.org/",
-            "https/sling.apache.org.443/");
-        assertEqualUri("https://sling.apache.org/site/index.html",
-            "https/sling.apache.org.443/site/index.html");
-    }
-
-    @Test public void test_to_url_any_999() {
-        // http with arbitrary port
-        assertEqualUri("http://sling.apache.org:123",
-            "http/sling.apache.org.123");
-        assertEqualUri("http://sling.apache.org:456/",
-            "http/sling.apache.org.456/");
-        assertEqualUri("http://sling.apache.org:456/site/index.html",
-            "http/sling.apache.org.456/site/index.html");
-
-        // https with arbitrary port
-        assertEqualUri("https://sling.apache.org:987",
-            "https/sling.apache.org.987");
-        assertEqualUri("https://sling.apache.org:654/",
-            "https/sling.apache.org.654/");
-        assertEqualUri("https://sling.apache.org:321/site/index.html",
-            "https/sling.apache.org.321/site/index.html");
-
-        // any scheme with arbitrary port
-        assertEqualUri("gurk://sling.apache.org:987",
-            "gurk/sling.apache.org.987");
-        assertEqualUri("gurk://sling.apache.org:654/",
-            "gurk/sling.apache.org.654/");
-        assertEqualUri("gurk://sling.apache.org:321/site/index.html",
-            "gurk/sling.apache.org.321/site/index.html");
-    }
-
-    @Test public void test_to_url_any() {
-        // http without port
-        assertEqualUri("http://sling.apache.org", "http/sling.apache.org");
-        assertEqualUri("http://sling.apache.org/", "http/sling.apache.org/");
-        assertEqualUri("http://sling.apache.org/site/index.html",
-            "http/sling.apache.org/site/index.html");
-
-        // https without port
-        assertEqualUri("https://sling.apache.org", "https/sling.apache.org");
-        assertEqualUri("https://sling.apache.org/", "https/sling.apache.org/");
-        assertEqualUri("https://sling.apache.org/site/index.html",
-            "https/sling.apache.org/site/index.html");
-
-        // any scheme without port
-        assertEqualUri("gurk://sling.apache.org", "gurk/sling.apache.org");
-        assertEqualUri("gurk://sling.apache.org/", "gurk/sling.apache.org/");
-        assertEqualUri("gurk://sling.apache.org/site/index.html",
-            "gurk/sling.apache.org/site/index.html");
-    }
-
-    @Test public void test_fixUriPath() {
-        // http without port
-        assertEqualUriPath("http/sling.apache.org.80", "http/sling.apache.org");
-        assertEqualUriPath("http/sling.apache.org.80/",
-            "http/sling.apache.org/");
-        assertEqualUriPath("http/sling.apache.org.80/site/index.html",
-            "http/sling.apache.org/site/index.html");
-
-        // http with port
-        assertEqualUriPath("http/sling.apache.org.80",
-            "http/sling.apache.org.80");
-        assertEqualUriPath("http/sling.apache.org.80/",
-            "http/sling.apache.org.80/");
-        assertEqualUriPath("http/sling.apache.org.80/site/index.html",
-            "http/sling.apache.org.80/site/index.html");
-
-        // https without port
-        assertEqualUriPath("https/sling.apache.org.443",
-            "https/sling.apache.org");
-        assertEqualUriPath("https/sling.apache.org.443/",
-            "https/sling.apache.org/");
-        assertEqualUriPath("https/sling.apache.org.443/site/index.html",
-            "https/sling.apache.org/site/index.html");
-
-        // https with port
-        assertEqualUriPath("https/sling.apache.org.443",
-            "https/sling.apache.org.443");
-        assertEqualUriPath("https/sling.apache.org.443/",
-            "https/sling.apache.org.443/");
-        assertEqualUriPath("https/sling.apache.org.443/site/index.html",
-            "https/sling.apache.org.443/site/index.html");
-
-        // anything without port
-        assertEqualUriPath("gurk/sling.apache.org", "gurk/sling.apache.org");
-        assertEqualUriPath("gurk/sling.apache.org/", "gurk/sling.apache.org/");
-        assertEqualUriPath("gurk/sling.apache.org/site/index.html",
-            "gurk/sling.apache.org/site/index.html");
-
-        // http with port
-        assertEqualUriPath("gurk/sling.apache.org.123",
-            "gurk/sling.apache.org.123");
-        assertEqualUriPath("gurk/sling.apache.org.456/",
-            "gurk/sling.apache.org.456/");
-        assertEqualUriPath("gurk/sling.apache.org.789/site/index.html",
-            "gurk/sling.apache.org.789/site/index.html");
-
-    }
-
-    @Test public void test_isRegExp() {
-        TestCase.assertFalse(isRegExp("http/www.example.com.8080/bla"));
-        TestCase.assertTrue(isRegExp("http/.+\\.www.example.com.8080/bla"));
-        TestCase.assertTrue(isRegExp("http/(.+)\\.www.example.com.8080/bla"));
-        TestCase.assertTrue(isRegExp("http/(.+)\\.www.example.com.8080/bla"));
-        TestCase.assertTrue(isRegExp("http/[^.]+.www.example.com.8080/bla"));
-    }
-
-    @Test public void test_filterRegExp() {
-        TestCase.assertNull(filterRegExp((String[]) null));
-        TestCase.assertNull(filterRegExp(new String[0]));
-
-        String aString = "plain";
-        String aPattern = "http/[^.]+.www.example.com.8080/bla";
-
-        TestCase.assertNull(filterRegExp(aPattern));
-
-        String[] res = filterRegExp(aString);
-        TestCase.assertNotNull(res);
-        TestCase.assertEquals(1, res.length);
-        TestCase.assertEquals(aString, res[0]);
-
-        res = filterRegExp(aString, aPattern);
-        TestCase.assertNotNull(res);
-        TestCase.assertEquals(1, res.length);
-        TestCase.assertEquals(aString, res[0]);
-
-        res = filterRegExp(aPattern, aString, aPattern);
-        TestCase.assertNotNull(res);
-        TestCase.assertEquals(1, res.length);
-        TestCase.assertEquals(aString, res[0]);
-
-        res = filterRegExp(aPattern, aString);
-        TestCase.assertNotNull(res);
-        TestCase.assertEquals(1, res.length);
-        TestCase.assertEquals(aString, res[0]);
-    }
-
-    @Test public void test_compareTo() {
-        final MapEntry a = new MapEntry("/foo", 200, false, 5, new String[0]);
-        final MapEntry b = new MapEntry("/bar", 200, false, 5, new String[0]);
-
-        assertTrue(a.compareTo(b) > 0);
-        assertTrue(b.compareTo(a) < 0);
-        assertTrue(a.compareTo(a) == 0);
-        assertTrue(b.compareTo(b) == 0);
-    }
-
-    private void assertEqualUri(String expected, String uriPath) {
-        String uri = MapEntry.toURI(uriPath);
-        assertNotNull("Failed converting " + uriPath, uri);
-        assertEquals(expected, uri.toString());
-    }
-
-    private void assertEqualUriPath(String expected, String uriPath) {
-        String fixed = MapEntry.fixUriPath(uriPath);
-        assertNotNull(fixed);
-        assertEquals(expected, fixed);
-    }
-
-    private boolean isRegExp(final String string) {
-        try {
-            Method m = MapEntry.class.getDeclaredMethod("isRegExp", String.class);
-            m.setAccessible(true);
-            return (Boolean) m.invoke(null, string);
-        } catch (Exception e) {
-            fail(e.toString());
-            return false; // quiesc compiler
-        }
-    }
-
-    private String[] filterRegExp(final String... strings) {
-        try {
-            Method m = MapEntry.class.getDeclaredMethod("filterRegExp", String[].class);
-            m.setAccessible(true);
-            return (String[]) m.invoke(null, new Object[] {
-                strings
-            });
-        } catch (Exception e) {
-            fail(e.toString());
-            return null; // quiesc compiler
-        }
-    }
-}
diff --git a/src/test/java/org/apache/sling/resourceresolver/impl/observation/ResourceChangeListenerInfoTest.java b/src/test/java/org/apache/sling/resourceresolver/impl/observation/ResourceChangeListenerInfoTest.java
deleted file mode 100644
index cdcfd81..0000000
--- a/src/test/java/org/apache/sling/resourceresolver/impl/observation/ResourceChangeListenerInfoTest.java
+++ /dev/null
@@ -1,50 +0,0 @@
-/*******************************************************************************
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements.  See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- ******************************************************************************/
-package org.apache.sling.resourceresolver.impl.observation;
-
-import java.util.Set;
-
-import org.apache.sling.api.resource.observation.ResourceChangeListener;
-import org.junit.Test;
-import org.osgi.framework.ServiceReference;
-
-import static org.junit.Assert.assertTrue;
-import static org.mockito.Mockito.mock;
-import static org.mockito.Mockito.when;
-
-public class ResourceChangeListenerInfoTest {
-
-    @Test
-    public void testGetExpandedRelativePaths() {
-        ServiceReference reference = mock(ServiceReference.class);
-        when(reference.getProperty(ResourceChangeListener.PATHS)).thenReturn(new String[] {"./**/*.html"});
-        final ResourceChangeListenerInfo rcli = new ResourceChangeListenerInfo(reference, new String[] {"/apps/", "/libs/"});
-        Set<String> paths = rcli.getPaths().toStringSet();
-        assertTrue("PathSet " + paths.toString() + " does not contain /apps/**/*.html.", paths.contains("/apps/**/*.html"));
-        assertTrue("PathSet " + paths.toString() + " does not contain /libs/**/*.html.", paths.contains("/libs/**/*.html"));
-    }
-
-    @Test
-    public void testDotPathConfig() {
-        ServiceReference reference = mock(ServiceReference.class);
-        when(reference.getProperty(ResourceChangeListener.PATHS)).thenReturn(new String[] {"."});
-        final ResourceChangeListenerInfo rcli = new ResourceChangeListenerInfo(reference, new String[] {"/apps/", "/libs/"});
-        Set<String> paths = rcli.getPaths().toStringSet();
-        assertTrue("PathSet " + paths.toString() + " does not contain /apps/", paths.contains("/apps/"));
-        assertTrue("PathSet " + paths.toString() + " does not contain /libs/.", paths.contains("/libs/"));
-    }
-}
diff --git a/src/test/java/org/apache/sling/resourceresolver/impl/params/PathParserTest.java b/src/test/java/org/apache/sling/resourceresolver/impl/params/PathParserTest.java
deleted file mode 100644
index 5c81d6a..0000000
--- a/src/test/java/org/apache/sling/resourceresolver/impl/params/PathParserTest.java
+++ /dev/null
@@ -1,179 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *   http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-
-package org.apache.sling.resourceresolver.impl.params;
-
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertNull;
-import static org.junit.Assert.assertTrue;
-
-import java.util.HashMap;
-import java.util.Map;
-
-import org.apache.sling.resourceresolver.impl.params.PathParser;
-import org.junit.Test;
-
-public class PathParserTest {
-
-    private PathParser parser = new PathParser();
-
-    @Test
-    public void nullParsesToNull() {
-        parser.parse(null);
-        assertNull(parser.getPath());
-        assertTrue(parser.getParameters().isEmpty());
-    }
-
-    @Test
-    public void emptyParsesToEmpty() {
-        parser.parse("");
-        assertEquals("", parser.getPath());
-        assertTrue(parser.getParameters().isEmpty());
-    }
-
-    @Test
-    public void noParametersReturnEmptyMap() {
-        parser.parse("/path/with/no/parameters");
-        assertEquals("/path/with/no/parameters", parser.getPath());
-        assertTrue(parser.getParameters().isEmpty());
-    }
-
-    @Test
-    public void parameterCanBeAddedAfterResource() {
-        parser.parse("/content/test;key1=xyz");
-        assertEquals("/content/test", parser.getPath());
-        assertEquals(map("key1", "xyz"), parser.getParameters());
-
-        parser.parse("/content/test;key1=xyz.html");
-        assertEquals("/content/test.html", parser.getPath());
-        assertEquals(map("key1", "xyz"), parser.getParameters());
-    }
-
-    @Test
-    public void parameterCanBeEscaped() {
-        parser.parse("/content/test;key1='xyz'");
-        assertEquals("/content/test", parser.getPath());
-        assertEquals(map("key1", "xyz"), parser.getParameters());
-
-        parser.parse("/content/test;key1='xyz'.html");
-        assertEquals("/content/test.html", parser.getPath());
-        assertEquals(map("key1", "xyz"), parser.getParameters());
-    }
-
-    @Test
-    public void multipleParametersAreAllowed() {
-        parser.parse("/content/test;key1=xyz;key2=abc");
-        assertEquals("/content/test", parser.getPath());
-        assertEquals(map("key1", "xyz", "key2", "abc"), parser.getParameters());
-
-        parser.parse("/content/test;key1=xyz;key2=abc.html");
-        assertEquals("/content/test.html", parser.getPath());
-        assertEquals(map("key1", "xyz", "key2", "abc"), parser.getParameters());
-    }
-
-    @Test
-    public void multipleParametersCanBeEscaped() {
-        parser.parse("/content/test;key1='a.b';key2='c.d'");
-        assertEquals("/content/test", parser.getPath());
-        assertEquals(map("key1", "a.b", "key2", "c.d"), parser.getParameters());
-
-        parser.parse("/content/test;key1='a.b';key2='c.d'.html");
-        assertEquals("/content/test.html", parser.getPath());
-        assertEquals(map("key1", "a.b", "key2", "c.d"), parser.getParameters());
-    }
-
-    @Test
-    public void parameterCanBeAddedAfterExtension() {
-        parser.parse("/content/test.html;key1=xyz");
-        assertEquals("/content/test.html", parser.getPath());
-        assertEquals(map("key1", "xyz"), parser.getParameters());
-
-        parser.parse("/content/test.html;key1=xyz/suffix");
-        assertEquals("/content/test.html/suffix", parser.getPath());
-        assertEquals(map("key1", "xyz"), parser.getParameters());
-
-    }
-
-    @Test
-    public void dotDoesntHaveToBeEscapedAfterExtension() {
-        parser.parse("/content/test.html;v=1.0");
-        assertEquals("/content/test.html", parser.getPath());
-        assertEquals(map("v", "1.0"), parser.getParameters());
-
-        parser.parse("/content/test.html;v=1.0/suffix");
-        assertEquals("/content/test.html/suffix", parser.getPath());
-        assertEquals(map("v", "1.0"), parser.getParameters());
-    }
-
-    @Test
-    public void slashHaveToBeEscapedAfterExtension() {
-        parser.parse("/content/test.html;v='1/0'");
-        assertEquals("/content/test.html", parser.getPath());
-        assertEquals(map("v", "1/0"), parser.getParameters());
-
-        parser.parse("/content/test.html;v='1/0'/suffix");
-        assertEquals("/content/test.html/suffix", parser.getPath());
-        assertEquals(map("v", "1/0"), parser.getParameters());
-    }
-
-    @Test
-    public void quoteHasToBeClosed() {
-        testInvalidParams("/content/test;key1='a.b;key2=cde.html/asd");
-    }
-
-    @Test
-    public void emptyValueIsAllowed() {
-        parser.parse("/content/test;key1=''.html");
-        assertEquals("/content/test.html", parser.getPath());
-        assertEquals(map("key1", ""), parser.getParameters());
-
-        parser.parse("/content/test;key1=.html");
-        assertEquals("/content/test.html", parser.getPath());
-        assertEquals(map("key1", ""), parser.getParameters());
-    }
-
-    @Test
-    public void parametersWithoutEqualsSignAreInvalid() {
-        testInvalidParams("/content/test;key1.html");
-    }
-
-    @Test
-    public void parametersInTheMiddleOfThePathAreInvalid() {
-        testInvalidParams("/content;key=value/test.html");
-    }
-
-    @Test
-    public void parametersInTheSuffixAreInvalid() {
-        testInvalidParams("/content/test.html/suffix;key=value");
-    }
-
-    private static Map<String, String> map(String... values) {
-        Map<String, String> m = new HashMap<String, String>();
-        for (int i = 0; i < values.length; i += 2) {
-            m.put(values[i], values[i + 1]);
-        }
-        return m;
-    }
-
-    private void testInvalidParams(String path) {
-        parser.parse(path);
-        assertEquals(path, parser.getPath());
-        assertEquals(map(), parser.getParameters());
-    }
-}
diff --git a/src/test/java/org/apache/sling/resourceresolver/impl/providers/ResourceProviderTrackerTest.java b/src/test/java/org/apache/sling/resourceresolver/impl/providers/ResourceProviderTrackerTest.java
deleted file mode 100644
index 9105929..0000000
--- a/src/test/java/org/apache/sling/resourceresolver/impl/providers/ResourceProviderTrackerTest.java
+++ /dev/null
@@ -1,299 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *   http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-package org.apache.sling.resourceresolver.impl.providers;
-
-import static org.hamcrest.Matchers.arrayWithSize;
-import static org.hamcrest.Matchers.equalTo;
-import static org.hamcrest.Matchers.hasSize;
-import static org.junit.Assert.assertFalse;
-import static org.junit.Assert.assertThat;
-import static org.junit.Assert.assertTrue;
-import static org.mockito.Mockito.mock;
-
-import java.util.Collections;
-import java.util.List;
-import java.util.concurrent.atomic.AtomicBoolean;
-
-import org.apache.sling.api.resource.observation.ResourceChange;
-import org.apache.sling.api.resource.path.Path;
-import org.apache.sling.api.resource.path.PathSet;
-import org.apache.sling.api.resource.runtime.dto.AuthType;
-import org.apache.sling.api.resource.runtime.dto.RuntimeDTO;
-import org.apache.sling.resourceresolver.impl.Fixture;
-import org.apache.sling.resourceresolver.impl.providers.ResourceProviderTracker.ChangeListener;
-import org.apache.sling.resourceresolver.impl.providers.ResourceProviderTracker.ObservationReporterGenerator;
-import org.apache.sling.spi.resource.provider.ObservationReporter;
-import org.apache.sling.spi.resource.provider.ObserverConfiguration;
-import org.apache.sling.spi.resource.provider.ResourceProvider;
-import org.apache.sling.testing.mock.osgi.MockOsgi;
-import org.junit.Before;
-import org.junit.Test;
-import org.osgi.framework.BundleContext;
-import org.osgi.service.event.EventAdmin;
-
-public class ResourceProviderTrackerTest {
-
-    private ResourceProviderInfo rp2Info;
-    private ResourceProviderTracker tracker;
-    private Fixture fixture;
-
-    @Before
-    public void prepare() throws Exception {
-        BundleContext bundleContext = MockOsgi.newBundleContext();
-
-        fixture = new Fixture(bundleContext);
-
-        EventAdmin eventAdmin = mock(EventAdmin.class);
-
-        @SuppressWarnings("unchecked")
-        ResourceProvider<Object> rp = mock(ResourceProvider.class);
-        @SuppressWarnings("unchecked")
-        ResourceProvider<Object> rp2 = mock(ResourceProvider.class);
-        @SuppressWarnings("unchecked")
-        ResourceProvider<Object> rp3 = mock(ResourceProvider.class);
-
-        fixture.registerResourceProvider(rp, "/", AuthType.no);
-        rp2Info = fixture.registerResourceProvider(rp2, "/path", AuthType.lazy);
-        fixture.registerResourceProvider(rp3, "invalid", AuthType.no);
-
-        tracker = new ResourceProviderTracker();
-
-        tracker.setObservationReporterGenerator(new SimpleObservationReporterGenerator(new NoDothingObservationReporter()));
-        tracker.activate(bundleContext, eventAdmin, new DoNothingChangeListener());
-    }
-
-    @Test
-    public void activate() {
-
-        // since the OSGi mocks are asynchronous we don't have to wait for the changes to propagate
-
-        assertThat(tracker.getResourceProviderStorage().getAllHandlers().size(), equalTo(2));
-
-        fixture.unregisterResourceProvider(rp2Info);
-
-        assertThat(tracker.getResourceProviderStorage().getAllHandlers().size(), equalTo(1));
-    }
-
-    @Test
-    public void deactivate() {
-
-        tracker.deactivate();
-
-        assertThat(tracker.getResourceProviderStorage().getAllHandlers(), hasSize(0));
-    }
-
-    @Test
-    public void testActivationDeactivation() throws Exception {
-        final BundleContext bundleContext = MockOsgi.newBundleContext();
-        final EventAdmin eventAdmin = mock(EventAdmin.class);
-
-        final Fixture fixture = new Fixture(bundleContext);
-        final ResourceProviderTracker tracker = new ResourceProviderTracker();
-        tracker.setObservationReporterGenerator(new SimpleObservationReporterGenerator(new NoDothingObservationReporter()));
-
-        // create boolean markers for the listener
-        final AtomicBoolean addedCalled = new AtomicBoolean(false);
-        final AtomicBoolean removedCalled = new AtomicBoolean(false);
-
-        final ChangeListener listener = new ChangeListener() {
-
-            @Override
-            public void providerAdded() {
-                addedCalled.set(true);
-            }
-
-            @Override
-            public void providerRemoved(String name, String pid, boolean stateful, boolean used) {
-                removedCalled.set(true);
-            }
-
-        };
-        // activate and check that no listener is called yet
-        tracker.activate(bundleContext, eventAdmin, listener);
-        assertFalse(addedCalled.get());
-        assertFalse(removedCalled.get());
-
-        // add a new resource provider
-        @SuppressWarnings("unchecked")
-        ResourceProvider<Object> rp = mock(ResourceProvider.class);
-        final ResourceProviderInfo info = fixture.registerResourceProvider(rp, "/", AuthType.no);
-
-        // check added is called but not removed
-        assertTrue(addedCalled.get());
-        assertFalse(removedCalled.get());
-
-        // verify a single provider
-        assertThat(tracker.getResourceProviderStorage().getAllHandlers().size(), equalTo(1));
-
-        // reset boolean markers
-        addedCalled.set(false);
-        removedCalled.set(false);
-
-        // remove provider
-        fixture.unregisterResourceProvider(info);
-
-        // verify removed is called but not added
-        assertTrue(removedCalled.get());
-        assertFalse(addedCalled.get());
-
-        // no provider anymore
-        assertThat(tracker.getResourceProviderStorage().getAllHandlers().size(), equalTo(0));
-    }
-
-    @Test
-    public void testReactivation() throws Exception {
-        final BundleContext bundleContext = MockOsgi.newBundleContext();
-        final EventAdmin eventAdmin = mock(EventAdmin.class);
-
-        final Fixture fixture = new Fixture(bundleContext);
-        final ResourceProviderTracker tracker = new ResourceProviderTracker();
-        tracker.setObservationReporterGenerator(new SimpleObservationReporterGenerator(new NoDothingObservationReporter()));
-
-        // create boolean markers for the listener
-        final AtomicBoolean addedCalled = new AtomicBoolean(false);
-        final AtomicBoolean removedCalled = new AtomicBoolean(false);
-
-        final ChangeListener listener = new ChangeListener() {
-
-            @Override
-            public void providerAdded() {
-                addedCalled.set(true);
-            }
-
-            @Override
-            public void providerRemoved(String name, String pid, boolean stateful, boolean used) {
-                removedCalled.set(true);
-            }
-
-        };
-        // activate and check that no listener is called yet
-        tracker.activate(bundleContext, eventAdmin, listener);
-        assertFalse(addedCalled.get());
-        assertFalse(removedCalled.get());
-
-        // activate and check that no listener is called yet
-        @SuppressWarnings("unchecked")
-        ResourceProvider<Object> rp = mock(ResourceProvider.class);
-        final ResourceProviderInfo info = fixture.registerResourceProvider(rp, "/", AuthType.no);
-
-        // check added is called but not removed
-        assertTrue(addedCalled.get());
-        assertFalse(removedCalled.get());
-
-        // verify a single provider
-        assertThat(tracker.getResourceProviderStorage().getAllHandlers().size(), equalTo(1));
-
-        // reset boolean markers
-        addedCalled.set(false);
-        removedCalled.set(false);
-
-        // add overlay provider
-        final ResourceProviderInfo infoOverlay = fixture.registerResourceProvider(rp, "/", AuthType.no);
-
-        // check added and removed is called
-        assertTrue(addedCalled.get());
-        assertTrue(removedCalled.get());
-
-        // verify a single provider
-        assertThat(tracker.getResourceProviderStorage().getAllHandlers().size(), equalTo(1));
-
-        // reset boolean markers
-        addedCalled.set(false);
-        removedCalled.set(false);
-
-        // unregister overlay provider
-        fixture.unregisterResourceProvider(infoOverlay);
-
-        // check added and removed is called
-        assertTrue(addedCalled.get());
-        assertTrue(removedCalled.get());
-
-        // verify a single provider
-        assertThat(tracker.getResourceProviderStorage().getAllHandlers().size(), equalTo(1));
-
-        // reset boolean markers
-        addedCalled.set(false);
-        removedCalled.set(false);
-
-        // unregister first provider
-        fixture.unregisterResourceProvider(info);
-
-        // check removed is called but not added
-        assertTrue(removedCalled.get());
-        assertFalse(addedCalled.get());
-
-        // verify no provider
-        assertThat(tracker.getResourceProviderStorage().getAllHandlers().size(), equalTo(0));
-    }
-
-    @Test
-    public void fillDto() throws Exception {
-
-        RuntimeDTO dto = new RuntimeDTO();
-
-        tracker.fill(dto);
-
-        assertThat( dto.providers, arrayWithSize(2));
-        assertThat( dto.failedProviders, arrayWithSize(1));
-    }
-
-    static final class NoDothingObservationReporter implements ObservationReporter {
-        @Override
-        public void reportChanges(Iterable<ResourceChange> changes, boolean distribute) {
-        }
-
-        @Override
-        public List<ObserverConfiguration> getObserverConfigurations() {
-            return Collections.emptyList();
-        }
-    }
-
-    static final class SimpleObservationReporterGenerator implements ObservationReporterGenerator {
-        private final ObservationReporter reporter;
-
-        SimpleObservationReporterGenerator(ObservationReporter reporter) {
-            this.reporter = reporter;
-        }
-
-        @Override
-        public ObservationReporter createProviderReporter() {
-            return reporter;
-        }
-
-        @Override
-        public ObservationReporter create(Path path, PathSet excludes) {
-            return reporter;
-        }
-    }
-
-    static final class DoNothingChangeListener implements ChangeListener {
-
-        @Override
-        public void providerAdded() {
-            // TODO Auto-generated method stub
-
-        }
-
-        @Override
-        public void providerRemoved(String name, String pid, boolean stateful, boolean used) {
-            // TODO Auto-generated method stub
-
-        }
-    }
-}
\ No newline at end of file
diff --git a/src/test/java/org/apache/sling/resourceresolver/impl/providers/stateful/AuthenticatedResourceProviderTest.java b/src/test/java/org/apache/sling/resourceresolver/impl/providers/stateful/AuthenticatedResourceProviderTest.java
deleted file mode 100644
index 319cd95..0000000
--- a/src/test/java/org/apache/sling/resourceresolver/impl/providers/stateful/AuthenticatedResourceProviderTest.java
+++ /dev/null
@@ -1,109 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *   http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-package org.apache.sling.resourceresolver.impl.providers.stateful;
-
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertFalse;
-import static org.junit.Assert.assertTrue;
-import static org.mockito.Mockito.mock;
-import static org.mockito.Mockito.verify;
-import static org.mockito.Mockito.when;
-
-import org.apache.sling.api.resource.PersistenceException;
-import org.apache.sling.api.resource.Resource;
-import org.apache.sling.api.resource.ResourceResolver;
-import org.apache.sling.api.security.AccessSecurityException;
-import org.apache.sling.api.security.ResourceAccessSecurity;
-import org.apache.sling.resourceresolver.impl.ResourceAccessSecurityTracker;
-import org.apache.sling.resourceresolver.impl.providers.ResourceProviderHandler;
-import org.apache.sling.spi.resource.provider.QueryLanguageProvider;
-import org.apache.sling.spi.resource.provider.ResolveContext;
-import org.apache.sling.spi.resource.provider.ResourceProvider;
-import org.junit.Before;
-import org.junit.Test;
-
-public class AuthenticatedResourceProviderTest {
-
-    private AuthenticatedResourceProvider src;
-
-    private ResourceAccessSecurity security;
-    private ResourceResolver resourceResolver;
-    private ResolveContext<Object> resolveContext;
-    private ResourceProvider<Object> resourceProvider;
-    private QueryLanguageProvider<Object> queryLanguageProvider;
-
-    private boolean useRAS;
-
-    @Before
-    public void prepare() throws PersistenceException, AccessSecurityException {
-        this.resourceResolver = mock(ResourceResolver.class);
-        this.resolveContext = mock(ResolveContext.class);
-        when(this.resolveContext.getResourceResolver()).thenReturn(this.resourceResolver);
-
-        this.security = mock(ResourceAccessSecurity.class);
-
-        this.queryLanguageProvider = mock(QueryLanguageProvider.class);
-
-        this.resourceProvider = mock(ResourceProvider.class);
-        when(resourceProvider.getQueryLanguageProvider()).thenReturn(this.queryLanguageProvider);
-
-        final ResourceProviderHandler handler = mock(ResourceProviderHandler.class);
-        when(handler.getResourceProvider()).thenReturn(this.resourceProvider);
-
-        useRAS = false;
-
-        final ResourceAccessSecurityTracker securityTracker = new ResourceAccessSecurityTracker() {
-            @Override
-            public ResourceAccessSecurity getApplicationResourceAccessSecurity() {
-                if ( useRAS) {
-                    return security;
-                }
-                return null;
-            }
-        };
-
-        this.src = new AuthenticatedResourceProvider(handler, false, this.resolveContext, securityTracker);
-
-    }
-
-    @Test public void testBasics() throws Exception {
-        assertEquals(this.resolveContext, this.src.getResolveContext());
-
-        this.src.refresh();
-        verify(this.resourceProvider).refresh(this.resolveContext);
-
-        when(this.resourceProvider.isLive(this.resolveContext)).thenReturn(true);
-        assertTrue(this.src.isLive());
-        when(this.resourceProvider.isLive(this.resolveContext)).thenReturn(false);
-        assertFalse(this.src.isLive());
-
-        this.src.commit();
-        verify(this.resourceProvider).commit(this.resolveContext);
-    }
-
-    @Test public void testGetParent() {
-        final Resource child = mock(Resource.class);
-        when(child.getPath()).thenReturn("/parent/child");
-        final Resource parent = mock(Resource.class);
-        when(parent.getPath()).thenReturn("/parent");
-        when(this.resourceProvider.getParent(this.resolveContext, child)).thenReturn(parent);
-
-        assertEquals("/parent", this.src.getParent(child).getPath());
-    }
-}
diff --git a/src/test/java/org/apache/sling/resourceresolver/impl/providers/stateful/SecureResourceProviderDecoratorTest.java b/src/test/java/org/apache/sling/resourceresolver/impl/providers/stateful/SecureResourceProviderDecoratorTest.java
deleted file mode 100644
index 8442a71..0000000
--- a/src/test/java/org/apache/sling/resourceresolver/impl/providers/stateful/SecureResourceProviderDecoratorTest.java
+++ /dev/null
@@ -1,153 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *   http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-package org.apache.sling.resourceresolver.impl.providers.stateful;
-
-import static org.hamcrest.MatcherAssert.assertThat;
-import static org.hamcrest.Matchers.equalTo;
-import static org.junit.Assert.assertNotNull;
-import static org.junit.Assert.assertNull;
-import static org.junit.Assert.fail;
-import static org.mockito.Mockito.mock;
-import static org.mockito.Mockito.verify;
-import static org.mockito.Mockito.when;
-
-import java.util.Arrays;
-import java.util.Collections;
-import java.util.Iterator;
-
-import org.apache.sling.api.resource.PersistenceException;
-import org.apache.sling.api.resource.Resource;
-import org.apache.sling.api.resource.ResourceResolver;
-import org.apache.sling.api.security.AccessSecurityException;
-import org.apache.sling.api.security.ResourceAccessSecurity;
-import org.apache.sling.resourceresolver.impl.ResourceAccessSecurityTracker;
-import org.apache.sling.resourceresolver.impl.providers.ResourceProviderHandler;
-import org.apache.sling.spi.resource.provider.QueryLanguageProvider;
-import org.apache.sling.spi.resource.provider.ResolveContext;
-import org.apache.sling.spi.resource.provider.ResourceProvider;
-import org.junit.Before;
-import org.junit.Test;
-import org.mockito.Mockito;
-
-public class SecureResourceProviderDecoratorTest {
-
-    private ResourceAccessSecurity security;
-    private ResourceResolver rr;
-    private ResolveContext resolveContext;
-    private AuthenticatedResourceProvider src;
-    private ResourceProvider rp;
-    private Resource first;
-    private Resource second;
-
-    @Before
-    public void prepare() throws PersistenceException, AccessSecurityException {
-
-        rr = mock(ResourceResolver.class);
-        resolveContext = mock(ResolveContext.class);
-        when(resolveContext.getResourceResolver()).thenReturn(rr);
-
-        security = mock(ResourceAccessSecurity.class);
-        first = mock(Resource.class);
-        second = mock(Resource.class);
-
-        when(security.getReadableResource(first)).thenReturn(first);
-        when(security.getReadableResource(second)).thenReturn(null);
-        when(security.transformQuery("FIND ALL", "MockQueryLanguage", rr)).thenReturn("FIND ALL");
-
-        QueryLanguageProvider qlp = mock(QueryLanguageProvider.class);
-
-        rp = mock(ResourceProvider.class);
-        when(rp.getQueryLanguageProvider()).thenReturn(qlp);
-
-        when(rp.create(resolveContext, "/some/path", Collections.<String, Object> emptyMap())).thenReturn(mock(Resource.class));
-        when(qlp.findResources(resolveContext, "FIND ALL", "MockQueryLanguage")).thenReturn(Arrays.asList(first, second).iterator());
-
-        ResourceAccessSecurityTracker securityTracker = new ResourceAccessSecurityTracker() {
-            @Override
-            public ResourceAccessSecurity getApplicationResourceAccessSecurity() {
-                return security;
-            }
-        };
-
-        final ResourceProviderHandler handler = mock(ResourceProviderHandler.class);
-        when(handler.getResourceProvider()).thenReturn(this.rp);
-
-        src = new AuthenticatedResourceProvider(handler, false, resolveContext, securityTracker);
-
-    }
-
-    @Test
-    public void create_success() throws PersistenceException {
-
-        when(security.canCreate("/some/path", rr)).thenReturn(true);
-
-        assertNotNull("expected resource to be created", src.create(rr, "/some/path", Collections.<String, Object> emptyMap()));
-    }
-
-    @Test
-    public void create_failure() throws PersistenceException {
-
-        when(security.canCreate("/some/path", rr)).thenReturn(false);
-
-        assertNull("expected resource to not be created", src.create(rr, "/some/path", Collections.<String, Object> emptyMap()));
-    }
-
-    @Test
-    public void delete_success() throws PersistenceException {
-
-        Resource toDelete = mock(Resource.class);
-
-        when(security.canDelete(toDelete)).thenReturn(true);
-
-        src.delete(toDelete);
-
-        verify(rp).delete(resolveContext, toDelete);
-    }
-
-    @Test
-    public void delete_failure() throws PersistenceException {
-
-        Resource toDelete = mock(Resource.class);
-
-        when(security.canDelete(toDelete)).thenReturn(false);
-
-        try {
-            src.delete(toDelete);
-            fail();
-        } catch ( PersistenceException pe ) {
-            // correct
-        }
-
-        Mockito.verifyZeroInteractions(rp);
-    }
-
-    @Test
-    public void find() {
-
-        Iterator<Resource> resources = src.findResources("FIND ALL", "MockQueryLanguage");
-
-        assertThat("resources should contain at least one item", resources.hasNext(), equalTo(true));
-
-        Resource resource = resources.next();
-
-        assertThat("unexpected resource found", resource, equalTo(first));
-
-        assertThat("resources should exactly at least one item", resources.hasNext(), equalTo(false));
-    }
-}
diff --git a/src/test/java/org/apache/sling/resourceresolver/impl/providers/tree/PathTreeTest.java b/src/test/java/org/apache/sling/resourceresolver/impl/providers/tree/PathTreeTest.java
deleted file mode 100644
index 3a4fb21..0000000
--- a/src/test/java/org/apache/sling/resourceresolver/impl/providers/tree/PathTreeTest.java
+++ /dev/null
@@ -1,110 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *   http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-package org.apache.sling.resourceresolver.impl.providers.tree;
-
-import static java.util.Arrays.asList;
-import static org.hamcrest.Matchers.equalTo;
-import static org.hamcrest.Matchers.nullValue;
-import static org.junit.Assert.assertThat;
-
-import org.hamcrest.Matchers;
-import org.junit.Before;
-import org.junit.Test;
-
-public class PathTreeTest {
-
-    private PathTree<Pathable> tree;
-
-    @Before
-    public void createTree() {
-
-        Pathable root = new StringPath("/");
-        Pathable libs = new StringPath("/libs");
-        Pathable libsSling = new StringPath("/libs/sling");
-        Pathable apps = new StringPath("/apps");
-
-        tree = new PathTree<Pathable>(asList(root, libs, libsSling, apps));
-    }
-
-    @Test
-    public void bestMatchForChildNode() {
-
-        assertPathHasBestMatch("/libs", "/libs");
-        assertPathHasExactMatch("/libs");
-    }
-    
-    private void assertPathHasBestMatch(String path, String expectedNode) {
-        
-        assertThat(tree.getBestMatchingNode(path).getValue().getPath(), equalTo(expectedNode));
-    }
-
-    private void assertPathHasExactMatch(String path) {
-        
-        assertThat(tree.getNode(path).getValue().getPath(), equalTo(path));
-    }
-
-    private void assertPathDoesNotHaveExactMatch(String path) {
-        
-        assertThat(tree.getNode(path), nullValue());
-    }
-
-    @Test
-    public void bestMatchForChildNodeNested() {
-
-        assertPathHasBestMatch("/apps/sling", "/apps");
-        assertPathDoesNotHaveExactMatch("/apps/sling");
-    }
-
-    @Test
-    public void bestMatchForChildNodeDeeplyNested() {
-        
-        assertPathHasBestMatch("/libs/sling/base/install", "/libs/sling");
-        assertPathDoesNotHaveExactMatch("/libs/sling/base/install");
-    }
-
-    @Test
-    public void bestMatchRootNodeFallback() {
-
-        assertPathHasBestMatch("/system", "/");
-        assertPathDoesNotHaveExactMatch("/system");
-    }
-    
-    @Test
-    public void bestMatchForInvalidPaths() {
-        
-        for ( String invalid : new String[] { null, "", "not/absolute/path"} ) {
-            assertThat("getBestMatchingNode(" + invalid + ")", tree.getBestMatchingNode(invalid), Matchers.nullValue());
-            assertThat("getNode(" + invalid + ")", tree.getNode(invalid), Matchers.nullValue());
-        }
-    }
-    
-    static class StringPath implements Pathable {
-
-        private final String path;
-
-        public StringPath(String path) {
-            this.path = path;
-        }
-
-        @Override
-        public String getPath() {
-            return path;
-        }
-    }
-}
\ No newline at end of file
diff --git a/src/test/resources/test-project/explicit-excludes.pom.xml b/src/test/resources/test-project/explicit-excludes.pom.xml
new file mode 100644
index 0000000..4fb5fe7
--- /dev/null
+++ b/src/test/resources/test-project/explicit-excludes.pom.xml
@@ -0,0 +1,52 @@
+<!--~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+  ~ 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.
+  ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~-->
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+    <modelVersion>4.0.0</modelVersion>
+
+    <groupId>org.apache.sling</groupId>
+    <artifactId>htl-maven-plugin-it-explicit-excludes</artifactId>
+    <version>0.0.1-SNAPSHOT</version>
+    <packaging>pom</packaging>
+
+    <name>HTL Maven Plugin IT - Explicit excludes</name>
+
+    <build>
+        <plugins>
+            <plugin>
+                <groupId>org.apache.sling</groupId>
+                <artifactId>htl-maven-plugin</artifactId>
+                <configuration>
+                    <sourceDirectory>src/main/resources</sourceDirectory>
+                    <!-- only script.html will be compiled -->
+                    <excludes>
+                        <exclude>**/exclude.html</exclude>
+                    </excludes>
+                </configuration>
+                <executions>
+                    <execution>
+                        <id>validate-scripts</id>
+                        <goals>
+                            <goal>validate</goal>
+                        </goals>
+                        <phase>compile</phase>
+                    </execution>
+                </executions>
+            </plugin>
+        </plugins>
+    </build>
+</project>
diff --git a/src/test/resources/test-project/explicit-includes.pom.xml b/src/test/resources/test-project/explicit-includes.pom.xml
new file mode 100644
index 0000000..9e073da
--- /dev/null
+++ b/src/test/resources/test-project/explicit-includes.pom.xml
@@ -0,0 +1,52 @@
+<!--~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+  ~ 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.
+  ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~-->
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+    <modelVersion>4.0.0</modelVersion>
+
+    <groupId>org.apache.sling</groupId>
+    <artifactId>htl-maven-plugin-it-explicit-includes</artifactId>
+    <version>0.0.1-SNAPSHOT</version>
+    <packaging>pom</packaging>
+
+    <name>HTL Maven Plugin IT - Explicit includes</name>
+
+    <build>
+        <plugins>
+            <plugin>
+                <groupId>org.apache.sling</groupId>
+                <artifactId>htl-maven-plugin</artifactId>
+                <configuration>
+                    <sourceDirectory>src/main/resources</sourceDirectory>
+                    <!-- only *.sly files will be compiled -->
+                    <includes>
+                        <include>**/*.sly</include>
+                    </includes>
+                </configuration>
+                <executions>
+                    <execution>
+                        <id>validate-scripts</id>
+                        <goals>
+                            <goal>validate</goal>
+                        </goals>
+                        <phase>compile</phase>
+                    </execution>
+                </executions>
+            </plugin>
+        </plugins>
+    </build>
+</project>
diff --git a/src/test/resources/test-project/fail-on-warnings.pom.xml b/src/test/resources/test-project/fail-on-warnings.pom.xml
new file mode 100644
index 0000000..f207e65
--- /dev/null
+++ b/src/test/resources/test-project/fail-on-warnings.pom.xml
@@ -0,0 +1,53 @@
+<!--~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+  ~ 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.
+  ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~-->
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+    <modelVersion>4.0.0</modelVersion>
+
+    <groupId>org.apache.sling</groupId>
+    <artifactId>htl-maven-plugin-it-fail-on-warnings</artifactId>
+    <version>0.0.1-SNAPSHOT</version>
+    <packaging>pom</packaging>
+
+    <name>HTL Maven Plugin IT - Fail On Warnings</name>
+
+    <build>
+        <plugins>
+            <plugin>
+                <groupId>org.apache.sling</groupId>
+                <artifactId>htl-maven-plugin</artifactId>
+                <configuration>
+                    <sourceDirectory>src/main/resources</sourceDirectory>
+                    <!-- only the warning.sly file will be compiled -->
+                    <includes>
+                        <include>**/warning.sly</include>
+                    </includes>
+                    <failOnWarnings>true</failOnWarnings>
+                </configuration>
+                <executions>
+                    <execution>
+                        <id>validate-scripts</id>
+                        <goals>
+                            <goal>validate</goal>
+                        </goals>
+                        <phase>compile</phase>
+                    </execution>
+                </executions>
+            </plugin>
+        </plugins>
+    </build>
+</project>
diff --git a/src/test/resources/test-project/src/main/resources/apps/projects/error.sly b/src/test/resources/test-project/src/main/resources/apps/projects/error.sly
new file mode 100644
index 0000000..ffe8613
--- /dev/null
+++ b/src/test/resources/test-project/src/main/resources/apps/projects/error.sly
@@ -0,0 +1,18 @@
+<!--/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+  ~ 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.
+  ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/-->
+<!--/* Intentionally add a Sightly error here; this file should be compiled by the plugin and fail the build. */-->
+${expression.notClosed
diff --git a/src/test/resources/test-project/src/main/resources/apps/projects/exclude.html b/src/test/resources/test-project/src/main/resources/apps/projects/exclude.html
new file mode 100644
index 0000000..95d56d6
--- /dev/null
+++ b/src/test/resources/test-project/src/main/resources/apps/projects/exclude.html
@@ -0,0 +1,18 @@
+<!--~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+  ~ 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.
+  ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~-->
+<!--/* Intentionally add a Sightly error here; this file should not be compiled by the plugin. */-->
+${expression.notClosed
diff --git a/src/test/resources/test-project/src/main/resources/apps/projects/script.html b/src/test/resources/test-project/src/main/resources/apps/projects/script.html
new file mode 100644
index 0000000..5df9256
--- /dev/null
+++ b/src/test/resources/test-project/src/main/resources/apps/projects/script.html
@@ -0,0 +1,17 @@
+<!--/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+  ~ 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.
+  ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/-->
+${this.is.an.expression @ i18n, locale='de'}
diff --git a/src/test/resources/test-project/src/main/resources/apps/projects/warning.sly b/src/test/resources/test-project/src/main/resources/apps/projects/warning.sly
new file mode 100644
index 0000000..fb79153
--- /dev/null
+++ b/src/test/resources/test-project/src/main/resources/apps/projects/warning.sly
@@ -0,0 +1,19 @@
+<!--~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+  ~ 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.
+  ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~-->
+<script>
+    var a = '${a}';
+</script>