Kill @Rewrite support in queries

These had been significantly pared down since almost all queries of
consequence are sent as-is to the secondary index subsystem. The
remaining queries just existed to simplify some arbitrary subtrees
into slightly less complicated subtrees. This required almost a
thousand lines of magical supporting code for something with no
remaining performance benefit. Let it die a graceful death.

Change-Id: I99ee92549b6619e7aa7529875149073f55c85c69
diff --git a/gerrit-antlr/src/main/antlr3/com/google/gerrit/server/query/Query.g b/gerrit-antlr/src/main/antlr3/com/google/gerrit/server/query/Query.g
index 98f1af9..d0b5875 100644
--- a/gerrit-antlr/src/main/antlr3/com/google/gerrit/server/query/Query.g
+++ b/gerrit-antlr/src/main/antlr3/com/google/gerrit/server/query/Query.g
@@ -116,7 +116,6 @@
 conditionNot
   : '-' conditionBase -> ^(NOT conditionBase)
   | NOT^ conditionBase
-  | VARIABLE_ASSIGN^ conditionOr ')'!
   | conditionBase
   ;
 conditionBase
@@ -143,13 +142,6 @@
   : ('a'..'z' | '_')+
   ;
 
-VARIABLE_ASSIGN
-  : ('A'..'Z') ('A'..'Z' | 'a'..'Z')* '=' '(' {
-      String s = $text;
-      setText(s.substring(0, s.length() - 2));
-    }
-  ;
-
 EXACT_PHRASE
   : '"' ( ~('"') )* '"' {
       String s = $text;
diff --git a/gerrit-server/src/main/java/com/google/gerrit/server/index/IndexModule.java b/gerrit-server/src/main/java/com/google/gerrit/server/index/IndexModule.java
index 0cfc659..28f7f7e 100644
--- a/gerrit-server/src/main/java/com/google/gerrit/server/index/IndexModule.java
+++ b/gerrit-server/src/main/java/com/google/gerrit/server/index/IndexModule.java
@@ -22,7 +22,6 @@
 import com.google.gerrit.lifecycle.LifecycleModule;
 import com.google.gerrit.server.config.GerritServerConfig;
 import com.google.gerrit.server.git.WorkQueue;
-import com.google.gerrit.server.query.change.BasicChangeRewrites;
 import com.google.gerrit.server.query.change.ChangeQueryRewriter;
 import com.google.inject.Injector;
 import com.google.inject.Key;
@@ -69,7 +68,6 @@
   @Override
   protected void configure() {
     bind(ChangeQueryRewriter.class).to(IndexRewriteImpl.class);
-    bind(BasicChangeRewrites.class);
     bind(IndexCollection.class);
     listener().to(IndexCollection.class);
     factory(ChangeIndexer.Factory.class);
diff --git a/gerrit-server/src/main/java/com/google/gerrit/server/index/IndexRewriteImpl.java b/gerrit-server/src/main/java/com/google/gerrit/server/index/IndexRewriteImpl.java
index 7fbddfb..f551a7e 100644
--- a/gerrit-server/src/main/java/com/google/gerrit/server/index/IndexRewriteImpl.java
+++ b/gerrit-server/src/main/java/com/google/gerrit/server/index/IndexRewriteImpl.java
@@ -26,7 +26,6 @@
 import com.google.gerrit.server.query.Predicate;
 import com.google.gerrit.server.query.QueryParseException;
 import com.google.gerrit.server.query.change.AndSource;
-import com.google.gerrit.server.query.change.BasicChangeRewrites;
 import com.google.gerrit.server.query.change.ChangeData;
 import com.google.gerrit.server.query.change.ChangeQueryRewriter;
 import com.google.gerrit.server.query.change.ChangeStatusPredicate;
@@ -118,13 +117,10 @@
   }
 
   private final IndexCollection indexes;
-  private final BasicChangeRewrites basicRewrites;
 
   @Inject
-  IndexRewriteImpl(IndexCollection indexes,
-      BasicChangeRewrites basicRewrites) {
+  IndexRewriteImpl(IndexCollection indexes) {
     this.indexes = indexes;
-    this.basicRewrites = basicRewrites;
   }
 
   @Override
@@ -132,7 +128,6 @@
       int limit) throws QueryParseException {
     checkArgument(limit > 0, "limit must be positive: %s", limit);
     ChangeIndex index = indexes.getSearchIndex();
-    in = basicRewrites.rewrite(in);
     // Increase the limit rather than skipping, since we don't know how many
     // skipped results would have been filtered out by the enclosing AndSource.
     limit += start;
diff --git a/gerrit-server/src/main/java/com/google/gerrit/server/query/QueryBuilder.java b/gerrit-server/src/main/java/com/google/gerrit/server/query/QueryBuilder.java
index b3c6aeb..2a53e6d 100644
--- a/gerrit-server/src/main/java/com/google/gerrit/server/query/QueryBuilder.java
+++ b/gerrit-server/src/main/java/com/google/gerrit/server/query/QueryBuilder.java
@@ -24,7 +24,6 @@
 import static com.google.gerrit.server.query.QueryParser.NOT;
 import static com.google.gerrit.server.query.QueryParser.OR;
 import static com.google.gerrit.server.query.QueryParser.SINGLE_WORD;
-import static com.google.gerrit.server.query.QueryParser.VARIABLE_ASSIGN;
 
 import org.antlr.runtime.tree.Tree;
 
@@ -222,20 +221,6 @@
       case FIELD_NAME:
         return operator(r.getText(), onlyChildOf(r));
 
-      case VARIABLE_ASSIGN: {
-        final String var = r.getText();
-        final Tree opTree = onlyChildOf(r);
-        if (opTree.getType() == FIELD_NAME) {
-          final Tree val = onlyChildOf(opTree);
-          if (val.getType() == SINGLE_WORD && "*".equals(val.getText())) {
-            final String op = opTree.getText();
-            final WildPatternPredicate<T> pat = new WildPatternPredicate<>(op);
-            return new VariablePredicate<>(var, pat);
-          }
-        }
-        return new VariablePredicate<>(var, toPredicate(opTree));
-      }
-
       default:
         throw error("Unsupported operator: " + r);
     }
diff --git a/gerrit-server/src/main/java/com/google/gerrit/server/query/QueryRewriter.java b/gerrit-server/src/main/java/com/google/gerrit/server/query/QueryRewriter.java
deleted file mode 100644
index 6173fb6..0000000
--- a/gerrit-server/src/main/java/com/google/gerrit/server/query/QueryRewriter.java
+++ /dev/null
@@ -1,505 +0,0 @@
-// Copyright (C) 2009 The Android Open Source Project
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-package com.google.gerrit.server.query;
-
-import com.google.common.collect.Lists;
-import com.google.inject.name.Named;
-
-import java.lang.annotation.Annotation;
-import java.lang.annotation.ElementType;
-import java.lang.annotation.Retention;
-import java.lang.annotation.RetentionPolicy;
-import java.lang.annotation.Target;
-import java.lang.reflect.InvocationTargetException;
-import java.lang.reflect.Method;
-import java.lang.reflect.Modifier;
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.Collection;
-import java.util.Collections;
-import java.util.HashMap;
-import java.util.Iterator;
-import java.util.LinkedList;
-import java.util.List;
-import java.util.Map;
-
-/**
- * Rewrites a Predicate tree by applying rewrite rules.
- * <p>
- * Subclasses may document their rewrite rules by declaring public methods with
- * {@link Rewrite} annotations, such as:
- *
- * <pre>
- * &#064;Rewrite(&quot;A=(owner:*) B=(status:*)&quot;)
- * public Predicate r1_ownerStatus(@Named(&quot;A&quot;) OperatorPredicate owner,
- *     &#064;Named(&quot;B&quot;) OperatorPredicate status) {
- * }
- * </pre>
- * <p>
- * Rewrite methods are applied in order by declared name, so naming methods with
- * a numeric prefix to ensure a specific ordering (if required) is suggested.
- *
- * @param <T> type of object the predicate can evaluate in memory.
- */
-public abstract class QueryRewriter<T> {
-  /**
-   * Defines the rewrite rules known by a QueryRewriter.
-   *
-   * This class is thread-safe and may be reused or cached.
-   *
-   * @param <T> type of object the predicates can evaluate in memory.
-   * @param <R> type of the rewriter subclass.
-   */
-  public static class Definition<T, R extends QueryRewriter<T>> {
-    private final List<RewriteRule<T>> rewriteRules;
-
-    public Definition(Class<R> clazz, QueryBuilder<T> qb) {
-      rewriteRules = Lists.newArrayList();
-
-      Class<?> c = clazz;
-      while (c != QueryRewriter.class) {
-        Method[] declared = c.getDeclaredMethods();
-        for (Method m : declared) {
-          Rewrite rp = m.getAnnotation(Rewrite.class);
-          if ((m.getModifiers() & Modifier.ABSTRACT) != Modifier.ABSTRACT
-              && (m.getModifiers() & Modifier.PUBLIC) == Modifier.PUBLIC
-              && rp != null) {
-            rewriteRules.add(new MethodRewrite<>(qb, rp.value(), m));
-          }
-        }
-        c = c.getSuperclass();
-      }
-      Collections.sort(rewriteRules);
-    }
-  }
-
-  private final List<RewriteRule<T>> rewriteRules;
-
-  protected QueryRewriter(final Definition<T, ? extends QueryRewriter<T>> def) {
-    this.rewriteRules = def.rewriteRules;
-  }
-
-  /** Combine the passed predicates into a single AND node. */
-  public Predicate<T> and(Collection<? extends Predicate<T>> that) {
-    return Predicate.and(that);
-  }
-
-  /** Combine the passed predicates into a single AND node. */
-  public Predicate<T> and(@SuppressWarnings("unchecked") Predicate<T>... that) {
-    return and(Arrays.asList(that));
-  }
-
-  /** Combine the passed predicates into a single OR node. */
-  public Predicate<T> or(Collection<? extends Predicate<T>> that) {
-    return Predicate.or(that);
-  }
-
-  /** Combine the passed predicates into a single OR node. */
-  public Predicate<T> or(@SuppressWarnings("unchecked") Predicate<T>... that) {
-    return or(Arrays.asList(that));
-  }
-
-  /** Invert the passed node. */
-  public Predicate<T> not(Predicate<T> that) {
-    return Predicate.not(that);
-  }
-
-  protected Predicate<T> preRewrite(Predicate<T> in) {
-    return in;
-  }
-
-  /**
-   * Apply rewrites to a graph until it stops changing.
-   *
-   * @param in the graph to rewrite.
-   * @return the rewritten graph.
-   */
-  public final Predicate<T> rewrite(Predicate<T> in) {
-    in = preRewrite(in);
-    return rewriteImpl(in);
-  }
-
-  private Predicate<T> rewriteImpl(Predicate<T> in) {
-    Predicate<T> old;
-    do {
-      old = in;
-      in = rewriteOne(in);
-
-      if (old.equals(in) && in.getChildCount() > 0) {
-        List<Predicate<T>> n = new ArrayList<>(in.getChildCount());
-        for (Predicate<T> p : in.getChildren()) {
-          n.add(rewriteImpl(p));
-        }
-        n = removeDuplicates(n);
-        if (n.size() == 1 && (isAND(in) || isOR(in))) {
-          in = n.get(0);
-        } else {
-          in = in.copy(n);
-        }
-      }
-
-    } while (!old.equals(in));
-    return replaceGenericNodes(in);
-  }
-
-  protected Predicate<T> replaceGenericNodes(final Predicate<T> in) {
-    if (in instanceof NotPredicate) {
-      return not(replaceGenericNodes(in.getChild(0)));
-
-    } else if (in instanceof AndPredicate) {
-      List<Predicate<T>> n = new ArrayList<>(in.getChildCount());
-      for (Predicate<T> c : in.getChildren()) {
-        n.add(replaceGenericNodes(c));
-      }
-      return and(n);
-
-    } else if (in instanceof OrPredicate) {
-      List<Predicate<T>> n = new ArrayList<>(in.getChildCount());
-      for (Predicate<T> c : in.getChildren()) {
-        n.add(replaceGenericNodes(c));
-      }
-      return or(n);
-
-    } else {
-      return in;
-    }
-  }
-
-  private Predicate<T> rewriteOne(Predicate<T> input) {
-    Predicate<T> best = null;
-    for (RewriteRule<T> r : rewriteRules) {
-      Predicate<T> n = r.rewrite(this, input);
-      if (n == null) {
-        continue;
-      }
-
-      if (!r.useBestCost()) {
-        return n;
-      }
-
-      if (best == null || n.getCost() < best.getCost()) {
-        best = n;
-        continue;
-      }
-    }
-    return best != null ? best : input;
-  }
-
-  private static class MatchResult<T> {
-    private static final MatchResult<?> FAIL = new MatchResult<>(null);
-    private static final MatchResult<?> OK = new MatchResult<>(null);
-
-    @SuppressWarnings("unchecked")
-    static <T> MatchResult<T> fail() {
-      return (MatchResult<T>) FAIL;
-    }
-
-    @SuppressWarnings("unchecked")
-    static <T> MatchResult<T> ok() {
-      return (MatchResult<T>) OK;
-    }
-
-    final Predicate<T> extra;
-
-    MatchResult(Predicate<T> extra) {
-      this.extra = extra;
-    }
-
-    boolean success() {
-      return this != FAIL;
-    }
-  }
-
-  private MatchResult<T> match(final Map<String, Predicate<T>> outVars,
-      final Predicate<T> pattern, final Predicate<T> actual) {
-    if (pattern instanceof VariablePredicate) {
-      final VariablePredicate<T> v = (VariablePredicate<T>) pattern;
-      final MatchResult<T> r = match(outVars, v.getChild(0), actual);
-      if (r.success()) {
-        Predicate<T> old = outVars.get(v.getName());
-        if (old == null) {
-          outVars.put(v.getName(), actual);
-          return r;
-        } else if (old.equals(actual)) {
-          return r;
-        } else {
-          return MatchResult.fail();
-        }
-      } else {
-        return MatchResult.fail();
-      }
-    }
-
-    if ((isAND(pattern) && isAND(actual)) //
-        || (isOR(pattern) && isOR(actual)) //
-        || (isNOT(pattern) && isNOT(actual)) //
-    ) {
-      // Order doesn't actually matter here. That does make our logic quite
-      // a bit more complex as we need to consult each child at most once,
-      // but in any order.
-      //
-      final LinkedList<Predicate<T>> have = dup(actual);
-      final LinkedList<Predicate<T>> extra = new LinkedList<>();
-      for (final Predicate<T> pat : pattern.getChildren()) {
-        boolean found = false;
-        for (final Iterator<Predicate<T>> i = have.iterator(); i.hasNext();) {
-          final MatchResult<T> r = match(outVars, pat, i.next());
-          if (r.success()) {
-            found = true;
-            i.remove();
-            if (r.extra != null) {
-              extra.add(r.extra);
-            }
-            break;
-          }
-        }
-        if (!found) {
-          return MatchResult.fail();
-        }
-      }
-      have.addAll(extra);
-      switch (have.size()) {
-        case 0:
-          return MatchResult.ok();
-        case 1:
-          if (isNOT(actual)) {
-            return new MatchResult<>(actual.copy(have));
-          }
-          return new MatchResult<>(have.get(0));
-        default:
-          return new MatchResult<>(actual.copy(have));
-      }
-
-    } else if (pattern.equals(actual)) {
-      return MatchResult.ok();
-
-    } else if (pattern instanceof WildPatternPredicate
-        && actual instanceof OperatorPredicate
-        && ((OperatorPredicate<T>) pattern).getOperator().equals(
-            ((OperatorPredicate<T>) actual).getOperator())) {
-      return MatchResult.ok();
-
-    } else {
-      return MatchResult.fail();
-    }
-  }
-
-  private static <T> LinkedList<Predicate<T>> dup(final Predicate<T> actual) {
-    return new LinkedList<>(actual.getChildren());
-  }
-
-  /**
-   * Denotes a method which wants to replace a predicate expression.
-   * <p>
-   * This annotation must be applied to a public method which returns
-   * {@link Predicate}. The arguments of the method should {@link Predicate}, or
-   * any subclass of it. The annotation value is a query language string which
-   * describes the subtree this rewrite applies to. Method arguments should be
-   * named with a {@link Named} annotation, and the same names should be used in
-   * the query.
-   * <p>
-   * For example:
-   *
-   * <pre>
-   * &#064;Rewrite(&quot;A=(owner:*) B=(status:*)&quot;)
-   * public Predicate ownerStatus(@Named(&quot;A&quot;) OperatorPredicate owner,
-   *     &#064;Named(&quot;B&quot;) OperatorPredicate status) {
-   * }
-   * </pre>
-   *
-   * matches an AND Predicate with at least two children, one being an operator
-   * predicate called "owner" and the other being an operator predicate called
-   * "status". The variables in the query are matched by name against the
-   * parameters.
-   */
-  @Retention(RetentionPolicy.RUNTIME)
-  @Target(ElementType.METHOD)
-  protected @interface Rewrite {
-    String value();
-  }
-
-  @Retention(RetentionPolicy.RUNTIME)
-  @Target(ElementType.METHOD)
-  protected @interface NoCostComputation {
-  }
-
-  /** Applies a rewrite rule to a Predicate. */
-  protected interface RewriteRule<T> extends Comparable<RewriteRule<T>> {
-    /**
-     * Apply a rewrite rule to the Predicate.
-     *
-     * @param input the input predicate to be tested, and possibly rewritten.
-     * @return a rewritten form of the predicate if this rule matches with the
-     *         tree {@code input} and has a rewrite for it; {@code null} if this
-     *         rule does not want this predicate.
-     */
-    Predicate<T> rewrite(QueryRewriter<T> rewriter, Predicate<T> input);
-
-    /** @return true if the best cost should be selected. */
-    boolean useBestCost();
-  }
-
-  /** Implements the magic behind {@link Rewrite} annotations. */
-  private static class MethodRewrite<T> implements RewriteRule<T> {
-    private final Method method;
-    private final Predicate<T> pattern;
-    private final String[] argNames;
-    private final Class<? extends Predicate<T>>[] argTypes;
-    private final boolean useBestCost;
-
-    @SuppressWarnings("unchecked")
-    MethodRewrite(QueryBuilder<T> queryBuilder, String patternText, Method m) {
-      method = m;
-      useBestCost = m.getAnnotation(NoCostComputation.class) == null;
-
-      Predicate<T> p;
-      try {
-        p = queryBuilder.parse(patternText);
-      } catch (QueryParseException e) {
-        throw new RuntimeException("Bad @Rewrite(\"" + patternText + "\")"
-            + " on " + m.toGenericString() + " in " + m.getDeclaringClass()
-            + ": " + e.getMessage(), e);
-      }
-      if (!Predicate.class.isAssignableFrom(m.getReturnType())) {
-        throw new RuntimeException(m.toGenericString() + " in "
-            + m.getDeclaringClass() + " must return " + Predicate.class);
-      }
-
-      pattern = p;
-      argNames = new String[method.getParameterTypes().length];
-      argTypes = new Class[argNames.length];
-      for (int i = 0; i < argNames.length; i++) {
-        Named name = null;
-        for (Annotation a : method.getParameterAnnotations()[i]) {
-          if (a instanceof Named) {
-            name = (Named) a;
-            break;
-          }
-        }
-        if (name == null) {
-          throw new RuntimeException("Argument " + (i + 1) + " of "
-              + m.toGenericString() + " in " + m.getDeclaringClass()
-              + " has no @Named annotation");
-        }
-        if (!Predicate.class.isAssignableFrom(method.getParameterTypes()[i])) {
-          throw new RuntimeException("Argument " + (i + 1) + " of "
-              + m.toGenericString() + " in " + m.getDeclaringClass()
-              + " must be of type " + Predicate.class);
-        }
-        argNames[i] = name.value();
-        argTypes[i] = (Class<Predicate<T>>) method.getParameterTypes()[i];
-      }
-    }
-
-    @Override
-    public boolean useBestCost() {
-      return useBestCost;
-    }
-
-    @SuppressWarnings("unchecked")
-    @Override
-    public Predicate<T> rewrite(QueryRewriter<T> rewriter,
-        final Predicate<T> input) {
-      final HashMap<String, Predicate<T>> args = new HashMap<>();
-      final MatchResult<T> res = rewriter.match(args, pattern, input);
-      if (!res.success()) {
-        return null;
-      }
-
-      final Predicate<T>[] argList = new Predicate[argNames.length];
-      for (int i = 0; i < argList.length; i++) {
-        argList[i] = args.get(argNames[i]);
-        if (argList[i] == null) {
-          final String a = "@Named(\"" + argNames[i] + "\")";
-          throw error(new IllegalStateException("No value bound for " + a));
-        }
-        if (!argTypes[i].isInstance(argList[i])) {
-          return null;
-        }
-      }
-
-      final Predicate<T> rep;
-      try {
-        rep = (Predicate<T>) method.invoke(rewriter, (Object[]) argList);
-      } catch (IllegalArgumentException e) {
-        throw error(e);
-      } catch (IllegalAccessException e) {
-        throw error(e);
-      } catch (InvocationTargetException e) {
-        throw error(e.getCause());
-      }
-
-      if (rep instanceof RewritePredicate) {
-        ((RewritePredicate<T>) rep).init(method.getName(), argList);
-      }
-
-      if (res.extra == null) {
-        return rep;
-      }
-
-      Predicate<T> extra = removeDuplicates(res.extra);
-      Predicate<T>[] newArgs = new Predicate[] {extra, rep};
-      return input.copy(Arrays.asList(newArgs));
-    }
-
-    private IllegalArgumentException error(Throwable e) {
-      final String msg = "Cannot apply " + method.getName();
-      return new IllegalArgumentException(msg, e);
-    }
-
-    @Override
-    public int compareTo(RewriteRule<T> in) {
-      if (in instanceof MethodRewrite) {
-        return method.getName().compareTo(
-            ((MethodRewrite<T>) in).method.getName());
-      }
-      return 1;
-    }
-  }
-
-  private static <T> Predicate<T> removeDuplicates(Predicate<T> in) {
-    if (in.getChildCount() > 0) {
-      List<Predicate<T>> n = removeDuplicates(in.getChildren());
-      if (n.size() == 1 && (isAND(in) || isOR(in))) {
-        in = n.get(0);
-      } else {
-        in = in.copy(n);
-      }
-    }
-    return in;
-  }
-
-  private static <T> List<Predicate<T>> removeDuplicates(List<Predicate<T>> n) {
-    List<Predicate<T>> r = new ArrayList<>();
-    for (Predicate<T> p : n) {
-      if (!r.contains(p)) {
-        r.add(p);
-      }
-    }
-    return r;
-  }
-
-  private static <T> boolean isAND(final Predicate<T> p) {
-    return p instanceof AndPredicate;
-  }
-
-  private static <T> boolean isOR(final Predicate<T> p) {
-    return p instanceof OrPredicate;
-  }
-
-  private static <T> boolean isNOT(final Predicate<T> p) {
-    return p instanceof NotPredicate;
-  }
-}
diff --git a/gerrit-server/src/main/java/com/google/gerrit/server/query/RewritePredicate.java b/gerrit-server/src/main/java/com/google/gerrit/server/query/RewritePredicate.java
deleted file mode 100644
index f4a2111..0000000
--- a/gerrit-server/src/main/java/com/google/gerrit/server/query/RewritePredicate.java
+++ /dev/null
@@ -1,79 +0,0 @@
-// Copyright (C) 2010 The Android Open Source Project
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-package com.google.gerrit.server.query;
-
-import com.google.common.collect.ImmutableList;
-
-import java.util.Collection;
-import java.util.Collections;
-import java.util.List;
-
-public abstract class RewritePredicate<T> extends Predicate<T> {
-  private boolean init;
-  private String name = getClass().getSimpleName();
-  private List<Predicate<T>> children = Collections.emptyList();
-
-  protected void init(String name, @SuppressWarnings("unchecked") Predicate<T>... args) {
-    this.init = true;
-    this.name = name;
-    this.children = ImmutableList.copyOf(args);
-  }
-
-  @Override
-  public Predicate<T> copy(Collection<? extends Predicate<T>> children) {
-    return this;
-  }
-
-  @SuppressWarnings("unchecked")
-  @Override
-  public boolean equals(Object other) {
-    if (other instanceof RewritePredicate) {
-      RewritePredicate<T> that = (RewritePredicate<T>) other;
-      if (this.init && that.init) {
-        return this.getClass() == that.getClass()
-            && this.name.equals(that.name)
-            && this.children.equals(that.children);
-      }
-    }
-    return this == other;
-  }
-
-  @Override
-  public int hashCode() {
-    int h = getClass().hashCode();
-    if (!children.isEmpty()) {
-      h *= 31;
-      h += children.get(0).hashCode();
-    }
-    return h;
-  }
-
-  @Override
-  public final String toString() {
-    final StringBuilder r = new StringBuilder();
-    r.append(name);
-    if (!children.isEmpty()) {
-      r.append("(");
-      for (int i = 0; i < children.size(); i++) {
-        if (i != 0) {
-          r.append(" ");
-        }
-        r.append(children.get(i));
-      }
-      r.append(")");
-    }
-    return r.toString();
-  }
-}
diff --git a/gerrit-server/src/main/java/com/google/gerrit/server/query/VariablePredicate.java b/gerrit-server/src/main/java/com/google/gerrit/server/query/VariablePredicate.java
deleted file mode 100644
index e298e5f..0000000
--- a/gerrit-server/src/main/java/com/google/gerrit/server/query/VariablePredicate.java
+++ /dev/null
@@ -1,99 +0,0 @@
-// Copyright (C) 2009 The Android Open Source Project
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-package com.google.gerrit.server.query;
-
-import com.google.gwtorm.server.OrmException;
-
-import java.util.Collection;
-import java.util.Collections;
-import java.util.List;
-
-/**
- * Holds another predicate in a named variable.
- *
- * @see QueryRewriter
- */
-public class VariablePredicate<T> extends Predicate<T> {
-  private final String name;
-  private final Predicate<T> that;
-
-  protected VariablePredicate(final String name, final Predicate<T> that) {
-    this.name = name;
-    this.that = that;
-  }
-
-  public String getName() {
-    return name;
-  }
-
-  @Override
-  public final List<Predicate<T>> getChildren() {
-    return Collections.singletonList(that);
-  }
-
-  @Override
-  public final int getChildCount() {
-    return 1;
-  }
-
-  @Override
-  public final Predicate<T> getChild(final int i) {
-    if (i != 0) {
-      throw new ArrayIndexOutOfBoundsException(i);
-    }
-    return that;
-  }
-
-  @Override
-  public Predicate<T> copy(final Collection<? extends Predicate<T>> children) {
-    if (children.size() != 1) {
-      throw new IllegalArgumentException("Expected exactly one child");
-    }
-    return new VariablePredicate<>(getName(), children.iterator().next());
-  }
-
-  @Override
-  public boolean match(final T object) throws OrmException {
-    return that.match(object);
-  }
-
-  @Override
-  public int getCost() {
-    return that.getCost();
-  }
-
-  @Override
-  public int hashCode() {
-    return getName().hashCode() * 31 + that.hashCode();
-  }
-
-  @Override
-  public boolean equals(final Object other) {
-    if (other == null) {
-      return false;
-    }
-    if (getClass() == other.getClass()) {
-      final VariablePredicate<?> v = (VariablePredicate<?>) other;
-      return getName().equals(v.getName())
-          && getChildren().equals(v.getChildren());
-    }
-    return false;
-  }
-
-  @Override
-  public final String toString() {
-    return getName() + "=(" + that.toString() + ")";
-  }
-}
diff --git a/gerrit-server/src/main/java/com/google/gerrit/server/query/WildPatternPredicate.java b/gerrit-server/src/main/java/com/google/gerrit/server/query/WildPatternPredicate.java
deleted file mode 100644
index 981051b..0000000
--- a/gerrit-server/src/main/java/com/google/gerrit/server/query/WildPatternPredicate.java
+++ /dev/null
@@ -1,62 +0,0 @@
-// Copyright (C) 2009 The Android Open Source Project
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-package com.google.gerrit.server.query;
-
-/**
- * Predicate only for use in rewrite rule patterns.
- * <p>
- * May <b>only</b> be used when nested immediately within a
- * {@link VariablePredicate}. Within the QueryRewriter this predicate matches
- * any other operator whose name matches this predicate's operator name.
- *
- * @see QueryRewriter
- */
-public final class WildPatternPredicate<T> extends OperatorPredicate<T> {
-  public WildPatternPredicate(final String name) {
-    super(name, "*");
-  }
-
-  @Override
-  public boolean match(final T object) {
-    throw new UnsupportedOperationException("Cannot match " + toString());
-  }
-
-  @Override
-  public int getCost() {
-    return 0;
-  }
-
-  @Override
-  public int hashCode() {
-    return getOperator().hashCode() * 31;
-  }
-
-  @Override
-  public boolean equals(final Object other) {
-    if (other == null) {
-      return false;
-    }
-    if (getClass() == other.getClass()) {
-      final WildPatternPredicate<?> p = (WildPatternPredicate<?>) other;
-      return getOperator().equals(p.getOperator());
-    }
-    return false;
-  }
-
-  @Override
-  public String toString() {
-    return getOperator() + ":" + getValue();
-  }
-}
diff --git a/gerrit-server/src/main/java/com/google/gerrit/server/query/change/BasicChangeRewrites.java b/gerrit-server/src/main/java/com/google/gerrit/server/query/change/BasicChangeRewrites.java
deleted file mode 100644
index d167860..0000000
--- a/gerrit-server/src/main/java/com/google/gerrit/server/query/change/BasicChangeRewrites.java
+++ /dev/null
@@ -1,76 +0,0 @@
-// Copyright (C) 2013 The Android Open Source Project
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-package com.google.gerrit.server.query.change;
-
-import com.google.gerrit.reviewdb.client.Change;
-import com.google.gerrit.reviewdb.server.ReviewDb;
-import com.google.gerrit.server.query.Predicate;
-import com.google.gerrit.server.query.QueryRewriter;
-import com.google.inject.Inject;
-import com.google.inject.OutOfScopeException;
-import com.google.inject.Provider;
-
-public class BasicChangeRewrites extends QueryRewriter<ChangeData> {
-  private static final ChangeQueryBuilder BUILDER = new ChangeQueryBuilder(
-      new ChangeQueryBuilder.Arguments(
-          new InvalidProvider<ReviewDb>(),
-          new InvalidProvider<InternalChangeQuery>(),
-          new InvalidProvider<ChangeQueryRewriter>(),
-          null, null, null, null, null, null, null, null, null, null, null,
-          null, null, null, null, null, null, null, null, null));
-
-  private static final QueryRewriter.Definition<ChangeData, BasicChangeRewrites> mydef =
-      new QueryRewriter.Definition<>(BasicChangeRewrites.class, BUILDER);
-
-  @Inject
-  public BasicChangeRewrites() {
-    super(mydef);
-  }
-
-  @Rewrite("-status:open")
-  @NoCostComputation
-  public Predicate<ChangeData> r00_notOpen() {
-    return ChangeStatusPredicate.closed();
-  }
-
-  @Rewrite("-status:closed")
-  @NoCostComputation
-  public Predicate<ChangeData> r00_notClosed() {
-    return ChangeStatusPredicate.open();
-  }
-
-  @SuppressWarnings("unchecked")
-  @NoCostComputation
-  @Rewrite("-status:merged")
-  public Predicate<ChangeData> r00_notMerged() {
-    return or(ChangeStatusPredicate.open(),
-        new ChangeStatusPredicate(Change.Status.ABANDONED));
-  }
-
-  @SuppressWarnings("unchecked")
-  @NoCostComputation
-  @Rewrite("-status:abandoned")
-  public Predicate<ChangeData> r00_notAbandoned() {
-    return or(ChangeStatusPredicate.open(),
-        new ChangeStatusPredicate(Change.Status.MERGED));
-  }
-
-  private static final class InvalidProvider<T> implements Provider<T> {
-    @Override
-    public T get() {
-      throw new OutOfScopeException("Not available at init");
-    }
-  }
-}
diff --git a/gerrit-server/src/test/java/com/google/gerrit/server/index/IndexRewriteTest.java b/gerrit-server/src/test/java/com/google/gerrit/server/index/IndexRewriteTest.java
index 042459b..8d7866d 100644
--- a/gerrit-server/src/test/java/com/google/gerrit/server/index/IndexRewriteTest.java
+++ b/gerrit-server/src/test/java/com/google/gerrit/server/index/IndexRewriteTest.java
@@ -30,7 +30,6 @@
 import com.google.gerrit.server.query.Predicate;
 import com.google.gerrit.server.query.QueryParseException;
 import com.google.gerrit.server.query.change.AndSource;
-import com.google.gerrit.server.query.change.BasicChangeRewrites;
 import com.google.gerrit.server.query.change.ChangeData;
 import com.google.gerrit.server.query.change.ChangeQueryBuilder;
 import com.google.gerrit.server.query.change.OrSource;
@@ -54,7 +53,7 @@
     indexes = new IndexCollection();
     indexes.setSearchIndex(index);
     queryBuilder = new FakeQueryBuilder(indexes);
-    rewrite = new IndexRewriteImpl(indexes, new BasicChangeRewrites());
+    rewrite = new IndexRewriteImpl(indexes);
   }
 
   @Test
@@ -94,9 +93,9 @@
   @Test
   public void testThreeLevelTreeWithAllIndexPredicates() throws Exception {
     Predicate<ChangeData> in =
-        parse("-status:abandoned (status:open OR status:merged)");
+        parse("-status:abandoned (file:a OR file:b)");
     assertEquals(
-        query(parse("status:new OR status:submitted OR status:draft OR status:merged")),
+        query(in),
         rewrite.rewrite(in, 0, DEFAULT_MAX_QUERY_LIMIT));
   }