// where
 private void handleFlowResults(Queue<Env<AttrContext>> queue, ListBuffer<Element> elems) {
   for (Env<AttrContext> env : queue) {
     switch (env.tree.getTag()) {
       case JCTree.CLASSDEF:
         JCClassDecl cdef = (JCClassDecl) env.tree;
         if (cdef.sym != null) elems.append(cdef.sym);
         break;
       case JCTree.TOPLEVEL:
         JCCompilationUnit unit = (JCCompilationUnit) env.tree;
         if (unit.packge != null) elems.append(unit.packge);
         break;
     }
   }
   genList.addAll(queue);
 }
  /**
   * Translate the given abstract syntax trees to elements.
   *
   * @param trees a list of abstract syntax trees.
   * @throws java.io.IOException TODO
   * @return a list of elements corresponding to the top level classes in the abstract syntax trees
   */
  public Iterable<? extends TypeElement> enter(Iterable<? extends CompilationUnitTree> trees)
      throws IOException {
    prepareCompiler();

    ListBuffer<JCCompilationUnit> roots = null;

    if (trees == null) {
      // If there are still files which were specified to be compiled
      // (i.e. in fileObjects) but which have not yet been entered,
      // then we make sure they have been parsed and add them to the
      // list to be entered.
      if (notYetEntered.size() > 0) {
        if (!parsed) parse(); // TODO would be nice to specify files needed to be parsed
        for (JavaFileObject file : fileObjects) {
          JCCompilationUnit unit = notYetEntered.remove(file);
          if (unit != null) {
            if (roots == null) roots = new ListBuffer<JCCompilationUnit>();
            roots.append(unit);
          }
        }
        notYetEntered.clear();
      }
    } else {
      for (CompilationUnitTree cu : trees) {
        if (cu instanceof JCCompilationUnit) {
          if (roots == null) roots = new ListBuffer<JCCompilationUnit>();
          roots.append((JCCompilationUnit) cu);
          notYetEntered.remove(cu.getSourceFile());
        } else throw new IllegalArgumentException(cu.toString());
      }
    }

    if (roots == null) return List.nil();

    try {
      List<JCCompilationUnit> units = compiler.enterTrees(roots.toList());

      if (notYetEntered.isEmpty()) compiler = compiler.processAnnotations(units);

      ListBuffer<TypeElement> elements = new ListBuffer<TypeElement>();
      for (JCCompilationUnit unit : units) {
        for (JCTree node : unit.defs) {
          if (node.getTag() == JCTree.CLASSDEF) {
            JCClassDecl cdef = (JCClassDecl) node;
            if (cdef.sym != null) // maybe null if errors in anno processing
            elements.append(cdef.sym);
          }
        }
      }
      return elements.toList();
    } finally {
      compiler.log.flush();
    }
  }
    void run(Queue<Env<AttrContext>> list, Iterable<? extends TypeElement> classes) {
      Set<TypeElement> set = new HashSet<TypeElement>();
      for (TypeElement item : classes) set.add(item);

      ListBuffer<Env<AttrContext>> defer = ListBuffer.<Env<AttrContext>>lb();
      while (list.peek() != null) {
        Env<AttrContext> env = list.remove();
        ClassSymbol csym = env.enclClass.sym;
        if (csym != null && set.contains(csym.outermostClass())) process(env);
        else defer = defer.append(env);
      }

      list.addAll(defer);
    }
 private static List<JavaFileObject> toList(Iterable<? extends JavaFileObject> fileObjects) {
   if (fileObjects == null) return List.nil();
   ListBuffer<JavaFileObject> result = new ListBuffer<JavaFileObject>();
   for (JavaFileObject fo : fileObjects) result.append(fo);
   return result.toList();
 }
 private static String[] toArray(Iterable<String> iter) {
   ListBuffer<String> result = new ListBuffer<String>();
   if (iter != null) for (String s : iter) result.append(s);
   return result.toArray(new String[result.length()]);
 }