public static List<TextRange> calculateHighlights(final long byteOffsetFromInc,
                                                      final long byteOffsetToInc) {
        validateOffsetArgs(byteOffsetFromInc, byteOffsetToInc);

        long currByteOffsetFromInc = byteOffsetFromInc;
        long currByteOffsetToInc;
        int iteration = 1;
        final List<TextRange> highlights = new ArrayList<>();
        while (true) {
            final long lineNoFrom = currByteOffsetFromInc / HexDump.MAX_BYTES_PER_LINE;
            final long lineNoTo = byteOffsetToInc / HexDump.MAX_BYTES_PER_LINE;
            final boolean isLastLineOfHighlight = lineNoFrom == lineNoTo;

            final long firstByteOnLineOffsetInc = ((currByteOffsetFromInc / HexDump.MAX_BYTES_PER_LINE)
                    * HexDump.MAX_BYTES_PER_LINE);

            if (isLastLineOfHighlight) {
                currByteOffsetToInc = byteOffsetToInc;
            } else {
                final long lastByteOnLineOffsetInc =
                        firstByteOnLineOffsetInc
                                + HexDump.MAX_BYTES_PER_LINE
                                - 1;
                currByteOffsetToInc = lastByteOnLineOffsetInc;
            }

            final TextRange highlight = new TextRange(
                    calculateLocation(currByteOffsetFromInc),
                    calculateLocation(currByteOffsetToInc, false)); // +1 to get 2nd of hex pair
            highlights.add(highlight);

            final TextRange decodeCharHighlight = new TextRange(
                    calculateDecodedCharLocation(currByteOffsetFromInc),
                    calculateDecodedCharLocation(currByteOffsetToInc));
            highlights.add(decodeCharHighlight);

            LOGGER.debug("iteration: {}, lineNoFrom: {}, lineNoTo: {}, firstByteOnLineOffsetInc: {}, " +
                            "isLastLineOfHighlight: {}, " +
                            "currByteOffsetFromInc: {}, currByteOffsetToInc: {}, highlight: {}",
                    iteration,
                    lineNoFrom,
                    lineNoTo,
                    firstByteOnLineOffsetInc,
                    isLastLineOfHighlight,
                    currByteOffsetFromInc,
                    currByteOffsetToInc,
                    highlight);

            if (isLastLineOfHighlight) {
                break;
            }
            // Start next iter at the beginning of the next line.
            currByteOffsetFromInc = firstByteOnLineOffsetInc + HexDump.MAX_BYTES_PER_LINE;
            iteration++;
        }
        return highlights;
    }
Translates a contiguous range of bytes into a set of highlight blocks defined in terms
of line/col positions in the rendered hex dump. It highlights both the middle hex pairs
block and the right hand decoded chars column. For example a range of bytes that spans
two lines of the hex dump will result in four highlight {@link TextRange}s, two for the
two hex pair lines and two for the two decoded chars lines.
stroom-util/src/main/java/stroom/util/string/HexDumpUtil.java