/// <summary>
        /// Converts an IDataProducer into a future array.
        /// </summary>
        /// <remarks>This will force all values to be buffered</remarks>
        public static IFuture <TSource[]> ToFutureArray <TSource>(this IDataProducer <TSource> source)
        {
            source.ThrowIfNull("source");

            Future <TSource[]> ret  = new Future <TSource[]>();
            List <TSource>     list = source.ToList();

            source.EndOfData += () => ret.Value = list.ToArray();

            return(ret);
        }
        /// <summary>
        /// Converts an IDataProducer into an IEnumerable. The results
        /// are buffered in memory (as a list), so be warned that this loses the "streaming"
        /// nature of most of the IDataProducer extension methods. The list is returned
        /// immediately, but further data productions add to it. You must therefore be careful
        /// when the list is used - it is a good idea to only use it after all data has been
        /// produced.
        /// </summary>
        /// <remarks>This will force all values to be buffered</remarks>
        public static IEnumerable <TSource> AsEnumerable <TSource>(this IDataProducer <TSource> source)
        {
            source.ThrowIfNull("source");

            return(source.ToList());
        }