<?xml version="1.0" encoding="UTF-8"?>
<commit>
  <added type="array">
    <added>
      <filename>IServiceOriented.ServiceBus/DuplicateIdentifierException.cs</filename>
    </added>
    <added>
      <filename>IServiceOriented.ServiceBus/ListenerEndpointCollection.cs</filename>
    </added>
    <added>
      <filename>IServiceOriented.ServiceBus/SubscriptionEndpointCollection.cs</filename>
    </added>
  </added>
  <modified type="array">
    <modified>
      <diff>@@ -15,9 +15,7 @@ namespace IServiceOriented.ServiceBus.Samples.Chat
             MessageDelivery.RegisterKnownType(typeof(ChatFilter2));
             MessageDelivery.RegisterKnownType(typeof(SendMessageRequest));
             MessageDelivery.RegisterKnownType(typeof(SendMessageRequest2));
-            MessageDelivery.RegisterKnownType(typeof(WcfListener));
-            MessageDelivery.RegisterKnownType(typeof(WcfDispatcher));            
-
+            
             if(args.Length == 0)
             {
                 Console.WriteLine(&quot;usage: Chat.exe [server | client]&quot;);</diff>
      <filename>IServiceOriented.ServiceBus.Samples.Chat/Program.cs</filename>
    </modified>
    <modified>
      <diff>@@ -132,7 +132,7 @@ namespace IServiceOriented.ServiceBus.UnitTests
 
             SubscriptionEndpoint endpoint = new SubscriptionEndpoint(Guid.NewGuid(), &quot;SubscriptionName&quot;, &quot;http://localhost/test&quot;, &quot;SubscriptionConfigName&quot;, typeof(IContract), new WcfDispatcher(), new PassThroughMessageFilter());
 
-            MessageDelivery enqueued = new MessageDelivery(endpoint.Id, &quot;randomAction&quot;,&quot;randomMessageData&quot;, 3, new ReadOnlyDictionary&lt;string,object&gt;());
+            MessageDelivery enqueued = new MessageDelivery(endpoint.Id, typeof(MessageDelivery), &quot;randomAction&quot;,&quot;randomMessageData&quot;, 3, new ReadOnlyDictionary&lt;string,object&gt;());
             Assert.IsNull(queue.Peek(TimeSpan.FromSeconds(1)), &quot;Queue must be empty to start transaction test&quot;);
 
             // Enqueue, but abort transaction
@@ -196,7 +196,7 @@ namespace IServiceOriented.ServiceBus.UnitTests
 
             SubscriptionEndpoint endpoint = new SubscriptionEndpoint(Guid.NewGuid(), &quot;SubscriptionName&quot;, &quot;http://localhost/test&quot;, &quot;SubscriptionConfigName&quot;, typeof(IContract), new WcfDispatcher(), new PassThroughMessageFilter());
 
-            MessageDelivery enqueued = new MessageDelivery(endpoint.Id, messageAction, messageData, 3, new ReadOnlyDictionary&lt;string,object&gt;());
+            MessageDelivery enqueued = new MessageDelivery(endpoint.Id, typeof(MessageDelivery), messageAction, messageData, 3, new ReadOnlyDictionary&lt;string,object&gt;());
                 
             using (TransactionScope ts = new TransactionScope())
             {</diff>
      <filename>IServiceOriented.ServiceBus.UnitTests/MsmqMessageDeliveryQueueTest.cs</filename>
    </modified>
    <modified>
      <diff>@@ -65,7 +65,7 @@ namespace IServiceOriented.ServiceBus.UnitTests
         void putMessageAndGet(object message)
         {
             SubscriptionEndpoint subscription = new SubscriptionEndpoint(Guid.NewGuid(), &quot;test&quot;, &quot;configurationName&quot;, &quot;address&quot;, typeof(IServiceBusManagementService), new WcfDispatcher(), null);
-            MessageDelivery failure = new MessageDelivery(subscription.Id, &quot;action&quot;, message, 3, new ReadOnlyDictionary&lt;string,object&gt;());
+            MessageDelivery failure = new MessageDelivery(subscription.Id, typeof(MessageDelivery), &quot;action&quot;, message, 3, new ReadOnlyDictionary&lt;string,object&gt;());
             
             NonTransactionalMemoryQueue failureQueue = new NonTransactionalMemoryQueue();
             failureQueue.Enqueue(failure);</diff>
      <filename>IServiceOriented.ServiceBus.UnitTests/ServiceBusManagementTest.cs</filename>
    </modified>
    <modified>
      <diff>@@ -7,6 +7,9 @@ using System.Threading;
 
 namespace IServiceOriented.ServiceBus
 {
+    /// &lt;summary&gt;
+    /// Used for countdown events. When the count reaches zero, the event will be set.
+    /// &lt;/summary&gt;
     public class CountdownLatch : IDisposable
     {
         public CountdownLatch(int count)
@@ -17,8 +20,13 @@ namespace IServiceOriented.ServiceBus
         int _count;
         ManualResetEvent _handle = new ManualResetEvent(false);
 
+        /// &lt;summary&gt;
+        /// Decrement the count. Set the event to signalled if the count is zero;
+        /// &lt;/summary&gt;
+        /// &lt;returns&gt;The new count&lt;/returns&gt;
         public int Tick()
         {
+            if (_disposed) throw new ObjectDisposedException(&quot;CoundownLatch&quot;);
             int count = Interlocked.Decrement(ref _count);
             if (count == 0)
             {
@@ -31,12 +39,24 @@ namespace IServiceOriented.ServiceBus
         {
             get
             {
+                if (_disposed) throw new ObjectDisposedException(&quot;CoundownLatch&quot;);
                 return _handle;
             }
         }
 
         volatile bool _disposed;
 
+        /// &lt;summary&gt;
+        /// Reset the count and set the event to non signalled.
+        /// &lt;/summary&gt;
+        public void Reset(int count)
+        {
+            if (_disposed) throw new ObjectDisposedException(&quot;CoundownLatch&quot;);
+            
+            _count = count;
+            _handle.Reset();
+        }
+
         protected virtual void Dispose(bool disposing)
         {
             if (disposing &amp;&amp; !_disposed)
@@ -56,5 +76,10 @@ namespace IServiceOriented.ServiceBus
 
             GC.SuppressFinalize(this);
         }
+
+        ~CountdownLatch()
+        {
+            Dispose(false);
+        }
     }
 }</diff>
      <filename>IServiceOriented.ServiceBus/CountdownLatch.cs</filename>
    </modified>
    <modified>
      <diff>@@ -8,12 +8,21 @@ using System.Runtime.Serialization;
 
 namespace IServiceOriented.ServiceBus
 {    
+    /// &lt;summary&gt;
+    /// Base class for all service bus dispatchers.
+    /// &lt;/summary&gt;
+    /// &lt;remarks&gt;
+    /// Dispatchers are responsible for delivering messages to subscription endpoints.
+    /// &lt;/remarks&gt;
     [Serializable]
     [DataContract]
     public abstract class Dispatcher : IDisposable
     {
         [NonSerialized]
         ServiceBusRuntime _runtime;
+        /// &lt;summary&gt;
+        /// Gets the service bus instance associated with this dispatcher.
+        /// &lt;/summary&gt;
         public ServiceBusRuntime Runtime
         {
             get
@@ -28,6 +37,9 @@ namespace IServiceOriented.ServiceBus
 
         [NonSerialized]
         SubscriptionEndpoint _endpoint;        
+        /// &lt;summary&gt;
+        /// Gets the subscription endpoint associated with this dispatcher.
+        /// &lt;/summary&gt;
         public SubscriptionEndpoint Endpoint
         {
             get
@@ -103,6 +115,10 @@ namespace IServiceOriented.ServiceBus
         /// &lt;/summary&gt;
         protected abstract void Dispatch(SubscriptionEndpoint endpoint, string action, object message);
 
+        /// &lt;summary&gt;
+        /// Dispose any resources held by this dispatcher.
+        /// &lt;/summary&gt;
+        /// &lt;param name=&quot;disposing&quot;&gt;Indicates whether this method is being called as a result of a direct call to Dispose (true) or by the object's finalizer (false).&lt;/param&gt;
         protected virtual void Dispose(bool disposing)
         {
             
@@ -117,6 +133,11 @@ namespace IServiceOriented.ServiceBus
         }
 
         #endregion
+
+        ~Dispatcher()
+        {
+            Dispose(false);
+        }
     }
 
 </diff>
      <filename>IServiceOriented.ServiceBus/Dispatcher.cs</filename>
    </modified>
    <modified>
      <diff>@@ -8,6 +8,9 @@ using System.Runtime.Serialization;
 
 namespace IServiceOriented.ServiceBus
 {
+    /// &lt;summary&gt;
+    /// Base class for service bus endpoints.
+    /// &lt;/summary&gt;
     [Serializable]
     [DataContract]
     public abstract class Endpoint
@@ -31,6 +34,10 @@ namespace IServiceOriented.ServiceBus
         }
 
         Guid _endpointId = Guid.NewGuid();
+        
+        /// &lt;summary&gt;
+        /// Gets the unique identifier of the endpoint.
+        /// &lt;/summary&gt;
         [DataMember]
         public Guid Id
         {
@@ -43,7 +50,11 @@ namespace IServiceOriented.ServiceBus
                 _endpointId = value;
             }
         }
+
         Type _contractType;                
+        /// &lt;summary&gt;
+        /// Gets the Type of the contract supported by the endpoint.
+        /// &lt;/summary&gt;
         public Type ContractType
         {
             get
@@ -56,6 +67,9 @@ namespace IServiceOriented.ServiceBus
             }
         }
 
+        /// &lt;summary&gt;
+        /// Gets the name of the contract type supported by the endpoint.
+        /// &lt;/summary&gt;
         [DataMember]
         public string ContractTypeName
         {
@@ -74,6 +88,9 @@ namespace IServiceOriented.ServiceBus
         }
 
         string _address;
+        /// &lt;summary&gt;
+        /// Gets the address of the endpoint.
+        /// &lt;/summary&gt;
         [DataMember]
         public string Address
         {
@@ -88,6 +105,9 @@ namespace IServiceOriented.ServiceBus
         }
 
         string _configurationName;
+        /// &lt;summary&gt;
+        /// Gets the name of the configuration used by the endpoint.
+        /// &lt;/summary&gt;
         [DataMember]
         public string ConfigurationName
         {
@@ -102,6 +122,9 @@ namespace IServiceOriented.ServiceBus
         }
 
         string _name;
+        /// &lt;summary&gt;
+        /// Gets the name of this endpoint.
+        /// &lt;/summary&gt;
         [DataMember]
         public string Name
         {
@@ -116,6 +139,9 @@ namespace IServiceOriented.ServiceBus
         }
 
         bool _transient;
+        /// &lt;summary&gt;
+        /// Gets a boolean value indicating whether this endpoint is transient (true) or should be persisted (false).
+        /// &lt;/summary&gt;
         [DataMember]
         public bool Transient
         {
@@ -128,8 +154,5 @@ namespace IServiceOriented.ServiceBus
                 _transient = value;
             }
         }
-    }
-
-
-    
+    }    
 }</diff>
      <filename>IServiceOriented.ServiceBus/Endpoint.cs</filename>
    </modified>
    <modified>
      <diff>@@ -7,11 +7,28 @@ using System.Reflection;
 
 namespace IServiceOriented.ServiceBus
 {
+    /// &lt;summary&gt;
+    /// Gaurds an object with locks.
+    /// &lt;/summary&gt;
+    /// &lt;typeparam name=&quot;TRead&quot;&gt;Read only type of the contained data.&lt;/typeparam&gt;
+    /// &lt;typeparam name=&quot;TWrite&quot;&gt;Writeable type of the contained data.&lt;/typeparam&gt;
     public interface ILockedObject&lt;TRead, TWrite&gt; : IDisposable
     {
+        /// &lt;summary&gt;
+        /// Access the contained value for read access.
+        /// &lt;/summary&gt;
+        /// &lt;param name=&quot;action&quot;&gt;&lt;/param&gt;
         void Read(Action&lt;TRead&gt; action);
+        /// &lt;summary&gt;
+        /// Access the contained value for write access.
+        /// &lt;/summary&gt;
+        /// &lt;param name=&quot;action&quot;&gt;&lt;/param&gt;
         void Write(Action&lt;TWrite&gt; action);
         
+        /// &lt;summary&gt;
+        /// Access the contained value with write access and set to a new value.
+        /// &lt;/summary&gt;
+        /// &lt;param name=&quot;value&quot;&gt;&lt;/param&gt;
         void SetValue(TWrite value);
             
     }</diff>
      <filename>IServiceOriented.ServiceBus/ILockedObject.cs</filename>
    </modified>
    <modified>
      <diff>@@ -6,35 +6,64 @@ using System.Text;
 
 namespace IServiceOriented.ServiceBus
 {
+    /// &lt;summary&gt;
+    /// A read-only dictionary.
+    /// &lt;/summary&gt;
+    /// &lt;typeparam name=&quot;K&quot;&gt;Key type&lt;/typeparam&gt;
+    /// &lt;typeparam name=&quot;V&quot;&gt;Value type&lt;/typeparam&gt;
     public interface IReadOnlyDictionary&lt;K,V&gt; : IEnumerable&lt;KeyValuePair&lt;K,V&gt;&gt;
     {
+        /// &lt;summary&gt;
+        /// Get the keys associated with this dictionary instance.
+        /// &lt;/summary&gt;
         IEnumerable&lt;K&gt; Keys
         {
             get;
         }
 
+        /// &lt;summary&gt;
+        /// Get the values contained by this dictionary instance.
+        /// &lt;/summary&gt;
         IEnumerable&lt;V&gt; Values
         {
             get;
         }
 
+        /// &lt;summary&gt;
+        /// Get the value associated with a specific key.
+        /// &lt;/summary&gt;
         V this[K key]
         {
             get;
         }
 
+        /// &lt;summary&gt;
+        /// Get the number of items contained by this dictionary.
+        /// &lt;/summary&gt;
         int Count
         {
             get;
         }
 
+        /// &lt;summary&gt;
+        /// Check to see if the dictionary contains a specific key.
+        /// &lt;/summary&gt;
         bool ContainsKey(K key);
-        bool Contains(KeyValuePair&lt;K,V&gt; value);
+        /// &lt;summary&gt;
+        /// Check to see if the dictionary contains a specific key value pair.
+        /// &lt;/summary&gt;
+        bool Contains(KeyValuePair&lt;K, V&gt; value);
 
     }
 
+    /// &lt;summary&gt;
+    /// Extension methods for read only dicionaries
+    /// &lt;/summary&gt;
     public static class ReadOnlyDictionaryExtensions
     {
+        /// &lt;summary&gt;
+        /// Convert a read only dictionary to a writeable dictionary.
+        /// &lt;/summary&gt;
         public static Dictionary&lt;K, V&gt; ToDictionary&lt;K,V&gt;(this IReadOnlyDictionary&lt;K, V&gt; readOnlyDictionary)
         {
             Dictionary&lt;K, V&gt; dict = new Dictionary&lt;K, V&gt;();
@@ -45,11 +74,19 @@ namespace IServiceOriented.ServiceBus
             return dict;
         }
 
+        /// &lt;summary&gt;
+        /// Convert a dictionary to a read only dictionary.
+        /// &lt;/summary&gt;
         public static ReadOnlyDictionary&lt;K, V&gt; MakeReadOnly&lt;K, V&gt;(this IDictionary&lt;K, V&gt; dictionary)
         {
             return dictionary.MakeReadOnly(false);
         }
-        public static ReadOnlyDictionary&lt;K, V&gt; MakeReadOnly&lt;K,V&gt;(this IDictionary&lt;K, V&gt; dictionary, bool copy)
+
+        /// &lt;summary&gt;
+        /// Convert a dictionary to a read only dictionary.
+        /// &lt;/summary&gt;
+        /// &lt;param name=&quot;copy&quot;&gt;Specifies if the dictionary should be copied (true) or wrapped (false).&lt;/param&gt;
+        public static ReadOnlyDictionary&lt;K, V&gt; MakeReadOnly&lt;K, V&gt;(this IDictionary&lt;K, V&gt; dictionary, bool copy)
         {
             return new ReadOnlyDictionary&lt;K, V&gt;(dictionary, copy);
         }</diff>
      <filename>IServiceOriented.ServiceBus/IReadOnlyDictionary.cs</filename>
    </modified>
    <modified>
      <diff>@@ -62,6 +62,7 @@
   &lt;ItemGroup&gt;
     &lt;Compile Include=&quot;CountdownLatch.cs&quot; /&gt;
     &lt;Compile Include=&quot;Dispatcher.cs&quot; /&gt;
+    &lt;Compile Include=&quot;DuplicateIdentifierException.cs&quot; /&gt;
     &lt;Compile Include=&quot;Endpoint.cs&quot; /&gt;
     &lt;Compile Include=&quot;IReadOnlyDictionary.cs&quot; /&gt;
     &lt;Compile Include=&quot;Listener.cs&quot; /&gt;
@@ -69,11 +70,13 @@
     &lt;Compile Include=&quot;InvalidContractException.cs&quot; /&gt;
     &lt;Compile Include=&quot;ListenerEndpoint.cs&quot; /&gt;
     &lt;Compile Include=&quot;IMessageDeliveryQueue.cs&quot; /&gt;
+    &lt;Compile Include=&quot;ListenerEndpointCollection.cs&quot; /&gt;
     &lt;Compile Include=&quot;PublishRequest.cs&quot; /&gt;
     &lt;Compile Include=&quot;ReadOnlyDictionary.cs&quot; /&gt;
     &lt;Compile Include=&quot;SqlSubscriptionPersistenceService.cs&quot;&gt;
       &lt;SubType&gt;Code&lt;/SubType&gt;
     &lt;/Compile&gt;
+    &lt;Compile Include=&quot;SubscriptionEndpointCollection.cs&quot; /&gt;
     &lt;Compile Include=&quot;TransformationDispatcher.cs&quot; /&gt;
     &lt;Compile Include=&quot;ReaderWriterLockedObject.cs&quot; /&gt;
     &lt;Compile Include=&quot;UnhandledMessageFilter.cs&quot; /&gt;</diff>
      <filename>IServiceOriented.ServiceBus/IServiceOriented.ServiceBus.csproj</filename>
    </modified>
    <modified>
      <diff>@@ -6,12 +6,21 @@ using System.Runtime.Serialization;
 
 namespace IServiceOriented.ServiceBus
 {    
+    /// &lt;summary&gt;
+    /// Base class for all service host listeners.
+    /// &lt;/summary&gt;
+    /// &lt;remarks&gt;
+    /// Listeners are responsible for receiving messages and publishing them to the bus.
+    /// &lt;/remarks&gt;
     [Serializable]
     [DataContract]
     public abstract class Listener : IDisposable
     {
         [NonSerialized]
         ServiceBusRuntime _runtime;
+        /// &lt;summary&gt;
+        /// Gets the service bus instance that this listener is associated with.
+        /// &lt;/summary&gt;
         public ServiceBusRuntime Runtime
         {
             get
@@ -26,6 +35,9 @@ namespace IServiceOriented.ServiceBus
 
         [NonSerialized]
         ListenerEndpoint _endpoint;
+        /// &lt;summary&gt;
+        /// Gets the listener endpoint that this listener is associated with.
+        /// &lt;/summary&gt;
         public ListenerEndpoint Endpoint
         {
             get
@@ -40,6 +52,9 @@ namespace IServiceOriented.ServiceBus
 
         [NonSerialized]
         bool _started;
+        /// &lt;summary&gt;
+        /// Gets a boolean value indicating whether this listener has been started.
+        /// &lt;/summary&gt;
         public bool Started
         {
             get
@@ -64,14 +79,24 @@ namespace IServiceOriented.ServiceBus
             Started = false;
         }
 
+        /// &lt;summary&gt;
+        /// Perform any actions that should be performed when this listener starts.
+        /// &lt;/summary&gt;
         protected virtual void OnStart()
         {
         }
 
+        /// &lt;summary&gt;
+        /// Perform any actions that should be performed when this listener stops.
+        /// &lt;/summary&gt;
         protected virtual void OnStop()
         {
         }
 
+        /// &lt;summary&gt;
+        /// Dispose any resources held by this listener.
+        /// &lt;/summary&gt;
+        /// &lt;param name=&quot;disposing&quot;&gt;Indicates whether this method is being called as a result of a direct call to Dispose (true) or by the object's finalizer (false).&lt;/param&gt;
         protected virtual void Dispose(bool disposing)
         {
 
@@ -86,6 +111,11 @@ namespace IServiceOriented.ServiceBus
         }
 
         #endregion
+
+        ~Listener()
+        {
+            Dispose(false);
+        }
     }
 
 }    </diff>
      <filename>IServiceOriented.ServiceBus/Listener.cs</filename>
    </modified>
    <modified>
      <diff>@@ -6,15 +6,24 @@ using System.Runtime.Serialization;
 
 namespace IServiceOriented.ServiceBus
 {
+    /// &lt;summary&gt;
+    /// Represents a listener endpoint.
+    /// &lt;/summary&gt;
     [DataContract]
     public sealed class ListenerEndpoint : Endpoint
     {
         public ListenerEndpoint(Guid id, string name, string configurationName, string address, Type contractType, Listener listener) : base(id, name, configurationName, address, contractType)
-        {
+        {            
             Listener = listener;
         }
 
         Listener _listener;
+        /// &lt;summary&gt;
+        /// The listener used by this endpoint
+        /// &lt;/summary&gt;
+        /// &lt;remarks&gt;
+        /// Listeners cannot be shared by multiple endpoints.
+        /// &lt;/remarks&gt;
         [DataMember]
         public Listener Listener
         {</diff>
      <filename>IServiceOriented.ServiceBus/ListenerEndpoint.cs</filename>
    </modified>
    <modified>
      <diff>@@ -8,12 +8,15 @@ using System.Runtime.Serialization;
 
 namespace IServiceOriented.ServiceBus
 {
+    /// &lt;summary&gt;
+    /// Represents a message to be delivered.
+    /// &lt;/summary&gt;
     [Serializable]
     [DataContract]
     [KnownType(&quot;GetKnownTypes&quot;)]
     public class MessageDelivery 
     {
-        public MessageDelivery(Guid subscriptionEndpointId, string action, object message, int maxRetries, ReadOnlyDictionary&lt;string,object&gt; context)
+        public MessageDelivery(Guid subscriptionEndpointId, Type contractType, string action, object message, int maxRetries, ReadOnlyDictionary&lt;string,object&gt; context)
         {
             _messageId = Guid.NewGuid().ToString();
             _subscriptionEndpointId = subscriptionEndpointId;
@@ -21,9 +24,10 @@ namespace IServiceOriented.ServiceBus
             _message = message;
             _maxRetries = maxRetries;
             _context = context;
+            ContractType = contractType;
         }
 
-        public MessageDelivery(string messageId, Guid subscriptionEndpointId, string action, object message, int maxRetries, int retryCount, DateTime? timeToProcess, int queueCount, ReadOnlyDictionary&lt;string, object&gt; context)
+        public MessageDelivery(string messageId, Guid subscriptionEndpointId, Type contractType, string action, object message, int maxRetries, int retryCount, DateTime? timeToProcess, int queueCount, ReadOnlyDictionary&lt;string, object&gt; context)
         {
             _messageId = messageId;
             _subscriptionEndpointId = subscriptionEndpointId;
@@ -34,8 +38,12 @@ namespace IServiceOriented.ServiceBus
             _queueCount = queueCount;
             _maxRetries = maxRetries;
             _context = context;
+            ContractType = contractType;
         }
 
+        /// &lt;summary&gt;
+        /// Gets a list of types that have been registered for message delivery.
+        /// &lt;/summary&gt;        
         public static Type[] GetKnownTypes()
         {
             lock (_knownTypes)
@@ -44,7 +52,10 @@ namespace IServiceOriented.ServiceBus
             }
         }
         
-        static List&lt;Type&gt; _knownTypes = new List&lt;Type&gt;(new Type[] { typeof(UnhandledMessageFilter), typeof(Guid[]) } );
+        static List&lt;Type&gt; _knownTypes = new List&lt;Type&gt;(new Type[] { typeof(UnhandledMessageFilter), typeof(Guid[]), typeof(WcfListener), typeof(WcfDispatcher), typeof(TypedMessageFilter) } );
+        /// &lt;summary&gt;
+        /// Clears the list of types registered for message delivery.
+        /// &lt;/summary&gt;
         public static void ClearKnownTypes()
         {
             lock (_knownTypes)
@@ -53,6 +64,9 @@ namespace IServiceOriented.ServiceBus
             }
         }
 
+        /// &lt;summary&gt;
+        /// Register a type for message delivery.
+        /// &lt;/summary&gt;
         public static void RegisterKnownType(Type type)
         {
             lock (_knownTypes)
@@ -64,6 +78,9 @@ namespace IServiceOriented.ServiceBus
             }
         }
 
+        /// &lt;summary&gt;
+        /// Unregister a type for message delivery.
+        /// &lt;/summary&gt;
         public static void UnregisterKnownType(Type type)
         {
             lock (_knownTypes)
@@ -77,6 +94,9 @@ namespace IServiceOriented.ServiceBus
 
 
         int _queueCount;
+        /// &lt;summary&gt;
+        /// The number of times that this message has been queued
+        /// &lt;/summary&gt;
         [DataMember]
         public int QueueCount
         {
@@ -90,6 +110,11 @@ namespace IServiceOriented.ServiceBus
             }
         }
         
+        /// &lt;summary&gt;
+        /// Increment the queue count.
+        /// &lt;/summary&gt;
+        /// &lt;returns&gt;The new queue count.&lt;/returns&gt;
+        /// &lt;remarks&gt;This method is not thread safe.&lt;/remarks&gt;
         public int IncrementQueueCount()
         {
             return _queueCount++; 
@@ -97,6 +122,9 @@ namespace IServiceOriented.ServiceBus
 
 
         private string _messageId;
+        /// &lt;summary&gt;
+        /// Gets the unique identifier of this message
+        /// &lt;/summary&gt;
         [DataMember]
         public string MessageId
         {
@@ -105,14 +133,65 @@ namespace IServiceOriented.ServiceBus
         }
 
         private Guid _subscriptionEndpointId;
+        /// &lt;summary&gt;
+        /// Gets the identifier of the subscription that this message is associated with.
+        /// &lt;/summary&gt;
         [DataMember]
         public Guid SubscriptionEndpointId
         {
             get { return _subscriptionEndpointId; }
             private set { _subscriptionEndpointId = value; }
-        } 
+        }
+
+        private Type _contractType;
+        /// &lt;summary&gt;
+        /// Gets the type of contract associated with this message delivery.
+        /// &lt;/summary&gt;
+        public Type ContractType
+        {
+            get
+            {
+                return _contractType;
+            }
+            set
+            {
+                _contractType = value;
+            }
+        }
+
+        /// &lt;summary&gt;
+        /// Gets the name of the contract type associated with this message delivery.
+        /// &lt;/summary&gt;
+        [DataMember]
+        public string ContractTypeName
+        {
+            get
+            {
+                if (_contractType == null) return null;
+                return _contractType.AssemblyQualifiedName;
+            }
+            set
+            {
+                if (value == null)
+                {
+                    ContractType = null;
+                }
+                else
+                {
+                    Type type = Type.GetType(value);
+                    if (type == null)
+                    {
+                        throw new InvalidOperationException(&quot;The type specified does not exist&quot;);
+                    }
+                    ContractType = type;
+                }
+            }
+        }
 
         private string _action;
+        /// &lt;summary&gt;
+        /// Gets the action associated with this message.
+        /// &lt;/summary&gt;
         [DataMember]
         public string Action
         {
@@ -121,7 +200,9 @@ namespace IServiceOriented.ServiceBus
         }
 
         private  object _message;
-
+        /// &lt;summary&gt;
+        /// Gets the message contents.
+        /// &lt;/summary&gt;
         [DataMember]
         public object Message
         {
@@ -130,6 +211,9 @@ namespace IServiceOriented.ServiceBus
         } 
 
         private int _retryCount;
+        /// &lt;summary&gt;
+        /// Gets the number of times this message has been retried.
+        /// &lt;/summary&gt;
         [DataMember]
         public int RetryCount
         {
@@ -138,6 +222,9 @@ namespace IServiceOriented.ServiceBus
         } 
 
         private DateTime? _timeToProcess;
+        /// &lt;summary&gt;
+        /// Gets the time that this message should be processed (or null if immediately).
+        /// &lt;/summary&gt;
         [DataMember]
         public DateTime? TimeToProcess
         {
@@ -146,6 +233,9 @@ namespace IServiceOriented.ServiceBus
         }
 
 
+        /// &lt;summary&gt;
+        /// Gets the maximum number of times this message will be retried.
+        /// &lt;/summary&gt;
         [DataMember]
         public int MaxRetries
         {
@@ -154,6 +244,9 @@ namespace IServiceOriented.ServiceBus
         }
 
 
+        /// &lt;summary&gt;
+        /// Gets a boolean value indicating whether the maximum number of retries has been met.
+        /// &lt;/summary&gt;
         public bool RetriesMaxed
         {
             get
@@ -164,6 +257,9 @@ namespace IServiceOriented.ServiceBus
 
         ReadOnlyDictionary&lt;string, object&gt; _context = new ReadOnlyDictionary&lt;string, object&gt;();
         
+        /// &lt;summary&gt;
+        /// Gets the context associated with this message.
+        /// &lt;/summary&gt;
         [DataMember]
         public ReadOnlyDictionary&lt;string, object&gt; Context
         {
@@ -179,10 +275,16 @@ namespace IServiceOriented.ServiceBus
 
         private int _maxRetries;
         
+        /// &lt;summary&gt;
+        /// Create a retry message based off of this message.
+        /// &lt;/summary&gt;
+        /// &lt;param name=&quot;resetRetryCount&quot;&gt;Whether or not to reset the retry count.&lt;/param&gt;
+        /// &lt;param name=&quot;timeToDeliver&quot;&gt;Time to deliver the retry message.&lt;/param&gt;
+        /// &lt;returns&gt;A new MessageDelivery.&lt;/returns&gt;
         public MessageDelivery CreateRetry(bool resetRetryCount, DateTime timeToDeliver)
         {            
             int retryCount = resetRetryCount ? 0 : (_retryCount + 1);            
-            return new MessageDelivery(_messageId, _subscriptionEndpointId, _action, _message, _maxRetries, retryCount, timeToDeliver, QueueCount+1, _context);             
+            return new MessageDelivery(_messageId, _subscriptionEndpointId, _contractType, _action, _message, _maxRetries, retryCount, timeToDeliver, QueueCount+1, _context);             
         }        
     }
 }</diff>
      <filename>IServiceOriented.ServiceBus/MessageDelivery.cs</filename>
    </modified>
    <modified>
      <diff>@@ -7,10 +7,18 @@ using System.Runtime.Serialization;
 
 namespace IServiceOriented.ServiceBus
 {
+    /// &lt;summary&gt;
+    /// Base class for message filters.
+    /// &lt;/summary&gt;
     [Serializable]
     [DataContract]
     public abstract class MessageFilter
     {
+        /// &lt;summary&gt;
+        /// Determine whether a message should be included or skipped.
+        /// &lt;/summary&gt;
+        /// &lt;param name=&quot;request&quot;&gt;&lt;/param&gt;
+        /// &lt;returns&gt;true if the message should be included, false if the message should be skipped.&lt;/returns&gt;
         public abstract bool Include(PublishRequest request);        
     }
 	</diff>
      <filename>IServiceOriented.ServiceBus/MessageFilter.cs</filename>
    </modified>
    <modified>
      <diff>@@ -130,7 +130,13 @@ namespace IServiceOriented.ServiceBus
             GC.SuppressFinalize(this);
         }
 
+        
         #endregion
+
+        ~ReaderWriterLockedObject()
+        {
+            Dispose(false);
+        }
     }
 
 }</diff>
      <filename>IServiceOriented.ServiceBus/ReaderWriterLockedObject.cs</filename>
    </modified>
    <modified>
      <diff>@@ -351,7 +351,7 @@ namespace IServiceOriented.ServiceBus
         public event EventHandler&lt;EndpointEventArgs&gt; ListenerAdded;
         public event EventHandler&lt;EndpointEventArgs&gt; ListenerRemoved;
         
-		List&lt;ListenerEndpoint&gt; _listenerEndpoints = new List&lt;ListenerEndpoint&gt;();
+		ListenerEndpointCollection _listenerEndpoints = new ListenerEndpointCollection();
         object _listenerEndpointsLock = new object();
 
 		public IEnumerable&lt;Endpoint&gt; ListeningEndpoints
@@ -362,7 +362,7 @@ namespace IServiceOriented.ServiceBus
 			}
 		}
 
-        ReaderWriterLockedObject&lt;IEnumerable&lt;SubscriptionEndpoint&gt;, IList&lt;SubscriptionEndpoint&gt;&gt; _subscriptions = new ReaderWriterLockedObject&lt;IEnumerable&lt;SubscriptionEndpoint&gt;, IList&lt;SubscriptionEndpoint&gt;&gt;(new List&lt;SubscriptionEndpoint&gt;(), l =&gt; l);
+        ReaderWriterLockedObject&lt;IEnumerable&lt;SubscriptionEndpoint&gt;, SubscriptionEndpointCollection&gt; _subscriptions = new ReaderWriterLockedObject&lt;IEnumerable&lt;SubscriptionEndpoint&gt;, SubscriptionEndpointCollection&gt;(new SubscriptionEndpointCollection(), l =&gt; l);
 
         public static void VerifyContract(Type contractType)
         {
@@ -576,11 +576,11 @@ namespace IServiceOriented.ServiceBus
             return endpoint;
         }
 				
-		protected void QueueDelivery(Guid subscriptionEndpointId, string action, object message, ReadOnlyDictionary&lt;string, object&gt; context)
+		protected void QueueDelivery(Guid subscriptionEndpointId, Type contractType, string action, object message, ReadOnlyDictionary&lt;string, object&gt; context)
 		{
             if (message == null) throw new ArgumentNullException(&quot;message&quot;);
 
-			MessageDelivery delivery = new MessageDelivery(subscriptionEndpointId, action, message, _maxRetries, context);
+			MessageDelivery delivery = new MessageDelivery(subscriptionEndpointId, contractType, action, message, _maxRetries, context);
 			_messageDeliveryQueue.Enqueue(delivery);
 		}
 
@@ -819,7 +819,7 @@ namespace IServiceOriented.ServiceBus
 
                         if (include)
                         {
-                            QueueDelivery(subscription.Id, publishRequest.Action, publishRequest.Message, publishRequest.Context);
+                            QueueDelivery(subscription.Id, publishRequest.Contract, publishRequest.Action, publishRequest.Message, publishRequest.Context);
                             handled = true;
                         }
                     }
@@ -829,7 +829,7 @@ namespace IServiceOriented.ServiceBus
                     {
                         foreach (SubscriptionEndpoint subscription in unhandledFilters)
                         {
-                            QueueDelivery(subscription.Id, publishRequest.Action, publishRequest.Message, publishRequest.Context);
+                            QueueDelivery(subscription.Id, publishRequest.Contract, publishRequest.Action, publishRequest.Message, publishRequest.Context);
                         }
                     }
 
@@ -1064,6 +1064,11 @@ namespace IServiceOriented.ServiceBus
 
             GC.SuppressFinalize(this);
         }
+
+        ~ServiceBusRuntime()
+        {
+            Dispose(false);
+        }
 	}
 			
 	</diff>
      <filename>IServiceOriented.ServiceBus/ServiceBusRuntime.cs</filename>
    </modified>
    <modified>
      <diff>@@ -7,6 +7,9 @@ using System.Runtime.Serialization;
 
 namespace IServiceOriented.ServiceBus
 {
+    /// &lt;summary&gt;
+    /// Represents a subscription endpoint.
+    /// &lt;/summary&gt;
     [Serializable]
     [DataContract]
     public sealed class SubscriptionEndpoint : Endpoint
@@ -26,6 +29,9 @@ namespace IServiceOriented.ServiceBus
         }
 
         MessageFilter _filter;
+        /// &lt;summary&gt;
+        /// The filter to be applied to this subscription or null if all messages should be included.
+        /// &lt;/summary&gt;
         [DataMember]
         public MessageFilter Filter
         {
@@ -40,6 +46,9 @@ namespace IServiceOriented.ServiceBus
         }
 
         Dispatcher _dispatcher;
+        /// &lt;summary&gt;
+        /// The Dispatcher used to send messages to this endpoint.
+        /// &lt;/summary&gt;
         [DataMember]
         public Dispatcher Dispatcher
         {</diff>
      <filename>IServiceOriented.ServiceBus/SubscriptionEndpoint.cs</filename>
    </modified>
    <modified>
      <diff>@@ -6,6 +6,9 @@ using System.Text;
 using System.Runtime.Serialization;
 namespace IServiceOriented.ServiceBus
 {
+    /// &lt;summary&gt;
+    /// Provides support for message transformation. The TransformationDispatcher transforms a PublishRequest and publishes the transformed request to the bus.
+    /// &lt;/summary&gt;
     [Serializable]
     [DataContract]
     public abstract class TransformationDispatcher : Dispatcher
@@ -15,7 +18,12 @@ namespace IServiceOriented.ServiceBus
             
         }
 
-        protected abstract PublishRequest Transform(PublishRequest information);
+        /// &lt;summary&gt;
+        /// Performs a transformation of a PublishRequest
+        /// &lt;/summary&gt;
+        /// &lt;param name=&quot;request&quot;&gt;An incoming publish request.&lt;/param&gt;
+        /// &lt;returns&gt;The transformed request or null if the message cannot be transformed.&lt;/returns&gt;
+        protected abstract PublishRequest Transform(PublishRequest request);
 
         public const string TransformedByKeyName = &quot;TransformedBy&quot;;
         
@@ -33,7 +41,7 @@ namespace IServiceOriented.ServiceBus
             }
 
             // Don't transform this message more than once
-            if (!oldTransformedByList.Contains(endpoint.Id))
+            if (!oldTransformedByList.Contains(endpoint.Id) || AllowMultipleTransforms)
             {
                 Guid[] newTransformedByList = new Guid[oldTransformedByList.Length + 1];
                 newTransformedByList[newTransformedByList.Length - 1] = endpoint.Id;
@@ -42,12 +50,28 @@ namespace IServiceOriented.ServiceBus
                 context = newContext.MakeReadOnly();
 
                 PublishRequest result = Transform(new PublishRequest(endpoint.ContractType, action, message, context));
-                Runtime.Publish(new PublishRequest(result.Contract, result.Action, result.Message, context));
+                if (result != null)
+                {
+                    Runtime.Publish(new PublishRequest(result.Contract, result.Action, result.Message, context));
+                }
             }
             else
             {
                 System.Diagnostics.Trace.TraceInformation(&quot;Skipping already transformed message (&quot; + DispatchContext.MessageDelivery.MessageId +&quot;)&quot;); 
             }
         }
+
+        /// &lt;summary&gt;
+        /// Gets or sets whether this endpoint can transform a message multiple times.
+        /// &lt;/summary&gt;
+        /// &lt;remarks&gt;
+        /// Setting this property to true can cause cycles if it transforms both to and from a certain message type.
+        /// &lt;/remarks&gt;
+        [DataMember]
+        public bool AllowMultipleTransforms
+        {
+            get;
+            set;
+        }
     }
 }</diff>
      <filename>IServiceOriented.ServiceBus/TransformationDispatcher.cs</filename>
    </modified>
    <modified>
      <diff>@@ -9,6 +9,9 @@ using System.Runtime.Serialization;
 
 namespace IServiceOriented.ServiceBus
 {    
+    /// &lt;summary&gt;
+    /// Provides support for dispatching messages to WCF endpoints.
+    /// &lt;/summary&gt;
     [Serializable]
     [DataContract]
     public class WcfDispatcher : Dispatcher</diff>
      <filename>IServiceOriented.ServiceBus/WcfDispatcher.cs</filename>
    </modified>
    <modified>
      <diff>@@ -9,6 +9,12 @@ using System.Runtime.Serialization;
 
 namespace IServiceOriented.ServiceBus
 {
+    /// &lt;summary&gt;
+    /// Provides support for hosting WCF service contracts with the service bus.
+    /// &lt;/summary&gt;
+    /// &lt;remarks&gt;
+    /// Currently, contracts are restricted to one way, single parameter, methods.
+    /// &lt;/remarks&gt;
     [Serializable]
     [DataContract]
     public class WcfListener : Listener</diff>
      <filename>IServiceOriented.ServiceBus/WcfListener.cs</filename>
    </modified>
  </modified>
  <removed type="array"/>
  <parents type="array">
    <parent>
      <id>46870d58158e9bda7494e71b5e61ce751cc9e19e</id>
    </parent>
  </parents>
  <author>
    <name>JEzell</name>
    <email>jezell@gmail.com</email>
  </author>
  <url>http://github.com/jezell/iserviceoriented/commit/cffe8a8a6f1b41efaf0f8237913db8f0cc984e4c</url>
  <id>cffe8a8a6f1b41efaf0f8237913db8f0cc984e4c</id>
  <committed-date>2008-08-31T18:10:54-07:00</committed-date>
  <authored-date>2008-08-31T18:10:54-07:00</authored-date>
  <message>Adding some xml comments</message>
  <tree>66139a42d72402ff5022f78e86ad80301265cf0f</tree>
  <committer>
    <name>JEzell</name>
    <email>jezell@gmail.com</email>
  </committer>
</commit>
