docs: public static GrammaticalStructure fromStringReps(List<String> tokens,
           List<String> posTags, List<String> deps) {
        if (tokens.size() != posTags.size()) {
           throw new RuntimeException(String.format(
                 "tokens.size(): %d != pos.size(): %d\n", tokens.size(), posTags
                       .size()));
        }
  
        List<TreeGraphNode> tgWordNodes = new ArrayList<TreeGraphNode>(tokens
              .size());
        List<TreeGraphNode> tgPOSNodes = new ArrayList<TreeGraphNode>(tokens
              .size());
        Iterator<String> tokensIter = tokens.iterator();
        Iterator<String> posIter = posTags.iterator();
  
        SemanticHeadFinder headFinder = new SemanticHeadFinder();
  
        while (tokensIter.hasNext()) {
           String wordString = tokensIter.next();
           String posString = posIter.next();
           TreeGraphNode word = new TreeGraphNode(new Word(wordString));
           TreeGraphNode pos = new TreeGraphNode(new Word(posString));
           tgWordNodes.add(word);
           tgPOSNodes.add(pos);
           TreeGraphNode[] childArr = { word };
           pos.setChildren(childArr);
           word.setParent(pos);
           pos.percolateHeads(headFinder);
        }
  
        TreeGraphNode root = new TreeGraphNode(new StringLabel("ROOT"));
  
        root
              .setChildren(tgPOSNodes
                    .toArray(new TreeGraphNode[tgPOSNodes.size()]));
  
        root.setIndex(0);
  
        // Build list of TypedDependencies
        List<TypedDependency> tdeps = new ArrayList<TypedDependency>(deps.size());
  
        for (String depString : deps) {
           int firstBracket = depString.indexOf('(');
           if (firstBracket == -1) throwDepFormatException(depString);
  
  
           String type = depString.substring(0, firstBracket);
  
           if (depString.charAt(depString.length() - 1) != ')') throwDepFormatException(depString);
  
           String args = depString.substring(firstBracket + 1,
                 depString.length() - 1);
  
           int argSep = args.indexOf(", ");
           if (argSep == -1) throwDepFormatException(depString);
  
           String parentArg = args.substring(0, argSep);
           String childArg  = args.substring(argSep + 2);
           int parentDash = parentArg.lastIndexOf('-');
           if (parentDash == -1) throwDepFormatException(depString);
           int childDash = childArg.lastIndexOf('-');
           if (childDash == -1) throwDepFormatException(depString);
           //System.err.printf("parentArg: %s\n", parentArg);
           int parentIdx = Integer.parseInt(parentArg.substring(parentDash+1).replace("'", ""));
  
           int childIdx = Integer.parseInt(childArg.substring(childDash+1).replace("'", ""));
  
           GrammaticalRelation grel = new GrammaticalRelation(GrammaticalRelation.Language.Any, type, null, null, DEPENDENT);
  
           TypedDependency tdep =
              new TypedDependency(grel, (parentIdx == 0 ? root: tgWordNodes.get(parentIdx-1)),
                                  tgWordNodes.get(childIdx-1));
           tdeps.add(tdep);
        }
  
        // TODO add some elegant way to construct language
        // appropriate GrammaticalStructures (e.g., English, Chinese, etc.)
        return new GrammaticalStructure(tdeps, root) {
           private static final long serialVersionUID = 1L;
        };
     }