https://html.spec.whatwg.org/multipage/syntax.html#prescan-a-byte-stream-to-determine-its-encoding
482219
function prescanMetaCharset(buffer) {
  const l = Math.min(buffer.length, 1024);
  for (let i = 0; i < l; i++) {
    let c = buffer[i];
    if (c === 0x3C) {
      // "<"
      let c1 = buffer[i + 1];
      let c2 = buffer[i + 2];
      const c3 = buffer[i + 3];
      const c4 = buffer[i + 4];
      const c5 = buffer[i + 5];
      // !-- (comment start)
      if (c1 === 0x21 && c2 === 0x2D && c3 === 0x2D) {
        i += 4;
        for (; i < l; i++) {
          c = buffer[i];
          c1 = buffer[i + 1];
          c2 = buffer[i + 2];
          // --> (comment end)
          if (c === 0x2D && c1 === 0x2D && c2 === 0x3E) {
            i += 2;
            break;
          }
        }
      } else if ((c1 === 0x4D || c1 === 0x6D) &&
         (c2 === 0x45 || c2 === 0x65) &&
         (c3 === 0x54 || c3 === 0x74) &&
         (c4 === 0x41 || c4 === 0x61) &&
         (isSpaceCharacter(c5) || c5 === 0x2F)) {
        // "meta" + space or /
        i += 6;
        let gotPragma = false;
        let needPragma = null;
        let charset = null;

        let attrRes;
        do {
          attrRes = getAttribute(buffer, i, l);
          if (attrRes.attr) {
            if (attrRes.attr.name === "http-equiv") {
              gotPragma = attrRes.attr.value === "content-type";
            } else if (attrRes.attr.name === "content" && !charset) {
              charset = extractCharacterEncodingFromMeta(attrRes.attr.value);
              if (charset !== null) {
                needPragma = true;
              }
            } else if (attrRes.attr.name === "charset") {
              charset = whatwgEncoding.labelToName(attrRes.attr.value);
              needPragma = false;
            }
          }
          i = attrRes.i;
        } while (attrRes.attr);

        if (needPragma === null) {
          continue;
        }
        if (needPragma === true && gotPragma === false) {
          continue;
        }
        if (charset === null) {
          continue;
        }

        if (charset === "UTF-16LE" || charset === "UTF-16BE") {
          charset = "UTF-8";
        }
        if (charset === "x-user-defined") {
          charset = "windows-1252";
        }

        return charset;
      } else if ((c1 >= 0x41 && c1 <= 0x5A) || (c1 >= 0x61 && c1 <= 0x7A)) {
        // a-z or A-Z
        for (i += 2; i < l; i++) {
          c = buffer[i];
          // space or >
          if (isSpaceCharacter(c) || c === 0x3E) {
            break;
          }
        }
        let attrRes;
        do {
          attrRes = getAttribute(buffer, i, l);
          i = attrRes.i;
        } while (attrRes.attr);
      } else if (c1 === 0x21 || c1 === 0x2F || c1 === 0x3F) {
        // ! or / or ?
        for (i += 2; i < l; i++) {
          c = buffer[i];
          // >
          if (c === 0x3E) {
            break;
          }
        }
      }
    }
  }
  return null;
}
530467
function(file) {
    var result = getRawData(file),
        type = utils.getTypeOf(result);
    if (type === "string") {
        if (!file.options.binary) {
            // unicode text !
            // unicode string => binary string is a painful process, check if we can avoid it.
            if (textEncoder) {
                return textEncoder.encode(result);
            }
            if (support.nodebuffer) {
                return nodeBuffer(result, "utf-8");
            }
        }
        return file.asBinary();
    }
    return result;
}
1279439
private boolean parseLine(ByteBuffer buffer) {
        boolean handle = false;

        // Process headers
        while (_state.ordinal() < State.HEADER.ordinal() && buffer.hasRemaining() && !handle) {
            // process each character
            HttpTokens.Token t = next(buffer);
            if (t == null)
                break;

            if (_maxHeaderBytes > 0 && ++_headerBytes > _maxHeaderBytes) {
                if (_state == State.URI) {
                    LOG.warn("URI is too large >" + _maxHeaderBytes);
                    throw new BadMessageException(HttpStatus.URI_TOO_LONG_414);
                } else {
                    if (_requestHandler != null)
                        LOG.warn("request is too large >" + _maxHeaderBytes);
                    else
                        LOG.warn("response is too large >" + _maxHeaderBytes);
                    throw new BadMessageException(HttpStatus.REQUEST_HEADER_FIELDS_TOO_LARGE_431);
                }
            }

            switch (_state) {
                case METHOD:
                    switch (t.getType()) {
                        case SPACE:
                            _length = _string.length();
                            _methodString = takeString();

                            if (_compliances.contains(HttpComplianceSection.METHOD_CASE_SENSITIVE)) {
                                HttpMethod method = HttpMethod.CACHE.get(_methodString);
                                if (method != null)
                                    _methodString = method.asString();
                            } else {
                                HttpMethod method = HttpMethod.INSENSITIVE_CACHE.get(_methodString);

                                if (method != null) {
                                    if (!method.asString().equals(_methodString))
                                        handleViolation(HttpComplianceSection.METHOD_CASE_SENSITIVE, _methodString);
                                    _methodString = method.asString();
                                }
                            }

                            setState(State.SPACE1);
                            break;

                        case LF:
                            throw new BadMessageException("No URI");

                        case ALPHA:
                        case DIGIT:
                        case TCHAR:
                            _string.append(t.getChar());
                            break;

                        default:
                            throw new IllegalCharacterException(_state, t, buffer);
                    }
                    break;

                case RESPONSE_VERSION:
                    switch (t.getType()) {
                        case SPACE:
                            _length = _string.length();
                            String version = takeString();
                            _version = HttpVersion.CACHE.get(version);
                            checkVersion();
                            setState(State.SPACE1);
                            break;

                        case ALPHA:
                        case DIGIT:
                        case TCHAR:
                        case VCHAR:
                        case COLON:
                            _string.append(t.getChar());
                            break;
                        default:
                            throw new IllegalCharacterException(_state, t, buffer);
                    }
                    break;

                case SPACE1:
                    switch (t.getType()) {
                        case SPACE:
                            break;

                        case ALPHA:
                        case DIGIT:
                        case TCHAR:
                        case VCHAR:
                        case COLON:
                            if (_responseHandler != null) {
                                if (t.getType() != HttpTokens.Type.DIGIT)
                                    throw new IllegalCharacterException(_state, t, buffer);
                                setState(State.STATUS);
                                setResponseStatus(t.getByte() - '0');
                            } else {
                                _uri.reset();
                                setState(State.URI);
                                // quick scan for space or EoBuffer
                                if (buffer.hasArray()) {
                                    byte[] array = buffer.array();
                                    int p = buffer.arrayOffset() + buffer.position();
                                    int l = buffer.arrayOffset() + buffer.limit();
                                    int i = p;
                                    while (i < l && array[i] > HttpTokens.SPACE)
                                        i++;

                                    int len = i - p;
                                    _headerBytes += len;

                                    if (_maxHeaderBytes > 0 && ++_headerBytes > _maxHeaderBytes) {
                                        LOG.warn("URI is too large >" + _maxHeaderBytes);
                                        throw new BadMessageException(HttpStatus.URI_TOO_LONG_414);
                                    }
                                    _uri.append(array, p - 1, len + 1);
                                    buffer.position(i - buffer.arrayOffset());
                                } else
                                    _uri.append(t.getByte());
                            }
                            break;

                        default:
                            throw new BadMessageException(HttpStatus.BAD_REQUEST_400, _requestHandler != null ? "No URI" : "No Status");
                    }
                    break;

                case STATUS:
                    switch (t.getType()) {
                        case SPACE:
                            setState(State.SPACE2);
                            break;

                        case DIGIT:
                            _responseStatus = _responseStatus * 10 + (t.getByte() - '0');
                            if (_responseStatus >= 1000)
                                throw new BadMessageException("Bad status");
                            break;

                        case LF:
                            setState(State.HEADER);
                            handle = _responseHandler.startResponse(_version, _responseStatus, null) || handle;
                            break;

                        default:
                            throw new IllegalCharacterException(_state, t, buffer);
                    }
                    break;

                case URI:
                    switch (t.getType()) {
                        case SPACE:
                            setState(State.SPACE2);
                            break;

                        case LF:
                            // HTTP/0.9
                            if (complianceViolation(HttpComplianceSection.NO_HTTP_0_9, "No request version"))
                                throw new BadMessageException("HTTP/0.9 not supported");
                            handle = _requestHandler.startRequest(_methodString, _uri.toString(), HttpVersion.HTTP_0_9);
                            setState(State.END);
                            BufferUtils.clear(buffer);
                            handle = handleHeaderContentMessage() || handle;
                            break;

                        case ALPHA:
                        case DIGIT:
                        case TCHAR:
                        case VCHAR:
                        case COLON:
                        case OTEXT:
                            _uri.append(t.getByte());
                            break;

                        default:
                            throw new IllegalCharacterException(_state, t, buffer);
                    }
                    break;

                case SPACE2:
                    switch (t.getType()) {
                        case SPACE:
                            break;

                        case ALPHA:
                        case DIGIT:
                        case TCHAR:
                        case VCHAR:
                        case COLON:
                            _string.setLength(0);
                            _string.append(t.getChar());
                            if (_responseHandler != null) {
                                _length = 1;
                                setState(State.REASON);
                            } else {
                                setState(State.REQUEST_VERSION);

                                // try quick look ahead for HTTP Version
                                HttpVersion version;
                                if (buffer.position() > 0 && buffer.hasArray())
                                    version = HttpVersion.lookAheadGet(buffer.array(), buffer.arrayOffset() + buffer.position() - 1, buffer.arrayOffset() + buffer.limit());
                                else
                                    version = HttpVersion.CACHE.getBest(buffer, 0, buffer.remaining());

                                if (version != null) {
                                    int pos = buffer.position() + version.asString().length() - 1;
                                    if (pos < buffer.limit()) {
                                        byte n = buffer.get(pos);
                                        if (n == HttpTokens.CARRIAGE_RETURN) {
                                            _cr = true;
                                            _version = version;
                                            checkVersion();
                                            _string.setLength(0);
                                            buffer.position(pos + 1);
                                        } else if (n == HttpTokens.LINE_FEED) {
                                            _version = version;
                                            checkVersion();
                                            _string.setLength(0);
                                            buffer.position(pos);
                                        }
                                    }
                                }
                            }
                            break;

                        case LF:
                            if (_responseHandler != null) {
                                setState(State.HEADER);
                                handle = _responseHandler.startResponse(_version, _responseStatus, null) || handle;
                            } else {
                                // HTTP/0.9
                                if (complianceViolation(HttpComplianceSection.NO_HTTP_0_9, "No request version"))
                                    throw new BadMessageException("HTTP/0.9 not supported");

                                handle = _requestHandler.startRequest(_methodString, _uri.toString(), HttpVersion.HTTP_0_9);
                                setState(State.END);
                                BufferUtils.clear(buffer);
                                handle = handleHeaderContentMessage() || handle;
                            }
                            break;

                        default:
                            throw new IllegalCharacterException(_state, t, buffer);
                    }
                    break;

                case REQUEST_VERSION:
                    switch (t.getType()) {
                        case LF:
                            if (_version == null) {
                                _length = _string.length();
                                _version = HttpVersion.CACHE.get(takeString());
                            }
                            checkVersion();

                            // Should we try to cache header fields?
                            if (_fieldCache == null && _version.getVersion() >= HttpVersion.HTTP_1_1.getVersion() && _handler.getHeaderCacheSize() > 0) {
                                int header_cache = _handler.getHeaderCacheSize();
                                _fieldCache = new ArrayTernaryTrie<>(header_cache);
                            }

                            setState(State.HEADER);

                            handle = _requestHandler.startRequest(_methodString, _uri.toString(), _version) || handle;
                            continue;

                        case ALPHA:
                        case DIGIT:
                        case TCHAR:
                        case VCHAR:
                        case COLON:
                            _string.append(t.getChar());
                            break;

                        default:
                            throw new IllegalCharacterException(_state, t, buffer);
                    }
                    break;

                case REASON:
                    switch (t.getType()) {
                        case LF:
                            String reason = takeString();
                            setState(State.HEADER);
                            handle = _responseHandler.startResponse(_version, _responseStatus, reason) || handle;
                            continue;

                        case ALPHA:
                        case DIGIT:
                        case TCHAR:
                        case VCHAR:
                        case COLON:
                        case OTEXT: // TODO should this be UTF8
                            _string.append(t.getChar());
                            _length = _string.length();
                            break;

                        case SPACE:
                        case HTAB:
                            _string.append(t.getChar());
                            break;

                        default:
                            throw new IllegalCharacterException(_state, t, buffer);
                    }
                    break;

                default:
                    throw new IllegalStateException(_state.toString());
            }
        }

        return handle;
    }
