@Override
    public Predicate visit(AndPredicate andPredicate, IndexRegistry indexes) {
        Predicate[] originalPredicates = andPredicate.predicates;
        List<Predicate> toBeAdded = null;
        boolean modified = false;
        Predicate[] target = originalPredicates;
        for (int i = 0; i < target.length; i++) {
            Predicate predicate = target[i];
            if (predicate instanceof AndPredicate andPredicateInstance) {
                Predicate[] subPredicates = andPredicateInstance.predicates;
                if (!modified) {
                    modified = true;
                    target = createCopy(target);
                }
                toBeAdded = replaceFirstAndStoreOthers(target, subPredicates, i, toBeAdded);
            }
        }
        Predicate[] newInners = createNewInners(target, toBeAdded);
        if (newInners == originalPredicates) {
            return andPredicate;
        }
        return new AndPredicate(newInners);
    }
@Test
    public void visitAndPredicate_whenHasInnerAndPredicate_thenFlattenIt() {
        // (a1 = 1 and (a2 = 2 and a3 = 3))  -->  (a1 = 1 and a2 = 2 and a3 = 3)

        Predicate a1 = equal("a1", 1);
        Predicate a2 = equal("a2", 2);
        Predicate a3 = equal("a3", 3);

        AndPredicate innerAnd = (AndPredicate) and(a2, a3);
        AndPredicate outerAnd = (AndPredicate) and(a1, innerAnd);

        AndPredicate result = (AndPredicate) visitor.visit(outerAnd, indexes);
        Predicate[] inners = result.predicates;
        assertEquals(3, inners.length);
    }