//  [java]
    static Document parseInputStream(InputStream input, String charsetName, String baseUri, Parser parser) throws IOException  {
        if (input == null) 
            return new Document(baseUri);
        input = ConstrainableInputStream.wrap(input, bufferSize, 0);
        Document doc = null;
        boolean fullyRead = false;
        input.mark(bufferSize);
        ByteBuffer firstBytes = readToByteBuffer(input, firstReadBufferSize - 1); 
        fullyRead = input.read() == -1;
        input.reset();
        BomCharset bomCharset = detectCharsetFromBom(firstBytes);
        if (bomCharset != null)
            charsetName = bomCharset.charset;
        if (charsetName == null) { 
            String docData = Charset.forName(defaultCharset).decode(firstBytes).toString();
            doc = parser.parseInput(docData, baseUri);
            Elements metaElements = doc.select("meta[http-equiv=content-type], meta[charset]");
            String foundCharset = null; 
            for (Element meta : metaElements) {
                if (meta.hasAttr("http-equiv"))
                    foundCharset = getCharsetFromContentType(meta.attr("content"));
                if (foundCharset == null && meta.hasAttr("charset"))
                    foundCharset = meta.attr("charset");
                if (foundCharset != null)
                    break;
            }
            if (foundCharset == null && doc.childNodeSize() > 0) {
                Node first = doc.childNode(0);
                XmlDeclaration decl = null;
                if (first instanceof XmlDeclaration)
                    decl = (XmlDeclaration) first;
                else if (first instanceof Comment) {
                    Comment comment = (Comment) first;
                    if (comment.isXmlDeclaration())
                        decl = comment.asXmlDeclaration();
                }
                if (decl != null) {
                    if (decl.name().equalsIgnoreCase("xml"))
                        foundCharset = decl.attr("encoding");
                }
            }
            foundCharset = validateCharset(foundCharset);
            if (foundCharset != null && !foundCharset.equalsIgnoreCase(defaultCharset)) { 
                foundCharset = foundCharset.trim().replaceAll("[\"']", "");
                charsetName = foundCharset;
                doc = null;
            } else if (!fullyRead) {
                doc = null;
            }
        } else { 
            Validate.notEmpty(charsetName, "Must set charset arg to character set of file to parse. Set to null to attempt to detect from HTML");
        }
        if (doc == null) {
            if (charsetName == null)
                charsetName = defaultCharset;
            BufferedReader reader = new BufferedReader(new InputStreamReader(input, charsetName), bufferSize);
            if (bomCharset != null && bomCharset.offset) 
                reader.skip(1);
            try {
                doc = parser.parseInput(reader, baseUri);
            } catch (UncheckedIOException e) {
                throw e.ioException();
            }
            Charset charset = Charset.forName(charsetName);
            doc.outputSettings().charset(charset);
            if (!charset.canEncode()) {
                doc.charset(Charset.forName(defaultCharset));
            }
        }
        input.close();
        return doc;
    }