code: @NotNull
      public List<String> extractGrams(@NotNull CharSequence text) {
          text = applyPadding(text);
          int len = text.length();
  
          //the actual size will be totalNumGrams or less (filter)
          int totalNumGrams = 0;
          for (Integer gramLength : gramLengths) {
              int num = len - (gramLength - 1);
              if (num >= 1) { //yes can be negative
                  totalNumGrams += num;
              }
          }
          if (totalNumGrams <= 0) {
              return Collections.emptyList();
          }
          List<String> grams = new ArrayList<>(totalNumGrams);
  
          for (Integer gramLength : gramLengths) {
              int numGrams = len - (gramLength -1);
              if (numGrams >= 1) { //yes can be negative
                  for (int pos=0; pos<numGrams; pos++) {
                      String gram = text.subSequence(pos, pos + gramLength).toString();
                      if (filter==null || filter.use(gram)) {
                          grams.add(gram);
                      }
                  }
              }
          }
          return grams;
      }
docs: Creates the n-grams for a given text in the order they occur.
  
  <p>Example: extractSortedGrams("Foo bar", 2) => [Fo,oo,o , b,ba,ar]</p>
  
  @param  text
  @return The grams, empty if the input was empty or if none for that gramLength fits.