private Tree getTree(Vertex v, int k, int kPrime) {
    lazyKthBest(v, k, kPrime);
    String goalStr = (String)stateNumberer.object(v.goal);
    int start = v.start;
    // int end = v.end;

    List<Derivation> dHatV = dHat.get(v);

    if (isTag[v.goal]) {
      IntTaggedWord tagging = new IntTaggedWord(words[start], tagNumberer.number(goalStr));
      float tagScore = lex.score(tagging, start);
      if (tagScore > Float.NEGATIVE_INFINITY || floodTags) {
        // return a pre-terminal tree
        CoreLabel terminalLabel = getCoreLabel(start);
        
        Tree wordNode = tf.newLeaf(terminalLabel);
        Tree tagNode = tf.newTreeNode(goalStr, Collections.singletonList(wordNode));
        if(tagNode instanceof HasTag)
          ((HasTag) tagNode.label()).setTag(goalStr);

        return tagNode;
      } else {
        assert false;
      }
    }

    if (k-1 >= dHatV.size()) {
      return null;
    }

    Derivation d = dHatV.get(k-1);

    List<Tree> children = new ArrayList<Tree>();
    for (int i = 0; i < d.arc.size(); i++) {
      Vertex child = d.arc.tails.get(i);
      Tree t = getTree(child, d.j.get(i), kPrime);
      assert (t != null);
      children.add(t);
    }

    return tf.newTreeNode(goalStr,children);
  }