/**
  * Parse the specified files returning a list of abstract syntax trees.
  *
  * @throws java.io.IOException TODO
  * @return a list of abstract syntax trees
  */
 public Iterable<? extends CompilationUnitTree> parse() throws IOException {
   try {
     prepareCompiler();
     List<JCCompilationUnit> units = compiler.parseFiles(fileObjects);
     for (JCCompilationUnit unit : units) {
       JavaFileObject file = unit.getSourceFile();
       if (notYetEntered.containsKey(file)) notYetEntered.put(file, unit);
     }
     return units;
   } finally {
     parsed = true;
     if (compiler != null && compiler.log != null) compiler.log.flush();
   }
 }
 private void prepareCompiler() throws IOException {
   if (used.getAndSet(true)) {
     if (compiler == null) throw new IllegalStateException();
   } else {
     initContext();
     compilerMain.setOptions(Options.instance(context));
     compilerMain.filenames = new LinkedHashSet<File>();
     Collection<File> filenames = compilerMain.processArgs(CommandLine.parse(args), classNames);
     if (!filenames.isEmpty())
       throw new IllegalArgumentException("Malformed arguments " + toString(filenames, " "));
     compiler = JavaCompiler.instance(context);
     compiler.keepComments = true;
     compiler.genEndPos = true;
     // NOTE: this value will be updated after annotation processing
     compiler.initProcessAnnotations(processors);
     notYetEntered = new HashMap<JavaFileObject, JCCompilationUnit>();
     for (JavaFileObject file : fileObjects) notYetEntered.put(file, null);
     genList = new ListBuffer<Env<AttrContext>>();
     // endContext will be called when all classes have been generated
     // TODO: should handle the case after each phase if errors have occurred
     args = null;
     classNames = null;
   }
 }