diff --git a/arquillian/arquillian-tomee-tests/pom.xml b/arquillian/arquillian-tomee-tests/pom.xml
index f95e596..4d91886 100644
--- a/arquillian/arquillian-tomee-tests/pom.xml
+++ b/arquillian/arquillian-tomee-tests/pom.xml
@@ -398,60 +398,6 @@
                 </configuration>
               </execution>
               <execution>
-                <id>test-tomee-webapp-remote</id>
-                <phase>test</phase>
-                <goals>
-                  <goal>test</goal>
-                </goals>
-                <configuration>
-                  <skip>${skip.webapp.webprofile}</skip>
-                  <systemPropertyVariables>
-                    <tomee.version>${project.version}</tomee.version>
-                    <tomee.tomcatVersion>${tomcat.version}</tomee.tomcatVersion>
-                    <tomee.artifactId>tomee-webapp</tomee.artifactId>
-                    <arquillian.launch>tomee-webapp</arquillian.launch>
-                    <openejb.arquillian.adapter>tomee-webapp</openejb.arquillian.adapter>
-                  </systemPropertyVariables>
-                </configuration>
-              </execution>
-              <execution>
-                <id>test-tomee-webapp-remote-plus</id>
-                <phase>test</phase>
-                <goals>
-                  <goal>test</goal>
-                </goals>
-                <configuration>
-                  <skip>${skip.webapp.plus}</skip>
-                  <systemPropertyVariables>
-                    <tomee.version>${project.version}</tomee.version>
-                    <tomee.tomcatVersion>${tomcat.version}</tomee.tomcatVersion>
-                    <tomee.artifactId>tomee-plus-webapp</tomee.artifactId>
-                    <arquillian.launch>tomee-webapp</arquillian.launch>
-                    <openejb.arquillian.adapter>tomee-webapp</openejb.arquillian.adapter>
-                  </systemPropertyVariables>
-                </configuration>
-              </execution>
-              <execution>
-                <id>test-tomee-webapp-remote-plume</id>
-                <phase>test</phase>
-                <goals>
-                  <goal>test</goal>
-                </goals>
-                <configuration>
-                  <skip>${skip.webapp.plume}</skip>
-                  <systemPropertyVariables>
-                    <tomee.version>${project.version}</tomee.version>
-                    <tomee.tomcatVersion>${tomcat.version}</tomee.tomcatVersion>
-                    <tomee.artifactId>tomee-plume-webapp</tomee.artifactId>
-                    <arquillian.launch>tomee-webapp</arquillian.launch>
-                    <openejb.arquillian.adapter>tomee-webapp</openejb.arquillian.adapter>
-                  </systemPropertyVariables>
-                  <excludes>
-                    <exclude>**/AppComposerTest.java</exclude>
-                  </excludes>
-                </configuration>
-              </execution>
-              <execution>
                 <id>test-tomee-remote-microprofile</id>
                 <phase>test</phase>
                 <goals>
@@ -468,26 +414,6 @@
                   </systemPropertyVariables>
                 </configuration>
               </execution>
-              <execution>
-                <id>test-tomee-webapp-remote-microprofile</id>
-                <phase>test</phase>
-                <goals>
-                  <goal>test</goal>
-                </goals>
-                <configuration>
-                  <skip>${skip.webapp.microprofile}</skip>
-                  <systemPropertyVariables>
-                    <tomee.version>${project.version}</tomee.version>
-                    <tomee.tomcatVersion>${tomcat.version}</tomee.tomcatVersion>
-                    <tomee.artifactId>tomee-microprofile-webapp</tomee.artifactId>
-                    <arquillian.launch>tomee-webapp</arquillian.launch>
-                    <openejb.arquillian.adapter>tomee-webapp</openejb.arquillian.adapter>
-                  </systemPropertyVariables>
-                  <excludes>
-                    <exclude>**/AppComposerTest.java</exclude>
-                  </excludes>
-                </configuration>
-              </execution>
             </executions>
             <configuration>
               <skip>true</skip>
@@ -650,63 +576,6 @@
                   </excludes>
                 </configuration>
               </execution>
-
-              <!-- Tomcat + war against Web Profile, JAX-RS and Plus -->
-
-              <execution>
-                <id>test-tomee-webapp-remote-webprofile</id>
-                <phase>test</phase>
-                <goals>
-                  <goal>test</goal>
-                </goals>
-                <configuration>
-                  <skip>${maven.test.skip}</skip>
-                  <systemPropertyVariables>
-                    <tomee.version>${project.version}</tomee.version>
-                    <tomee.tomcatVersion>${tomcat.version}</tomee.tomcatVersion>
-                    <tomee.artifactId>tomee-webapp</tomee.artifactId>
-                    <arquillian.launch>tomee-webapp</arquillian.launch>
-                    <openejb.arquillian.adapter>tomee-webapp</openejb.arquillian.adapter>
-                  </systemPropertyVariables>
-                </configuration>
-              </execution>
-              <execution>
-                <id>test-tomee-webapp-remote-plus</id>
-                <phase>test</phase>
-                <goals>
-                  <goal>test</goal>
-                </goals>
-                <configuration>
-                  <skip>${maven.test.skip}</skip>
-                  <systemPropertyVariables>
-                    <tomee.version>${project.version}</tomee.version>
-                    <tomee.tomcatVersion>${tomcat.version}</tomee.tomcatVersion>
-                    <tomee.artifactId>tomee-plus-webapp</tomee.artifactId>
-                    <arquillian.launch>tomee-webapp</arquillian.launch>
-                    <openejb.arquillian.adapter>tomee-webapp</openejb.arquillian.adapter>
-                  </systemPropertyVariables>
-                </configuration>
-              </execution>
-              <execution>
-                <id>test-tomee-webapp-remote-plume</id>
-                <phase>test</phase>
-                <goals>
-                  <goal>test</goal>
-                </goals>
-                <configuration>
-                  <skip>${maven.test.skip}</skip>
-                  <systemPropertyVariables>
-                    <tomee.version>${project.version}</tomee.version>
-                    <tomee.tomcatVersion>${tomcat.version}</tomee.tomcatVersion>
-                    <tomee.artifactId>tomee-plume-webapp</tomee.artifactId>
-                    <arquillian.launch>tomee-webapp</arquillian.launch>
-                    <openejb.arquillian.adapter>tomee-webapp</openejb.arquillian.adapter>
-                  </systemPropertyVariables>
-                  <excludes>
-                    <exclude>**/AppComposerTest.java</exclude>
-                  </excludes>
-                </configuration>
-              </execution>
             </executions>
             <configuration>
               <skip>true</skip>
diff --git a/tomee/apache-tomee/pom.xml b/tomee/apache-tomee/pom.xml
index 9863409..86034dd 100644
--- a/tomee/apache-tomee/pom.xml
+++ b/tomee/apache-tomee/pom.xml
@@ -129,6 +129,14 @@
       <version>${project.version}</version>
       <type>jar</type>
     </dependency>
+
+    <!-- needed to compile in intellij for tomcat patches -->
+    <dependency>
+      <groupId>org.apache.tomcat</groupId>
+      <artifactId>tomcat-catalina</artifactId>
+      <version>${tomcat.version}</version>
+      <scope>provided</scope>
+    </dependency>
   </dependencies>
 
   <build>