1221473
def detect_pattern_format(pattern_filename, encoding, on_word_boundaries):
    '''
    
    '''
    tsv = True
    boundaries = on_word_boundaries
    with open_file(pattern_filename) as input_file:
        for line in input_file:
            line = line.decode(encoding)
            if line.count('\t') != 1:
                tsv = False
            if '\\b' in line:
                boundaries = True
            if boundaries and not tsv:
                break
    return tsv, boundaries
378033
boolean scanMultiLineComment() {
		while (true) {
			switch (state) {
			case 200:
				if (peek() == '#' && next() == '-' && next() == '-') {
					state = 201;
					continue ;
				}
				return fail();
			case 201:
				for (char c=next(); true; c=next()) {
					if (c == '-' && buf[forward + 1] == '-' && buf[forward + 2] == '#') {
						forward = forward + 3;
						if (lookForwardLineFeedAndEof() && deletePreviousTextTokenBlankTails()) {
							return prepareNextScan(peek() != EOF ? 1 : 0);
						} else {
							return prepareNextScan(0);
						}
					}
					if (c == EOF) {
						throw new ParseException("The multiline comment start block \"#--\" can not match the end block: \"--#\"", new Location(fileName, beginRow));
					}
				}
			default :
				return fail();
			}
		}
	}
