src/main/java/com/basistech/tclre/ColorMap.java
void subrange(int from, int to, State lp, State rp) throws RegexException {
        /* Avoid one call to map.get() for each character in the range.
         * This map will usually contain one item, but in complex cases more.
         * For example, if we had [a-f][g-h] and then someone asked for [f-g], there
         * would be two. Each of these new ranges will get a new color via subcolor.
         */
        Map<Range<Integer>, Short> curColors = map.subRangeMap(Range.closed(from, to)).asMapOfRanges();
        /*
         * To avoid concurrent mod problems, we need to copy the ranges we are working from.
         */
        List<Range<Integer>> ranges = Lists.newArrayList(curColors.keySet());
        for (Range<Integer> rangeToProcess : ranges) {
            // bound management here irritating.
            int start = rangeToProcess.lowerEndpoint();
            if (rangeToProcess.lowerBoundType() == BoundType.OPEN) {
                start++;
            }
            int end = rangeToProcess.upperEndpoint();
            if (rangeToProcess.upperBoundType() == BoundType.CLOSED) {
                end++;
            }
            // allocate a new subcolor and account it owning the entire range.
            short color = subcolor(start, end - start);
            compiler.getNfa().newarc(Compiler.PLAIN, color, lp, rp);
        }
    }
void subrange(int from, int to, State lp, State rp) throws RegexException {
        /* Avoid one call to map.get() for each character in the range.
         * This map will usually contain one item, but in complex cases more.
         * For example, if we had [a-f][g-h] and then someone asked for [f-g], there
         * would be two. Each of these new ranges will get a new color via subcolor.
         */
        Map<Range<Integer>, Short> curColors = map.subRangeMap(Range.closed(from, to)).asMapOfRanges();
        /*
         * To avoid concurrent mod problems, we need to copy the ranges we are working from.
         */
        List<Range<Integer>> ranges = Lists.newArrayList(curColors.keySet());
        for (Range<Integer> rangeToProcess : ranges) {
            // bound management here irritating.
            int start = rangeToProcess.lowerEndpoint();
            if (rangeToProcess.lowerBoundType() == BoundType.OPEN) {
                start++;
            }
            int end = rangeToProcess.upperEndpoint();
            if (rangeToProcess.upperBoundType() == BoundType.CLOSED) {
                end++;
            }
            // allocate a new subcolor and account it owning the entire range.
            short color = subcolor(start, end - start);
            compiler.getNfa().newarc(Compiler.PLAIN, color, lp, rp);
        }
    }
subrange - allocate new subcolors to this range of chars, fill in arcs.
The range will overlap existing ranges; even in the simplest case,
it will overlap the initial WHITE range. For each existing range that
it overlaps, allocate a new color, mark the range as mapping to that color,
and add an arc between the states for that color.