class ServletContainerRequest extends ContainerRequest {

    public static ServletContainerRequest create(final HttpServletRequest req) {
        // If the URL is forwarded, obtain the forwarding information
        final URL forwardedUrl = getForwardedUrl(req);
        String host;
        int port;
        if (forwardedUrl == null) {
            host = req.getServerName();
            port = req.getServerPort();
        } else {
            host = forwardedUrl.getHost();
            port = forwardedUrl.getPort();
            if (port < 0) {
                port = forwardedUrl.getDefaultPort();
            }
            LOG.debug("Assuming forwarded URL: {}", forwardedUrl);
        }

        // The common URI prefix for both baseUri and requestUri
        final StringBuilder commonUriBuilder = new StringBuilder();
        final String scheme = getScheme(req);
        commonUriBuilder.append(scheme);
        commonUriBuilder.append("://");
        commonUriBuilder.append(host);
        if (!(port < 0 || (port == 80 && "http".equals(scheme)) || (port == 443 && "https".equals(scheme)))) {
            commonUriBuilder.append(':');
            commonUriBuilder.append(port);
        }
        final String commonUriPrefix = commonUriBuilder.toString();

        // The Base URI - up to the servlet path
        final StringBuilder baseUriBuilder = new StringBuilder(commonUriPrefix);
        baseUriBuilder.append(req.getContextPath());
        baseUriBuilder.append(req.getServletPath());
        final URI baseUri = URI.create(baseUriBuilder.toString());

        // The RequestURI - everything in the URL
        final StringBuilder requestUriBuilder = new StringBuilder(commonUriPrefix);
        requestUriBuilder.append(req.getRequestURI());
        final String queryString = req.getQueryString();
        if (queryString != null) {
            requestUriBuilder.append('?');
            requestUriBuilder.append(queryString);
        }
        final URI requestUri = URI.create(requestUriBuilder.toString());
        return new ServletContainerRequest(getMethod(req), requestUri, baseUri, getEntityStream(req), getHeaders(req),
                                           getSecurityContext(req));
    }

    private  ServletContainerRequest(String method, URI requestUri, URI baseUri, InputStream entityStream,
                                    MultivaluedMap<String, String> httpHeaders, SecurityContext securityContext);

}