/// <summary>
        /// Return a message or null if timout passes without a complete message ending with Eof can be found
        /// </summary>
        /// <param name="cancelationToken"></param>
        /// <returns></returns>
        public async Task <IncomingMessage> ReadAsync(CancellationToken cancelationToken)
        {
            // at start, some left overs might still be at the begining of the buffer,
            // currentIndex can therefore be greater than 0
            byte[] eof = { 0x0D, 0x0A };

            var eofMatchCharCount = 0;

            while (eofMatchCharCount < eof.Length)
            {
                var byteCount = await _byteStream.ReadAsync(_buffer, _currentBufferIndex, BufferSize - _currentBufferIndex, cancelationToken);

                if (byteCount <= 0)
                {
                    return(null);
                }

                _currentBufferIndex += byteCount;
                while (eofMatchCharCount < eof.Length && byteCount > 0)
                {
                    if (_buffer[_currentBufferIndex - byteCount] == eof[eofMatchCharCount])
                    {
                        eofMatchCharCount++;
                    }
                    else
                    {
                        eofMatchCharCount = 0;
                    }
                    byteCount--;
                }

                if (eofMatchCharCount != eof.Length)
                {
                    continue;
                }

                var msgBytes = new byte[_currentBufferIndex - byteCount];
                for (var i = 0; i < _currentBufferIndex - byteCount; i++)
                {
                    msgBytes[i] = _buffer[i];
                }

                var parser = _parserFactory.Create(msgBytes);
                var msg    = parser.Parse(msgBytes);
                for (var i = 0; i < byteCount; i++)
                {
                    _buffer[i] = _buffer[_currentBufferIndex - byteCount + i];
                }
                _currentBufferIndex = byteCount;
                return(msg);
            }
            return(null);
        }