214954
private static int scanUriEscape(ByteToChar converter,
                                   byte []rawUri, int i, int len)
    throws IOException
  {
    int ch1 = i < len ? (rawUri[i++] & 0xff) : -1;

    if (ch1 == 'u') {
      ch1 = i < len ? (rawUri[i++] & 0xff) : -1;
      int ch2 = i < len ? (rawUri[i++] & 0xff) : -1;
      int ch3 = i < len ? (rawUri[i++] & 0xff) : -1;
      int ch4 = i < len ? (rawUri[i++] & 0xff) : -1;

      converter.addChar((char) ((toHex(ch1) << 12) +
                                (toHex(ch2) << 8) + 
                                (toHex(ch3) << 4) + 
                                (toHex(ch4))));
    }
    else {
      int ch2 = i < len ? (rawUri[i++] & 0xff) : -1;

      int b = (toHex(ch1) << 4) + toHex(ch2);;

      converter.addByte(b);
    }

    return i;
  }
751066
public static byte[] process(CharSequence html) {
		ByteArrayOutputStream baos = null;
		try {
			baos = new ByteArrayOutputStream();
			process(html, baos);
			return baos.toByteArray();
		}
		finally {
			if (baos != null) {
				try {
					baos.close();
				}
				catch (IOException e) {
					log.warn("Close Byte Array Inpout Stream Error Caused.", e);
				}
			}
		}
	}
