docs: static OffsetIndex buildOffsetIndex(ByteSource source) throws IOException {
      final Map<Symbol, OffsetRange<ByteOffset>> ret = Maps.newHashMap();
  
      // we could be more efficient and deal with the byte stream as it comes along,
      // but these files don't exceed 50 MB, so it's simpler just to read it all in
      final byte[] fileAsBytes = source.read();
  
      // Okay, kids, don't try this at home. In general searching byte-by-byte through UTF-8 is a
      // bad idea, because multibyte characters will trip you up.  However, in this particular case:
      //   (a) all of the characters in our search strings are single-byte, and
      //   (b) for the begin and end probes, they are long enough that the chances of them occurring
      //         accidentally starting at a non-initial character of a multibyte character
      //         is vanishingly small.  It could be a problem for docIdEnd, being only a single character,
      //         but this will only be a problem if we have non-ASCII unicode characters in the doc IDs
      //         which is not the case for Gigaword.
      int startDocInclusive;
      int nextSearchIdx = 0;
      while ((startDocInclusive = findBytes(fileAsBytes, beginProbe, nextSearchIdx)) != NOT_FOUND) {
        final int startDocIDInclusive = startDocInclusive + beginProbe.length; // double check this!
        final int endDocIDIdxExclusive = findBytes(fileAsBytes, docIdEnd, startDocIDInclusive + 1);
        if (endDocIDIdxExclusive != NOT_FOUND) {
          final String docID = bytesAsString(fileAsBytes, startDocIDInclusive, endDocIDIdxExclusive);
          final int endTagIdx = findBytes(fileAsBytes, endProbe, endDocIDIdxExclusive + 1);
          if (endTagIdx != NOT_FOUND) {
            final int endDocIdxInclusive = endTagIdx + endProbe.length - 1;
            if (ret.containsKey(Symbol.from(docID))) {
              log.warn("Document ID {} occurs more than once; using latest version", docID);
            }
            ret.put(Symbol.from(docID),
                OffsetRange.byteOffsetRange(startDocInclusive, endDocIdxInclusive));
            nextSearchIdx = endDocIdxInclusive + 1;
          } else {
            throw new IOException("Failed to find closing document tag in " + source);
          }
        } else {
          throw new IOException("Failed to find end of document ID in " + source);
        }
      }
      return OffsetIndices.forMap(ret);
    }