/// <summary>
        /// Buffered receive
        /// </summary>
        /// <param name="buffer"></param>
        /// <param name="ct"></param>
        /// <returns></returns>
        public override Task <ProxyAsyncResult> ReceiveAsync(
            ArraySegment <byte> buffer, CancellationToken ct)
        {
            if (buffer.Count == 0)
            {
                return(Task.FromResult(new ProxyAsyncResult()));
            }

            if (_lastData != null)
            {
                int copied = CopyBuffer(ref buffer);
                if (copied > 0)
                {
                    if (_lastRead == null || _lastRead.Result.Count != copied)
                    {
                        var result = new ProxyAsyncResult();
                        result.Count = copied;
                        _lastRead    = Task.FromResult(result);
                    }
                    return(_lastRead);
                }
            }
            _lastRead = ReceiveInternalAsync(buffer, ct);
            return(_lastRead);
        }
        /// <summary>
        /// Receive using async state machine
        /// </summary>
        /// <param name="buffer"></param>
        /// <param name="ct"></param>
        /// <returns></returns>
        public async Task <ProxyAsyncResult> ReceiveInternalAsync(
            ArraySegment <byte> buffer, CancellationToken ct)
        {
            var result = new ProxyAsyncResult();

            while (true)
            {
                if (_lastData == null)
                {
                    // Get new data
                    _lastData = await ReceiveAsync(ct).ConfigureAwait(false);

                    _offset = 0;

                    // Disconnect, break
                    if (_lastData == null)
                    {
                        break;
                    }

                    // Break on 0 sized packets
                    if (_lastData.Payload.Length == 0)
                    {
                        _lastData = null;
                        break;
                    }
#if PERF
                    _transferred      += _lastData.Payload.Length;
                    Console.CursorLeft = 0; Console.CursorTop = 0;
                    Console.WriteLine(
                        $"{ _transferred / _transferredw.ElapsedMilliseconds} kB/sec");
#endif
                }
                result.Count = CopyBuffer(ref buffer);
                if (result.Count > 0)
                {
                    break;
                }
            }
            return(result);
        }