private static IList <ArraySegment <byte> > SerializeResponse <TResponse>(TResponse protocolResponse)
            where TResponse : IProtocolResponse, new()
        {
            ProtocolEncoder encoder = new ProtocolEncoder();

            MessageHeadersDictionary responseHeaders = new MessageHeadersDictionary();

            byte[] identifier     = encoder.Encode(protocolResponse.GetIdentifier());
            byte[] headers        = ProtocolMessageHeaderSerializer.Serialize(responseHeaders);
            byte[] serializedBody = ProtocolBodySerializer.Serialize(protocolResponse);

            return(ProtocolSerializer.Serialize(identifier, headers, serializedBody));
        }
        public TResponse Execute <TResponse>(IProtocolRequest <TResponse> request)
            where TResponse : class, IProtocolResponse, new()
        {
            if (_connection == null)
            {
                throw new ConnectionRequiredException();
            }

            MessageHeadersDictionary headers = new MessageHeadersDictionary();

            byte[] requestHeaders    = ProtocolMessageHeaderSerializer.Serialize(headers);
            byte[] requestBody       = ProtocolBodySerializer.Serialize(request);
            byte[] requestIdentifier = _encoder.Encode(request.GetIdentifier());
            IList <ArraySegment <byte> > serializedRequest = ProtocolSerializer.Serialize(requestIdentifier, requestHeaders, requestBody);

            byte[] responseEncoded = _connection.Send(serializedRequest);

            var    deserializedObject = ProtocolSerializer.Deserialize(responseEncoded);
            string expectedIdentifier = new TResponse().GetIdentifier();
            string identifier         = _encoder.Decode(deserializedObject.ControlCommand);

            if (identifier != expectedIdentifier)
            {
                if (identifier == ErrorResponse.Identifier)
                {
                    ErrorResponse errorResponse = ProtocolBodySerializer.Deserialize <ErrorResponse>(deserializedObject.Body);
                    throw new CustomException(errorResponse.Message);
                }

                throw new InvalidResponseException();
            }

            TResponse response = ProtocolBodySerializer.Deserialize <TResponse>(deserializedObject.Body);

            return(response);
        }