docs: public static ParametricFactorGraph buildSequenceModel(Iterable<String> emissionFeatureLines,
        String featureDelimiter) {
      // Read in the possible values of each variable.
      List<String> words = StringUtils.readColumnFromDelimitedLines(emissionFeatureLines, 0, featureDelimiter);
      List<String> labels = StringUtils.readColumnFromDelimitedLines(emissionFeatureLines, 1, featureDelimiter);
      List<String> emissionFeatures = StringUtils.readColumnFromDelimitedLines(emissionFeatureLines, 2, featureDelimiter);
      // Create dictionaries for each variable's values.
      DiscreteVariable wordType = new DiscreteVariable("word", words);
      DiscreteVariable labelType = new DiscreteVariable("label", labels);
      DiscreteVariable emissionFeatureType = new DiscreteVariable("emissionFeature", emissionFeatures);
  
      // Create a dynamic factor graph with a single plate replicating
      // the input/output variables.
      ParametricFactorGraphBuilder builder = new ParametricFactorGraphBuilder();
      builder.addPlate(PLATE_NAME, new VariableNumMap(Ints.asList(1, 2),
          Arrays.asList(INPUT_NAME, OUTPUT_NAME), Arrays.asList(wordType, labelType)), 10000);
      String inputPattern = PLATE_NAME + "/?(0)/" + INPUT_NAME;
      String outputPattern = PLATE_NAME + "/?(0)/" + OUTPUT_NAME;
      String nextOutputPattern = PLATE_NAME + "/?(1)/" + OUTPUT_NAME;
      VariableNumMap plateVars = new VariableNumMap(Ints.asList(1, 2),
          Arrays.asList(inputPattern, outputPattern), Arrays.asList(wordType, labelType));
  
      // Read in the emission features (for the word/label weights).
      VariableNumMap x = plateVars.getVariablesByName(inputPattern);
      VariableNumMap y = plateVars.getVariablesByName(outputPattern);
      VariableNumMap emissionFeatureVar = VariableNumMap.singleton(0, "emissionFeature", emissionFeatureType);
      TableFactor emissionFeatureFactor = TableFactor.fromDelimitedFile(
          Arrays.asList(x, y, emissionFeatureVar), emissionFeatureLines,
          featureDelimiter, false, SparseTensorBuilder.getFactory())
          .cacheWeightPermutations();
  
      System.out.println(emissionFeatureFactor.getVars());
  
      // Add a parametric factor for the word/label weights
      DiscreteLogLinearFactor emissionFactor = new DiscreteLogLinearFactor(x.union(y), emissionFeatureVar,
          emissionFeatureFactor);
      builder.addFactor(WORD_LABEL_FACTOR, emissionFactor,
          VariableNamePattern.fromTemplateVariables(plateVars, VariableNumMap.EMPTY));
  
      // Create a factor connecting adjacent labels
      VariableNumMap adjacentVars = new VariableNumMap(Ints.asList(0, 1),
          Arrays.asList(outputPattern, nextOutputPattern), Arrays.asList(labelType, labelType));
      builder.addFactor(TRANSITION_FACTOR, DiscreteLogLinearFactor.createIndicatorFactor(adjacentVars),
          VariableNamePattern.fromTemplateVariables(adjacentVars, VariableNumMap.EMPTY));
  
      return builder.build();
    }