docs: public static VariableNumPattern fromTemplateVariables(VariableNumMap templateVariables,
        VariableNumMap fixedVariables, DynamicVariableSet variableSet) {
      
      int[] plateStarts = new int[templateVariables.size()];
      int[] plateEnds = new int[templateVariables.size()];
      int[] plateReplicationSizes = new int[templateVariables.size()];
      int[] plateVarOffsets = new int[templateVariables.size()];
      int[] plateMatchIndexOffsets = new int[templateVariables.size()];
  
      int[] templateVariableNums = templateVariables.getVariableNumsArray();
      String[] templateVariableNames = templateVariables.getVariableNamesArray();
      for (int i = 0; i < templateVariableNums.length; i++) {
        String variableName = templateVariableNames[i];
        String[] parts = variableSet.partitionVariableName(variableName);
        
        Preconditions.checkArgument(parts.length == 3);
        String plateName = parts[0];
        int varOffset = Integer.parseInt(parts[1].replaceAll("[?()]", ""));
        String withinPlateVariableName = parts[2];
        
        plateStarts[i] = variableSet.getPlateStartIndex(plateName);
        plateEnds[i] = variableSet.getPlateEndIndex(plateName);
        plateReplicationSizes[i] = variableSet.getPlate(plateName).getMaximumPlateSize();
        plateVarOffsets[i] = variableSet.getPlate(plateName).getFixedVariables()
            .getVariableByName(withinPlateVariableName);
        plateMatchIndexOffsets[i] = varOffset;
      }
      
      // Normalize the index offsets so the maximum offset is 0.
      if (plateMatchIndexOffsets.length > 0) {
        int maxOffset = Ints.max(plateMatchIndexOffsets);
        for (int i = 0; i < plateMatchIndexOffsets.length; i++) {
          plateMatchIndexOffsets[i] -= maxOffset;
        }
      }
  
      return new VariableNumPattern(plateStarts, plateEnds, plateReplicationSizes, plateVarOffsets,
          plateMatchIndexOffsets, templateVariables, fixedVariables);
    }