704954
def decode_html(html):
    
    if isinstance(html, unicode):
        return html

    match = CHARSET_META_TAG_PATTERN.search(html)
    if match:
        declared_encoding = match.group(1).decode("ASCII")
        # proceed unknown encoding as if it wasn't found at all
        with ignored(LookupError):
            return html.decode(declared_encoding, "ignore")

    # try to enforce UTF-8 firstly
    with ignored(UnicodeDecodeError):
        return html.decode("utf8")

    text = TAG_MARK_PATTERN.sub(to_bytes(" "), html)
    diff = text.decode("utf8", "ignore").encode("utf8")
    sizes = len(diff), len(text)

    # 99% of text is UTF-8
    if abs(len(text) - len(diff)) < max(sizes) * 0.01:
        return html.decode("utf8", "ignore")

    # try detect encoding
    encoding = "utf8"
    encoding_detector = chardet.detect(text)
    if encoding_detector["encoding"]:
        encoding = encoding_detector["encoding"]

    return html.decode(encoding, "ignore")
749147
function __decode_utf8(buffer) {

        var text = "";

        var bytes = new Uint8Array(buffer);
        for (var i=0; i<bytes.length; i++) {

            // Get current byte
            var value = bytes[i];

            // Start new codepoint if nothing yet read
            if (bytes_remaining === 0) {

                // 1 byte (0xxxxxxx)
                if ((value | 0x7F) === 0x7F)
                    text += String.fromCharCode(value);

                // 2 byte (110xxxxx)
                else if ((value | 0x1F) === 0xDF) {
                    codepoint = value & 0x1F;
                    bytes_remaining = 1;
                }

                // 3 byte (1110xxxx)
                else if ((value | 0x0F )=== 0xEF) {
                    codepoint = value & 0x0F;
                    bytes_remaining = 2;
                }

                // 4 byte (11110xxx)
                else if ((value | 0x07) === 0xF7) {
                    codepoint = value & 0x07;
                    bytes_remaining = 3;
                }

                // Invalid byte
                else
                    text += "\uFFFD";

            }

            // Continue existing codepoint (10xxxxxx)
            else if ((value | 0x3F) === 0xBF) {

                codepoint = (codepoint << 6) | (value & 0x3F);
                bytes_remaining--;

                // Write codepoint if finished
                if (bytes_remaining === 0)
                    text += String.fromCharCode(codepoint);

            }

            // Invalid byte
            else {
                bytes_remaining = 0;
                text += "\uFFFD";
            }

        }

        return text;

    }
