package org.angularjs.closurerunner;

import com.google.common.collect.ArrayListMultimap;

import com.google.javascript.jscomp.AbstractCompiler;
import com.google.javascript.jscomp.CommandLineRunner;
import com.google.javascript.jscomp.CompilerOptions;
import com.google.javascript.jscomp.CompilerPass;
import com.google.javascript.jscomp.CustomPassExecutionTime;

import java.io.IOException;
import java.io.PrintStream;

import java.util.ArrayList;
import java.util.List;

public class NgClosureRunner extends CommandLineRunner {

  private boolean minerrPass;
  private String minerrErrors, minerrUrl;

  protected NgClosureRunner(String[] args, 
                            boolean minerrPass, 
                            String minerrErrors, 
                            String minerrUrl) {
    super(args);
    this.minerrPass = minerrPass;
    
    if (minerrErrors != null) {
      this.minerrErrors = minerrErrors;
    } else {
      this.minerrErrors = "errors.json";
    }
    this.minerrUrl = minerrUrl;
  }

  private CompilerPass createMinerrPass() throws IOException {
    AbstractCompiler compiler = createCompiler();
    PrintStream output = new PrintStream(minerrErrors);

    if (minerrUrl != null) {
      return new MinerrPass(compiler, output, MinerrPass.substituteInSource(minerrUrl));
    }
    return new MinerrPass(compiler, output);
  }

  @Override
  protected CompilerOptions createOptions() {
    CompilerOptions options = super.createOptions();

    if (minerrPass) {
      if (options.customPasses == null) {
        options.customPasses = ArrayListMultimap.create();
      }
      try {
        options.customPasses.put(CustomPassExecutionTime.BEFORE_OPTIMIZATIONS,
          createMinerrPass());
      } catch (IOException e) {
        System.err.println(e);
        System.exit(1);
      }
    }
    return options;
  }

  public static void main(String[] args) {
    boolean minerrPass = false;
    String minerrErrors = "errors.json", minerrUrl = null;
    List<String> passthruArgs = new ArrayList<String>();

    for (int i = 0; i < args.length; i++) {
      String arg = args[i];
      if (arg.equals("--minerr_pass")) {
        minerrPass = true;
      } else if (arg.equals("--minerr_errors")) {
        minerrErrors = args[++i];
      } else if (arg.equals("--minerr_url")) {
        minerrUrl = args[++i];
      } else {
        passthruArgs.add(arg);
      }
    }

    NgClosureRunner runner = new NgClosureRunner(passthruArgs.toArray(new String[]{}), 
      minerrPass, minerrErrors, minerrUrl);

    if (runner.shouldRunCompiler()) {
      runner.run();
    } else {
      System.exit(-1);
    }
  }
}
@@ -134,24 +134,70 @@
 ctCompiler;%0A
+import com.google.javascript.jscomp.Compiler;%0A
 import com.g
@@ -642,16 +642,51 @@
 nerrUrl;
+%0A  private Compiler cachedCompiler;
 %0A%0A  prot
@@ -1930,16 +1930,251 @@
 s;%0A  %7D%0A%0A
+  @Override%0A  protected Compiler createCompiler() %7B%0A    // Always use the same compiler.%0A    if (cachedCompiler != null) %7B%0A      return cachedCompiler;%0A    %7D%0A    cachedCompiler = super.createCompiler();%0A    return cachedCompiler;%0A  %7D%0A%0A
   public

Fix null pointer/2 fighting compilers bug