protected override async Task <bool> OnNextAsync(CancellationToken cancellationToken)
        {
            // if we are in a batch, iterate over it
            // if not, wait for the next batch

            while (!cancellationToken.IsCancellationRequested)
            {
                if (m_batch == null)
                {
                    if (!await m_iterator.MoveNextAsync(cancellationToken).ConfigureAwait(false))
                    {                     // inner completed
                        return(Completed());
                    }

                    if (cancellationToken.IsCancellationRequested)
                    {
                        break;
                    }

                    IEnumerable <TResult> sequence;
                    if (!m_selector.Async)
                    {
                        sequence = m_selector.Invoke(m_iterator.Current);
                    }
                    else
                    {
                        sequence = await m_selector.InvokeAsync(m_iterator.Current, cancellationToken).ConfigureAwait(false);
                    }
                    if (sequence == null)
                    {
                        throw new InvalidOperationException("The inner sequence returned a null collection");
                    }

                    m_batch = sequence.GetEnumerator();
                    Contract.Assert(m_batch != null);
                }

                if (!m_batch.MoveNext())
                {                 // the current batch is exhausted, move to the next
                    m_batch.Dispose();
                    m_batch = null;
                    continue;
                }

                return(Publish(m_batch.Current));
            }

            return(Canceled(cancellationToken));
        }
        protected override async Task <bool> OnNextAsync(CancellationToken cancellationToken)
        {
            if (m_remaining != null && m_remaining.Value <= 0)
            {             // reached limit!
                return(Completed());
            }

            while (!cancellationToken.IsCancellationRequested)
            {
                if (!await m_iterator.MoveNext(cancellationToken).ConfigureAwait(false))
                {                 // completed
                    return(Completed());
                }
                if (cancellationToken.IsCancellationRequested)
                {
                    break;
                }

                #region Filtering...

                TSource current = m_iterator.Current;
                if (m_filter != null)
                {
                    if (!m_filter.Async)
                    {
                        if (!m_filter.Invoke(current))
                        {
                            continue;
                        }
                    }
                    else
                    {
                        if (!await m_filter.InvokeAsync(current, cancellationToken).ConfigureAwait(false))
                        {
                            continue;
                        }
                    }
                }

                #endregion

                #region Skipping...

                if (m_skipped != null)
                {
                    if (m_skipped.Value > 0)
                    {                     // skip this result
                        m_skipped = m_skipped.Value - 1;
                        continue;
                    }
                    // we can now start outputing results...
                    m_skipped = null;
                }

                #endregion

                #region Transforming...

                TResult result;
                if (!m_transform.Async)
                {
                    result = m_transform.Invoke(current);
                }
                else
                {
                    result = await m_transform.InvokeAsync(current, cancellationToken).ConfigureAwait(false);
                }

                #endregion

                #region Publishing...

                if (m_remaining != null)
                {                 // decrement remaining quota
                    m_remaining = m_remaining.Value - 1;
                }

                return(Publish(result));

                #endregion
            }

            return(Canceled(cancellationToken));
        }