963356
function isPctEncoded (chr) {
        if (!isPercentDigitDigit(chr, 0)) {
            return false;
        }
        var firstCharCode = parseHex2(chr, 1);
        var numBytes = utf8.numBytes(firstCharCode);
        if (numBytes === 0) {
            return false;
        }
        for (var byteNumber = 1; byteNumber < numBytes; byteNumber += 1) {
            if (!isPercentDigitDigit(chr, 3*byteNumber) || !utf8.isValidFollowingCharCode(parseHex2(chr, 3*byteNumber + 1))) {
                return false;
            }
        }
        return true;
    }
379488
private static String getBOMEncoding(final BufferedInputStream is) throws IOException {
        String encoding = null;
        final int[] bytes = new int[3];
        is.mark(3);
        bytes[0] = is.read();
        bytes[1] = is.read();
        bytes[2] = is.read();

        if (bytes[0] == 0xFE && bytes[1] == 0xFF) {
            encoding = UTF_16BE;
            is.reset();
            is.read();
            is.read();
        } else if (bytes[0] == 0xFF && bytes[1] == 0xFE) {
            encoding = UTF_16LE;
            is.reset();
            is.read();
            is.read();
        } else if (bytes[0] == 0xEF && bytes[1] == 0xBB && bytes[2] == 0xBF) {
            encoding = UTF_8;
        } else {
            is.reset();
        }
        return encoding;
    }
