private void doContextualEscaping(SoyFileSetNode soyTree) throws SoySyntaxException {
   List<TemplateNode> extraTemplates = contextualAutoescaper.rewrite(soyTree);
   // TODO: Run the redundant template remover here and rename after CL 16642341 is in.
   if (!extraTemplates.isEmpty()) {
     // TODO: pull out somewhere else.  Ideally do the merge as part of the redundant template
     // removal.
     Map<String, SoyFileNode> containingFile = Maps.newHashMap();
     for (SoyFileNode fileNode : soyTree.getChildren()) {
       for (TemplateNode templateNode : fileNode.getChildren()) {
         String name =
             templateNode instanceof TemplateDelegateNode
                 ? ((TemplateDelegateNode) templateNode).getDelTemplateName()
                 : templateNode.getTemplateName();
         containingFile.put(DerivedTemplateUtils.getBaseName(name), fileNode);
       }
     }
     for (TemplateNode extraTemplate : extraTemplates) {
       String name =
           extraTemplate instanceof TemplateDelegateNode
               ? ((TemplateDelegateNode) extraTemplate).getDelTemplateName()
               : extraTemplate.getTemplateName();
       containingFile.get(DerivedTemplateUtils.getBaseName(name)).addChild(extraTemplate);
     }
   }
 }
  /**
   * Generates Incremental DOM JS source files given a Soy parse tree, an options object, an
   * optional bundle of translated messages, and information on where to put the output files.
   *
   * @param soyTree The Soy parse tree to generate JS source code for.
   * @param jsSrcOptions The compilation options relevant to this backend.
   * @param outputPathFormat The format string defining how to build the output file path
   *     corresponding to an input file path.
   * @throws SoySyntaxException If a syntax error is found.
   * @throws IOException If there is an error in opening/writing an output JS file.
   */
  public void genJsFiles(
      SoyFileSetNode soyTree, SoyJsSrcOptions jsSrcOptions, String outputPathFormat)
      throws SoySyntaxException, IOException {

    List<String> jsFileContents = genJsSrc(soyTree, jsSrcOptions);

    ImmutableList<SoyFileNode> srcsToCompile =
        ImmutableList.copyOf(
            Iterables.filter(soyTree.getChildren(), SoyFileNode.MATCH_SRC_FILENODE));

    if (srcsToCompile.size() != jsFileContents.size()) {
      throw new AssertionError(
          String.format(
              "Expected to generate %d code chunk(s), got %d",
              srcsToCompile.size(), jsFileContents.size()));
    }

    Multimap<String, Integer> outputs =
        MainEntryPointUtils.mapOutputsToSrcs(
            null /* locale */, outputPathFormat, "" /* inputPathsPrefix */, srcsToCompile);

    for (String outputFilePath : outputs.keySet()) {
      Writer out = Files.newWriter(new File(outputFilePath), UTF_8);
      try {
        boolean isFirst = true;
        for (int inputFileIndex : outputs.get(outputFilePath)) {
          if (isFirst) {
            isFirst = false;
          } else {
            // Concatenating JS files is not safe unless we know that the last statement from one
            // couldn't combine with the isFirst statement of the next.  Inserting a semicolon will
            // prevent this from happening.
            out.write("\n;\n");
          }
          out.write(jsFileContents.get(inputFileIndex));
        }
      } finally {
        out.close();
      }
    }
  }