class HttpServletRequestImplFactory {

    public HttpServletRequestImpl createFromSocket(final Socket socket)
            throws IOException, ProtocolException {

        HttpServletRequestImpl.Builder builder = HttpServletRequestImpl.createNewBuilder();

        InputStream in = socket.getInputStream();
        // The order matters

        RequestStatus status;
        try {
            status = statusParser.parse(getStatusLine(in));
        } catch (MalformedInputException e) {
            throw new MalformedStatusLineException("Malformed status line " + e.getMessage());
        }

        int uriLengthExceededWith = status.getUri().length() - URI_MAX_LENGTH;
        if (uriLengthExceededWith > 0) {
            throw new UriTooLongProtocolException("Uri length exceeded max length with"
                    + uriLengthExceededWith + " characters");
        }

        if (!isValidProtocol(status.getProtocol())) {
            throw new UnsupportedProtocolException("Protocol " + status.getProtocol() + " is not supported");
        }

        assignSocketMetadata(socket, builder);

        try {
            builder.withGetParameters(queryStringParser.parse(status.getQueryString()));
        } catch (MalformedInputException e) {
            // This should never happen
        }

        Headers headers = computeHeaders(in);

        builder.withServletContext(getImplicitServletContext())
                .withInputStream(in)
                .withStatus(status)
                .withPathTranslated(status.getUri()) // TODO There is no way to make it work under Android
                .withPathInfo("")
                .withRemoteUser(null)
                .withPrincipal(null)
                .withHeaders(headers)
                .withCookies(getCookies(headers));

        if (status.getMethod().equalsIgnoreCase(HttpServletRequest.METHOD_POST)) {
            try {
                handlePostRequest(builder, in, headers);
            } catch (MalformedInputException e) {
                throw new ProtocolException("Malformed post input");
            }
        }

        return builder.build();
    }

    public  HttpServletRequestImplFactory(final Parser<Headers> headersParser,
                                         final Parser<Map<String, String>> queryStringParser,
                                         final Parser<RequestStatus> statusParser,
                                         final Parser<Map<String, Cookie>> cookieParser,
                                         final Parser<MultipartHeadersPart> multipartHeadersPartParser,
                                         final String tempPath);

}