private Predicate<ChangeData> rewriteImpl(Predicate<ChangeData> in,ChangeIndex index,QueryOptions opts,MutableInteger leafTerms) throws QueryParseException {
  if (isIndexPredicate(in,index)) {
    if (++leafTerms.value > config.maxTerms()) {
      throw new QueryParseException("too many terms in query");
    }
    return in;
  }
 else   if (in instanceof LimitPredicate) {
    return new LimitPredicate<>(ChangeQueryBuilder.FIELD_LIMIT,opts.limit());
  }
 else   if (!isRewritePossible(in)) {
    return null;
  }
  int n=in.getChildCount();
  BitSet isIndexed=new BitSet(n);
  BitSet notIndexed=new BitSet(n);
  BitSet rewritten=new BitSet(n);
  List<Predicate<ChangeData>> newChildren=Lists.newArrayListWithCapacity(n);
  for (int i=0; i < n; i++) {
    Predicate<ChangeData> c=in.getChild(i);
    Predicate<ChangeData> nc=rewriteImpl(c,index,opts,leafTerms);
    if (nc == c) {
      isIndexed.set(i);
      newChildren.add(c);
    }
 else     if (nc == null) {
      notIndexed.set(i);
      newChildren.add(c);
    }
 else {
      rewritten.set(i);
      newChildren.add(nc);
    }
  }
  if (isIndexed.cardinality() == n) {
    return in;
  }
 else   if (notIndexed.cardinality() == n) {
    return null;
  }
 else   if (rewritten.cardinality() == n) {
    return in.copy(newChildren);
  }
  return partitionChildren(in,newChildren,isIndexed,index,opts);
}

private Predicate < ChangeData > rewriteImpl ( Predicate < ChangeData > in , ChangeIndex index , QueryOptions opts , MutableInteger leafTerms ) throws QueryParseException { if ( isIndexPredicate ( in , index ) ) { if ( ++ leafTerms . value > config . maxTerms ( ) ) { throw new QueryParseException ( "too many terms in query" ) ; } return in ; } else if ( in instanceof LimitPredicate ) { return new LimitPredicate < > ( ChangeQueryBuilder . FIELD_LIMIT , opts . limit ( ) ) ; } else if ( ! isRewritePossible ( in ) ) { return null ; } int n = in . getChildCount ( ) ; BitSet isIndexed = new BitSet ( n ) ; BitSet notIndexed = new BitSet ( n ) ; BitSet rewritten = new BitSet ( n ) ; List < Predicate < ChangeData > > newChildren = Lists . newArrayListWithCapacity ( n ) ; for ( int i = 0 ; i < n ; i ++ ) { Predicate < ChangeData > c = in . getChild ( i ) ; Predicate < ChangeData > nc = rewriteImpl ( c , index , opts , leafTerms ) ; if ( nc == c ) { isIndexed . set ( i ) ; newChildren . add ( c ) ; } else if ( nc == null ) { notIndexed . set ( i ) ; newChildren . add ( c ) ; } else { rewritten . set ( i ) ; newChildren . add ( nc ) ; } } if ( isIndexed . cardinality ( ) == n ) { return in ; } else if ( notIndexed . cardinality ( ) == n ) { return null ; } else if ( rewritten . cardinality ( ) == n ) { return in . copy ( newChildren ) ; } return partitionChildren ( in , newChildren , isIndexed , index , opts ) ; }
rewrite a single predicate subtree .
