private static IOrderedDataProducer <TSource> OrderBy <TSource, TKey>(IDataProducer <TSource> source, DotNet20.Func <TSource, TKey> selector, IComparer <TKey> comparer, bool descending)
        {
            source.ThrowIfNull("source");
            comparer.ThrowIfNull("comparer");

            IComparer <TSource> itemComparer = new ProjectionComparer <TSource, TKey>(selector, comparer);

            if (descending)
            {
                itemComparer = itemComparer.Reverse();
            }

            // first, discard any existing "order by"s by going back to the producer
            IOrderedDataProducer <TSource> orderedProducer;
            bool first = true;

            while ((orderedProducer = source as IOrderedDataProducer <TSource>) != null)
            {
                if (first)
                {
                    // keep the top-most comparer to enforce a balanced sort
                    itemComparer = new LinkedComparer <TSource>(itemComparer, orderedProducer.Comparer);
                    first        = false;
                }
                source = orderedProducer.BaseProducer;
            }
            return(new OrderedDataProducer <TSource>(source, itemComparer));
        }
        private static IOrderedDataProducer <TSource> ThenBy <TSource, TKey>(IOrderedDataProducer <TSource> source, DotNet20.Func <TSource, TKey> selector, IComparer <TKey> comparer, bool descending)
        {
            comparer.ThrowIfNull("comparer");
            IComparer <TSource> itemComparer = new ProjectionComparer <TSource, TKey>(selector, comparer);

            if (descending)
            {
                itemComparer = itemComparer.Reverse();
            }
            itemComparer = new LinkedComparer <TSource>(source.Comparer, itemComparer);
            return(new OrderedDataProducer <TSource>(source, itemComparer));
        }