public GroupedItems <T, K, I> GroupItems(IEnumerable <T> items) { List <I> nullTo = null; List <Pair <I, T> > nonKeyTo = null; IDictionary <K, IList <Pair <I, T> > > groupItems = null; // Perform grouping if (CollectionUtil.IsNotNullOrEmpty(items)) { int i = 0; foreach (var item in items) { I index = indexCreator(item, i++); // register any nulls if (item == null) { if (nullTo == null) { nullTo = new List <I>(); } nullTo.Add(index); } else { K key = keyCreator(item); if (key == null) { // register null key if (nonKeyTo == null) { nonKeyTo = new List <Pair <I, T> >(); } nonKeyTo.Add(new Pair <I, T>(index, item)); } else { // register keyed item if (groupItems == null) { groupItems = new Dictionary <K, IList <Pair <I, T> > >(); } CollectionUtil.AddToMappedList(groupItems, key, new Pair <I, T>(index, item)); } } } } return(new GroupedItems <T, K, I>() { NullItems = nullTo ?? Immutable.ReadOnlyList <I>(), NullKeyItems = nonKeyTo ?? Immutable.ReadOnlyList <Pair <I, T> >(), GroupItems = groupItems ?? Immutable.Dictionary <K, IList <Pair <I, T> > >() }); }