private void NextHandler(Task <bool> t)
            {
                if (t.IsFaulted)
                {
                    ExceptionHelper.AddException(ref _error, ExceptionHelper.Extract(t.Exception));
                    _done = true;
                    if (TryDispose())
                    {
                        Signal();
                    }
                }
                else if (t.Result)
                {
                    IAsyncEnumerator <TResult> src;
                    try
                    {
                        src = _mapper(_source.Current).GetAsyncEnumerator();
                    }
                    catch (Exception ex)
                    {
                        ExceptionHelper.AddException(ref _error, ex);
                        _done = true;
                        Dispose(_source);
                        Signal();
                        return;
                    }

                    if (TryDispose())
                    {
                        Interlocked.Increment(ref _allDisposeWip);
                        var inner = new InnerHandler(src, this);

                        for (; ;)
                        {
                            var curr = Volatile.Read(ref _current);
                            if (curr == DisposedInnerHandler)
                            {
                                inner.Dispose();
                                break;
                            }
                            if (Interlocked.CompareExchange(ref _current, inner, curr) == curr)
                            {
                                curr?.Dispose();
                                inner.MoveNext();
                                MoveNext();
                                return;
                            }
                        }
                    }
                }
                else
                {
                    _done = true;
                    if (TryDispose())
                    {
                        Signal();
                    }
                }
            }
            private void Handle(Task <bool> task)
            {
                if (task.IsCanceled)
                {
                    AddException(new OperationCanceledException());
                    _done = true;
                    if (TryDispose())
                    {
                        Signal();
                    }
                }
                else if (task.IsFaulted)
                {
                    AddException(task.Exception);
                    _done = true;
                    if (TryDispose())
                    {
                        Signal();
                    }
                }
                else
                {
                    if (task.Result)
                    {
                        var v = _source.Current;

                        if (TryDispose())
                        {
                            var cts = CancellationTokenSource.CreateLinkedTokenSource(_sourceCTS.Token);
                            IAsyncEnumerator <TResult> innerSource;
                            try
                            {
                                innerSource = _mapper(v)
                                              .GetAsyncEnumerator(cts.Token);
                            }
                            catch (Exception ex)
                            {
                                _source.DisposeAsync();

                                AddException(ex);
                                _done = true;
                                Signal();
                                return;
                            }

                            var handler = new InnerHandler(this, innerSource, _prefetch, cts);
                            Interlocked.Increment(ref _allDisposeWip);
                            if (Add(handler))
                            {
                                handler.MoveNext();

                                if (Interlocked.Decrement(ref _outstanding) != 0)
                                {
                                    MoveNext();
                                }
                            }
                            else
                            {
                                // This will decrement _allDisposeWip so
                                // that the DisposeAsync() can be released eventually
                                DisposeOne();
                            }
                        }
                    }
                    else
                    {
                        _done = true;
                        if (TryDispose())
                        {
                            Signal();
                        }
                    }
                }
            }
            private void NextHandler(Task <bool> t)
            {
                if (t.IsFaulted)
                {
                    ExceptionHelper.AddException(ref _error, ExceptionHelper.Extract(t.Exception));
                    _sourceDone = true;
                    if (TryDispose())
                    {
                        ResumeHelper.Resume(ref _resume);
                    }
                }
                else if (t.Result)
                {
                    var cts = CancellationTokenSource.CreateLinkedTokenSource(_ct);
                    IAsyncEnumerator <TResult> src;
                    try
                    {
                        src = _mapper(_source.Current).GetAsyncEnumerator(cts.Token);
                    }
                    catch (Exception ex)
                    {
                        ExceptionHelper.AddException(ref _error, ex);
                        _sourceDone = true;
                        src         = null;
                        if (TryDispose())
                        {
                            ResumeHelper.Resume(ref _resume);
                            return;
                        }
                    }

                    if (src != null)
                    {
                        Interlocked.Increment(ref _disposeWip);
                        var inner = new InnerHandler(src, this, cts);
                        _inners.Enqueue(inner);

                        if (_disposeRequested)
                        {
                            while (_inners.TryDequeue(out var inner2))
                            {
                                inner2.Dispose();
                            }
                        }

                        if (TryDispose())
                        {
                            inner.MoveNext();
                            if (Interlocked.Decrement(ref _sourceOutstanding) != 0)
                            {
                                MoveNextSource();
                            }
                            ResumeHelper.Resume(ref _resume);
                        }
                    }
                }
                else
                {
                    _sourceDone = true;
                    if (TryDispose())
                    {
                        ResumeHelper.Resume(ref _resume);
                    }
                }
            }