/// <summary>
        /// Get parsed messages from FileZilla admin interface
        /// </summary>
        /// <returns></returns>
        public FileZillaMessage[] ReceiveMessages()
        {
            var data = Receive();
            var list = new List <FileZillaMessage>();

            using (var memoryStream = new MemoryStream())
            {
                memoryStream.Append(data);
                using (var reader = new BinaryReader(memoryStream))
                {
                    while (reader.BaseStream.Position < reader.BaseStream.Length)
                    {
                        var b     = reader.ReadByte();
                        var count = reader.ReadInt32();

                        while ((reader.BaseStream.Length - reader.BaseStream.Position) < count)
                        {
                            var buffer = Receive();
                            memoryStream.Append(buffer);
                        }

                        byte[] payload = reader.ReadBytes(count);
                        var    message = new FileZillaMessage((MessageOrigin)(b & 0x3), (MessageType)(b >> 2), payload, ProtocolVersion);
                        list.Add(message);
                    }
                }
            }
            return(list.ToArray());
        }
        /// <summary>
        /// Handle unmatched messages when calling ReceiveMessage method. Override to provide your own implementation (e.g. for logging)
        /// </summary>
        /// <param name="messageType">messageType sought</param>
        /// <param name="message">actual message</param>
        /// <returns>True if message can safely be ignored, False if message reception should be terminated.</returns>
        protected virtual bool HandleUnmatchedMessage(MessageType messageType, FileZillaMessage message)
        {
#if DEBUG
            LogData(string.Format("Unmatched message: {0}/{1} with length {2}", message.MessageOrigin, message.MessageType, message.RawData.Length), message.RawData);
#endif
            return(message.MessageOrigin == MessageOrigin.ServerMessage ||
                   (message.MessageOrigin == MessageOrigin.ServerReply && message.MessageType == MessageType.Authenticate));
        }
        /// <summary>
        /// Receive specific message matching MessageType. Note! This filters away all ServerMessages to get to that particular message.
        /// </summary>
        /// <param name="messageType"></param>
        /// <returns>FileZilla message matching MessageType</returns>
        public FileZillaMessage ReceiveMessage(MessageType messageType)
        {
            for (int retry = 0; retry < 5; retry++)
            {
                var messages = ReceiveMessages();
                FileZillaMessage fileZillaMessage   = null;
                bool             allMessagesHandled = true;
                foreach (FileZillaMessage check in messages)
                {
                    if (check.MessageOrigin == MessageOrigin.ServerReply && check.MessageType == messageType)
                    {
                        if (fileZillaMessage != null)
                        {
                            throw new ProtocolException("Multiple commands matched");
                        }
                        fileZillaMessage = check;
                    }
                    else
                    {
                        if (!HandleUnmatchedMessage(messageType, check))
                        {
                            allMessagesHandled = false;
                            break;
                        }
                    }
                }

                if (!allMessagesHandled)
                {
                    throw ProtocolException.Create(messageType, messages);
                }

                if (fileZillaMessage != null)
                {
                    return(fileZillaMessage);
                }

                // Jedi mind trick: This is not the message you are looking for: Do it all again
            }

            throw new ProtocolException("Unable to receive message: " + messageType);
        }