docs: private AlignedExpressionTree decodeCfgParse(CfgParseTree t, int numAppliedArguments) {
      Preconditions.checkArgument(!t.getRoot().equals(ParametricCfgAlignmentModel.SKIP_EXPRESSION));
  
      if (t.isTerminal()) {
        // Expression tree spans have an exclusive end index.
        int[] spanStarts = new int[] {t.getSpanStart()};
        int[] spanEnds = new int[] {t.getSpanEnd() + 1};
        List<String> words = Lists.newArrayList();
        for (Object o : t.getTerminalProductions()) {
          words.add((String) o);
        }
        ExpressionNode root = ((ExpressionNode) t.getRoot());
        return AlignedExpressionTree.forTerminal(root.getExpression(), root.getType(), 
            numAppliedArguments, spanStarts, spanEnds, words);
      } else {
        ExpressionNode parent = ((ExpressionNode) t.getRoot());
        ExpressionNode left = ((ExpressionNode) t.getLeft().getRoot());
        ExpressionNode right = ((ExpressionNode) t.getRight().getRoot());
  
        if (left.equals(ParametricCfgAlignmentModel.SKIP_EXPRESSION)) {
          return decodeCfgParse(t.getRight(), numAppliedArguments);
        } else if (right.equals(ParametricCfgAlignmentModel.SKIP_EXPRESSION)) {
          return decodeCfgParse(t.getLeft(), numAppliedArguments);
        } else {
          // A combination of expressions.
          CfgParseTree argTree = null;
          CfgParseTree funcTree = null;
  
          // The argument's expression node must have 0 applied arguments
          // while the function's node must have > 0.
          if (left.getNumAppliedArguments() == 0) {
            // Thing on the right is the function
            funcTree = t.getRight();
            argTree = t.getLeft();
          } else if (right.getNumAppliedArguments() == 0) {
            // Thing on the left is the function
            funcTree = t.getLeft();
            argTree = t.getRight();
          }
  
          Preconditions.checkState(funcTree != null && argTree!= null, "Tree is broken %s", t); 
          
          AlignedExpressionTree leftTree = decodeCfgParse(argTree, 0);
          AlignedExpressionTree rightTree = decodeCfgParse(funcTree, numAppliedArguments + 1);
  
          return AlignedExpressionTree.forNonterminal(parent.getExpression(), parent.getType(), 
              numAppliedArguments, leftTree, rightTree);
        }
      }
    }