/// <summary>
        /// Adds a message to the subscription store.
        /// </summary>
        public void Add(Address subscriber, MessageType messageType)
        {
            var toSend = new Message {Formatter = q.Formatter, Recoverable = true, Label = subscriber.ToString(), Body = messageType.TypeName +  ", Version=" + messageType.Version};

            q.Send(toSend, GetTransactionType());

            AddToLookup(subscriber, messageType, toSend.Id);
        }
        /// <summary>
        /// Adds a message to the subscription store.
        /// </summary>
        public void Add(Address subscriber, MessageType messageType)
        {
            var toSend = new Message {
                Formatter = q.Formatter, Recoverable = true, Label = subscriber.ToString(), Body = messageType.TypeName + ", Version=" + messageType.Version
            };

            q.Send(toSend, GetTransactionType());

            AddToLookup(subscriber, messageType, toSend.Id);
        }
        /// <summary>
        /// Removes a message from the subscription store.
        /// </summary>
        public void Remove(Address subscriber, MessageType messageType)
        {
            var messageId = RemoveFromLookup(subscriber, messageType);

            if (messageId == null)
            {
                return;
            }

            q.ReceiveById(messageId, GetTransactionType());
        }
        /// <summary>
        /// Adds a message to the lookup to find message from
        /// subscriber, to message type, to message id
        /// </summary>
        private void AddToLookup(Address subscriber, MessageType typeName, string messageId)
        {
            lock (lookup)
            {
                if (!lookup.ContainsKey(subscriber))
                {
                    lookup.Add(subscriber, new Dictionary <MessageType, string>());
                }

                if (!lookup[subscriber].ContainsKey(typeName))
                {
                    lookup[subscriber].Add(typeName, messageId);
                }
            }
        }
        void ISubscriptionStorage.Init()
        {
            string path = MsmqUtilities.GetFullPath(Queue);

            q = new MessageQueue(path);

            bool transactional;

            try
            {
                transactional = q.Transactional;
            }
            catch (Exception ex)
            {
                throw new ArgumentException(string.Format("There is a problem with the subscription storage queue {0}. See enclosed exception for details.", Queue), ex);
            }

            if (!transactional && SettingsHolder.Get <bool>("Transactions.Enabled"))
            {
                throw new ArgumentException("Queue must be transactional (" + Queue + ").");
            }

            var mpf = new MessagePropertyFilter();

            mpf.SetAll();

            q.Formatter = new XmlMessageFormatter(new[] { typeof(string) });

            q.MessageReadPropertyFilter = mpf;

            foreach (var m in q.GetAllMessages())
            {
                var subscriber        = Address.Parse(m.Label);
                var messageTypeString = m.Body as string;
                var messageType       = new MessageType(messageTypeString); //this will parse both 2.6 and 3.0 type strings

                entries.Add(new Entry {
                    MessageType = messageType, Subscriber = subscriber
                });
                AddToLookup(subscriber, messageType, m.Id);
            }
        }
        string RemoveFromLookup(Address subscriber, MessageType typeName)
        {
            string messageId = null;

            lock (lookup)
            {
                Dictionary <MessageType, string> endpoints;
                if (lookup.TryGetValue(subscriber, out endpoints))
                {
                    if (endpoints.TryGetValue(typeName, out messageId))
                    {
                        endpoints.Remove(typeName);
                        if (endpoints.Count == 0)
                        {
                            lookup.Remove(subscriber);
                        }
                    }
                }
            }
            return(messageId);
        }
        void ISubscriptionStorage.Init()
        {
            string path = MsmqUtilities.GetFullPath(Queue);

            q = new MessageQueue(path);

            bool transactional;
            try
            {
                transactional = q.Transactional;
            }
            catch (Exception ex)
            {
                throw new ArgumentException(string.Format("There is a problem with the subscription storage queue {0}. See enclosed exception for details.", Queue), ex);
            }

            if (!transactional && SettingsHolder.Get<bool>("Transactions.Enabled"))
                throw new ArgumentException("Queue must be transactional (" + Queue + ").");

            var mpf = new MessagePropertyFilter();
            mpf.SetAll();

            q.Formatter = new XmlMessageFormatter(new[] { typeof(string) });

            q.MessageReadPropertyFilter = mpf;

            foreach (var m in q.GetAllMessages())
            {
                var subscriber = Address.Parse(m.Label);
                var messageTypeString = m.Body as string;
                var messageType = new MessageType(messageTypeString); //this will parse both 2.6 and 3.0 type strings

                entries.Add(new Entry { MessageType = messageType, Subscriber = subscriber });
                AddToLookup(subscriber, messageType, m.Id);
            }
        }
 string RemoveFromLookup(Address subscriber, MessageType typeName)
 {
     string messageId = null;
     lock (lookup)
     {
         Dictionary<MessageType, string> endpoints;
         if (lookup.TryGetValue(subscriber, out endpoints))
         {
             if (endpoints.TryGetValue(typeName, out messageId))
             {
                 endpoints.Remove(typeName);
                 if (endpoints.Count == 0)
                 {
                     lookup.Remove(subscriber);
                 }
             }
         }
     }
     return messageId;
 }
        /// <summary>
        /// Adds a message to the lookup to find message from
        /// subscriber, to message type, to message id
        /// </summary>
        private void AddToLookup(Address subscriber, MessageType typeName, string messageId)
        {
            lock (lookup)
            {
                if (!lookup.ContainsKey(subscriber))
                    lookup.Add(subscriber, new Dictionary<MessageType, string>());

                if (!lookup[subscriber].ContainsKey(typeName))
                    lookup[subscriber].Add(typeName, messageId);
            }
        }
        /// <summary>
        /// Removes a message from the subscription store.
        /// </summary>
        public void Remove(Address subscriber, MessageType messageType)
        {
            var messageId = RemoveFromLookup(subscriber, messageType);

            if (messageId == null)
                return;

            q.ReceiveById(messageId, GetTransactionType());
        }