docs: protected void serveResource(final HttpServletRequest request, final HttpServletResponse response, final boolean content)
  			throws IOException, ServletException {
  
  		boolean serveContent = content;
  
  		// Identify the requested resource path
  		final String path = getRelativePath(request);
  		if (log.isDebugEnabled()) {
  			if (serveContent)
  				log.debug("DefaultServlet.serveResource:  Serving resource '" + path + "' headers and data");
  			else
  				log.debug("DefaultServlet.serveResource:  Serving resource '" + path + "' headers only");
  		}
  
  		final CacheEntry cacheEntry = lookupCache(path);
  
  		if (!cacheEntry.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("Missing resource : " + requestUri);
  			}
  
  			response.sendError(HttpServletResponse.SC_NOT_FOUND, requestUri);
  			return;
  		}
  
  		// If the resource is not a collection, and the resource path
  		// ends with "/" or "\", return NOT FOUND
  		if (path.endsWith("/") || (path.endsWith("\\"))) {
  			// 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();
  			}
  			response.sendError(HttpServletResponse.SC_NOT_FOUND, requestUri);
  			return;
  		}
  
  		final boolean isError = response.getStatus() >= HttpServletResponse.SC_BAD_REQUEST;
  
  		// Check if the conditions specified in the optional If headers are
  		// satisfied.
  
  		// Checking If headers
  		final boolean included = (request.getAttribute(RequestDispatcher.INCLUDE_CONTEXT_PATH) != null);
  		if (!included && !isError && !checkIfHeaders(request, response, cacheEntry.getAttributes())) {
  			return;
  		}
  
  		// Find content type.
  		String contentType = cacheEntry.getAttributes().getMimeType();
  		if (contentType == null) {
  			contentType = getServletContext().getMimeType(cacheEntry.getName());
  			cacheEntry.getAttributes().setMimeType(contentType);
  		}
  
  		ArrayList<Range> ranges = null;
  		long contentLength = -1L;
  
  		if (!isError) {
  			if (acceptsRanges()) {
  				// Accept ranges header
  				response.setHeader("Accept-Ranges", "bytes");
  			}
  
  			// Parse range specifier
  			ranges = parseRange(request, response, cacheEntry.getAttributes());
  
  			// ETag header
  			response.setHeader("ETag", cacheEntry.getAttributes().getETag());
  
  			// Last-Modified header
  			response.setHeader("Last-Modified", cacheEntry.getAttributes().getLastModifiedHttp());
  		}
  
  		// Get content length
  		contentLength = cacheEntry.getAttributes().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 (final IllegalStateException e) {
  				// If it fails, we try to get a Writer instead if we're
  				// trying to serve a text file
  				if ((contentType == null) || (contentType.startsWith("text")) || (contentType.endsWith("xml"))
  						|| (contentType.contains("/javascript"))) {
  					writer = response.getWriter();
  					// Cannot reliably serve partial content with a Writer
  					ranges = FULL;
  				} else {
  					throw e;
  				}
  			}
  
  		}
  
  		// Check to see if a Filter, Valve of 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;
  		}
  
  		if (isError || (((ranges == null) || (ranges.isEmpty())) && (request.getHeader("Range") == null)) || (ranges == FULL)) {
  
  			// Set the appropriate output headers
  			if (contentType != null) {
  				if (log.isDebugEnabled())
  					log.debug("DefaultServlet.serveFile:  contentType='" + contentType + "'");
  				response.setContentType(contentType);
  			}
  			if ((cacheEntry.getResource() != null) && (contentLength >= 0) && (!serveContent || ostream != null)) {
  				if (log.isDebugEnabled())
  					log.debug("DefaultServlet.serveFile:  contentLength=" + contentLength);
  				// Don't set a content length if something else has already
  				// written to the response.
  				if (contentWritten == 0) {
  					if (contentLength < Integer.MAX_VALUE) {
  						response.setContentLength((int) contentLength);
  					} else {
  						// Set the content-length as String to be able to use a
  						// long
  						response.setHeader("content-length", "" + contentLength);
  					}
  				}
  			}
  
  			final InputStream renderResult = null;
  
  			// Copy the input stream to our output stream (if requested)
  			if (serveContent) {
  				try {
  					response.setBufferSize(getOutputBufferSize());
  				} catch (final IllegalStateException e) {
  					// Silent catch
  				}
  				if (ostream != null) {
  					copy(cacheEntry, renderResult, ostream);
  				} else {
  					copy(cacheEntry, renderResult, writer);
  				}
  			}
  
  		} else {
  
  			if ((ranges == null) || (ranges.isEmpty()))
  				return;
  
  			// Partial content response.
  
  			response.setStatus(HttpServletResponse.SC_PARTIAL_CONTENT);
  
  			if (ranges.size() == 1) {
  
  				final Range range = ranges.get(0);
  				response.addHeader("Content-Range", "bytes " + range.start + "-" + range.end + "/" + range.length);
  				final long length = range.end - range.start + 1;
  				if (length < Integer.MAX_VALUE) {
  					response.setContentLength((int) length);
  				} else {
  					// Set the content-length as String to be able to use a long
  					response.setHeader("content-length", "" + length);
  				}
  
  				if (contentType != null) {
  					if (log.isDebugEnabled())
  						log.debug("DefaultServlet.serveFile:  contentType='" + contentType + "'");
  					response.setContentType(contentType);
  				}
  
  				if (serveContent) {
  					try {
  						response.setBufferSize(getOutputBufferSize());
  					} catch (final IllegalStateException e) {
  						// Silent catch
  					}
  					if (ostream != null) {
  						copy(cacheEntry, ostream, range);
  					} else {
  						// we should not get here
  						throw new IllegalStateException();
  					}
  				}
  
  			} else {
  
  				response.setContentType("multipart/byteranges; boundary=" + mimeSeparation);
  
  				if (serveContent) {
  					try {
  						response.setBufferSize(getOutputBufferSize());
  					} catch (final IllegalStateException e) {
  						// Silent catch
  					}
  					if (ostream != null) {
  						copy(cacheEntry, ostream, ranges.iterator(), contentType);
  					} else {
  						// we should not get here
  						throw new IllegalStateException();
  					}
  				}
  
  			}
  
  		}
  
  	}