private String compile(HtmlLibrary library, ClosureOptimizationLevel opt, InputStream js)
     throws IOException {
   CompilationLevel compilationLevel = opt.toCompilationLevel();
   if (null == compilationLevel) {
     // return original input
     return IOUtils.toString(js);
   }
   SourceFile input = SourceFile.fromInputStream(getLibraryName(library), js);
   // TODO externs not supported, should avoid ADVANCED compilation
   SourceFile extern = SourceFile.fromCode("TODO", StringUtils.EMPTY);
   CompilerOptions options = new CompilerOptions();
   compilationLevel.setOptionsForCompilationLevel(options);
   // ES5 assumption to allow getters/setters
   options.setLanguageIn(CompilerOptions.LanguageMode.ECMASCRIPT5);
   Compiler compiler = new Compiler();
   compiler.compile(extern, input, options);
   return compiler.toSource();
 }
  /** @throws ExecutionException */
  public void run() throws ExecutionException {
    final Compiler compiler = new Compiler();
    final CompilerOptions options = new CompilerOptions();
    closureOptimization.setOptionsForCompilationLevel(options);

    final List<JSSourceFile> externs = Collections.emptyList();
    final List<JSSourceFile> sources = new ArrayList<JSSourceFile>();
    if (closurePreScript != null) {
      getLogger().info("Include PreScript:");
      sources.add(JSSourceFile.fromCode("closurePreScript.js", closurePreScript));
    }
    getFiles(sources);
    if (closurePostScript != null) {
      getLogger().info("Include PostScript:");
      sources.add(JSSourceFile.fromCode("closurePostScript.js", closurePostScript));
    }

    getLogger().info("Got " + sources.size() + " source files");
    final Result result = compiler.compile(externs, sources, options);
    if (!result.success) {
      throw new ExecutionException("Failed to compile scripts");
    }

    getLogger().info("Writing compiled js to " + closureTargetFile);
    try {
      FileUtils.forceMkdir(closureTargetFile.getParentFile());
      final FileWriter writer = new FileWriter(closureTargetFile);
      try {
        String preSource =
            closurePreScriptFile != null ? FileUtils.readFileToString(closurePreScriptFile) : "";
        String postSource =
            closurePostScriptFile != null ? FileUtils.readFileToString(closurePostScriptFile) : "";

        StringBuilder sb = new StringBuilder();
        sb.append(preSource).append(compiler.toSource()).append(postSource);
        writer.write(sb.toString());
      } finally {
        writer.close();
      }
    } catch (IOException e) {
      throw new ExecutionException("Failed to write target file: " + closureTargetFile, e);
    }
  }