*/
  public static Pair<List<Tree>,List<Tree>> getAnnotatedBinaryTreebankFromTreebank(Treebank trainTreebank,
      Treebank tuneTreebank,
      Options op) {
    Timing.startTime();
    // setup tree transforms
    TreebankLangParserParams tlpParams = op.tlpParams;
    TreebankLanguagePack tlp = tlpParams.treebankLanguagePack();

    if (Test.verbose) {
      PrintWriter pwErr = tlpParams.pw(System.err);
      pwErr.print("Training ");
      pwErr.println(trainTreebank.textualSummary(tlp));
    }

    System.err.print("Binarizing trees...");
    TreeAnnotatorAndBinarizer binarizer;
    if (!Train.leftToRight) {
      binarizer = new TreeAnnotatorAndBinarizer(tlpParams, op.forceCNF, !Train.outsideFactor(), true);
    } else {
      binarizer = new TreeAnnotatorAndBinarizer(tlpParams.headFinder(), new LeftHeadFinder(), tlpParams, op.forceCNF, !Train.outsideFactor(), true);
    }
    CollinsPuncTransformer collinsPuncTransformer = null;
    if (Train.collinsPunc) {
      collinsPuncTransformer = new CollinsPuncTransformer(tlp);
    }
    List<Tree> binaryTrainTrees = new ArrayList<Tree>();
    List<Tree> binaryTuneTrees = new ArrayList<Tree>();

    if (Train.selectiveSplit) {
      Train.splitters = ParentAnnotationStats.getSplitCategories(trainTreebank, Train.tagSelectiveSplit, 0, Train.selectiveSplitCutOff, Train.tagSelectiveSplitCutOff, tlp);
      removeDeleteSplittersFromSplitters(tlp);
      if (Test.verbose) {
        List<String> list = new ArrayList<String>(Train.splitters);
        Collections.sort(list);
        System.err.println("Parent split categories: " + list);
      }
    }
    if (Train.selectivePostSplit) {
      // Do all the transformations once just to learn selective splits on annotated categories
      TreeTransformer myTransformer = new TreeAnnotator(tlpParams.headFinder(), tlpParams);
      Treebank annotatedTB = trainTreebank.transform(myTransformer);
      Train.postSplitters = ParentAnnotationStats.getSplitCategories(annotatedTB, true, 0, Train.selectivePostSplitCutOff, Train.tagSelectivePostSplitCutOff, tlp);
      if (Test.verbose) {
        System.err.println("Parent post annotation split categories: " + Train.postSplitters);
      }
    }
    if (Train.hSelSplit) {
      // We run through all the trees once just to gather counts for hSelSplit!
      int ptt = Train.printTreeTransformations;
      Train.printTreeTransformations = 0;
      binarizer.setDoSelectiveSplit(false);
      for (Tree tree : trainTreebank) {
        if (Train.collinsPunc) {
          tree = collinsPuncTransformer.transformTree(tree);
        }
        binarizer.transformTree(tree);
      }
      binarizer.setDoSelectiveSplit(true);
      Train.printTreeTransformations = ptt;
    }
    // we've done all the setup now. here's where the train treebank is transformed.
    for (Tree tree : trainTreebank) {
      if (Train.collinsPunc) {
        tree = collinsPuncTransformer.transformTree(tree);
      }
      tree = binarizer.transformTree(tree);
      if (tree.yield().size() - 1 <= trainLengthLimit) {
        // TEG: have to subtract off the boundary symbol!
        binaryTrainTrees.add(tree);
      }
    }
    if (Train.printAnnotatedStateCounts) {
      binarizer.printStateCounts();
    }
    if (Train.printAnnotatedRuleCounts) {
      binarizer.printRuleCounts();
    }

    if (tuneTreebank != null) {
      for (Tree tree : tuneTreebank) {
        if (Train.collinsPunc) {
          tree = collinsPuncTransformer.transformTree(tree);
        }
        tree = binarizer.transformTree(tree);
        if (tree.yield().size() - 1 <= trainLengthLimit) {
          binaryTuneTrees.add(tree);
        }
      }
    }

    Timing.tick("done.");
    if (Test.verbose) {
      binarizer.dumpStats();
    }

    return new Pair<List<Tree>,List<Tree>>(binaryTrainTrees, binaryTuneTrees);
  }