3530
function() {

    var _buffer = 0;
    var _buflen = 0;
    var _length = 0;
    var _base64 = '';

    var _this = {};

    var writeEncoded = function(b) {
      _base64 += String.fromCharCode(encode(b & 0x3f) );
    };

    var encode = function(n) {
      if (n < 0) {
        // error.
      } else if (n < 26) {
        return 0x41 + n;
      } else if (n < 52) {
        return 0x61 + (n - 26);
      } else if (n < 62) {
        return 0x30 + (n - 52);
      } else if (n == 62) {
        return 0x2b;
      } else if (n == 63) {
        return 0x2f;
      }
      throw 'n:' + n;
    };

    _this.writeByte = function(n) {

      _buffer = (_buffer << 8) | (n & 0xff);
      _buflen += 8;
      _length += 1;

      while (_buflen >= 6) {
        writeEncoded(_buffer >>> (_buflen - 6) );
        _buflen -= 6;
      }
    };

    _this.flush = function() {

      if (_buflen > 0) {
        writeEncoded(_buffer << (6 - _buflen) );
        _buffer = 0;
        _buflen = 0;
      }

      if (_length % 3 != 0) {
        // padding
        var padlen = 3 - _length % 3;
        for (var i = 0; i < padlen; i += 1) {
          _base64 += '=';
        }
      }
    };

    _this.toString = function() {
      return _base64;
    };

    return _this;
  }
856221
private void convertHTMLCode(ArrayList<ArrayList<TextPiece>> wordsByPage) {
	DocInfo docInfo = new DocInfo();
	String[] html2Char = docInfo.getHtml2CharMapping(); // Only define this
							    // mapping string
							    // when we detect
							    // the files in HTML
							    // codes
	int pageNum = 0;

	for (ArrayList<TextPiece> wordsOfAPage : wordsByPage) {
	    pageNum++;
	    for (int i = 0; i < wordsOfAPage.size(); i++) {
		TextPiece currentWord = wordsOfAPage.get(i);
		String realText = "";
		String textinHTMLCode = currentWord.getText();

	    }
	}
    }
140984
public static String HTMLEntityEncode(String input) {
        String next = scriptPattern.matcher(input).replaceAll("&#x73;cript");

        StringBuffer sb = new StringBuffer();
        for (int i = 0; i < next.length(); ++i) {
            char ch = next.charAt(i);

            if (ch == '<') {
                sb.append("&lt;");
            } else if (ch == '>') {
                sb.append("&gt;");
            } else {
                sb.append(ch);
            }
        }

        return sb.toString();
    }
862159
@NonNull
    private String determineEncoding(HttpRequest request) {
        MediaType mimeType = request.getContentType();
        if (mimeType == null) return Charsets.UTF_8.name();
        Charset charset = mimeType.getCharset();
        return charset == null ? Charsets.UTF_8.name() : charset.name();
    }