diff --git a/tomee/apache-tomee/src/patch/java/org/apache/catalina/servlets/DefaultServlet.java b/tomee/apache-tomee/src/patch/java/org/apache/catalina/servlets/DefaultServlet.java
new file mode 100644
index 0000000..7b3c0b7
--- /dev/null
+++ b/tomee/apache-tomee/src/patch/java/org/apache/catalina/servlets/DefaultServlet.java
@@ -0,0 +1,3054 @@
+/*
+ * 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.catalina.servlets;
+
+import java.io.BufferedInputStream;
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileNotFoundException;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.InputStreamReader;
+import java.io.OutputStreamWriter;
+import java.io.PrintWriter;
+import java.io.RandomAccessFile;
+import java.io.Reader;
+import java.io.Serializable;
+import java.io.StringReader;
+import java.io.StringWriter;
+import java.io.UnsupportedEncodingException;
+import java.nio.charset.Charset;
+import java.nio.charset.StandardCharsets;
+import java.security.AccessController;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.Comparator;
+import java.util.Enumeration;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Locale;
+
+import javax.servlet.DispatcherType;
+import javax.servlet.RequestDispatcher;
+import javax.servlet.ServletContext;
+import javax.servlet.ServletException;
+import javax.servlet.ServletOutputStream;
+import javax.servlet.ServletResponse;
+import javax.servlet.ServletResponseWrapper;
+import javax.servlet.UnavailableException;
+import javax.servlet.http.HttpServlet;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+import javax.xml.parsers.DocumentBuilder;
+import javax.xml.parsers.DocumentBuilderFactory;
+import javax.xml.parsers.ParserConfigurationException;
+import javax.xml.transform.Source;
+import javax.xml.transform.Transformer;
+import javax.xml.transform.TransformerException;
+import javax.xml.transform.TransformerFactory;
+import javax.xml.transform.dom.DOMSource;
+import javax.xml.transform.stream.StreamResult;
+import javax.xml.transform.stream.StreamSource;
+
+import org.apache.catalina.Context;
+import org.apache.catalina.Globals;
+import org.apache.catalina.WebResource;
+import org.apache.catalina.WebResourceRoot;
+import org.apache.catalina.connector.RequestFacade;
+import org.apache.catalina.connector.ResponseFacade;
+import org.apache.catalina.util.IOTools;
+import org.apache.catalina.util.ServerInfo;
+import org.apache.catalina.util.URLEncoder;
+import org.apache.catalina.webresources.CachedResource;
+import org.apache.tomcat.util.buf.B2CConverter;
+import org.apache.tomcat.util.http.ResponseUtil;
+import org.apache.tomcat.util.http.parser.ContentRange;
+import org.apache.tomcat.util.http.parser.EntityTag;
+import org.apache.tomcat.util.http.parser.Ranges;
+import org.apache.tomcat.util.res.StringManager;
+import org.apache.tomcat.util.security.Escape;
+import org.apache.tomcat.util.security.PrivilegedGetTccl;
+import org.apache.tomcat.util.security.PrivilegedSetTccl;
+import org.w3c.dom.Document;
+import org.xml.sax.InputSource;
+import org.xml.sax.SAXException;
+import org.xml.sax.ext.EntityResolver2;
+
+
+/**
+ * <p>The default resource-serving servlet for most web applications,
+ * used to serve static resources such as HTML pages and images.
+ * </p>
+ * <p>
+ * This servlet is intended to be mapped to <em>/</em> e.g.:
+ * </p>
+ * <pre>
+ *   &lt;servlet-mapping&gt;
+ *       &lt;servlet-name&gt;default&lt;/servlet-name&gt;
+ *       &lt;url-pattern&gt;/&lt;/url-pattern&gt;
+ *   &lt;/servlet-mapping&gt;
+ * </pre>
+ * <p>It can be mapped to sub-paths, however in all cases resources are served
+ * from the web application resource root using the full path from the root
+ * of the web application context.
+ * <br>e.g. given a web application structure:
+ *</p>
+ * <pre>
+ * /context
+ *   /images
+ *     tomcat2.jpg
+ *   /static
+ *     /images
+ *       tomcat.jpg
+ * </pre>
+ * <p>
+ * ... and a servlet mapping that maps only <code>/static/*</code> to the default servlet:
+ * </p>
+ * <pre>
+ *   &lt;servlet-mapping&gt;
+ *       &lt;servlet-name&gt;default&lt;/servlet-name&gt;
+ *       &lt;url-pattern&gt;/static/*&lt;/url-pattern&gt;
+ *   &lt;/servlet-mapping&gt;
+ * </pre>
+ * <p>
+ * Then a request to <code>/context/static/images/tomcat.jpg</code> will succeed
+ * while a request to <code>/context/images/tomcat2.jpg</code> will fail.
+ * </p>
+ * @author Craig R. McClanahan
+ * @author Remy Maucherat
+ */
+public class DefaultServlet extends HttpServlet {
+
+    private static final long serialVersionUID = 1L;
+
+    /**
+     * The string manager for this package.
+     */
+    protected static final StringManager sm = StringManager.getManager(DefaultServlet.class);
+
+    private static final DocumentBuilderFactory factory;
+
+    private static final SecureEntityResolver secureEntityResolver;
+
+    /**
+     * Full range marker.
+     */
+    protected static final ArrayList<Range> FULL = new ArrayList<>();
+
+    private static final Range IGNORE = new Range();
+
+    /**
+     * MIME multipart separation string
+     */
+    protected static final String mimeSeparation = "CATALINA_MIME_BOUNDARY";
+
+    /**
+     * Size of file transfer buffer in bytes.
+     */
+    protected static final int BUFFER_SIZE = 4096;
+
+
+    // ----------------------------------------------------- Static Initializer
+
+    static {
+        if (Globals.IS_SECURITY_ENABLED) {
+            factory = DocumentBuilderFactory.newInstance();
+            factory.setNamespaceAware(true);
+            factory.setValidating(false);
+            secureEntityResolver = new SecureEntityResolver();
+        } else {
+            factory = null;
+            secureEntityResolver = null;
+        }
+    }
+
+
+    // ----------------------------------------------------- Instance Variables
+
+    /**
+     * The debugging detail level for this servlet.
+     */
+    protected int debug = 0;
+
+    /**
+     * The input buffer size to use when serving resources.
+     */
+    protected int input = 2048;
+
+    /**
+     * Should we generate directory listings?
+     */
+    protected boolean listings = false;
+
+    /**
+     * Read only flag. By default, it's set to true.
+     */
+    protected boolean readOnly = true;
+
+    /**
+     * List of compression formats to serve and their preference order.
+     */
+    protected CompressionFormat[] compressionFormats;
+
+    /**
+     * The output buffer size to use when serving resources.
+     */
+    protected int output = 2048;
+
+    /**
+     * Allow customized directory listing per directory.
+     */
+    protected String localXsltFile = null;
+
+    /**
+     * Allow customized directory listing per context.
+     */
+    protected String contextXsltFile = null;
+
+    /**
+     * Allow customized directory listing per instance.
+     */
+    protected String globalXsltFile = null;
+
+    /**
+     * Allow a readme file to be included.
+     */
+    protected String readmeFile = null;
+
+    /**
+     * The complete set of web application resources
+     */
+    protected transient WebResourceRoot resources = null;
+
+    /**
+     * File encoding to be used when reading static files. If none is specified
+     * the platform default is used.
+     */
+    protected String fileEncoding = null;
+    private transient Charset fileEncodingCharset = null;
+
+    /**
+     * If a file has a BOM, should that be used in preference to fileEncoding?
+     *
+     * - true  - BoM is stripped if present and any BoM found used to determine
+     *            the encoding used to read the resource. This is the default.
+     *
+     * - false - BoM is stripped and resource is read using the configured file
+     *            encoding (which will be the platform default if not explicitly
+     *            configured)
+     *
+     * - path-through - as current false but does not strip the BoM from the output
+     */
+    private String useBomIfPresent = "true";
+
+    /**
+     * Minimum size for sendfile usage in bytes.
+     */
+    protected int sendfileSize = 48 * 1024;
+
+    /**
+     * Should the Accept-Ranges: bytes header be send with static resources?
+     */
+    protected boolean useAcceptRanges = true;
+
+    /**
+     * Flag to determine if server information is presented.
+     */
+    protected boolean showServerInfo = true;
+
+    /**
+     * Flag to determine if resources should be sorted.
+     */
+    protected boolean sortListings = false;
+
+    /**
+     * The sorting manager for sorting files and directories.
+     */
+    protected transient SortManager sortManager;
+
+    /**
+     * Flag that indicates whether partial PUTs are permitted.
+     */
+    private boolean allowPartialPut = true;
+
+
+    // --------------------------------------------------------- Public Methods
+
+    /**
+     * Finalize this servlet.
+     */
+    @Override
+    public void destroy() {
+        // NOOP
+    }
+
+
+    /**
+     * Initialize this servlet.
+     */
+    @Override
+    public void init() throws ServletException {
+
+        if (getServletConfig().getInitParameter("debug") != null) {
+            debug = Integer.parseInt(getServletConfig().getInitParameter("debug"));
+        }
+
+        if (getServletConfig().getInitParameter("input") != null) {
+            input = Integer.parseInt(getServletConfig().getInitParameter("input"));
+        }
+
+        if (getServletConfig().getInitParameter("output") != null) {
+            output = Integer.parseInt(getServletConfig().getInitParameter("output"));
+        }
+
+        listings = Boolean.parseBoolean(getServletConfig().getInitParameter("listings"));
+
+        if (getServletConfig().getInitParameter("readonly") != null) {
+            readOnly = Boolean.parseBoolean(getServletConfig().getInitParameter("readonly"));
+        }
+
+        compressionFormats = parseCompressionFormats(
+            getServletConfig().getInitParameter("precompressed"),
+            getServletConfig().getInitParameter("gzip"));
+
+        if (getServletConfig().getInitParameter("sendfileSize") != null) {
+            sendfileSize = Integer.parseInt(getServletConfig().getInitParameter("sendfileSize")) * 1024;
+        }
+
+        fileEncoding = getServletConfig().getInitParameter("fileEncoding");
+        if (fileEncoding == null) {
+            fileEncodingCharset = Charset.defaultCharset();
+            fileEncoding = fileEncodingCharset.name();
+        } else {
+            try {
+                fileEncodingCharset = B2CConverter.getCharset(fileEncoding);
+            } catch (UnsupportedEncodingException e) {
+                throw new ServletException(e);
+            }
+        }
+
+        final String useBomIfPresentConfig = getServletConfig().getInitParameter("useBomIfPresent");
+        if (useBomIfPresentConfig != null) {
+            if (!Arrays.asList("true", "false", "pass-through").contains(useBomIfPresentConfig)) {
+                if (debug > 0) {
+                    log("DefaultServlet.init:  unsupported value " + useBomIfPresentConfig + " for useBomIfPresent." +
+                        " One of 'true', 'false', 'pass-through' is expected. Using 'true' by default.");
+                }
+            }
+            useBomIfPresent = useBomIfPresentConfig;
+        }
+
+        globalXsltFile = getServletConfig().getInitParameter("globalXsltFile");
+        contextXsltFile = getServletConfig().getInitParameter("contextXsltFile");
+        localXsltFile = getServletConfig().getInitParameter("localXsltFile");
+        readmeFile = getServletConfig().getInitParameter("readmeFile");
+
+        if (getServletConfig().getInitParameter("useAcceptRanges") != null) {
+            useAcceptRanges = Boolean.parseBoolean(getServletConfig().getInitParameter("useAcceptRanges"));
+        }
+
+        // Sanity check on the specified buffer sizes
+        if (input < 256) {
+            input = 256;
+        }
+        if (output < 256) {
+            output = 256;
+        }
+
+        if (debug > 0) {
+            log("DefaultServlet.init:  input buffer size=" + input +
+                ", output buffer size=" + output);
+        }
+
+        // Load the web resources
+        resources = (WebResourceRoot) getServletContext().getAttribute(Globals.RESOURCES_ATTR);
+
+        if (resources == null) {
+            throw new UnavailableException(sm.getString("defaultServlet.noResources"));
+        }
+
+        if (getServletConfig().getInitParameter("showServerInfo") != null) {
+            showServerInfo = Boolean.parseBoolean(getServletConfig().getInitParameter("showServerInfo"));
+        }
+
+        if (getServletConfig().getInitParameter("sortListings") != null) {
+            sortListings = Boolean.parseBoolean(getServletConfig().getInitParameter("sortListings"));
+
+            if(sortListings) {
+                boolean sortDirectoriesFirst;
+                if (getServletConfig().getInitParameter("sortDirectoriesFirst") != null) {
+                    sortDirectoriesFirst = Boolean.parseBoolean(getServletConfig().getInitParameter("sortDirectoriesFirst"));
+                } else {
+                    sortDirectoriesFirst = false;
+                }
+
+                sortManager = new SortManager(sortDirectoriesFirst);
+            }
+        }
+
+        if (getServletConfig().getInitParameter("allowPartialPut") != null) {
+            allowPartialPut = Boolean.parseBoolean(getServletConfig().getInitParameter("allowPartialPut"));
+        }
+    }
+
+    private CompressionFormat[] parseCompressionFormats(String precompressed, String gzip) {
+        List<CompressionFormat> ret = new ArrayList<>();
+        if (precompressed != null && precompressed.indexOf('=') > 0) {
+            for (String pair : precompressed.split(",")) {
+                String[] setting = pair.split("=");
+                String encoding = setting[0];
+                String extension = setting[1];
+                ret.add(new CompressionFormat(extension, encoding));
+            }
+        } else if (precompressed != null) {
+            if (Boolean.parseBoolean(precompressed)) {
+                ret.add(new CompressionFormat(".br", "br"));
+                ret.add(new CompressionFormat(".gz", "gzip"));
+            }
+        } else if (Boolean.parseBoolean(gzip)) {
+            // gzip handling is for backwards compatibility with Tomcat 8.x
+            ret.add(new CompressionFormat(".gz", "gzip"));
+        }
+        return ret.toArray(new CompressionFormat[0]);
+    }
+
+
+    // ------------------------------------------------------ Protected Methods
+
+
+    /**
+     * Return the relative path associated with this servlet.
+     *
+     * @param request The servlet request we are processing
+     * @return the relative path
+     */
+    protected String getRelativePath(HttpServletRequest request) {
+        return getRelativePath(request, false);
+    }
+
+    protected String getRelativePath(HttpServletRequest request, boolean allowEmptyPath) {
+        // IMPORTANT: DefaultServlet can be mapped to '/' or '/path/*' but always
+        // serves resources from the web app root with context rooted paths.
+        // i.e. it cannot be used to mount the web app root under a sub-path
+        // This method must construct a complete context rooted path, although
+        // subclasses can change this behaviour.
+
+        String servletPath;
+        String pathInfo;
+
+        if (request.getAttribute(RequestDispatcher.INCLUDE_REQUEST_URI) != null) {
+            // For includes, get the info from the attributes
+            pathInfo = (String) request.getAttribute(RequestDispatcher.INCLUDE_PATH_INFO);
+            servletPath = (String) request.getAttribute(RequestDispatcher.INCLUDE_SERVLET_PATH);
+        } else {
+            pathInfo = request.getPathInfo();
+            servletPath = request.getServletPath();
+        }
+
+        StringBuilder result = new StringBuilder();
+        if (servletPath.length() > 0) {
+            result.append(servletPath);
+        }
+        if (pathInfo != null) {
+            result.append(pathInfo);
+        }
+        if (result.length() == 0 && !allowEmptyPath) {
+            result.append('/');
+        }
+
+        return result.toString();
+    }
+
+
+    /**
+     * Determines the appropriate path to prepend resources with
+     * when generating directory listings. Depending on the behaviour of
+     * {@link #getRelativePath(HttpServletRequest)} this will change.
+     * @param request the request to determine the path for
+     * @return the prefix to apply to all resources in the listing.
+     */
+    protected String getPathPrefix(final HttpServletRequest request) {
+        return request.getContextPath();
+    }
+
+
+    @Override
+    protected void service(HttpServletRequest req, HttpServletResponse resp)
+        throws ServletException, IOException {
+
+        if (req.getDispatcherType() == DispatcherType.ERROR) {
+            doGet(req, resp);
+        } else {
+            super.service(req, resp);
+        }
+    }
+
+
+    /**
+     * Process a GET request for the specified resource.
+     *
+     * @param request The servlet request we are processing
+     * @param response The servlet response we are creating
+     *
+     * @exception IOException if an input/output error occurs
+     * @exception ServletException if a servlet-specified error occurs
+     */
+    @Override
+    protected void doGet(HttpServletRequest request,
+                         HttpServletResponse response)
+        throws IOException, ServletException {
+
+        // Serve the requested resource, including the data content
+        serveResource(request, response, true, fileEncoding);
+
+    }
+
+
+    /**
+     * Process a HEAD request for the specified resource.
+     *
+     * @param request The servlet request we are processing
+     * @param response The servlet response we are creating
+     *
+     * @exception IOException if an input/output error occurs
+     * @exception ServletException if a servlet-specified error occurs
+     */
+    @Override
+    protected void doHead(HttpServletRequest request, HttpServletResponse response)
+        throws IOException, ServletException {
+        // Serve the requested resource, without the data content unless we are
+        // being included since in that case the content needs to be provided so
+        // the correct content length is reported for the including resource
+        boolean serveContent = DispatcherType.INCLUDE.equals(request.getDispatcherType());
+        serveResource(request, response, serveContent, fileEncoding);
+    }
+
+
+    /**
+     * Override default implementation to ensure that TRACE is correctly
+     * handled.
+     *
+     * @param req   the {@link HttpServletRequest} object that
+     *                  contains the request the client made of
+     *                  the servlet
+     *
+     * @param resp  the {@link HttpServletResponse} object that
+     *                  contains the response the servlet returns
+     *                  to the client
+     *
+     * @exception IOException   if an input or output error occurs
+     *                              while the servlet is handling the
+     *                              OPTIONS request
+     *
+     * @exception ServletException  if the request for the
+     *                                  OPTIONS cannot be handled
+     */
+    @Override
+    protected void doOptions(HttpServletRequest req, HttpServletResponse resp)
+        throws ServletException, IOException {
+
+        resp.setHeader("Allow", determineMethodsAllowed(req));
+    }
+
+
+    protected String determineMethodsAllowed(HttpServletRequest req) {
+        StringBuilder allow = new StringBuilder();
+
+        // Start with methods that are always allowed
+        allow.append("OPTIONS, GET, HEAD, POST");
+
+        // PUT and DELETE depend on readonly
+        if (!readOnly) {
+            allow.append(", PUT, DELETE");
+        }
+
+        // Trace - assume disabled unless we can prove otherwise
+        if (req instanceof RequestFacade &&
+            ((RequestFacade) req).getAllowTrace()) {
+            allow.append(", TRACE");
+        }
+
+        return allow.toString();
+    }
+
+
+    protected void sendNotAllowed(HttpServletRequest req, HttpServletResponse resp)
+        throws IOException {
+        resp.addHeader("Allow", determineMethodsAllowed(req));
+        resp.sendError(HttpServletResponse.SC_METHOD_NOT_ALLOWED);
+    }
+
+
+    /**
+     * Process a POST request for the specified resource.
+     *
+     * @param request The servlet request we are processing
+     * @param response The servlet response we are creating
+     *
+     * @exception IOException if an input/output error occurs
+     * @exception ServletException if a servlet-specified error occurs
+     */
+    @Override
+    protected void doPost(HttpServletRequest request,
+                          HttpServletResponse response)
+        throws IOException, ServletException {
+        doGet(request, response);
+    }
+
+
+    /**
+     * Process a PUT request for the specified resource.
+     *
+     * @param req The servlet request we are processing
+     * @param resp The servlet response we are creating
+     *
+     * @exception IOException if an input/output error occurs
+     * @exception ServletException if a servlet-specified error occurs
+     */
+    @Override
+    protected void doPut(HttpServletRequest req, HttpServletResponse resp)
+        throws ServletException, IOException {
+
+        if (readOnly) {
+            sendNotAllowed(req, resp);
+            return;
+        }
+
+        String path = getRelativePath(req);
+
+        WebResource resource = resources.getResource(path);
+
+        Range range = parseContentRange(req, resp);
+
+        if (range == null) {
+            // Processing error. parseContentRange() set the error code
+            return;
+        }
+
+        InputStream resourceInputStream = null;
+
+        try {
+            // Append data specified in ranges to existing content for this
+            // resource - create a temp. file on the local filesystem to
+            // perform this operation
+            // Assume just one range is specified for now
+            if (range == IGNORE) {
+                resourceInputStream = req.getInputStream();
+            } else {
+                File contentFile = executePartialPut(req, range, path);
+                resourceInputStream = new FileInputStream(contentFile);
+            }
+
+            if (resources.write(path, resourceInputStream, true)) {
+                if (resource.exists()) {
+                    resp.setStatus(HttpServletResponse.SC_NO_CONTENT);
+                } else {
+                    resp.setStatus(HttpServletResponse.SC_CREATED);
+                }
+            } else {
+                resp.sendError(HttpServletResponse.SC_CONFLICT);
+            }
+        } finally {
+            if (resourceInputStream != null) {
+                try {
+                    resourceInputStream.close();
+                } catch (IOException ioe) {
+                    // Ignore
+                }
+            }
+        }
+    }
+
+
+    /**
+     * Handle a partial PUT.  New content specified in request is appended to
+     * existing content in oldRevisionContent (if present). This code does
+     * not support simultaneous partial updates to the same resource.
+     * @param req The Servlet request
+     * @param range The range that will be written
+     * @param path The path
+     * @return the associated file object
+     * @throws IOException an IO error occurred
+     */
+    protected File executePartialPut(HttpServletRequest req, Range range,
+                                     String path)
+        throws IOException {
+
+        // Append data specified in ranges to existing content for this
+        // resource - create a temp. file on the local filesystem to
+        // perform this operation
+        File tempDir = (File) getServletContext().getAttribute
+            (ServletContext.TEMPDIR);
+        // Convert all '/' characters to '.' in resourcePath
+        String convertedResourcePath = path.replace('/', '.');
+        File contentFile = new File(tempDir, convertedResourcePath);
+        if (contentFile.createNewFile()) {
+            // Clean up contentFile when Tomcat is terminated
+            contentFile.deleteOnExit();
+        }
+
+        try (RandomAccessFile randAccessContentFile =
+                 new RandomAccessFile(contentFile, "rw")) {
+
+            WebResource oldResource = resources.getResource(path);
+
+            // Copy data in oldRevisionContent to contentFile
+            if (oldResource.isFile()) {
+                try (BufferedInputStream bufOldRevStream =
+                         new BufferedInputStream(oldResource.getInputStream(),
+                                                 BUFFER_SIZE)) {
+
+                    int numBytesRead;
+                    byte[] copyBuffer = new byte[BUFFER_SIZE];
+                    while ((numBytesRead = bufOldRevStream.read(copyBuffer)) != -1) {
+                        randAccessContentFile.write(copyBuffer, 0, numBytesRead);
+                    }
+
+                }
+            }
+
+            randAccessContentFile.setLength(range.length);
+
+            // Append data in request input stream to contentFile
+            randAccessContentFile.seek(range.start);
+            int numBytesRead;
+            byte[] transferBuffer = new byte[BUFFER_SIZE];
+            try (BufferedInputStream requestBufInStream =
+                     new BufferedInputStream(req.getInputStream(), BUFFER_SIZE)) {
+                while ((numBytesRead = requestBufInStream.read(transferBuffer)) != -1) {
+                    randAccessContentFile.write(transferBuffer, 0, numBytesRead);
+                }
+            }
+        }
+
+        return contentFile;
+    }
+
+
+    /**
+     * Process a DELETE request for the specified resource.
+     *
+     * @param req The servlet request we are processing
+     * @param resp The servlet response we are creating
+     *
+     * @exception IOException if an input/output error occurs
+     * @exception ServletException if a servlet-specified error occurs
+     */
+    @Override
+    protected void doDelete(HttpServletRequest req, HttpServletResponse resp)
+        throws ServletException, IOException {
+
+        if (readOnly) {
+            sendNotAllowed(req, resp);
+            return;
+        }
+
+        String path = getRelativePath(req);
+
+        WebResource resource = resources.getResource(path);
+
+        if (resource.exists()) {
+            if (resource.delete()) {
+                resp.setStatus(HttpServletResponse.SC_NO_CONTENT);
+            } else {
+                resp.sendError(HttpServletResponse.SC_METHOD_NOT_ALLOWED);
+            }
+        } else {
+            resp.sendError(HttpServletResponse.SC_NOT_FOUND);
+        }
+
+    }
+
+
+    /**
+     * Check if the conditions specified in the optional If headers are
+     * satisfied.
+     *
+     * @param request   The servlet request we are processing
+     * @param response  The servlet response we are creating
+     * @param resource  The resource
+     * @return <code>true</code> if the resource meets all the specified
+     *  conditions, and <code>false</code> if any of the conditions is not
+     *  satisfied, in which case request processing is stopped
+     * @throws IOException an IO error occurred
+     */
+    protected boolean checkIfHeaders(HttpServletRequest request,
+                                     HttpServletResponse response,
+                                     WebResource resource)
+        throws IOException {
+
+        return checkIfMatch(request, response, resource)
+               && checkIfModifiedSince(request, response, resource)
+               && checkIfNoneMatch(request, response, resource)
+               && checkIfUnmodifiedSince(request, response, resource);
+
+    }
+
+
+    /**
+     * URL rewriter.
+     *
+     * @param path Path which has to be rewritten
+     * @return the rewritten path
+     */
+    protected String rewriteUrl(String path) {
+        return URLEncoder.DEFAULT.encode(path, StandardCharsets.UTF_8);
+    }
+
+
+    /**
+     * Serve the specified resource, optionally including the data content.
+     *
+     * @param request       The servlet request we are processing
+     * @param response      The servlet response we are creating
+     * @param content       Should the content be included?
+     * @param inputEncoding The encoding to use if it is necessary to access the
+     *                      source as characters rather than as bytes
+     *
+     * @exception IOException if an input/output error occurs
+     * @exception ServletException if a servlet-specified error occurs
+     */
+    protected void serveResource(HttpServletRequest request,
+                                 HttpServletResponse response,
+                                 boolean content,
+                                 String inputEncoding)
+        throws IOException, ServletException {
+
+        boolean serveContent = content;
+
+        // Identify the requested resource path
+        String path = getRelativePath(request, true);
+
+        if (debug > 0) {
+            if (serveContent)
+                log("DefaultServlet.serveResource:  Serving resource '" +
+                    path + "' headers and data");
+            else
+                log("DefaultServlet.serveResource:  Serving resource '" +
+                    path + "' headers only");
+        }
+
+        if (path.length() == 0) {
+            // Context root redirect
+            doDirectoryRedirect(request, response);
+            return;
+        }
+
+        WebResource resource = resources.getResource(path);
+        boolean isError = DispatcherType.ERROR == request.getDispatcherType();
+
+        if (!resource.exists()) {
+            // Check if we're included so we can return the appropriate
+            // missing resource name in the error
+            String requestUri = (String) request.getAttribute(
+                RequestDispatcher.INCLUDE_REQUEST_URI);
+            if (requestUri == null) {
+                requestUri = request.getRequestURI();
+            } else {
+                // We're included
+                // SRV.9.3 says we must throw a FNFE
+                throw new FileNotFoundException(sm.getString(
+                    "defaultServlet.missingResource", requestUri));
+            }
+
+            if (isError) {
+                response.sendError(((Integer) request.getAttribute(
+                    RequestDispatcher.ERROR_STATUS_CODE)).intValue());
+            } else {
+                response.sendError(HttpServletResponse.SC_NOT_FOUND,
+                                   sm.getString("defaultServlet.missingResource", requestUri));
+            }
+            return;
+        }
+
+        if (!resource.canRead()) {
+            // Check if we're included so we can return the appropriate
+            // missing resource name in the error
+            String requestUri = (String) request.getAttribute(
+                RequestDispatcher.INCLUDE_REQUEST_URI);
+            if (requestUri == null) {
+                requestUri = request.getRequestURI();
+            } else {
+                // We're included
+                // Spec doesn't say what to do in this case but a FNFE seems
+                // reasonable
+                throw new FileNotFoundException(sm.getString(
+                    "defaultServlet.missingResource", requestUri));
+            }
+
+            if (isError) {
+                response.sendError(((Integer) request.getAttribute(
+                    RequestDispatcher.ERROR_STATUS_CODE)).intValue());
+            } else {
+                response.sendError(HttpServletResponse.SC_FORBIDDEN, requestUri);
+            }
+            return;
+        }
+
+        boolean included = false;
+        // Check if the conditions specified in the optional If headers are
+        // satisfied.
+        if (resource.isFile()) {
+            // Checking If headers
+            included = (request.getAttribute(
+                RequestDispatcher.INCLUDE_CONTEXT_PATH) != null);
+            if (!included && !isError && !checkIfHeaders(request, response, resource)) {
+                return;
+            }
+        }
+
+        // Find content type.
+        String contentType = resource.getMimeType();
+        if (contentType == null) {
+            contentType = getServletContext().getMimeType(resource.getName());
+            resource.setMimeType(contentType);
+        }
+
+        // These need to reflect the original resource, not the potentially
+        // precompressed version of the resource so get them now if they are going to
+        // be needed later
+        String eTag = null;
+        String lastModifiedHttp = null;
+        if (resource.isFile() && !isError) {
+            eTag = generateETag(resource);
+            lastModifiedHttp = resource.getLastModifiedHttp();
+        }
+
+
+        // Serve a precompressed version of the file if present
+        boolean usingPrecompressedVersion = false;
+        if (compressionFormats.length > 0 && !included && resource.isFile() &&
+            !pathEndsWithCompressedExtension(path)) {
+            List<PrecompressedResource> precompressedResources =
+                getAvailablePrecompressedResources(path);
+            if (!precompressedResources.isEmpty()) {
+                ResponseUtil.addVaryFieldName(response, "accept-encoding");
+                PrecompressedResource bestResource =
+                    getBestPrecompressedResource(request, precompressedResources);
+                if (bestResource != null) {
+                    response.addHeader("Content-Encoding", bestResource.format.encoding);
+                    resource = bestResource.resource;
+                    usingPrecompressedVersion = true;
+                }
+            }
+        }
+
+        ArrayList<Range> ranges = FULL;
+        long contentLength = -1L;
+
+        if (resource.isDirectory()) {
+            if (!path.endsWith("/")) {
+                doDirectoryRedirect(request, response);
+                return;
+            }
+
+            // Skip directory listings if we have been configured to
+            // suppress them
+            if (!listings) {
+                response.sendError(HttpServletResponse.SC_NOT_FOUND,
+                                   sm.getString("defaultServlet.missingResource", request.getRequestURI()));
+                return;
+            }
+            contentType = "text/html;charset=UTF-8";
+        } else {
+            if (!isError) {
+                if (useAcceptRanges) {
+                    // Accept ranges header
+                    response.setHeader("Accept-Ranges", "bytes");
+                }
+
+                // Parse range specifier
+                ranges = parseRange(request, response, resource);
+                if (ranges == null) {
+                    return;
+                }
+
+                // ETag header
+                response.setHeader("ETag", eTag);
+
+                // Last-Modified header
+                response.setHeader("Last-Modified", lastModifiedHttp);
+            }
+
+            // Get content length
+            contentLength = resource.getContentLength();
+            // Special case for zero length files, which would cause a
+            // (silent) ISE when setting the output buffer size
+            if (contentLength == 0L) {
+                serveContent = false;
+            }
+        }
+
+        ServletOutputStream ostream = null;
+        PrintWriter writer = null;
+
+        if (serveContent) {
+            // Trying to retrieve the servlet output stream
+            try {
+                ostream = response.getOutputStream();
+            } catch (IllegalStateException e) {
+                // If it fails, we try to get a Writer instead if we're
+                // trying to serve a text file
+                if (!usingPrecompressedVersion && isText(contentType)) {
+                    writer = response.getWriter();
+                    // Cannot reliably serve partial content with a Writer
+                    ranges = FULL;
+                } else {
+                    throw e;
+                }
+            }
+        }
+
+        // Check to see if a Filter, Valve or wrapper has written some content.
+        // If it has, disable range requests and setting of a content length
+        // since neither can be done reliably.
+        ServletResponse r = response;
+        long contentWritten = 0;
+        while (r instanceof ServletResponseWrapper) {
+            r = ((ServletResponseWrapper) r).getResponse();
+        }
+        if (r instanceof ResponseFacade) {
+            contentWritten = ((ResponseFacade) r).getContentWritten();
+        }
+        if (contentWritten > 0) {
+            ranges = FULL;
+        }
+
+        String outputEncoding = response.getCharacterEncoding();
+        Charset charset = B2CConverter.getCharset(outputEncoding);
+        boolean conversionRequired;
+        /*
+         * The test below deliberately uses != to compare two Strings. This is
+         * because the code is looking to see if the default character encoding
+         * has been returned because no explicit character encoding has been
+         * defined. There is no clean way of doing this via the Servlet API. It
+         * would be possible to add a Tomcat specific API but that would require
+         * quite a bit of code to get to the Tomcat specific request object that
+         * may have been wrapped. The != test is a (slightly hacky) quick way of
+         * doing this.
+         */
+        boolean outputEncodingSpecified =
+            outputEncoding != org.apache.coyote.Constants.DEFAULT_BODY_CHARSET.name() &&
+            outputEncoding != resources.getContext().getResponseCharacterEncoding();
+        if (!usingPrecompressedVersion && isText(contentType) && outputEncodingSpecified &&
+            !charset.equals(fileEncodingCharset)) {
+            conversionRequired = true;
+            // Conversion often results fewer/more/different bytes.
+            // That does not play nicely with range requests.
+            ranges = FULL;
+        } else {
+            conversionRequired = false;
+        }
+
+        if (resource.isDirectory() || isError || ranges == FULL ) {
+            // Set the appropriate output headers
+            if (contentType != null) {
+                if (debug > 0)
+                    log("DefaultServlet.serveFile:  contentType='" +
+                        contentType + "'");
+                // Don't override a previously set content type
+                if (response.getContentType() == null) {
+                    response.setContentType(contentType);
+                }
+            }
+            if (resource.isFile() && contentLength >= 0 &&
+                (!serveContent || ostream != null)) {
+                if (debug > 0)
+                    log("DefaultServlet.serveFile:  contentLength=" +
+                        contentLength);
+                // Don't set a content length if something else has already
+                // written to the response or if conversion will be taking place
+                if (contentWritten == 0 && !conversionRequired) {
+                    response.setContentLengthLong(contentLength);
+                }
+            }
+
+            if (serveContent) {
+                try {
+                    response.setBufferSize(output);
+                } catch (IllegalStateException e) {
+                    // Silent catch
+                }
+                InputStream renderResult = null;
+                if (ostream == null) {
+                    // Output via a writer so can't use sendfile or write
+                    // content directly.
+                    if (resource.isDirectory()) {
+                        renderResult = render(request, getPathPrefix(request), resource, inputEncoding);
+                    } else {
+                        renderResult = resource.getInputStream();
+                        if (included) {
+                            // Need to make sure any BOM is removed
+                            if (!renderResult.markSupported()) {
+                                renderResult = new BufferedInputStream(renderResult);
+                            }
+                            Charset bomCharset = processBom(renderResult, isStripBOM());
+                            if (bomCharset != null && "true".equals(useBomIfPresent)) {
+                                inputEncoding = bomCharset.name();
+                            }
+                        }
+                    }
+                    copy(renderResult, writer, inputEncoding);
+                } else {
+                    // Output is via an OutputStream
+                    if (resource.isDirectory()) {
+                        renderResult = render(request, getPathPrefix(request), resource, inputEncoding);
+                    } else {
+                        // Output is content of resource
+                        // Check to see if conversion is required
+                        if (conversionRequired || included) {
+                            // When including a file, we need to check for a BOM
+                            // to determine if a conversion is required, so we
+                            // might as well always convert
+                            InputStream source = resource.getInputStream();
+                            if (!source.markSupported()) {
+                                source = new BufferedInputStream(source);
+                            }
+                            Charset bomCharset = processBom(source, isStripBOM());
+                            if (bomCharset != null && "true".equals(useBomIfPresent)) {
+                                inputEncoding = bomCharset.name();
+                            }
+                            // Following test also ensures included resources
+                            // are converted if an explicit output encoding was
+                            // specified
+                            if (outputEncodingSpecified) {
+                                OutputStreamWriter osw = new OutputStreamWriter(ostream, charset);
+                                PrintWriter pw = new PrintWriter(osw);
+                                copy(source, pw, inputEncoding);
+                                pw.flush();
+                            } else {
+                                // Just included but no conversion
+                                renderResult = source;
+                            }
+                        } else {
+                            if (!checkSendfile(request, response, resource, contentLength, null)) {
+                                // sendfile not possible so check if resource
+                                // content is available directly via
+                                // CachedResource. Do not want to call
+                                // getContent() on other resource
+                                // implementations as that could trigger loading
+                                // the contents of a very large file into memory
+                                byte[] resourceBody = null;
+                                if (resource instanceof CachedResource) {
+                                    resourceBody = resource.getContent();
+                                }
+                                if (resourceBody == null) {
+                                    // Resource content not directly available,
+                                    // use InputStream
+                                    renderResult = resource.getInputStream();
+                                } else {
+                                    // Use the resource content directly
+                                    ostream.write(resourceBody);
+                                }
+                            }
+                        }
+                    }
+                    // If a stream was configured, it needs to be copied to
+                    // the output (this method closes the stream)
+                    if (renderResult != null) {
+                        copy(renderResult, ostream);
+                    }
+                }
+            }
+
+        } else {
+
+            if ((ranges == null) || (ranges.isEmpty()))
+                return;
+
+            // Partial content response.
+
+            response.setStatus(HttpServletResponse.SC_PARTIAL_CONTENT);
+
+            if (ranges.size() == 1) {
+
+                Range range = ranges.get(0);
+                response.addHeader("Content-Range", "bytes "
+                                   + range.start
+                                   + "-" + range.end + "/"
+                                   + range.length);
+                long length = range.end - range.start + 1;
+                response.setContentLengthLong(length);
+
+                if (contentType != null) {
+                    if (debug > 0)
+                        log("DefaultServlet.serveFile:  contentType='" +
+                            contentType + "'");
+                    response.setContentType(contentType);
+                }
+
+                if (serveContent) {
+                    try {
+                        response.setBufferSize(output);
+                    } catch (IllegalStateException e) {
+                        // Silent catch
+                    }
+                    if (ostream != null) {
+                        if (!checkSendfile(request, response, resource,
+                                range.end - range.start + 1, range))
+                            copy(resource, ostream, range);
+                    } else {
+                        // we should not get here
+                        throw new IllegalStateException();
+                    }
+                }
+            } else {
+                response.setContentType("multipart/byteranges; boundary="
+                                        + mimeSeparation);
+                if (serveContent) {
+                    try {
+                        response.setBufferSize(output);
+                    } catch (IllegalStateException e) {
+                        // Silent catch
+                    }
+                    if (ostream != null) {
+                        copy(resource, ostream, ranges.iterator(), contentType);
+                    } else {
+                        // we should not get here
+                        throw new IllegalStateException();
+                    }
+                }
+            }
+        }
+    }
+
+    /*
+     * useBomIfPresent can take 3 values (see init): true, false and pass-through
+     *
+     * When later is used, then not only we'll ignore the BOM and use the configured encoding
+     * but we'll also leave the BOM in the output
+     */
+    private boolean isStripBOM() {
+        return !"pass-through".equals(useBomIfPresent);
+    }
+
+    /*
+     * Code borrowed heavily from Jasper's EncodingDetector
+     */
+    private static Charset processBom(final InputStream is, final boolean stripBOM) throws IOException {
+        // Java supported character sets do not use BOMs longer than 4 bytes
+        byte[] bom = new byte[4];
+        is.mark(bom.length);
+
+        int count = is.read(bom);
+
+        // BOMs are at least 2 bytes
+        if (count < 2) {
+            skip(is, 0, stripBOM);
+            return null;
+        }
+
+        // Look for two byte BOMs
+        int b0 = bom[0] & 0xFF;
+        int b1 = bom[1] & 0xFF;
+        if (b0 == 0xFE && b1 == 0xFF) {
+            skip(is, 2, stripBOM);
+            return StandardCharsets.UTF_16BE;
+        }
+        // Delay the UTF_16LE check if there are more that 2 bytes since it
+        // overlaps with UTF-32LE.
+        if (count == 2 && b0 == 0xFF && b1 == 0xFE) {
+            skip(is, 2, stripBOM);
+            return StandardCharsets.UTF_16LE;
+        }
+
+        // Remaining BOMs are at least 3 bytes
+        if (count < 3) {
+            skip(is, 0, stripBOM);
+            return null;
+        }
+
+        // UTF-8 is only 3-byte BOM
+        int b2 = bom[2] & 0xFF;
+        if (b0 == 0xEF && b1 == 0xBB && b2 == 0xBF) {
+            skip(is, 3, stripBOM);
+            return StandardCharsets.UTF_8;
+        }
+
+        if (count < 4) {
+            skip(is, 0, stripBOM);
+            return null;
+        }
+
+        // Look for 4-byte BOMs
+        int b3 = bom[3] & 0xFF;
+        if (b0 == 0x00 && b1 == 0x00 && b2 == 0xFE && b3 == 0xFF) {
+            return Charset.forName("UTF-32BE");
+        }
+        if (b0 == 0xFF && b1 == 0xFE && b2 == 0x00 && b3 == 0x00) {
+            return Charset.forName("UTF-32LE");
+        }
+
+        // Now we can check for UTF16-LE. There is an assumption here that we
+        // won't see a UTF16-LE file with a BOM where the first real data is
+        // 0x00 0x00
+        if (b0 == 0xFF && b1 == 0xFE) {
+            skip(is, 2, stripBOM);
+            return StandardCharsets.UTF_16LE;
+        }
+
+        skip(is, 0, stripBOM);
+        return null;
+    }
+
+
+    private static void skip(final InputStream is, int skip, final boolean stripBOM) throws IOException {
+        is.reset();
+        while (stripBOM && skip-- > 0) {
+            is.read();
+        }
+    }
+
+
+    private static boolean isText(String contentType) {
+        return  contentType == null || contentType.startsWith("text") ||
+                contentType.endsWith("xml") || contentType.contains("/javascript");
+    }
+
+
+    private boolean pathEndsWithCompressedExtension(String path) {
+        for (CompressionFormat format : compressionFormats) {
+            if (path.endsWith(format.extension)) {
+                return true;
+            }
+        }
+        return false;
+    }
+
+    private List<PrecompressedResource> getAvailablePrecompressedResources(String path) {
+        List<PrecompressedResource> ret = new ArrayList<>(compressionFormats.length);
+        for (CompressionFormat format : compressionFormats) {
+            WebResource precompressedResource = resources.getResource(path + format.extension);
+            if (precompressedResource.exists() && precompressedResource.isFile()) {
+                ret.add(new PrecompressedResource(precompressedResource, format));
+            }
+        }
+        return ret;
+    }
+
+    /**
+     * Match the client preferred encoding formats to the available precompressed resources.
+     *
+     * @param request   The servlet request we are processing
+     * @param precompressedResources   List of available precompressed resources.
+     * @return The best matching precompressed resource or null if no match was found.
+     */
+    private PrecompressedResource getBestPrecompressedResource(HttpServletRequest request,
+                                                               List<PrecompressedResource> precompressedResources) {
+        Enumeration<String> headers = request.getHeaders("Accept-Encoding");
+        PrecompressedResource bestResource = null;
+        double bestResourceQuality = 0;
+        int bestResourcePreference = Integer.MAX_VALUE;
+        while (headers.hasMoreElements()) {
+            String header = headers.nextElement();
+            for (String preference : header.split(",")) {
+                double quality = 1;
+                int qualityIdx = preference.indexOf(';');
+                if (qualityIdx > 0) {
+                    int equalsIdx = preference.indexOf('=', qualityIdx + 1);
+                    if (equalsIdx == -1) {
+                        continue;
+                    }
+                    quality = Double.parseDouble(preference.substring(equalsIdx + 1).trim());
+                }
+                if (quality >= bestResourceQuality) {
+                    String encoding = preference;
+                    if (qualityIdx > 0) {
+                        encoding = encoding.substring(0, qualityIdx);
+                    }
+                    encoding = encoding.trim();
+                    if ("identity".equals(encoding)) {
+                        bestResource = null;
+                        bestResourceQuality = quality;
+                        bestResourcePreference = Integer.MAX_VALUE;
+                        continue;
+                    }
+                    if ("*".equals(encoding)) {
+                        bestResource = precompressedResources.get(0);
+                        bestResourceQuality = quality;
+                        bestResourcePreference = 0;
+                        continue;
+                    }
+                    for (int i = 0; i < precompressedResources.size(); ++i) {
+                        PrecompressedResource resource = precompressedResources.get(i);
+                        if (encoding.equals(resource.format.encoding)) {
+                            if (quality > bestResourceQuality || i < bestResourcePreference) {
+                                bestResource = resource;
+                                bestResourceQuality = quality;
+                                bestResourcePreference = i;
+                            }
+                            break;
+                        }
+                    }
+                }
+            }
+        }
+        return bestResource;
+    }
+
+    private void doDirectoryRedirect(HttpServletRequest request, HttpServletResponse response)
+        throws IOException {
+        StringBuilder location = new StringBuilder(request.getRequestURI());
+        location.append('/');
+        if (request.getQueryString() != null) {
+            location.append('?');
+            location.append(request.getQueryString());
+        }
+        // Avoid protocol relative redirects
+        while (location.length() > 1 && location.charAt(1) == '/') {
+            location.deleteCharAt(0);
+        }
+        response.sendRedirect(response.encodeRedirectURL(location.toString()));
+    }
+
+    /**
+     * Parse the content-range header.
+     *
+     * @param request The servlet request we are processing
+     * @param response The servlet response we are creating
+     * @return the partial content-range, {@code null} if the content-range
+     *         header was invalid or {@code #IGNORE} if there is no header to
+     *         process
+     * @throws IOException an IO error occurred
+     */
+    protected Range parseContentRange(HttpServletRequest request,
+                                             HttpServletResponse response)
+        throws IOException {
+
+        // Retrieving the content-range header (if any is specified
+        String contentRangeHeader = request.getHeader("Content-Range");
+
+        if (contentRangeHeader == null) {
+            return IGNORE;
+        }
+
+        if (!allowPartialPut) {
+            response.sendError(HttpServletResponse.SC_BAD_REQUEST);
+            return null;
+        }
+
+        ContentRange contentRange = ContentRange.parse(new StringReader(contentRangeHeader));
+
+        if (contentRange == null) {
+            response.sendError(HttpServletResponse.SC_BAD_REQUEST);
+            return null;
+        }
+
+
+        // bytes is the only range unit supported
+        if (!contentRange.getUnits().equals("bytes")) {
+            response.sendError(HttpServletResponse.SC_BAD_REQUEST);
+            return null;
+        }
+
+        // TODO: Remove the internal representation and use Ranges
+        // Convert to internal representation
+        Range range = new Range();
+        range.start = contentRange.getStart();
+        range.end = contentRange.getEnd();
+        range.length = contentRange.getLength();
+
+        if (!range.validate()) {
+            response.sendError(HttpServletResponse.SC_BAD_REQUEST);
+            return null;
+        }
+
+        return range;
+    }
+
+
+    /**
+     * Parse the range header.
+     *
+     * @param request   The servlet request we are processing
+     * @param response  The servlet response we are creating
+     * @param resource  The resource
+     * @return a list of ranges, {@code null} if the range header was invalid or
+     *         {@code #FULL} if the Range header should be ignored.
+     * @throws IOException an IO error occurred
+     */
+    protected ArrayList<Range> parseRange(HttpServletRequest request,
+                                HttpServletResponse response,
+                                WebResource resource) throws IOException {
+
+        // Range headers are only valid on GET requests. That implies they are
+        // also valid on HEAD requests. This method is only called by doGet()
+        // and doHead() so no need to check the request method.
+
+        // Checking If-Range
+        String headerValue = request.getHeader("If-Range");
+
+        if (headerValue != null) {
+
+            long headerValueTime = (-1L);
+            try {
+                headerValueTime = request.getDateHeader("If-Range");
+            } catch (IllegalArgumentException e) {
+                // Ignore
+            }
+
+            String eTag = generateETag(resource);
+            long lastModified = resource.getLastModified();
+
+            if (headerValueTime == (-1L)) {
+                // If the ETag the client gave does not match the entity
+                // etag, then the entire entity is returned.
+                if (!eTag.equals(headerValue.trim())) {
+                    return FULL;
+                }
+            } else {
+                // If the timestamp of the entity the client got differs from
+                // the last modification date of the entity, the entire entity
+                // is returned.
+                if (Math.abs(lastModified - headerValueTime) > 1000) {
+                    return FULL;
+                }
+            }
+        }
+
+        long fileLength = resource.getContentLength();
+
+        if (fileLength == 0) {
+            // Range header makes no sense for a zero length resource. Tomcat
+            // therefore opts to ignore it.
+            return FULL;
+        }
+
+        // Retrieving the range header (if any is specified
+        String rangeHeader = request.getHeader("Range");
+
+        if (rangeHeader == null) {
+            // No Range header is the same as ignoring any Range header
+            return FULL;
+        }
+
+        Ranges ranges = Ranges.parse(new StringReader(rangeHeader));
+
+        if (ranges == null) {
+            // The Range header is present but not formatted correctly.
+            // Could argue for a 400 response but 416 is more specific.
+            // There is also the option to ignore the (invalid) Range header.
+            // RFC7233#4.4 notes that many servers do ignore the Range header in
+            // these circumstances but Tomcat has always returned a 416.
+            response.addHeader("Content-Range", "bytes */" + fileLength);
+            response.sendError(HttpServletResponse.SC_REQUESTED_RANGE_NOT_SATISFIABLE);
+            return null;
+        }
+
+        // bytes is the only range unit supported (and I don't see the point
+        // of adding new ones).
+        if (!ranges.getUnits().equals("bytes")) {
+            // RFC7233#3.1 Servers must ignore range units they don't understand
+            return FULL;
+        }
+
+        // TODO: Remove the internal representation and use Ranges
+        // Convert to internal representation
+        ArrayList<Range> result = new ArrayList<>();
+
+        for (Ranges.Entry entry : ranges.getEntries()) {
+            Range currentRange = new Range();
+            if (entry.getStart() == -1) {
+                currentRange.start = fileLength - entry.getEnd();
+                if (currentRange.start < 0) {
+                    currentRange.start = 0;
+                }
+                currentRange.end = fileLength - 1;
+            } else if (entry.getEnd() == -1) {
+                currentRange.start = entry.getStart();
+                currentRange.end = fileLength - 1;
+            } else {
+                currentRange.start = entry.getStart();
+                currentRange.end = entry.getEnd();
+            }
+            currentRange.length = fileLength;
+
+            if (!currentRange.validate()) {
+                response.addHeader("Content-Range", "bytes */" + fileLength);
+                response.sendError(HttpServletResponse.SC_REQUESTED_RANGE_NOT_SATISFIABLE);
+                return null;
+            }
+
+            result.add(currentRange);
+        }
+
+        return result;
+    }
+
+
+    /**
+     * Decide which way to render. HTML or XML.
+     *
+     * @param contextPath The path
+     * @param resource    The resource
+     * @param encoding    The encoding to use to process the readme (if any)
+     *
+     * @return the input stream with the rendered output
+     *
+     * @throws IOException an IO error occurred
+     * @throws ServletException rendering error
+     *
+     * @deprecated Use {@link #render(HttpServletRequest, String, WebResource, String)} instead
+     */
+    @Deprecated
+    protected InputStream render(String contextPath, WebResource resource, String encoding)
+        throws IOException, ServletException {
+
+        return render(null, contextPath, resource, encoding);
+    }
+
+    /**
+     * Decide which way to render. HTML or XML.
+     *
+     * @param request     The HttpServletRequest being served
+     * @param contextPath The path
+     * @param resource    The resource
+     * @param encoding    The encoding to use to process the readme (if any)
+     *
+     * @return the input stream with the rendered output
+     *
+     * @throws IOException an IO error occurred
+     * @throws ServletException rendering error
+     */
+    protected InputStream render(HttpServletRequest request, String contextPath, WebResource resource, String encoding)
+        throws IOException, ServletException {
+
+        Source xsltSource = findXsltSource(resource);
+
+        if (xsltSource == null) {
+            return renderHtml(request, contextPath, resource, encoding);
+        }
+        return renderXml(request, contextPath, resource, xsltSource, encoding);
+    }
+
+
+    /**
+     * Return an InputStream to an XML representation of the contents this
+     * directory.
+     *
+     * @param contextPath Context path to which our internal paths are relative
+     * @param resource    The associated resource
+     * @param xsltSource  The XSL stylesheet
+     * @param encoding    The encoding to use to process the readme (if any)
+     *
+     * @return the XML data
+     *
+     * @throws IOException an IO error occurred
+     * @throws ServletException rendering error
+     * @deprecated Unused. Will be removed in Tomcat 10
+     * @deprecated Use {@link #render(HttpServletRequest, String, WebResource, String)} instead
+     */
+    @Deprecated
+    protected InputStream renderXml(String contextPath, WebResource resource, Source xsltSource,
+            String encoding)
+        throws ServletException, IOException
+    {
+        return renderXml(null, contextPath, resource, xsltSource, encoding);
+    }
+
+    /**
+     * Return an InputStream to an XML representation of the contents this
+     * directory.
+     *
+     * @param request     The HttpServletRequest being served
+     * @param contextPath Context path to which our internal paths are relative
+     * @param resource    The associated resource
+     * @param xsltSource  The XSL stylesheet
+     * @param encoding    The encoding to use to process the readme (if any)
+     *
+     * @return the XML data
+     *
+     * @throws IOException an IO error occurred
+     * @throws ServletException rendering error
+     */
+    protected InputStream renderXml(HttpServletRequest request, String contextPath, WebResource resource, Source xsltSource,
+                                    String encoding)
+        throws IOException, ServletException {
+
+        StringBuilder sb = new StringBuilder();
+
+        sb.append("<?xml version=\"1.0\"?>");
+        sb.append("<listing ");
+        sb.append(" contextPath='");
+        sb.append(contextPath);
+        sb.append('\'');
+        sb.append(" directory='");
+        sb.append(resource.getName());
+        sb.append("' ");
+        sb.append(" hasParent='").append(!resource.getName().equals("/"));
+        sb.append("'>");
+
+        sb.append("<entries>");
+
+        String[] entries = resources.list(resource.getWebappPath());
+
+        // rewriteUrl(contextPath) is expensive. cache result for later reuse
+        String rewrittenContextPath =  rewriteUrl(contextPath);
+        String directoryWebappPath = resource.getWebappPath();
+
+        for (String entry : entries) {
+
+            if (entry.equalsIgnoreCase("WEB-INF") ||
+                entry.equalsIgnoreCase("META-INF") ||
+                entry.equalsIgnoreCase(localXsltFile))
+                continue;
+
+            if ((directoryWebappPath + entry).equals(contextXsltFile))
+                continue;
+
+            WebResource childResource =
+                resources.getResource(directoryWebappPath + entry);
+            if (!childResource.exists()) {
+                continue;
+            }
+
+            sb.append("<entry");
+            sb.append(" type='")
+              .append(childResource.isDirectory()?"dir":"file")
+              .append('\'');
+            sb.append(" urlPath='")
+              .append(rewrittenContextPath)
+              .append(rewriteUrl(directoryWebappPath + entry))
+              .append(childResource.isDirectory()?"/":"")
+              .append('\'');
+            if (childResource.isFile()) {
+                sb.append(" size='")
+                  .append(renderSize(childResource.getContentLength()))
+                  .append('\'');
+            }
+            sb.append(" date='")
+              .append(childResource.getLastModifiedHttp())
+              .append('\'');
+
+            sb.append('>');
+            sb.append(Escape.htmlElementContent(entry));
+            if (childResource.isDirectory())
+                sb.append('/');
+            sb.append("</entry>");
+        }
+        sb.append("</entries>");
+
+        String readme = getReadme(resource, encoding);
+
+        if (readme!=null) {
+            sb.append("<readme><![CDATA[");
+            sb.append(readme);
+            sb.append("]]></readme>");
+        }
+
+        sb.append("</listing>");
+
+        // Prevent possible memory leak. Ensure Transformer and
+        // TransformerFactory are not loaded from the web application.
+        ClassLoader original;
+        if (Globals.IS_SECURITY_ENABLED) {
+            PrivilegedGetTccl pa = new PrivilegedGetTccl();
+            original = AccessController.doPrivileged(pa);
+        } else {
+            original = Thread.currentThread().getContextClassLoader();
+        }
+        try {
+            if (Globals.IS_SECURITY_ENABLED) {
+                PrivilegedSetTccl pa =
+                    new PrivilegedSetTccl(DefaultServlet.class.getClassLoader());
+                AccessController.doPrivileged(pa);
+            } else {
+                Thread.currentThread().setContextClassLoader(
+                    DefaultServlet.class.getClassLoader());
+            }
+
+            TransformerFactory tFactory = TransformerFactory.newInstance();
+            Source xmlSource = new StreamSource(new StringReader(sb.toString()));
+            Transformer transformer = tFactory.newTransformer(xsltSource);
+
+            ByteArrayOutputStream stream = new ByteArrayOutputStream();
+            OutputStreamWriter osWriter = new OutputStreamWriter(stream, StandardCharsets.UTF_8);
+            StreamResult out = new StreamResult(osWriter);
+            transformer.transform(xmlSource, out);
+            osWriter.flush();
+            return new ByteArrayInputStream(stream.toByteArray());
+        } catch (TransformerException e) {
+            throw new ServletException(sm.getString("defaultServlet.xslError"), e);
+        } finally {
+            if (Globals.IS_SECURITY_ENABLED) {
+                PrivilegedSetTccl pa = new PrivilegedSetTccl(original);
+                AccessController.doPrivileged(pa);
+            } else {
+                Thread.currentThread().setContextClassLoader(original);
+            }
+        }
+    }
+
+    /**
+     * Return an InputStream to an HTML representation of the contents of this
+     * directory.
+     *
+     * @param contextPath Context path to which our internal paths are relative
+     * @param resource    The associated resource
+     * @param encoding    The encoding to use to process the readme (if any)
+     *
+     * @return the HTML data
+     *
+     * @throws IOException an IO error occurred
+     *
+     * @deprecated Unused. Will be removed in Tomcat 10
+     * @deprecated Use {@link #renderHtml(HttpServletRequest, String, WebResource, String)} instead
+     */
+    @Deprecated
+    protected InputStream renderHtml(String contextPath, WebResource resource, String encoding)
+        throws IOException {
+        return renderHtml(null, contextPath, resource, encoding);
+    }
+
+    /**
+     * Return an InputStream to an HTML representation of the contents of this
+     * directory.
+     *
+     * @param request     The HttpServletRequest being served
+     * @param contextPath Context path to which our internal paths are relative
+     * @param resource    The associated resource
+     * @param encoding    The encoding to use to process the readme (if any)
+     *
+     * @return the HTML data
+     *
+     * @throws IOException an IO error occurred
+     */
+    protected InputStream renderHtml(HttpServletRequest request, String contextPath, WebResource resource, String encoding)
+        throws IOException {
+
+        // Prepare a writer to a buffered area
+        ByteArrayOutputStream stream = new ByteArrayOutputStream();
+        OutputStreamWriter osWriter = new OutputStreamWriter(stream, StandardCharsets.UTF_8);
+        PrintWriter writer = new PrintWriter(osWriter);
+
+        StringBuilder sb = new StringBuilder();
+
+        String directoryWebappPath = resource.getWebappPath();
+        WebResource[] entries = resources.listResources(directoryWebappPath);
+
+        // rewriteUrl(contextPath) is expensive. cache result for later reuse
+        String rewrittenContextPath =  rewriteUrl(contextPath);
+
+        // Render the page header
+        sb.append("<!doctype html><html>\r\n");
+        /* TODO Activate this as soon as we use smClient with the request locales
+        sb.append("<!doctype html><html lang=\"");
+        sb.append(smClient.getLocale().getLanguage()).append("\">\r\n");
+        */
+        sb.append("<head>\r\n");
+        sb.append("<title>");
+        sb.append(sm.getString("directory.title", directoryWebappPath));
+        sb.append("</title>\r\n");
+        sb.append("<style>");
+        sb.append(org.apache.catalina.util.TomcatCSS.TOMCAT_CSS);
+        sb.append("</style> ");
+        sb.append("</head>\r\n");
+        sb.append("<body>");
+        sb.append("<h1>");
+        sb.append(sm.getString("directory.title", directoryWebappPath));
+
+        // Render the link to our parent (if required)
+        String parentDirectory = directoryWebappPath;
+        if (parentDirectory.endsWith("/")) {
+            parentDirectory =
+                parentDirectory.substring(0, parentDirectory.length() - 1);
+        }
+        int slash = parentDirectory.lastIndexOf('/');
+        if (slash >= 0) {
+            String parent = directoryWebappPath.substring(0, slash);
+            sb.append(" - <a href=\"");
+            sb.append(rewrittenContextPath);
+            if (parent.equals(""))
+                parent = "/";
+            sb.append(rewriteUrl(parent));
+            if (!parent.endsWith("/"))
+                sb.append('/');
+            sb.append("\">");
+            sb.append("<b>");
+            sb.append(sm.getString("directory.parent", parent));
+            sb.append("</b>");
+            sb.append("</a>");
+        }
+
+        sb.append("</h1>");
+        sb.append("<hr class=\"line\">");
+
+        sb.append("<table width=\"100%\" cellspacing=\"0\"" +
+                  " cellpadding=\"5\" align=\"center\">\r\n");
+
+        SortManager.Order order;
+        if(sortListings && null != request)
+            order = sortManager.getOrder(request.getQueryString());
+        else
+            order = null;
+        // Render the column headings
+        sb.append("<tr>\r\n");
+        sb.append("<td align=\"left\"><font size=\"+1\"><strong>");
+        if(sortListings && null != request) {
+            sb.append("<a href=\"?C=N;O=");
+            sb.append(getOrderChar(order, 'N'));
+            sb.append("\">");
+            sb.append(sm.getString("directory.filename"));
+            sb.append("</a>");
+        } else {
+            sb.append(sm.getString("directory.filename"));
+        }
+        sb.append("</strong></font></td>\r\n");
+        sb.append("<td align=\"center\"><font size=\"+1\"><strong>");
+        if(sortListings && null != request) {
+            sb.append("<a href=\"?C=S;O=");
+            sb.append(getOrderChar(order, 'S'));
+            sb.append("\">");
+            sb.append(sm.getString("directory.size"));
+            sb.append("</a>");
+        } else {
+            sb.append(sm.getString("directory.size"));
+        }
+        sb.append("</strong></font></td>\r\n");
+        sb.append("<td align=\"right\"><font size=\"+1\"><strong>");
+        if(sortListings && null != request) {
+            sb.append("<a href=\"?C=M;O=");
+            sb.append(getOrderChar(order, 'M'));
+            sb.append("\">");
+            sb.append(sm.getString("directory.lastModified"));
+            sb.append("</a>");
+        } else {
+            sb.append(sm.getString("directory.lastModified"));
+        }
+        sb.append("</strong></font></td>\r\n");
+        sb.append("</tr>");
+
+        if(null != sortManager && null != request) {
+            sortManager.sort(entries, request.getQueryString());
+        }
+
+        boolean shade = false;
+        for (WebResource childResource : entries) {
+            String filename = childResource.getName();
+            if (filename.equalsIgnoreCase("WEB-INF") ||
+                filename.equalsIgnoreCase("META-INF"))
+                continue;
+
+            if (!childResource.exists()) {
+                continue;
+            }
+
+            sb.append("<tr");
+            if (shade)
+                sb.append(" bgcolor=\"#eeeeee\"");
+            sb.append(">\r\n");
+            shade = !shade;
+
+            sb.append("<td align=\"left\">&nbsp;&nbsp;\r\n");
+            sb.append("<a href=\"");
+            sb.append(rewrittenContextPath);
+            sb.append(rewriteUrl(childResource.getWebappPath()));
+            if (childResource.isDirectory())
+                sb.append('/');
+            sb.append("\"><tt>");
+            sb.append(Escape.htmlElementContent(filename));
+            if (childResource.isDirectory())
+                sb.append('/');
+            sb.append("</tt></a></td>\r\n");
+
+            sb.append("<td align=\"right\"><tt>");
+            if (childResource.isDirectory())
+                sb.append("&nbsp;");
+            else
+                sb.append(renderSize(childResource.getContentLength()));
+            sb.append("</tt></td>\r\n");
+
+            sb.append("<td align=\"right\"><tt>");
+            sb.append(childResource.getLastModifiedHttp());
+            sb.append("</tt></td>\r\n");
+
+            sb.append("</tr>\r\n");
+        }
+
+        // Render the page footer
+        sb.append("</table>\r\n");
+
+        sb.append("<hr class=\"line\">");
+
+        String readme = getReadme(resource, encoding);
+        if (readme!=null) {
+            sb.append(readme);
+            sb.append("<hr class=\"line\">");
+        }
+
+        if (showServerInfo) {
+            sb.append("<h3>").append(ServerInfo.getServerInfo()).append("</h3>");
+        }
+        sb.append("</body>\r\n");
+        sb.append("</html>\r\n");
+
+        // Return an input stream to the underlying bytes
+        writer.write(sb.toString());
+        writer.flush();
+        return new ByteArrayInputStream(stream.toByteArray());
+
+    }
+
+
+    /**
+     * Render the specified file size (in bytes).
+     *
+     * @param size File size (in bytes)
+     * @return the formatted size
+     */
+    protected String renderSize(long size) {
+
+        long leftSide = size / 1024;
+        long rightSide = (size % 1024) / 103;   // Makes 1 digit
+        if ((leftSide == 0) && (rightSide == 0) && (size > 0))
+            rightSide = 1;
+
+        return ("" + leftSide + "." + rightSide + " kb");
+
+    }
+
+
+    /**
+     * Get the readme file as a string.
+     * @param directory The directory to search
+     * @param encoding The readme encoding
+     * @return the readme for the specified directory
+     */
+    protected String getReadme(WebResource directory, String encoding) {
+
+        if (readmeFile != null) {
+            WebResource resource = resources.getResource(
+                directory.getWebappPath() + readmeFile);
+            if (resource.isFile()) {
+                StringWriter buffer = new StringWriter();
+                InputStreamReader reader = null;
+                try (InputStream is = resource.getInputStream()){
+                    if (encoding != null) {
+                        reader = new InputStreamReader(is, encoding);
+                    } else {
+                        reader = new InputStreamReader(is);
+                    }
+                    copyRange(reader, new PrintWriter(buffer));
+                } catch (IOException e) {
+                    log(sm.getString("defaultServlet.readerCloseFailed"), e);
+                } finally {
+                    if (reader != null) {
+                        try {
+                            reader.close();
+                        } catch (IOException e) {
+                        }
+                    }
+                }
+                return buffer.toString();
+            } else {
+                if (debug > 10)
+                    log("readme '" + readmeFile + "' not found");
+
+                return null;
+            }
+        }
+
+        return null;
+    }
+
+
+    /**
+     * Return a Source for the xsl template (if possible).
+     * @param directory The directory to search
+     * @return the source for the specified directory
+     * @throws IOException an IO error occurred
+     */
+    protected Source findXsltSource(WebResource directory)
+        throws IOException {
+
+        if (localXsltFile != null) {
+            WebResource resource = resources.getResource(
+                directory.getWebappPath() + localXsltFile);
+            if (resource.isFile()) {
+                InputStream is = resource.getInputStream();
+                if (is != null) {
+                    if (Globals.IS_SECURITY_ENABLED) {
+                        return secureXslt(is);
+                    } else {
+                        return new StreamSource(is);
+                    }
+                }
+            }
+            if (debug > 10) {
+                log("localXsltFile '" + localXsltFile + "' not found");
+            }
+        }
+
+        if (contextXsltFile != null) {
+            InputStream is =
+                getServletContext().getResourceAsStream(contextXsltFile);
+            if (is != null) {
+                if (Globals.IS_SECURITY_ENABLED) {
+                    return secureXslt(is);
+                } else {
+                    return new StreamSource(is);
+                }
+            }
+
+            if (debug > 10)
+                log("contextXsltFile '" + contextXsltFile + "' not found");
+        }
+
+        /*  Open and read in file in one fell swoop to reduce chance
+         *  chance of leaving handle open.
+         */
+        if (globalXsltFile != null) {
+            File f = validateGlobalXsltFile();
+            if (f != null) {
+                long globalXsltFileSize = f.length();
+                if (globalXsltFileSize > Integer.MAX_VALUE) {
+                    log("globalXsltFile [" + f.getAbsolutePath() + "] is too big to buffer");
+                } else {
+                    try (FileInputStream fis = new FileInputStream(f)){
+                        byte b[] = new byte[(int)f.length()];
+                        IOTools.readFully(fis, b);
+                        return new StreamSource(new ByteArrayInputStream(b));
+                    }
+                }
+            }
+        }
+
+        return null;
+    }
+
+
+    private File validateGlobalXsltFile() {
+        Context context = resources.getContext();
+
+        File baseConf = new File(context.getCatalinaBase(), "conf");
+        File result = validateGlobalXsltFile(baseConf);
+        if (result == null) {
+            File homeConf = new File(context.getCatalinaHome(), "conf");
+            if (!baseConf.equals(homeConf)) {
+                result = validateGlobalXsltFile(homeConf);
+            }
+        }
+
+        return result;
+    }
+
+
+    private File validateGlobalXsltFile(File base) {
+        File candidate = new File(globalXsltFile);
+        if (!candidate.isAbsolute()) {
+            candidate = new File(base, globalXsltFile);
+        }
+
+        if (!candidate.isFile()) {
+            return null;
+        }
+
+        // First check that the resulting path is under the provided base
+        try {
+            if (!candidate.getCanonicalFile().toPath().startsWith(base.getCanonicalFile().toPath())) {
+                return null;
+            }
+        } catch (IOException ioe) {
+            return null;
+        }
+
+        // Next check that an .xsl or .xslt file has been specified
+        String nameLower = candidate.getName().toLowerCase(Locale.ENGLISH);
+        if (!nameLower.endsWith(".xslt") && !nameLower.endsWith(".xsl")) {
+            return null;
+        }
+
+        return candidate;
+    }
+
+
+    private Source secureXslt(InputStream is) {
+        // Need to filter out any external entities
+        Source result = null;
+        try {
+            DocumentBuilder builder = factory.newDocumentBuilder();
+            builder.setEntityResolver(secureEntityResolver);
+            Document document = builder.parse(is);
+            result = new DOMSource(document);
+        } catch (ParserConfigurationException | SAXException | IOException e) {
+            if (debug > 0) {
+                log(e.getMessage(), e);
+            }
+        } finally {
+            if (is != null) {
+                try {
+                    is.close();
+                } catch (IOException e) {
+                    // Ignore
+                }
+            }
+        }
+        return result;
+    }
+
+
+    // -------------------------------------------------------- protected Methods
+
+    /**
+     * Check if sendfile can be used.
+     * @param request The Servlet request
+     * @param response The Servlet response
+     * @param resource The resource
+     * @param length The length which will be written (will be used only if
+     *  range is null)
+     * @param range The range that will be written
+     * @return <code>true</code> if sendfile should be used (writing is then
+     *  delegated to the endpoint)
+     */
+    protected boolean checkSendfile(HttpServletRequest request,
+                                    HttpServletResponse response,
+                                    WebResource resource,
+                                  long length, Range range) {
+        String canonicalPath;
+        if (sendfileSize > 0
+            && length > sendfileSize
+            && (Boolean.TRUE.equals(request.getAttribute(Globals.SENDFILE_SUPPORTED_ATTR)))
+            && (request.getClass().getName().equals("org.apache.catalina.connector.RequestFacade"))
+            && (response.getClass().getName().equals("org.apache.catalina.connector.ResponseFacade"))
+            && resource.isFile()
+            && ((canonicalPath = resource.getCanonicalPath()) != null)
+        ) {
+            request.setAttribute(Globals.SENDFILE_FILENAME_ATTR, canonicalPath);
+            if (range == null) {
+                request.setAttribute(Globals.SENDFILE_FILE_START_ATTR, Long.valueOf(0L));
+                request.setAttribute(Globals.SENDFILE_FILE_END_ATTR, Long.valueOf(length));
+            } else {
+                request.setAttribute(Globals.SENDFILE_FILE_START_ATTR, Long.valueOf(range.start));
+                request.setAttribute(Globals.SENDFILE_FILE_END_ATTR, Long.valueOf(range.end + 1));
+            }
+            return true;
+        }
+        return false;
+    }
+
+
+    /**
+     * Check if the if-match condition is satisfied.
+     *
+     * @param request   The servlet request we are processing
+     * @param response  The servlet response we are creating
+     * @param resource  The resource
+     * @return <code>true</code> if the resource meets the specified condition,
+     *  and <code>false</code> if the condition is not satisfied, in which case
+     *  request processing is stopped
+     * @throws IOException an IO error occurred
+     */
+    protected boolean checkIfMatch(HttpServletRequest request, HttpServletResponse response, WebResource resource)
+        throws IOException {
+
+        String headerValue = request.getHeader("If-Match");
+        if (headerValue != null) {
+
+            boolean conditionSatisfied;
+
+            if (!headerValue.equals("*")) {
+                String resourceETag = generateETag(resource);
+                if (resourceETag == null) {
+                    conditionSatisfied = false;
+                } else {
+                    // RFC 7232 requires strong comparison for If-Match headers
+                    Boolean matched = EntityTag.compareEntityTag(new StringReader(headerValue), false, resourceETag);
+                    if (matched == null) {
+                        if (debug > 10) {
+                            log("DefaultServlet.checkIfMatch:  Invalid header value [" + headerValue + "]");
+                        }
+                        response.sendError(HttpServletResponse.SC_BAD_REQUEST);
+                        return false;
+                    }
+                    conditionSatisfied = matched.booleanValue();
+                }
+            } else {
+                conditionSatisfied = true;
+            }
+
+            if (!conditionSatisfied) {
+                response.sendError(HttpServletResponse.SC_PRECONDITION_FAILED);
+                return false;
+            }
+        }
+        return true;
+    }
+
+
+    /**
+     * Check if the if-modified-since condition is satisfied.
+     *
+     * @param request   The servlet request we are processing
+     * @param response  The servlet response we are creating
+     * @param resource  The resource
+     * @return <code>true</code> if the resource meets the specified condition,
+     *  and <code>false</code> if the condition is not satisfied, in which case
+     *  request processing is stopped
+     */
+    protected boolean checkIfModifiedSince(HttpServletRequest request,
+                                           HttpServletResponse response, WebResource resource) {
+        try {
+            long headerValue = request.getDateHeader("If-Modified-Since");
+            long lastModified = resource.getLastModified();
+            if (headerValue != -1) {
+
+                // If an If-None-Match header has been specified, if modified since
+                // is ignored.
+                if ((request.getHeader("If-None-Match") == null)
+                    && (lastModified < headerValue + 1000)) {
+                    // The entity has not been modified since the date
+                    // specified by the client. This is not an error case.
+                    response.setStatus(HttpServletResponse.SC_NOT_MODIFIED);
+                    response.setHeader("ETag", generateETag(resource));
+
+                    return false;
+                }
+            }
+        } catch (IllegalArgumentException illegalArgument) {
+            return true;
+        }
+        return true;
+    }
+
+
+    /**
+     * Check if the if-none-match condition is satisfied.
+     *
+     * @param request   The servlet request we are processing
+     * @param response  The servlet response we are creating
+     * @param resource  The resource
+     * @return <code>true</code> if the resource meets the specified condition,
+     *  and <code>false</code> if the condition is not satisfied, in which case
+     *  request processing is stopped
+     * @throws IOException an IO error occurred
+     */
+    protected boolean checkIfNoneMatch(HttpServletRequest request, HttpServletResponse response, WebResource resource)
+        throws IOException {
+
+        String headerValue = request.getHeader("If-None-Match");
+        if (headerValue != null) {
+
+            boolean conditionSatisfied;
+
+            String resourceETag = generateETag(resource);
+            if (!headerValue.equals("*")) {
+                if (resourceETag == null) {
+                    conditionSatisfied = false;
+                } else {
+                    // RFC 7232 requires weak comparison for If-None-Match headers
+                    Boolean matched = EntityTag.compareEntityTag(new StringReader(headerValue), true, resourceETag);
+                    if (matched == null) {
+                        if (debug > 10) {
+                            log("DefaultServlet.checkIfNoneMatch:  Invalid header value [" + headerValue + "]");
+                        }
+                        response.sendError(HttpServletResponse.SC_BAD_REQUEST);
+                        return false;
+                    }
+                    conditionSatisfied = matched.booleanValue();
+                }
+            } else {
+                conditionSatisfied = true;
+            }
+
+            if (conditionSatisfied) {
+                // For GET and HEAD, we should respond with
+                // 304 Not Modified.
+                // For every other method, 412 Precondition Failed is sent
+                // back.
+                if ("GET".equals(request.getMethod()) || "HEAD".equals(request.getMethod())) {
+                    response.setStatus(HttpServletResponse.SC_NOT_MODIFIED);
+                    response.setHeader("ETag", resourceETag);
+                } else {
+                    response.sendError(HttpServletResponse.SC_PRECONDITION_FAILED);
+                }
+                return false;
+            }
+        }
+        return true;
+    }
+
+
+    /**
+     * Check if the if-unmodified-since condition is satisfied.
+     *
+     * @param request   The servlet request we are processing
+     * @param response  The servlet response we are creating
+     * @param resource  The resource
+     * @return <code>true</code> if the resource meets the specified condition,
+     *  and <code>false</code> if the condition is not satisfied, in which case
+     *  request processing is stopped
+     * @throws IOException an IO error occurred
+     */
+    protected boolean checkIfUnmodifiedSince(HttpServletRequest request,
+                                             HttpServletResponse response, WebResource resource)
+        throws IOException {
+        try {
+            long lastModified = resource.getLastModified();
+            long headerValue = request.getDateHeader("If-Unmodified-Since");
+            if (headerValue != -1) {
+                if ( lastModified >= (headerValue + 1000)) {
+                    // The entity has not been modified since the date
+                    // specified by the client. This is not an error case.
+                    response.sendError(HttpServletResponse.SC_PRECONDITION_FAILED);
+                    return false;
+                }
+            }
+        } catch(IllegalArgumentException illegalArgument) {
+            return true;
+        }
+        return true;
+    }
+
+
+    /**
+     * Provides the entity tag (the ETag header) for the given resource.
+     * Intended to be over-ridden by custom DefaultServlet implementations that
+     * wish to use an alternative format for the entity tag.
+     *
+     * @param resource  The resource for which an entity tag is required.
+     *
+     * @return The result of calling {@link WebResource#getETag()} on the given
+     *         resource
+     */
+    protected String generateETag(WebResource resource) {
+        return resource.getETag();
+    }
+
+
+    /**
+     * Copy the contents of the specified input stream to the specified
+     * output stream, and ensure that both streams are closed before returning
+     * (even in the face of an exception).
+     *
+     * @param is        The input stream to read the source resource from
+     * @param ostream   The output stream to write to
+     *
+     * @exception IOException if an input/output error occurs
+     */
+    protected void copy(InputStream is, ServletOutputStream ostream) throws IOException {
+
+        IOException exception = null;
+        InputStream istream = new BufferedInputStream(is, input);
+
+        // Copy the input stream to the output stream
+        exception = copyRange(istream, ostream);
+
+        // Clean up the input stream
+        istream.close();
+
+        // Rethrow any exception that has occurred
+        if (exception != null)
+            throw exception;
+    }
+
+
+    /**
+     * Copy the contents of the specified input stream to the specified
+     * output stream, and ensure that both streams are closed before returning
+     * (even in the face of an exception).
+     *
+     * @param is        The input stream to read the source resource from
+     * @param writer    The writer to write to
+     * @param encoding  The encoding to use when reading the source input stream
+     *
+     * @exception IOException if an input/output error occurs
+     */
+    protected void copy(InputStream is, PrintWriter writer, String encoding) throws IOException {
+        IOException exception = null;
+
+        Reader reader;
+        if (encoding == null) {
+            reader = new InputStreamReader(is);
+        } else {
+            reader = new InputStreamReader(is, encoding);
+        }
+
+        // Copy the input stream to the output stream
+        exception = copyRange(reader, writer);
+
+        // Clean up the reader
+        reader.close();
+
+        // Rethrow any exception that has occurred
+        if (exception != null) {
+            throw exception;
+        }
+    }
+
+
+    /**
+     * Copy the contents of the specified input stream to the specified
+     * output stream, and ensure that both streams are closed before returning
+     * (even in the face of an exception).
+     *
+     * @param resource  The source resource
+     * @param ostream   The output stream to write to
+     * @param range     Range the client wanted to retrieve
+     * @exception IOException if an input/output error occurs
+     */
+    protected void copy(WebResource resource, ServletOutputStream ostream,
+                      Range range)
+        throws IOException {
+
+        IOException exception = null;
+
+        InputStream resourceInputStream = resource.getInputStream();
+        InputStream istream =
+            new BufferedInputStream(resourceInputStream, input);
+        exception = copyRange(istream, ostream, range.start, range.end);
+
+        // Clean up the input stream
+        istream.close();
+
+        // Rethrow any exception that has occurred
+        if (exception != null)
+            throw exception;
+
+    }
+
+
+    /**
+     * Copy the contents of the specified input stream to the specified
+     * output stream, and ensure that both streams are closed before returning
+     * (even in the face of an exception).
+     *
+     * @param resource      The source resource
+     * @param ostream       The output stream to write to
+     * @param ranges        Enumeration of the ranges the client wanted to
+     *                          retrieve
+     * @param contentType   Content type of the resource
+     * @exception IOException if an input/output error occurs
+     */
+    protected void copy(WebResource resource, ServletOutputStream ostream,
+                      Iterator<Range> ranges, String contentType)
+        throws IOException {
+
+        IOException exception = null;
+
+        while ( (exception == null) && (ranges.hasNext()) ) {
+
+            InputStream resourceInputStream = resource.getInputStream();
+            try (InputStream istream = new BufferedInputStream(resourceInputStream, input)) {
+
+                Range currentRange = ranges.next();
+
+                // Writing MIME header.
+                ostream.println();
+                ostream.println("--" + mimeSeparation);
+                if (contentType != null)
+                    ostream.println("Content-Type: " + contentType);
+                ostream.println("Content-Range: bytes " + currentRange.start
+                               + "-" + currentRange.end + "/"
+                               + currentRange.length);
+                ostream.println();
+
+                // Printing content
+                exception = copyRange(istream, ostream, currentRange.start,
+                                      currentRange.end);
+            }
+        }
+
+        ostream.println();
+        ostream.print("--" + mimeSeparation + "--");
+
+        // Rethrow any exception that has occurred
+        if (exception != null)
+            throw exception;
+
+    }
+
+
+    /**
+     * Copy the contents of the specified input stream to the specified
+     * output stream, and ensure that both streams are closed before returning
+     * (even in the face of an exception).
+     *
+     * @param istream The input stream to read from
+     * @param ostream The output stream to write to
+     * @return Exception which occurred during processing
+     */
+    protected IOException copyRange(InputStream istream,
+                                    ServletOutputStream ostream) {
+
+        // Copy the input stream to the output stream
+        IOException exception = null;
+        byte buffer[] = new byte[input];
+        int len = buffer.length;
+        while (true) {
+            try {
+                len = istream.read(buffer);
+                if (len == -1)
+                    break;
+                ostream.write(buffer, 0, len);
+            } catch (IOException e) {
+                exception = e;
+                len = -1;
+                break;
+            }
+        }
+        return exception;
+
+    }
+
+
+    /**
+     * Copy the contents of the specified input stream to the specified
+     * output stream, and ensure that both streams are closed before returning
+     * (even in the face of an exception).
+     *
+     * @param reader The reader to read from
+     * @param writer The writer to write to
+     * @return Exception which occurred during processing
+     */
+    protected IOException copyRange(Reader reader, PrintWriter writer) {
+
+        // Copy the input stream to the output stream
+        IOException exception = null;
+        char buffer[] = new char[input];
+        int len = buffer.length;
+        while (true) {
+            try {
+                len = reader.read(buffer);
+                if (len == -1)
+                    break;
+                writer.write(buffer, 0, len);
+            } catch (IOException e) {
+                exception = e;
+                len = -1;
+                break;
+            }
+        }
+        return exception;
+
+    }
+
+
+    /**
+     * Copy the contents of the specified input stream to the specified
+     * output stream, and ensure that both streams are closed before returning
+     * (even in the face of an exception).
+     *
+     * @param istream The input stream to read from
+     * @param ostream The output stream to write to
+     * @param start Start of the range which will be copied
+     * @param end End of the range which will be copied
+     * @return Exception which occurred during processing
+     */
+    protected IOException copyRange(InputStream istream,
+                                    ServletOutputStream ostream,
+                                    long start, long end) {
+
+        if (debug > 10)
+            log("Serving bytes:" + start + "-" + end);
+
+        long skipped = 0;
+        try {
+            skipped = istream.skip(start);
+        } catch (IOException e) {
+            return e;
+        }
+        if (skipped < start) {
+            return new IOException(sm.getString("defaultServlet.skipfail",
+                                                Long.valueOf(skipped), Long.valueOf(start)));
+        }
+
+        IOException exception = null;
+        long bytesToRead = end - start + 1;
+
+        byte buffer[] = new byte[input];
+        int len = buffer.length;
+        while ( (bytesToRead > 0) && (len >= buffer.length)) {
+            try {
+                len = istream.read(buffer);
+                if (bytesToRead >= len) {
+                    ostream.write(buffer, 0, len);
+                    bytesToRead -= len;
+                } else {
+                    ostream.write(buffer, 0, (int) bytesToRead);
+                    bytesToRead = 0;
+                }
+            } catch (IOException e) {
+                exception = e;
+                len = -1;
+            }
+            if (len < buffer.length)
+                break;
+        }
+
+        return exception;
+
+    }
+
+
+    protected static class Range {
+
+        public long start;
+        public long end;
+        public long length;
+
+        /**
+         * Validate range.
+         *
+         * @return true if the range is valid, otherwise false
+         */
+        public boolean validate() {
+            if (end >= length)
+                end = length - 1;
+            return (start >= 0) && (end >= 0) && (start <= end) && (length > 0);
+        }
+    }
+
+    protected static class CompressionFormat implements Serializable {
+        private static final long serialVersionUID = 1L;
+        public final String extension;
+        public final String encoding;
+
+        public CompressionFormat(String extension, String encoding) {
+            this.extension = extension;
+            this.encoding = encoding;
+        }
+    }
+
+    private static class PrecompressedResource {
+        public final WebResource resource;
+        public final CompressionFormat format;
+
+        private PrecompressedResource(WebResource resource, CompressionFormat format) {
+            this.resource = resource;
+            this.format = format;
+        }
+    }
+
+    /**
+     * This is secure in the sense that any attempt to use an external entity
+     * will trigger an exception.
+     */
+    private static class SecureEntityResolver implements EntityResolver2  {
+
+        @Override
+        public InputSource resolveEntity(String publicId, String systemId)
+            throws SAXException, IOException {
+            throw new SAXException(sm.getString("defaultServlet.blockExternalEntity",
+                                                publicId, systemId));
+        }
+
+        @Override
+        public InputSource getExternalSubset(String name, String baseURI)
+            throws SAXException, IOException {
+            throw new SAXException(sm.getString("defaultServlet.blockExternalSubset",
+                                                name, baseURI));
+        }
+
+        @Override
+        public InputSource resolveEntity(String name, String publicId,
+                                         String baseURI, String systemId) throws SAXException,
+                                                                                 IOException {
+            throw new SAXException(sm.getString("defaultServlet.blockExternalEntity2",
+                                                name, publicId, baseURI, systemId));
+        }
+    }
+
+    /**
+     * Gets the ordering character to be used for a particular column.
+     *
+     * @param order  The order that is currently being applied
+     * @param column The column that will be rendered.
+     *
+     * @return Either 'A' or 'D', to indicate "ascending" or "descending" sort
+     *         order.
+     */
+    private char getOrderChar(SortManager.Order order, char column) {
+        if(column == order.column) {
+            if(order.ascending) {
+                return 'D';
+            } else {
+                return 'A';
+            }
+        } else {
+            return 'D';
+        }
+    }
+
+    /**
+     * A class encapsulating the sorting of resources.
+     */
+    private static class SortManager
+    {
+        /**
+         * The default sort.
+         */
+        protected Comparator<WebResource> defaultResourceComparator;
+
+        /**
+         * Comparator to use when sorting resources by name.
+         */
+        protected Comparator<WebResource> resourceNameComparator;
+
+        /**
+         * Comparator to use when sorting files by name, ascending (reverse).
+         */
+        protected Comparator<WebResource> resourceNameComparatorAsc;
+
+        /**
+         * Comparator to use when sorting resources by size.
+         */
+        protected Comparator<WebResource> resourceSizeComparator;
+
+        /**
+         * Comparator to use when sorting files by size, ascending (reverse).
+         */
+        protected Comparator<WebResource> resourceSizeComparatorAsc;
+
+        /**
+         * Comparator to use when sorting resources by last-modified date.
+         */
+        protected Comparator<WebResource> resourceLastModifiedComparator;
+
+        /**
+         * Comparator to use when sorting files by last-modified date, ascending (reverse).
+         */
+        protected Comparator<WebResource> resourceLastModifiedComparatorAsc;
+
+        public SortManager(boolean directoriesFirst) {
+            resourceNameComparator = new ResourceNameComparator();
+            resourceNameComparatorAsc = Collections.reverseOrder(resourceNameComparator);
+            resourceSizeComparator = new ResourceSizeComparator(resourceNameComparator);
+            resourceSizeComparatorAsc = Collections.reverseOrder(resourceSizeComparator);
+            resourceLastModifiedComparator = new ResourceLastModifiedDateComparator(resourceNameComparator);
+            resourceLastModifiedComparatorAsc = Collections.reverseOrder(resourceLastModifiedComparator);
+
+            if(directoriesFirst) {
+                resourceNameComparator = new DirsFirstComparator(resourceNameComparator);
+                resourceNameComparatorAsc = new DirsFirstComparator(resourceNameComparatorAsc);
+                resourceSizeComparator = new DirsFirstComparator(resourceSizeComparator);
+                resourceSizeComparatorAsc = new DirsFirstComparator(resourceSizeComparatorAsc);
+                resourceLastModifiedComparator = new DirsFirstComparator(resourceLastModifiedComparator);
+                resourceLastModifiedComparatorAsc = new DirsFirstComparator(resourceLastModifiedComparatorAsc);
+            }
+
+            defaultResourceComparator = resourceNameComparator;
+        }
+
+        /**
+         * Sorts an array of resources according to an ordering string.
+         *
+         * @param resources The array to sort.
+         * @param order     The ordering string.
+         *
+         * @see #getOrder(String)
+         */
+        public void sort(WebResource[] resources, String order) {
+            Comparator<WebResource> comparator = getComparator(order);
+
+            if(null != comparator)
+                Arrays.sort(resources, comparator);
+        }
+
+        public Comparator<WebResource> getComparator(String order) {
+            return getComparator(getOrder(order));
+        }
+
+        public Comparator<WebResource> getComparator(Order order) {
+            if(null == order)
+                return defaultResourceComparator;
+
+            if('N' == order.column) {
+                if(order.ascending) {
+                    return resourceNameComparatorAsc;
+                } else {
+                    return resourceNameComparator;
+                }
+            }
+
+            if('S' == order.column) {
+                if(order.ascending) {
+                    return resourceSizeComparatorAsc;
+                } else {
+                    return resourceSizeComparator;
+                }
+            }
+
+            if('M' == order.column) {
+                if(order.ascending) {
+                    return resourceLastModifiedComparatorAsc;
+                } else {
+                    return resourceLastModifiedComparator;
+                }
+            }
+
+            return defaultResourceComparator;
+        }
+
+        /**
+         * Gets the Order to apply given an ordering-string. This
+         * ordering-string matches a subset of the ordering-strings
+         * supported by
+         * <a href="https://httpd.apache.org/docs/2.4/mod/mod_autoindex.html#query">Apache httpd</a>.
+         *
+         * @param order The ordering-string provided by the client.
+         *
+         * @return An Order specifying the column and ascending/descending to
+         *         be applied to resources.
+         */
+        public Order getOrder(String order) {
+            if(null == order || 0 == order.trim().length())
+                return Order.DEFAULT;
+
+            String[] options = order.split(";");
+
+            if(0 == options.length)
+                return Order.DEFAULT;
+
+            char column = '\0';
+            boolean ascending = false;
+
+            for(String option : options) {
+                option = option.trim();
+
+                if(2 < option.length()) {
+                    char opt = option.charAt(0);
+                    if('C' == opt)
+                        column = option.charAt(2);
+                    else if('O' == opt)
+                        ascending = ('A' == option.charAt(2));
+                }
+            }
+
+            if('N' == column) {
+                if(ascending) {
+                    return Order.NAME_ASC;
+                } else {
+                    return Order.NAME;
+                }
+            }
+
+            if('S' == column) {
+                if(ascending) {
+                    return Order.SIZE_ASC;
+                } else {
+                    return Order.SIZE;
+                }
+            }
+
+            if('M' == column) {
+                if(ascending) {
+                    return Order.LAST_MODIFIED_ASC;
+                } else {
+                    return Order.LAST_MODIFIED;
+                }
+            }
+
+            return Order.DEFAULT;
+        }
+
+        public static class Order {
+            final char column;
+            final boolean ascending;
+
+            public Order(char column, boolean ascending) {
+                this.column = column;
+                this.ascending = ascending;
+            }
+
+            public static final Order NAME = new Order('N', false);
+            public static final Order NAME_ASC = new Order('N', true);
+            public static final Order SIZE = new Order('S', false);
+            public static final Order SIZE_ASC = new Order('S', true);
+            public static final Order LAST_MODIFIED = new Order('M', false);
+            public static final Order LAST_MODIFIED_ASC = new Order('M', true);
+
+            public static final Order DEFAULT = NAME;
+        }
+    }
+
+    private static class DirsFirstComparator
+        implements Comparator<WebResource>
+    {
+        private final Comparator<WebResource> base;
+
+        public DirsFirstComparator(Comparator<WebResource> core) {
+            this.base = core;
+        }
+
+        @Override
+        public int compare(WebResource r1, WebResource r2) {
+            if(r1.isDirectory()) {
+                if(r2.isDirectory()) {
+                    return base.compare(r1, r2);
+                } else {
+                    return -1; // r1, directory, first
+                }
+            } else if(r2.isDirectory()) {
+                return 1; // r2, directory, first
+            } else {
+                return base.compare(r1, r2);
+            }
+        }
+    }
+
+    private static class ResourceNameComparator
+        implements Comparator<WebResource>
+    {
+        @Override
+        public int compare(WebResource r1, WebResource r2) {
+            return r1.getName().compareTo(r2.getName());
+        }
+    }
+
+    private static class ResourceSizeComparator
+        implements Comparator<WebResource>
+    {
+        private Comparator<WebResource> base;
+
+        public ResourceSizeComparator(Comparator<WebResource> base) {
+            this.base = base;
+        }
+
+        @Override
+        public int compare(WebResource r1, WebResource r2) {
+            int c = Long.compare(r1.getContentLength(), r2.getContentLength());
+
+            if(0 == c)
+                return base.compare(r1, r2);
+            else
+                return c;
+        }
+    }
+
+    private static class ResourceLastModifiedDateComparator
+        implements Comparator<WebResource>
+    {
+        private Comparator<WebResource> base;
+
+        public ResourceLastModifiedDateComparator(Comparator<WebResource> base) {
+            this.base = base;
+        }
+
+        @Override
+        public int compare(WebResource r1, WebResource r2) {
+            int c = Long.compare(r1.getLastModified(), r2.getLastModified());
+
+            if(0 == c)
+                return base.compare(r1, r2);
+            else
+                return c;
+        }
+    }
+}
