docs: private void detectEncoding() throws SAXException, IOException {
          byte[] signature = new byte[6];
  
          // Read the first six bytes for
          // autodetection.
          // Use 6 bytes for detection -- hsivonen 2010-10-22
          is.mark(6);
          is.read(signature);
          is.reset();
  
          //
          // FIRST: four byte encodings (who uses these?)
          //
          if (tryEncoding(signature, (byte) 0x00, (byte) 0x00, (byte) 0x00,
                  (byte) 0x3c)) {
              // UCS-4 must begin with "<?xml"
              // 0x00 0x00 0x00 0x3c: UCS-4, big-endian (1234)
              // "UTF-32BE"
              fatal("UTF-32BE is not supported. (XML processors are only required to support UTF-8 and UTF-16.)"); // 2010-10-22
              // hsivonen
          } else if (tryEncoding(signature, (byte) 0x3c, (byte) 0x00,
                  (byte) 0x00, (byte) 0x00)) {
              // 0x3c 0x00 0x00 0x00: UCS-4, little-endian (4321)
              // "UTF-32LE"
              fatal("UTF-32LE is not supported. (XML processors are only required to support UTF-8 and UTF-16.)"); // 2010-10-22
              // hsivonen
          } else if (tryEncoding(signature, (byte) 0x00, (byte) 0x00,
                  (byte) 0x3c, (byte) 0x00)) {
              // 0x00 0x00 0x3c 0x00: UCS-4, unusual (2143)
              fatal("Unsupported 32-bit encoding. (XML processors are only required to support UTF-8 and UTF-16.)"); // 2006-02-03
              // hsivonen
          } else if (tryEncoding(signature, (byte) 0x00, (byte) 0x3c,
                  (byte) 0x00, (byte) 0x00)) {
              // 0x00 0x3c 0x00 0x00: UCS-4, unusual (3421)
              fatal("Unsupported 32-bit encoding. (XML processors are only required to support UTF-8 and UTF-16.)"); // 2006-02-03
              // hsivonen
          } else if (tryEncoding(signature, (byte) 0x00, (byte) 0x00,
                  (byte) 0xfe, (byte) 0xff)) {
              // 00 00 fe ff UCS_4_1234 (with BOM)
              fatal("UTF-32 is not supported. (XML processors are only required to support UTF-8 and UTF-16.)"); // 2010-10-22
              // hsivonen
          } else if (tryEncoding(signature, (byte) 0x00, (byte) 0x3c,
                  (byte) 0x00, (byte) 0x00)) {
              // ff fe 00 00 UCS_4_4321 (with BOM)
              fatal("UTF-32 is not supported. (XML processors are only required to support UTF-8 and UTF-16.)"); // 2010-10-22
              // hsivonen
          }
          // SECOND: two byte encodings
          // note ... with 1/14/2000 errata the XML spec identifies some
          // more "broken UTF-16" autodetection cases, with no XML decl,
          // which we don't handle here (that's legal too).
          //
          else if (tryEncoding(signature, (byte) 0xfe, (byte) 0xff)) {
              // UCS-2 with a byte-order marker. (UTF-16)
              // 0xfe 0xff: UCS-2, big-endian (12)
              is.read();
              is.read();
              draconianInputStreamReader("UTF-16BE", is, false, "UTF-16");
          } else if (tryEncoding(signature, (byte) 0xff, (byte) 0xfe)) {
              // UCS-2 with a byte-order marker. (UTF-16)
              // 0xff 0xfe: UCS-2, little-endian (21)
              is.read();
              is.read();
              draconianInputStreamReader("UTF-16LE", is, false, "UTF-16");
          } else if (tryEncoding(signature, (byte) 0x00, (byte) 0x3c,
                  (byte) 0x00, (byte) 0x3f)) {
              // UTF-16BE (otherwise, malformed UTF-16)
              // 0x00 0x3c 0x00 0x3f: UCS-2, big-endian, no byte-order mark
              fatal("no byte-order mark for UTF-16 entity"); // s/UCS-2/UTF-16/
              // -- 2006-02-03
              // hsivonen
          } else if (tryEncoding(signature, (byte) 0x3c, (byte) 0x00,
                  (byte) 0x3f, (byte) 0x00)) {
              // UTF-16LE (otherwise, malformed UTF-16)
              // 0x3c 0x00 0x3f 0x00: UCS-2, little-endian, no byte-order mark
              fatal("no byte-order mark for UTF-16 entity"); // s/UCS-2/UTF-16/
              // -- 2006-02-03
              // hsivonen
          }
          //
          // THIRD: EBCDIC
          //
          else if (tryEncoding(signature, (byte) 0x4c, (byte) 0x6f, (byte) 0xa7,
                  (byte) 0x94)) {
              // 4c 6f a7 94 ... we don't understand EBCDIC flavors
              fatal("Unsupported EBCDIC encoding. (XML processors are only required to support UTF-8 and UTF-16.)");
          }
          //
          // FOURTH: ASCII-derived encodings, fixed and variable lengths
          //
          else if (signature[0] == (byte) 0x3c
                  && signature[1] == (byte) 0x3f
                  && signature[2] == (byte) 0x78
                  && signature[3] == (byte) 0x6d
                  && signature[4] == (byte) 0x6c
                  && (signature[5] == (byte) 0x20 || signature[5] == (byte) 0x0a
                          || signature[5] == (byte) 0x0d || signature[5] == (byte) 0x09)) {
              // Use 6 bytes for detection -- hsivonen 2010-10-22
              // ASCII derived
              // 0x3c 0x3f 0x78 0x6d: UTF-8 or other 8-bit markup (read ENCODING)
              characterEncoding = null;
              prefetchASCIIEncodingDecl();
          } else if ((signature[0] == (byte) 0xef) && (signature[1] == (byte) 0xbb)
                  && (signature[2] == (byte) 0xbf)) {
              // 0xef 0xbb 0xbf: UTF-8 BOM (not part of document text)
              // this un-needed notion slipped into XML 2nd ed through a
              // "non-normative" erratum; now required by MSFT and UDDI,
              // and E22 made it normative.
              is.read();
              is.read();
              is.read();
              draconianInputStreamReader("UTF-8", is, false);
          } else {
              // (default) UTF-8 without encoding/XML declaration
              draconianInputStreamReader("UTF-8", is, false);
          }
      }