/// <inheritdoc />
        public Task <AcquireWriteResult> AcquireWriteAsync(int desiredSpace, CancellationToken ctoken)
        {
            if (desiredSpace < 1)
            {
                return(Task.FromResult <AcquireWriteResult>(new AcquireWriteFaulted(new ArgumentOutOfRangeException("desiredSpace", "Must be at least one"))));
            }

            if (ctoken.IsCancellationRequested)
            {
                return(Task.FromResult <AcquireWriteResult>(new AcquireWriteCancelled()));
            }
            else
            {
                lock (syncRoot) {
                    if (eofSignaled)
                    {
                        return(Task.FromResult <AcquireWriteResult>(new AcquireWriteFaulted(new InvalidOperationException("Can't acquire for write after EOF has been signaled"))));
                    }
                    else if (!writeLocked.HasValue && (!capacity.HasValue || (capacity.Value - items.Count) >= desiredSpace))
                    {
                        writeLocked = desiredSpace;
                        return(Task.FromResult <AcquireWriteResult>(new AcquireWriteSucceeded(readPtr + items.Count, desiredSpace)));
                    }
                    else if (capacity.HasValue && desiredSpace > capacity.Value)
                    {
                        return(Task.FromResult <AcquireWriteResult>(
                                   new AcquireWriteFaulted(new InvalidOperationException("Attempting to acquire more space than will ever become available"))));
                    }
                    else
                    {
                        TaskCompletionSource <AcquireWriteResult> k = new TaskCompletionSource <AcquireWriteResult>();

                        WaitingWrite ww = new WaitingWrite()
                        {
                            id           = null,
                            desiredSpace = desiredSpace,
                            k            = k,
                            ctr          = null
                        };

                        long id = waitingWrites.Enqueue(ww);
                        ww.id = id;

                        ctoken.PostRegistration(ctr => SetRegistrationForAcquireWrite(id, ctr), () => CancelAcquireWrite(id));

                        return(k.Task);
                    }
                }
            }
        }
        private void CheckWaitingWrites()
        {
            if (!writeLocked.HasValue && waitingWrites.Count > 0)
            {
                WaitingWrite ww = waitingWrites.Peek();

                System.Diagnostics.Debug.Assert(capacity.HasValue, "If there is no capacity limit, there should never be any waiting writes");

                // ReSharper disable once PossibleInvalidOperationException
                if (capacity.Value - items.Count >= ww.desiredSpace)
                {
                    waitingWrites.Dequeue();

                    writeLocked = ww.desiredSpace;

                    ww.k.PostResult(new AcquireWriteSucceeded(readPtr + items.Count, ww.desiredSpace));
                    if (ww.ctr.HasValue)
                    {
                        ww.ctr.Value.PostDispose();
                    }
                }
            }
        }