private void splitFiles(String[] input) {
    Compiler compiler = new Compiler();
    List<SourceFile> files = Lists.newArrayList();

    for (int i = 0; i < input.length; i++) {
      files.add(SourceFile.fromCode("file" + i, input[i]));
    }

    compiler.init(ImmutableList.<SourceFile>of(), files, new CompilerOptions());
    compiler.parse();
    Node original = compiler.getRoot();
    Node root = original.cloneTree();

    AstParallelizer parallelizer = AstParallelizer.createNewFileLevelAstParallelizer(root);
    List<Node> forest = parallelizer.split();
    assertEquals(input.length, forest.size());
    int i = 0;
    for (Node n : forest) {
      Node tree = compiler.parseTestCode(input[i++]);
      assertEquals(compiler.toSource(tree), compiler.toSource(n));
    }

    parallelizer.join();
    assertTrue(original.isEquivalentTo(root));
  }
 /**
  * Splits the AST into subtree at different levels. The subtrees itself are usually not valid
  * javascript but they are all subtreess of some valid javascript.
  */
 public List<Node> split() {
   if (includeRoot) {
     forest.add(root);
   }
   split(root);
   return forest;
 }
  /**
   * Splits at function level with {@link AstParallelizer#split()}, verify the output matches what
   * is expected and then verify {@link AstParallelizer#join()} can reverse the whole process.
   */
  private void splitFunctions(String input, String... output) {
    Compiler compiler = new Compiler();
    Node original = compiler.parseTestCode(input);
    Node root = original.cloneTree();
    AstParallelizer parallelizer =
        AstParallelizer.createNewFunctionLevelAstParallelizer(root, true);
    List<Node> forest = parallelizer.split();
    assertEquals(output.length, forest.size());
    int i = 0;
    for (Node n : forest) {
      Node tree = compiler.parseTestCode(output[i++]);
      assertEquals(compiler.toSource(tree), compiler.toSource(n));
    }

    parallelizer.join();
    assertTrue(original.isEquivalentTo(root));
  }
 private void split(Node n) {
   Node c = n.getFirstChild();
   Node before = null;
   while (c != null) {
     Node next = c.getNext();
     if (shouldSplit.apply(c)) {
       Node placeHolder = placeHolderProvider.get();
       if (before == null) {
         forest.add(n.removeFirstChild());
         n.addChildToFront(placeHolder);
       } else {
         n.addChildAfter(placeHolder, c);
         n.removeChildAfter(before);
         forest.add(c);
       }
       recordSplitPoint(placeHolder, before, c);
       before = placeHolder;
     } else {
       split(c);
       before = c;
     }
     c = next;
   }
 }