code: public static void explode (final char cSep,
                                @Nullable final String sElements,
                                final int nMaxItems,
                                @Nonnull final Consumer <? super String> aConsumer)
    {
      ValueEnforcer.notNull (aConsumer, "Consumer");
  
      if (nMaxItems == 1)
        aConsumer.accept (sElements);
      else
        if (hasText (sElements))
        {
          // Do not use RegExPool.stringReplacePattern because of package
          // dependencies
          // Do not use String.split because it trims empty tokens from the end
          int nStartIndex = 0;
          int nMatchIndex;
          int nItemsAdded = 0;
          while ((nMatchIndex = sElements.indexOf (cSep, nStartIndex)) >= 0)
          {
            aConsumer.accept (sElements.substring (nStartIndex, nMatchIndex));
            // 1 == length of separator char
            nStartIndex = nMatchIndex + 1;
            ++nItemsAdded;
            if (nMaxItems > 0 && nItemsAdded == nMaxItems - 1)
            {
              // We have exactly one item the left: the rest of the string
              break;
            }
          }
          aConsumer.accept (sElements.substring (nStartIndex));
        }
    }
docs: Split the provided string by the provided separator and invoke the consumer
  for each matched element. The maximum number of elements can be specified.
  
  @param cSep
  The separator to use.
  @param sElements
  The concatenated String to convert. May be <code>null</code> or empty.
  @param nMaxItems
  The maximum number of items to explode. If the passed value is &le; 0
  all items are used. If max items is 1, than the result string is
  returned as is. If max items is larger than the number of elements
  found, it has no effect.
  @param aConsumer
  The non-<code>null</code> consumer that is invoked for each exploded
  element