protected final ParserData getParserDataFromTreebank(Treebank trainTreebank, DiskTreebank secondaryTrainTreebank, double weight, GrammarCompactor compactor) {
    System.err.println("Currently " + new Date());
    printOptions(true, 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));
      pwErr.print("Secondary training ");
      pwErr.println(secondaryTrainTreebank.textualSummary(tlp));
    }

    CompositeTreeTransformer trainTransformer = new CompositeTreeTransformer();

    if (Train.collinsPunc) {
      CollinsPuncTransformer collinsPuncTransformer = new CollinsPuncTransformer(tlp);
      trainTransformer.addTransformer(collinsPuncTransformer);
    }

    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);
    }
    trainTransformer.addTransformer(binarizer);

    CompositeTreebank wholeTreebank = new CompositeTreebank(trainTreebank, secondaryTrainTreebank);
    if (Train.selectiveSplit) {
      Train.splitters = ParentAnnotationStats.getSplitCategories(wholeTreebank, 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);
      }
    }

    Treebank transformedWholeTreebank = wholeTreebank;

    if (Train.selectivePostSplit) {
      // Do all the transformations once just to learn selective splits on annotated categories
      TreeTransformer annotator = new TreeAnnotator(tlpParams.headFinder(), tlpParams);
      //wholeTreebank.transformOnRead(annotator);
      transformedWholeTreebank = transformedWholeTreebank.transform(annotator);
      Train.postSplitters = ParentAnnotationStats.getSplitCategories(transformedWholeTreebank, 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 : transformedWholeTreebank) {
        trainTransformer.transformTree(tree);
      }
      binarizer.setDoSelectiveSplit(true);
      Train.printTreeTransformations = ptt;
    }

    trainTreebank = trainTreebank.transform(trainTransformer);
    //secondaryTrainTreebank.transformOnRead(trainTransformer);
    Treebank transformedSecondaryTrainTreebank = secondaryTrainTreebank.transform(trainTransformer);

    // extract grammars
    BinaryGrammarExtractor bgExtractor = new BinaryGrammarExtractor();
    // Extractor lexExtractor = new LexiconExtractor();
    AbstractTreeExtractor<DependencyGrammar> dgExtractor = new MLEDependencyGrammarExtractor(op);
    //TreeExtractor uwmExtractor = new UnknownWordModelExtractor(binaryTrainTrees.size());
    System.err.print("Extracting PCFG...");
    Pair<UnaryGrammar,BinaryGrammar> bgug = bgExtractor.extract(trainTreebank, transformedSecondaryTrainTreebank, weight);
    Timing.tick("done.");
    if (compactor != null) {
      System.err.print("Compacting grammar...");
      bgug = compactor.compactGrammar(bgug);
      Timing.tick("done.");
    }
    System.err.print("Compiling grammar...");
    BinaryGrammar bg = bgug.second;
    bg.splitRules();
    UnaryGrammar ug = bgug.first;
    ug.purgeRules();
    Timing.tick("done");
    System.err.print("Extracting Lexicon...");
    Lexicon lex = op.tlpParams.lex(op.lexOptions);
    // lex.train(wholeTreebank);
    //    lex.train(trainTreebank);
    //    ((BaseLexicon)lex).train(secondaryTrainTreebank, weight);
    // todo. BUG: With this implementation the lexicon is always trained with the
    // secondaryTreebank having a weight of 1.0.  But at least the code now is basically
    // correct rather than totally broken.  CDM Dec 2006.
    CompositeTreebank wholeBinaryTreebank = new CompositeTreebank(trainTreebank, transformedSecondaryTrainTreebank);
    lex.train(wholeBinaryTreebank);
    Timing.tick("done.");

    DependencyGrammar dg = null;
    if (op.doDep) {
      System.err.print("Extracting Dependencies...");
      dg = dgExtractor.extract(trainTreebank, transformedSecondaryTrainTreebank, weight);
      Timing.tick("done.");
    }
    Map<String,Numberer> numbs = Numberer.getNumberers();

    System.err.println("Done training parser.");
    return new ParserData(lex, bg, ug, dg, numbs, op);
  }