private static T Reduce(IEnumerable <T> source, int sign)
        {
            Func <Pair <bool, T>, T, Pair <bool, T> > intermediateReduce = AggregationMinMaxHelpers <T> .MakeIntermediateReduceFunction(sign);

            Func <Pair <bool, T>, Pair <bool, T>, Pair <bool, T> > finalReduce = AggregationMinMaxHelpers <T> .MakeFinalReduceFunction(sign);

            Func <Pair <bool, T>, T> resultSelector = AggregationMinMaxHelpers <T> .MakeResultSelectorFunction();

            AssociativeAggregationOperator <T, Pair <bool, T>, T> @operator = new AssociativeAggregationOperator <T, Pair <bool, T>, T>(source, new Pair <bool, T>(false, default(T)), null, true, intermediateReduce, finalReduce, resultSelector, default(T) != null, QueryAggregationOptions.AssociativeCommutative);

            return(@operator.Aggregate());
        }
        //-----------------------------------------------------------------------------------
        // Helper method to find the minimum or maximum element in the source.
        //

        private static T Reduce(IEnumerable <T> source, int sign)
        {
            Contract.Assert(source != null);
            Contract.Assert(sign == -1 || sign == 1);

            Func <Pair <bool, T>, T, Pair <bool, T> > intermediateReduce       = MakeIntermediateReduceFunction(sign);
            Func <Pair <bool, T>, Pair <bool, T>, Pair <bool, T> > finalReduce = MakeFinalReduceFunction(sign);
            Func <Pair <bool, T>, T> resultSelector = MakeResultSelectorFunction();

            AssociativeAggregationOperator <T, Pair <bool, T>, T> aggregation =
                new AssociativeAggregationOperator <T, Pair <bool, T>, T>(source, new Pair <bool, T>(false, default(T)), null,
                                                                          true, intermediateReduce, finalReduce, resultSelector, default(T) != null, QueryAggregationOptions.AssociativeCommutative);

            return(aggregation.Aggregate());
        }