public static HTTPRequest load(InputStream is) throws HTTPException {
        GeneralHTTPRequest request = new GeneralHTTPRequest();

        try {
            LineNumberReader reader = new LineNumberReader(new InputStreamReader(is));
            
            String requestLine = reader.readLine();
            Pattern requestPattern = Pattern.compile("([^ ]+) ([^ ]+) ([^ ]+)");
            Matcher matcher = requestPattern.matcher(requestLine);
            matcher.find();
            
            if (matcher.groupCount() != 3)
                throw new HTTPException(400, "Bad Request");

            String method = matcher.group(1);
            String url = matcher.group(2);
            String version = matcher.group(3);
            
            // store request version
            request.version = version;
            
            /*
            if (!method.equals(METHOD_GET))
                throw new HTTPException(405, "Method Not Allowed");
            */
            request.URI = url;
                
            // store request method
            request.method = method;
            
            if (!url.startsWith("/"))
                throw new HTTPException(400, "Bad Request");
            
            Pattern paramPattern = Pattern.compile("([^:]+):[ ]?.+");
            String line;
            while ((line = reader.readLine()).length() > 0) {
                Matcher m = paramPattern.matcher(line);
                m.find();
                
                if (m.groupCount() == 2)
                    request.headerFields.put(m.group(1), m.group(2));
            }
            
            int queryPos = url.indexOf("?");
            if (queryPos != -1) {
                request.queryString = url.substring(queryPos + 1);
                request.pathName = url.substring(0, queryPos);
            } else {
                request.pathName = url;
            }
            
            if (request.queryString != null) {
                Pattern qsPattern = Pattern.compile("([^=]+)=([^&]+)[&]?");
                Matcher qsMatcher = qsPattern.matcher(request.queryString);
                while (qsMatcher.find()) {
                    request.parameters.put(qsMatcher.group(1), qsMatcher.group(2));
                }
            }
                        
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
        
        return request;
    }