519161
function scanUnicodeRange(scanner) {
    var hexStart = scanner.tokenStart + 1; // skip +
    var hexLength = 0;

    scan: {
        if (scanner.tokenType === NUMBER) {
            if (scanner.source.charCodeAt(scanner.tokenStart) !== FULLSTOP && scanUnicodeNumber(scanner)) {
                scanner.next();
            } else if (scanner.source.charCodeAt(scanner.tokenStart) !== HYPHENMINUS) {
                break scan;
            }
        } else {
            scanner.next(); // PLUSSIGN
        }

        if (scanner.tokenType === HYPHENMINUS) {
            scanner.next();
        }

        if (scanner.tokenType === NUMBER) {
            scanner.next();
        }

        if (scanner.tokenType === IDENTIFIER) {
            scanner.next();
        }

        if (scanner.tokenStart === hexStart) {
            scanner.error('Unexpected input', hexStart);
        }
    }

    // validate for U+x{1,6} or U+x{1,6}-x{1,6}
    // where x is [0-9a-fA-F]
    for (var i = hexStart, wasHyphenMinus = false; i < scanner.tokenStart; i++) {
        var code = scanner.source.charCodeAt(i);

        if (isHex(code) === false && (code !== HYPHENMINUS || wasHyphenMinus)) {
            scanner.error('Unexpected input', i);
        }

        if (code === HYPHENMINUS) {
            // hex sequence shouldn't be an empty
            if (hexLength === 0) {
                scanner.error('Unexpected input', i);
            }

            wasHyphenMinus = true;
            hexLength = 0;
        } else {
            hexLength++;

            // too long hex sequence
            if (hexLength > 6) {
                scanner.error('Too long hex sequence', i);
            }
        }

    }

    // check we have a non-zero sequence
    if (hexLength === 0) {
        scanner.error('Unexpected input', i - 1);
    }

    // U+abc???
    if (!wasHyphenMinus) {
        // consume as many U+003F QUESTION MARK (?) code points as possible
        for (; hexLength < 6 && !scanner.eof; scanner.next()) {
            if (scanner.tokenType !== QUESTIONMARK) {
                break;
            }

            hexLength++;
        }
    }
}
1364518
@Nullable
  public static Charset determineXMLCharset (@Nonnull final byte [] aBytes)
  {
    ValueEnforcer.notNull (aBytes, "Bytes");

    Charset aParseCharset = null;
    int nSearchOfs = 0;

    if (aBytes.length > 0)
    {
      // Check if a BOM is present
      // Read at maximum 4 bytes (max BOM bytes)
      try (
          NonBlockingByteArrayInputStream aIS = new NonBlockingByteArrayInputStream (aBytes,
                                                                                     0,
                                                                                     Math.min (EUnicodeBOM.getMaximumByteCount (),
                                                                                               aBytes.length)))
      {
        // Check for BOM first
        final InputStreamAndCharset aISC = CharsetHelper.getInputStreamAndCharsetFromBOM (aIS);
        if (aISC.hasBOM ())
        {
          // A BOM was found, but not necessarily a charset could uniquely be
          // identified - skip the
          // BOM bytes and continue determination from there
          nSearchOfs = aISC.getBOM ().getByteCount ();
        }

        if (aISC.hasCharset ())
        {
          // A BOM was found, and that BOM also has a unique charset assigned
          aParseCharset = aISC.getCharset ();
        }
      }
    }

    // No charset found and enough bytes left?
    if (aParseCharset == null && aBytes.length - nSearchOfs >= 4)
      if (_match (aBytes, nSearchOfs, CS_UTF32_BE))
        aParseCharset = CHARSET_UTF_32BE;
      else
        if (_match (aBytes, nSearchOfs, CS_UTF32_LE))
          aParseCharset = CHARSET_UTF_32LE;
        else
          if (_match (aBytes, nSearchOfs, CS_UTF16_BE))
            aParseCharset = StandardCharsets.UTF_16BE;
          else
            if (_match (aBytes, nSearchOfs, CS_UTF16_LE))
              aParseCharset = StandardCharsets.UTF_16LE;
            else
              if (_match (aBytes, nSearchOfs, CS_UTF8))
                aParseCharset = StandardCharsets.UTF_8;
              else
                if (_match (aBytes, nSearchOfs, CS_EBCDIC))
                  aParseCharset = CHARSET_EBCDIC;
                else
                  if (_match (aBytes, nSearchOfs, CS_IBM290))
                    aParseCharset = CHARSET_IBM290;

    if (aParseCharset == null)
    {
      // Fallback charset is always UTF-8
      aParseCharset = FALLBACK_CHARSET;
    }

    // Now read with a reader
    return _parseXMLEncoding (aBytes, nSearchOfs, aParseCharset);
  }