// This partitioner that is simpler than the general case (don't use a list) is called in the case
        // of initialPartitionSize == partitionMultiplier == 1
        IEnumerator <KeyValuePair <long, T> > GetPartitionEnumeratorSimple(IEnumerator <T> src,
                                                                           PartitionerState state,
                                                                           bool last)
        {
            long index = -1;
            var  value = default(T);

            try
            {
                do
                {
                    lock (state.SyncLock)
                    {
                        if (!src.MoveNext())
                        {
                            break;
                        }

                        index = state.Index++;
                        value = src.Current;
                    }

                    yield return(new KeyValuePair <long, T> (index, value));
                }while (true);
            }
            finally
            {
                if (last)
                {
                    src.Dispose();
                }
            }
        }
        public override IList <IEnumerator <KeyValuePair <long, T> > > GetOrderablePartitions(int partitionCount)
        {
            if (partitionCount <= 0)
            {
                throw new ArgumentOutOfRangeException("partitionCount");
            }

            IEnumerator <KeyValuePair <long, T> >[] enumerators
                = new IEnumerator <KeyValuePair <long, T> > [partitionCount];

            PartitionerState state    = new PartitionerState();
            IEnumerator <T>  src      = source.GetEnumerator();
            bool             isSimple = initialPartitionSize == 1 && partitionMultiplier == 1;

            for (int i = 0; i < enumerators.Length; i++)
            {
                enumerators[i] = isSimple ? GetPartitionEnumeratorSimple(src, state, i == enumerators.Length - 1) : GetPartitionEnumerator(src, state);
            }

            return(enumerators);
        }
        IEnumerator <KeyValuePair <long, T> > GetPartitionEnumerator(IEnumerator <T> src, PartitionerState state)
        {
            int      count = initialPartitionSize;
            List <T> list  = new List <T> ();

            while (true)
            {
                list.Clear();
                long ind = -1;

                lock (state.SyncLock)
                {
                    ind = state.Index;

                    for (int i = 0; i < count; i++)
                    {
                        if (!src.MoveNext())
                        {
                            if (list.Count == 0)
                            {
                                yield break;
                            }
                            else
                            {
                                break;
                            }
                        }

                        list.Add(src.Current);
                        state.Index++;
                    }
                }

                for (int i = 0; i < list.Count; i++)
                {
                    yield return(new KeyValuePair <long, T> (ind + i, list[i]));
                }

                count *= partitionMultiplier;
            }
        }