code: public <A> void match(Map<A,? extends Collection<I>> samples, BiConsumer<T, A> consumer)
      {
          Map<A,Collection<I>> m = new HashMap<>(samples);
          boolean cont = true;
          while (cont)
          {
              cont = false;
              Iterator<Entry<A, Collection<I>>> iterator = m.entrySet().iterator();
              while (iterator.hasNext())
              {
                  Entry<A, Collection<I>> e = iterator.next();
                  T match = match(e.getValue());
                  if (match != null)
                  {
                      consumer.accept(match, e.getKey());
                      cont = true;
                      iterator.remove();
                  }
              }
          }
      }
docs: Matches A objects to T targets. Each A is mapped to subset of items. Each
  match is passed to consumer. Map is traversed as long as there are matches.
  Each match will remove targets mappings.
  @param <A>
  @param samples
  @param consumer