public static PredicateTreeAnnotations createPredicateTreeAnnotations(Predicate predicate) {
        PredicateTreeAnalyzerResult analyzerResult = PredicateTreeAnalyzer.analyzePredicateTree(predicate);
        // The tree size is used as the interval range.
        int intervalEnd = analyzerResult.treeSize;
        AnnotatorContext context = new AnnotatorContext(intervalEnd, analyzerResult.sizeMap);
        assignIntervalLabels(predicate, Interval.INTERVAL_BEGIN, intervalEnd, false, context);
        return new PredicateTreeAnnotations(
                analyzerResult.minFeature, intervalEnd, context.intervals, context.intervalsWithBounds,
                context.featureConjunctions);
    }
@Test
    void require_that_ands_below_ors_get_different_intervals() {
        Predicate p =
                or(
                        and(
                                feature("key1").inSet("value1"),
                                feature("key1").inSet("value1"),
                                feature("key1").inSet("value1")),
                        and(
                                feature("key2").inSet("value2"),
                                feature("key2").inSet("value2"),
                                feature("key2").inSet("value2")));
        PredicateTreeAnnotations r = PredicateTreeAnnotator.createPredicateTreeAnnotations(p);
        assertEquals(1, r.minFeature);
        assertEquals(6, r.intervalEnd);
        assertEquals(2, r.intervalMap.size());
        assertIntervalContains(r, "key1=value1", 0x00010001, 0x00020002, 0x00030006);
        assertIntervalContains(r, "key2=value2", 0x00010004, 0x00050005, 0x00060006);
    }