private List<Integer> lowerBounds(List<GrammarProductionElement> elems, int bound) {
   List<Integer> lowerBounds = new ArrayList<Integer>(elems.size());
   for (GrammarProductionElement grammarProductionElement : elems) {
     if (grammarProductionElement.getKind() == GrammarElementKind.GTERMINAL) {
       if (terms_are_single_char) {
         lowerBounds.add(1);
       } else {
         TerminalElement term = (TerminalElement) grammarProductionElement;
         lowerBounds.add(term.getNameNoQuotes().length());
       }
     } else {
       boolean canBeEmpty =
           grammarProductionElement.getKind() == GrammarElementKind.GNONTERMINAL
               && grammarProductionElement
                   .getGrammar()
                   .containsEpsilonProduction(grammarProductionElement.toString());
       lowerBounds.add(canBeEmpty ? 0 : 1);
     }
   }
   return lowerBounds;
 }