/// <summary>
        /// Converts an IDataProducer into a lookup.
        /// </summary>
        /// <param name="elementSelector">A transform function to produce a result element value from each element.</param>
        /// <param name="keySelector">A function to extract a key from each element.</param>
        /// <param name="keyComparer">Used to compare keys.</param>
        /// <param name="source">The data source.</param>
        /// <remarks>This will force all values to be buffered</remarks>
        public static ILookup <TKey, TElement> ToLookup <TSource, TKey, TElement>(
            this IDataProducer <TSource> source,
            Func <TSource, TKey> keySelector, Func <TSource, TElement> elementSelector, IEqualityComparer <TKey> keyComparer)
        {
            source.ThrowIfNull("source");
            keySelector.ThrowIfNull("keySelector");
            elementSelector.ThrowIfNull("elementSelector");
            keyComparer.ThrowIfNull("keyComparer");

            EditableLookup <TKey, TElement> lookup = new EditableLookup <TKey, TElement>(keyComparer);

            source.DataProduced += t => lookup.Add(keySelector(t), elementSelector(t));
            source.EndOfData    += () => lookup.TrimExcess();
            return(lookup);
        }