//-----------------------------------------------------------------------------------
        // Positions the enumerator over the next element. This includes merging as we
        // enumerate, by just incrementing indexes, etc.
        //
        // Return Value:
        //     True if there's a current element, false if we've reached the end.
        //

        public override bool MoveNext()
        {
            Debug.Assert(_channels != null);

            // If we're at the start, initialize the index.
            if (_channelIndex == -1)
            {
                _channelIndex = 0;
            }

            // If the index has reached the end, we bail.
            while (_channelIndex != _channels.Length)
            {
                SynchronousChannel <T> current = _channels[_channelIndex];
                Debug.Assert(current != null);

                if (current.Count == 0)
                {
                    // We're done with this channel, move on to the next one. We don't
                    // have to check that it's "done" since this is a synchronous consumer.
                    _channelIndex++;
                }
                else
                {
                    // Remember the "current" element and return.
                    _currentElement = current.Dequeue();
                    return(true);
                }
            }

            TraceHelpers.TraceInfo("[timing]: {0}: Completed the merge", DateTime.Now.Ticks);

            // If we got this far, it means we've exhausted our channels.
            Debug.Assert(_channelIndex == _channels.Length);

            return(false);
        }
 internal StopAndGoSpoolingTask(int taskIndex, QueryTaskGroupState groupState, QueryOperatorEnumerator <TInputOutput, TIgnoreKey> source, SynchronousChannel <TInputOutput> destination) : base(taskIndex, groupState)
 {
     this.m_source      = source;
     this.m_destination = destination;
 }