public static Multimap<Class<? extends Operator<?>>, Operator<?>> classifyOperatorsUpstream(
      Operator<?> start, Set<Class<? extends Operator<?>>> classes) {
    ImmutableMultimap.Builder<Class<? extends Operator<?>>, Operator<?>> resultMap =
        new ImmutableMultimap.Builder<Class<? extends Operator<?>>, Operator<?>>();
    List<Operator<?>> ops = new ArrayList<Operator<?>>();
    ops.add(start);
    while (!ops.isEmpty()) {
      List<Operator<?>> allParent = new ArrayList<Operator<?>>();
      for (Operator<?> op: ops) {
        for (Class<? extends Operator<?>> clazz: classes) {
          if (clazz.isInstance(op)) {
            resultMap.put(clazz, op);
          }
        }
        if (op.getParentOperators() != null) {
          allParent.addAll(op.getParentOperators());
        }
      }
      ops = allParent;
    }
    return resultMap.build();
  }
Given an operator and a set of classes, it classifies the operators it finds
upstream depending on the classes it instantiates.

If a given operator object is an instance of more than one of the input classes,
e.g. the operator instantiates one of the classes in the input set that is a
subclass of another class in the set, the operator will be associated to both
classes in the output map.

@param start the start operator
@param classes the set of classes
@return a multimap from each of the classes to the operators that instantiate
them
ql/src/java/org/apache/hadoop/hive/ql/exec/OperatorUtils.java