public void Subscribe(Address subscriber, IEnumerable<MessageType> messageTypes)
		{

			Action subscribeAction = () =>
			{
				using (var client = GetClient())
				{
					using (var tran = client.CreateTransaction())
					{
						foreach (var messageType in messageTypes)
						{
							tran.QueueCommand(c => c.Sets[GetSetName(messageType)].Add(subscriber.ToString()));
						}
						tran.Commit();
					}
				}
			};

			if (Transaction.Current != null)
			{
				Transaction.Current.EnlistVolatile(new ActionResourceManager(subscribeAction, null), EnlistmentOptions.None);
			}
			else
			{
				subscribeAction();
			}
		}
        public static void SetExceptionHeaders(this TransportMessage message,Exception e, Address failedQueue, string reason = null)
        {
            if (!string.IsNullOrWhiteSpace(reason))
            {
                message.Headers["NServiceBus.ExceptionInfo.Reason"] = reason;
            }
            message.Headers["NServiceBus.ExceptionInfo.ExceptionType"] = e.GetType().FullName;

            if (e.InnerException != null)
            {
                message.Headers["NServiceBus.ExceptionInfo.InnerExceptionType"] = e.InnerException.GetType().FullName;
            }

            message.Headers["NServiceBus.ExceptionInfo.HelpLink"] = e.HelpLink;
            message.Headers["NServiceBus.ExceptionInfo.Message"] = e.GetMessage();
            message.Headers["NServiceBus.ExceptionInfo.Source"] = e.Source;
            message.Headers["NServiceBus.ExceptionInfo.StackTrace"] = e.StackTrace;
            message.Headers[FaultsHeaderKeys.FailedQ] = failedQueue.ToString();
            message.Headers["NServiceBus.TimeOfFailure"] = DateTimeExtensions.ToWireFormattedString(DateTime.UtcNow);
        }
        internal static void SetExceptionHeaders(Dictionary<string, string> headers, Exception e, Address failedQueue, string reason, bool legacyStackTrace)
        {
            if (!string.IsNullOrWhiteSpace(reason))
            {
                headers["NServiceBus.ExceptionInfo.Reason"] = reason;
            }
            headers["NServiceBus.ExceptionInfo.ExceptionType"] = e.GetType().FullName;

            if (e.InnerException != null)
            {
                headers["NServiceBus.ExceptionInfo.InnerExceptionType"] = e.InnerException.GetType().FullName;
            }

            headers["NServiceBus.ExceptionInfo.HelpLink"] = e.HelpLink;
            headers["NServiceBus.ExceptionInfo.Message"] = e.GetMessage();
            headers["NServiceBus.ExceptionInfo.Source"] = e.Source; 
            if (legacyStackTrace)
            {
                headers["NServiceBus.ExceptionInfo.StackTrace"] = e.StackTrace;
            }
            else
            {
                headers["NServiceBus.ExceptionInfo.StackTrace"] = e.ToString();
            }
            headers[FaultsHeaderKeys.FailedQ] = failedQueue.ToString();
            headers["NServiceBus.TimeOfFailure"] = DateTimeExtensions.ToWireFormattedString(DateTime.UtcNow);

// ReSharper disable once ConditionIsAlwaysTrueOrFalse
            if(e.Data == null)
// ReSharper disable once HeuristicUnreachableCode
                return;

            foreach (DictionaryEntry entry in e.Data)
            {
                if (entry.Value == null)
                    continue;
                headers["NServiceBus.ExceptionInfo.Data." + entry.Key] = entry.Value.ToString();
            }
        }
		public void Init(Address address, bool transactional)
		{
			if (_log.IsDebugEnabled) _log.Debug("Initializing message receiver: " + address.ToString());
			
			_receiveAddress = address;
			_transactional = transactional;

			//Schedule expiry. Will only work in the host
			if (NServiceBus.Configure.Instance != null)
			{
				if (_log.IsDebugEnabled) _log.Debug("Scheduling claim expiry: " + address.ToString());
				NServiceBus.Schedule.Every(TimeSpan.FromSeconds(30)).Action("ExpireClaimed", () => 
				{
					_manager.ExpireClaimedMessages(_receiveAddress);
				});
			}
			
		}
		internal void DoSend(TransportMessage message, Address address)
		{
			using (var client = GetClient())
			{
				string hashName = GetMessageHashName(address);
				string queueName = GetMessageIdQueueName(address);
				string messageId = message.Id;
				
				string serializedMessage = Serialize(message);

				if (_log.IsDebugEnabled) _log.Debug("Sending message: " + address.ToString() + "/" + messageId);

				using (var tran = client.CreateTransaction())
				{
					tran.QueueCommand(c => c.Hashes[hashName].AddIfNotExists(new KeyValuePair<string, string>(messageId, serializedMessage))); //HSETNX
					tran.QueueCommand(c => c.Lists[queueName].Prepend(messageId)); //LPUSH 	
					tran.Commit();
				}

				if (_log.IsDebugEnabled) _log.Debug("Sent message: " + address.ToString() + "/" + messageId);
			}

		}
		public void Send(TransportMessage message, Address address)
		{

			string messageId = Guid.NewGuid().ToString("N");
			message.Id = messageId;

			if (Transaction.Current != null)
			{
				if (_log.IsDebugEnabled) _log.Debug("Enlisting message send in transaction: " + address.ToString() + "/" + messageId);
				Transaction.Current.EnlistVolatile(new SendResourceManager(() => DoSend(message, address)), EnlistmentOptions.None); //Pass new instance?
			}
			else
			{
				DoSend(message, address);
			}
		}
 public TransportMessage(string existingId, Dictionary<string, string> existingHeaders, Address replyToAddress):this(existingId,existingHeaders)
 {
     Headers[NServiceBus.Headers.ReplyToAddress] = replyToAddress.ToString();
 }