IAsyncResult IAsyncRelayTransport.BeginSendMessage(SerializedRelayMessage message, AsyncCallback callback, object state)
		{
			if (message == null) throw new ArgumentNullException("message");

			if (message.IsTwoWayMessage)
			{
				throw new ApplicationException("Cannot send pre-serialized out message.");
			}

			var result = new SimpleAsyncResult(callback, state);
			asyncSocketClient.SendOneWayAsync<MemoryStream>(
				(short)SocketCommand.HandleOneWayMessage,
				message.MessageStream,
				(messageStream, stream) => stream.Write(
					messageStream.GetBuffer(),
					(int)messageStream.Position,
					(int)messageStream.Length),
					args =>
					{
						result.Error = args.Error;
						result.CompleteOperation(args.CompletedSynchronously);
					});
			return result;
		}
		IAsyncResult IAsyncRelayTransport.BeginSendMessage(RelayMessage message, bool forceRoundTrip, AsyncCallback callback, object state)
		{
			if (message == null) throw new ArgumentNullException("message");

			if (message.IsTwoWayMessage)
			{
				var result = new RoundTripAsyncResult<RelayMessage>(callback, state)
				{
					SentMessage = message
				};
				asyncSocketClient.SendRoundTripAsync<RelayMessage>(
					(short)SocketCommand.HandleSyncMessage,
					message,
					RelayMessageFormatter.WriteRelayMessage,
					args =>
					{
						try
						{
							if (args.Error != null)
							{
								result.Error = args.Error;
								return;
							}

							if (args.Response != null)
							{
								result.ResponseMessage = RelayMessageFormatter.ReadRelayMessage(args.Response);
							}
						}
						catch (Exception ex)
						{
							result.Error = ex;
						}
						finally
						{
							result.Complete(args.CompletedSynchronously);
						}
					});
				return result;
			}
			else
			{
				var result = new SimpleAsyncResult(callback, state);
				if (forceRoundTrip)
				{
					asyncSocketClient.SendRoundTripAsync<RelayMessage>(
						(short)SocketCommand.HandleSyncMessage,
						message,
						RelayMessageFormatter.WriteRelayMessage,
						args =>
						{
							result.Error = args.Error;
							result.CompleteOperation(args.CompletedSynchronously);
						});
				}
				else
				{
					asyncSocketClient.SendOneWayAsync<RelayMessage>(
							(short)SocketCommand.HandleOneWayMessage,
							message,
							RelayMessageFormatter.WriteRelayMessage,
							args =>
							{
								result.Error = args.Error;
								result.CompleteOperation(args.CompletedSynchronously);
							});
				}
				return result;
			}
		}
        IAsyncResult IAsyncRelayTransport.BeginSendMessage(RelayMessage message, bool forceRoundTrip, AsyncCallback callback, object state)
        {
            if (message == null)
            {
                throw new ArgumentNullException("message");
            }

            if (message.IsTwoWayMessage)
            {
                var result = new RoundTripAsyncResult <RelayMessage>(callback, state)
                {
                    SentMessage = message
                };
                asyncSocketClient.SendRoundTripAsync <RelayMessage>(
                    (short)SocketCommand.HandleSyncMessage,
                    message,
                    RelayMessageFormatter.WriteRelayMessage,
                    args =>
                {
                    try
                    {
                        if (args.Error != null)
                        {
                            result.Error = args.Error;
                            return;
                        }

                        if (args.Response != null)
                        {
                            result.ResponseMessage = RelayMessageFormatter.ReadRelayMessage(args.Response);
                        }
                    }
                    catch (Exception ex)
                    {
                        result.Error = ex;
                    }
                    finally
                    {
                        result.Complete(args.CompletedSynchronously);
                    }
                });
                return(result);
            }
            else
            {
                var result = new SimpleAsyncResult(callback, state);
                if (forceRoundTrip)
                {
                    asyncSocketClient.SendRoundTripAsync <RelayMessage>(
                        (short)SocketCommand.HandleSyncMessage,
                        message,
                        RelayMessageFormatter.WriteRelayMessage,
                        args =>
                    {
                        result.Error = args.Error;
                        result.CompleteOperation(args.CompletedSynchronously);
                    });
                }
                else
                {
                    asyncSocketClient.SendOneWayAsync <RelayMessage>(
                        (short)SocketCommand.HandleOneWayMessage,
                        message,
                        RelayMessageFormatter.WriteRelayMessage,
                        args =>
                    {
                        result.Error = args.Error;
                        result.CompleteOperation(args.CompletedSynchronously);
                    });
                }
                return(result);
            }
        }