class ServerRunnable implements Runnable {

    @Override
    public void run() {
        HttpServletResponseImpl response = null;

        try {
            try {
                response = responseFactory.createFromSocket(socket);
                HttpServletRequestImpl request = requestFactory.createFromSocket(socket);

                LOGGER.log(Level.INFO, "Handling request {0} {1}", new Object[]{
                        request.getMethod(), request.getRequestURI()
                });

                String requestedPath = request.getRequestURI();

                if (pathHelper.isPathContainingIllegalCharacters(requestedPath)) {
                    throw new AccessDeniedException();
                }

                validateRequest(request);
                setDefaultResponseHeaders(request, response);
                serverConfig.getServletDispatcher().load(requestedPath, request, response);
            } catch (RuntimeException e) {
                if (response != null) {
                    httpErrorHandlerResolver.getHandler(e).serve(response);
                }

                throw e; // Make it logged by the main thread
            } finally {
                IOUtilities.closeSilently(socket);
            }
        } catch (IOException e) {
            LOGGER.log(Level.INFO, "Encountered IOException when handling request {0}", new Object[]{
                    e.getMessage()
            });
        }
    }

    public  ServerRunnable(final Socket socket,
                          final ServerConfig serverConfig,
                          final HttpServletRequestImplFactory requestFactory,
                          final HttpServletResponseImplFactory responseFactory,
                          final HttpErrorHandlerResolver httpErrorHandlerResolver,
                          final PathHelper pathHelper);

}