Iterable<T> (final @NotNull Iterable<? extends T> source, final @NotNull ProcessingContext context) { List<T> nulls = null; TreeMap<Comparable, List<T>> map = new TreeMap<>(); for (T t : source) { final Comparable weight = getWeight(t, context); if (weight == null) { if (nulls == null) nulls = new SmartList<>(); nulls.add(t); } else { List<T> list = map.get(weight); if (list == null) { map.put(weight, list = new SmartList<>()); } list.add(t); } } final List<List<T>> values = new ArrayList<>(myNegated ? map.descendingMap().values() : map.values()); ContainerUtil.addIfNotNull(values, nulls); return new Iterable<>() { @Override public Iterator<T> iterator() { return new FlatteningIterator<>(values.iterator()) { @Override protected Iterator<T> createValueIterator(List<T> group) { return myNext.classify(group, context).iterator(); } }; } }; }