internal static PartitionedStream <T, int> PartitionDataSource <T>(IEnumerable <T> source, int partitionCount, bool useStriping)
        {
            IParallelPartitionable <T> partitionable = source as IParallelPartitionable <T>;

            if (partitionable != null)
            {
                QueryOperatorEnumerator <T, int>[] partitions = partitionable.GetPartitions(partitionCount);
                if (partitions == null)
                {
                    throw new InvalidOperationException(System.Linq.SR.GetString("ParallelPartitionable_NullReturn"));
                }
                if (partitions.Length != partitionCount)
                {
                    throw new InvalidOperationException(System.Linq.SR.GetString("ParallelPartitionable_IncorretElementCount"));
                }
                PartitionedStream <T, int> stream2 = new PartitionedStream <T, int>(partitionCount, Util.GetDefaultComparer <int>(), OrdinalIndexState.Correct);
                for (int i = 0; i < partitionCount; i++)
                {
                    QueryOperatorEnumerator <T, int> enumerator = partitions[i];
                    if (enumerator == null)
                    {
                        throw new InvalidOperationException(System.Linq.SR.GetString("ParallelPartitionable_NullElement"));
                    }
                    stream2[i] = enumerator;
                }
                return(stream2);
            }
            return(new PartitionedDataSource <T>(source, partitionCount, useStriping));
        }
        //-----------------------------------------------------------------------------------
        // A factory method to construct a partitioned stream over a data source.
        //
        // Arguments:
        //    source                      - the data source to be partitioned
        //    partitionCount              - the number of partitions desired
        //    useOrdinalOrderPreservation - whether ordinal position must be tracked
        //    useStriping                 - whether striped partitioning should be used instead of range partitioning
        //

        internal static PartitionedStream <T, int> PartitionDataSource <T>(IEnumerable <T> source, int partitionCount, bool useStriping)
        {
            // The partitioned stream to return.
            PartitionedStream <T, int> returnValue;

            IParallelPartitionable <T> sourceAsPartitionable = source as IParallelPartitionable <T>;

            if (sourceAsPartitionable != null)
            {
                // The type overrides the partitioning algorithm, so we will use it instead of the default.
                // The returned enumerator must be the same size that we requested, otherwise we throw.
                QueryOperatorEnumerator <T, int>[] enumerators = sourceAsPartitionable.GetPartitions(partitionCount);
                if (enumerators == null)
                {
                    throw new InvalidOperationException(SR.GetString(SR.ParallelPartitionable_NullReturn));
                }
                else if (enumerators.Length != partitionCount)
                {
                    throw new InvalidOperationException(SR.GetString(SR.ParallelPartitionable_IncorretElementCount));
                }

                // Now just copy the enumerators into the stream, validating that the result is non-null.
                PartitionedStream <T, int> stream =
                    new PartitionedStream <T, int>(partitionCount, Util.GetDefaultComparer <int>(), OrdinalIndexState.Correct);
                for (int i = 0; i < partitionCount; i++)
                {
                    QueryOperatorEnumerator <T, int> currentEnumerator = enumerators[i];
                    if (currentEnumerator == null)
                    {
                        throw new InvalidOperationException(SR.GetString(SR.ParallelPartitionable_NullElement));
                    }
                    stream[i] = currentEnumerator;
                }

                returnValue = stream;
            }
            else
            {
                returnValue = new PartitionedDataSource <T>(source, partitionCount, useStriping);
            }

            Contract.Assert(returnValue.PartitionCount == partitionCount);

            return(returnValue);
        }