You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@activemq.apache.org by ta...@apache.org on 2018/08/27 21:15:44 UTC

[07/15] activemq-nms-amqp git commit: AMQNET-575: NMS AMQP Client Rework Add an NMS API implementation that wraps the AMQPnetLite .NET API.

http://git-wip-us.apache.org/repos/asf/activemq-nms-amqp/blob/432c9613/src/main/csharp/Util/IdGenerator.cs
----------------------------------------------------------------------
diff --git a/src/main/csharp/Util/IdGenerator.cs b/src/main/csharp/Util/IdGenerator.cs
new file mode 100644
index 0000000..965c748
--- /dev/null
+++ b/src/main/csharp/Util/IdGenerator.cs
@@ -0,0 +1,674 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+using System;
+using System.Net;
+using System.Security.Permissions;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+using Apache.NMS.Util;
+using Apache.NMS;
+
+namespace Apache.NMS.AMQP.Util
+{
+    #region Id Class
+
+    class Id : IComparable
+    {
+        public static readonly Id EMPTY = new Id();
+        protected const int DEFAULT_MAX_CAPACITY = 1;
+        protected static readonly int[] HashTable = new int[] { 2,3,5,7,11,13,17,19,23,29,31,37,41,43,47,53,59,61,67,71,73,79,83,89,97};
+        protected static readonly int HashTableSize = HashTable.Length;
+        protected delegate ComponentId InstanceFactory(object o);
+        protected static readonly Dictionary<Type, InstanceFactory> buildMap;
+
+        #region Class Initializer
+
+        static Id()
+        {
+            buildMap = new Dictionary<Type, InstanceFactory>();
+            buildMap.Add(typeof(String), (o) => { return new ComponentId<string>(o as string); });
+            buildMap.Add(typeof(UInt16), (o) => { return new ComponentId<UInt16>(Convert.ToUInt16(o)); });
+            buildMap.Add(typeof(UInt32), (o) => { return new ComponentId<UInt32>(Convert.ToUInt32(o)); });
+            buildMap.Add(typeof(UInt64), (o) => { return new ComponentId<UInt64>(Convert.ToUInt64(o)); });
+            buildMap.Add(typeof(Int16), (o) => { return new ComponentId<UInt16>(Convert.ToUInt16(o)); });
+            buildMap.Add(typeof(Int32), (o) => { return new ComponentId<UInt32>(Convert.ToUInt32(o)); });
+            buildMap.Add(typeof(Int64), (o) => { return new ComponentId<UInt64>(Convert.ToUInt64(o)); });
+            buildMap.Add(typeof(AtomicSequence), (o) =>
+            {
+                ulong val = 0;
+                AtomicSequence seq = o as AtomicSequence;
+                if (o != null && seq != null)
+                {
+                    val = seq.getAndIncrement();
+                }
+                return new ComponentId<UInt64>(val);
+            });
+            buildMap.Add(typeof(Guid), (o) =>
+            {
+                Guid id;
+                if (o == null)
+                {
+                    id = Guid.Empty;
+                }
+                else
+                {
+                    id = (Guid)o;
+                }
+                return new ComponentId<Guid>(id);
+            });
+            buildMap.Add(typeof(Id), (o) => { return new ComponentId<Id>(o as Id); });
+        }
+
+        #endregion
+
+        ComponentId[] components;
+        private bool isReadOnly = false;
+        private int length;
+        private int maxCapacity;
+        private int current;
+        private string componentDelimeter;
+        private int hashcode = 0;
+
+        #region Constructors
+
+        public Id(string delimeter, int size, int maxSize)
+        {
+            maxCapacity = Math.Max(maxSize, DEFAULT_MAX_CAPACITY);
+            length = size;
+            components = new ComponentId[length];
+            current = 0;
+            componentDelimeter = delimeter;
+        }
+
+        public Id(int size, int maxSize) : this(IdGenerator.ID_COMPONENT_DELIMETER, size, maxSize) { }
+
+        public Id(int size) : this(IdGenerator.ID_COMPONENT_DELIMETER, size, size) { }
+
+        public Id(params object[] args) : this(args.Length)
+        {
+            int added = this.AddAll(args);
+            if(added > maxCapacity)
+            {
+                Tracer.ErrorFormat("Id Format error.");
+            }
+            Generate();
+        }
+
+        #endregion
+
+        #region Public Properties
+
+        public int Size
+        {
+            get { return length; }
+        }
+
+        #endregion
+
+        #region Public Methods
+
+        public void Add(object component)
+        {
+            Tracer.DebugFormat("Adding Component To Id, component {0}, current index: {1}", component, current);
+            if (isReadOnly)
+            {
+                throw new NMSException("Invalid Operation when generating Component Id. Can not change id once generated.");
+            }
+            if (current >= maxCapacity)
+            {
+                throw new NMSException("Invalid Operation when generating Component Id. Can not add component. Adding Compoenent at full capacity " + maxCapacity);
+            }
+            if (current >= length)
+            {
+                grow(length * 2);
+            }
+            Type type = component.GetType();
+            InstanceFactory instf = null;
+            buildMap.TryGetValue(type, out instf);
+            if (instf == null)
+            {
+                throw new NMSException(string.Format("Invalid Id component type {0} for component {1}", type.ToString(), component.ToString()));
+            }
+            components[current] = instf(component);
+            current++;
+
+        }
+
+        public object[] GetComponents(int startIndex=0)
+        {
+            return GetComponents(startIndex, length);
+        }
+
+        public object[] GetComponents(int startIndex, int endIndex)
+        {
+            int eIndex = Math.Max(0,Math.Min(endIndex, length));
+            int sIndex = Math.Max(0, startIndex);
+            int resultLen = eIndex - sIndex;
+            if (resultLen<0)
+            {
+                return null;
+            }
+            object[] comps = new object[resultLen];
+            int index = 0;
+            for(int i=sIndex; i< eIndex; i++)
+            {
+                comps[index] = components[i].IdValue;
+                index++;
+            }
+            return comps;
+        }
+
+        public object GetComponent(int index)
+        {
+            if (isReadOnly)
+            {
+                if (index >= 0 && index < length)
+                {
+                    return components[index].IdValue;
+                }
+            }
+            return null;
+        }
+
+        public object GetFirstComponent(Type type)
+        {
+            if (isReadOnly)
+            {
+                for (int i = 0; i < length; i++)
+                {
+                    ComponentId cid = components[i];
+                    if (cid.ValueType.Equals(type))
+                    {
+                        return cid.IdValue;
+                    }
+                }
+            }
+            return null;
+        }
+
+        public object GetLastComponent(Type type)
+        {
+            if (isReadOnly)
+            {
+                for (int i = length; i > 0; i--)
+                {
+                    ComponentId cid = components[i - 1];
+                    if (cid.ValueType.Equals(type))
+                    {
+                        return cid.IdValue;
+                    }
+                }
+            }
+            return null;
+        }
+
+        public void Generate()
+        {
+            if (!isReadOnly)
+            {
+                isReadOnly = true;
+                this.GetHashCode();
+            }
+        }
+
+        #endregion
+
+        #region Object Override Methods
+
+        public override bool Equals(object obj)
+        {
+            if(GetHashCode() == obj.GetHashCode())
+            {
+                return true;
+            }
+            else
+            {
+                return CompareTo(obj) == 0;
+            }
+        }
+
+        public override int GetHashCode()
+        {
+            if(hashcode == 0 && isReadOnly && length > 0)
+            {
+                int hashIndex = 0;
+                ComponentId cid = components[0];
+                hashcode = HashTable[hashIndex] * cid.GetHashCode();
+                for (int i=1; i<length; i++)
+                {
+                    cid = components[i];
+                    hashIndex = i % HashTableSize;
+                    hashcode = hashcode ^ HashTable[hashIndex] * cid.GetHashCode(); 
+                }
+            }
+            return hashcode;
+        }
+
+        public override string ToString()
+        {
+            if (maxCapacity == 0)
+            {
+                return "0";
+            }
+            if (isReadOnly)
+            {
+                if (length == 0)
+                {
+                    return EMPTY.ToString();
+                }
+                StringBuilder sb = new StringBuilder();
+                ComponentId cid = this.components[0];
+                sb.Append(cid.ToString());
+                for (int i = 1; i < length; i++)
+                {
+                    cid = this.components[i];
+                    sb.Append(componentDelimeter);
+                    sb.Append(cid.ToString());
+                    
+                }
+                return sb.ToString();
+            }
+            else
+            {
+                return base.ToString();
+            }
+        }
+
+        #endregion
+
+        #region IComparable Methods
+
+        public int CompareTo(object obj)
+        {
+
+            if(obj!=null && obj is Id)
+            {
+                return CompareTo(obj as Id);
+            }
+            else if(obj == null)
+            {
+                return 1;
+            }
+            else
+            {
+                return -1;
+            }
+
+        }
+
+        public int CompareTo(Id that)
+        {
+            if(this.length > that.length)
+            {
+                return 1;
+            }
+            else if (this.length < that.length)
+            {
+                return -1;
+            }
+            else
+            {
+                int compare = 0;
+                for(int i=0; i<length; i++)
+                {
+                    ComponentId thisCid = this.components[i];
+                    ComponentId thatCid = that.components[i];
+                    compare = thisCid.CompareTo(thatCid);
+                    if ( compare > 0)
+                    {
+                        return 1;
+                    }
+                    else if ( compare < 0 )
+                    {
+                        return -1;
+                    }
+
+                }
+                return compare;
+            }
+        }
+
+        #endregion
+
+        #region Protected Methods
+
+        protected void grow(int newCapacity)
+        {
+            int size = Math.Min(newCapacity, maxCapacity);
+            ComponentId[] buffer = new ComponentId[size];
+            Array.Copy(this.components, buffer, this.length);
+            length = size;
+            this.components = buffer;
+        }
+
+        protected int AddAll(params object[] args)
+        {
+#if NET46
+            if(Tracer.IsDebugEnabled)
+            {
+                Tracer.DebugFormat("Adding Id components: {0} MaxCapacity: {1}", string.Join(",",
+                          args.Select(x => x.ToString()).ToArray()), maxCapacity);
+
+            }
+#else
+#endif
+            int added = 0;
+            foreach (object o in args)
+            {
+                Type type = o.GetType();
+
+                if (type.IsArray && type.Equals(typeof(object[])))
+                {
+                    object[] moreArgs = o as object[];
+                    int addlen = (moreArgs).Length;
+
+                    maxCapacity = maxCapacity + addlen - 1;
+                    added += this.AddAll(moreArgs);
+
+                }
+                else
+                {
+                    this.Add(o);
+                    added++;
+                }
+            }
+            return added;
+        }
+
+#endregion
+
+#region Inner ComponentId Classes
+
+        protected abstract class ComponentId : IComparable
+        {
+            protected object value;
+
+            protected ComponentId(object idvalue)
+            {
+                value = idvalue;
+            }
+
+            public object IdValue { get { return value; } }
+
+            public abstract Type ValueType { get; }
+
+            public virtual int CompareTo(object obj)
+            {
+                if(obj == null)
+                {
+                    return 1;
+                }
+                else if(obj is ComponentId)
+                {
+                    return CompareTo(obj as ComponentId);
+                }
+                else if (obj is IComparable)
+                {
+                    return -1 * (obj as IComparable).CompareTo(this.IdValue);
+                }
+                else
+                {
+                    return -1;
+                }
+            }
+
+            public virtual int CompareTo(ComponentId that)
+            {
+                if (this.ValueType.Equals(that.ValueType) || this.ValueType.IsEquivalentTo(that.ValueType))
+                {
+                    if (this.IdValue.Equals(that.IdValue))
+                    {
+                        return 0;
+                    }
+                    else
+                    {
+                        return this.GetHashCode() - that.GetHashCode();
+                    }
+                }
+                else if (this.IdValue is IComparable)
+                {
+                    return (this.IdValue as IComparable).CompareTo(that.IdValue);
+                }
+                else if (that.IdValue is IComparable)
+                {
+                    return -1 * (that.IdValue as IComparable).CompareTo(this.IdValue);
+                }
+                else
+                {
+                    return this.ValueType.GetHashCode() - that.ValueType.GetHashCode();
+                }
+                
+            }
+
+            public override bool Equals(object obj)
+            {
+                return CompareTo(obj) == 0;
+            }
+
+
+            public override int GetHashCode()
+            {
+                return this.IdValue.GetHashCode();
+            }
+
+            public override string ToString()
+            {
+                return value.ToString();
+            }
+        }
+        
+        protected class ComponentId<T> : ComponentId
+        {
+            public ComponentId(T val) : base(val)
+            {
+            }
+
+            public T Value
+            {
+                get { return (T)this.value; }
+            }
+
+            public override Type ValueType
+            {
+                get
+                {
+                    if (value != null)
+                    {
+                        return value.GetType();
+                    }
+                    return default(T).GetType();
+                }
+            }
+        }
+
+#endregion
+
+    }
+
+#endregion
+
+#region IdGenerator Class
+
+    class IdGenerator
+    {
+        public const string ID_COMPONENT_DELIMETER = ":";
+        protected static readonly string DEFAULT_PREFIX = "ID";
+        protected static string hostname = null;
+
+        protected readonly string prefix;
+        protected readonly AtomicSequence sequence = new AtomicSequence(1);
+
+#region Class Initializer
+
+        static IdGenerator()
+        {
+#if NETSTANDARD2_0
+            hostname = Dns.GetHostName();
+#else
+            DnsPermission permissions = null;
+            try
+            {
+                permissions = new DnsPermission(PermissionState.Unrestricted);
+            }
+            catch (Exception e)
+            {
+                Tracer.InfoFormat("{0}", e.StackTrace);
+            }
+            if (permissions != null)
+            {
+                hostname = Dns.GetHostName();
+            }
+#endif
+
+        }
+
+#endregion
+
+#region Constructors
+
+        public IdGenerator(string prefix)
+        {
+            this.prefix = RemoveEnd(prefix, ID_COMPONENT_DELIMETER)
+                + ((hostname == null)
+                    ?
+                    ""
+                    :
+                    ID_COMPONENT_DELIMETER + hostname)
+                ;
+        }
+
+        public IdGenerator() : this(DEFAULT_PREFIX)
+        {
+        }
+
+#endregion
+
+        public virtual Id GenerateId()
+        {
+            Id id = new Id(this.prefix, Guid.NewGuid(), sequence);
+            return id;
+        }
+
+        public virtual string generateID()
+        {
+            Id id = GenerateId();
+            return id.ToString();
+            //return string.Format("{0}{1}" + ID_COMPONENT_DELIMETER + "{2}", this.prefix, Guid.NewGuid().ToString(), sequence.getAndIncrement());
+        }
+
+        protected static string RemoveEnd(string s, string end)
+        {
+            string result = s;
+
+            if (s != null && end != null && s.EndsWith(end))
+            {
+                int sLen = s.Length;
+                int endLen = end.Length;
+                int newLen = sLen - endLen;
+                if (endLen > 0 && newLen > 0)
+                {
+                    StringBuilder sb = new StringBuilder(s, 0, newLen, newLen);
+                    result = sb.ToString();
+                }
+            }
+            return result;
+        }
+    }
+
+#endregion
+
+#region Derivative IdGenerator Classes
+
+    class NestedIdGenerator : IdGenerator
+    {
+        protected Id parentId;
+        protected bool removeParentPrefix;
+
+        public NestedIdGenerator(string prefix, Id pId, bool remove) : base(prefix)
+        {
+            parentId = pId;
+            removeParentPrefix = remove;
+        }
+
+        public NestedIdGenerator(string prefix, Id pId) : this(prefix, pId, false) { }
+
+        public NestedIdGenerator(Id pId):this(DEFAULT_PREFIX, pId) { }
+
+        public override Id GenerateId()
+        {
+            Id id;
+            if (removeParentPrefix)
+            {
+                int componentIndex = (parentId.Size == 1) ? 0 : 1;
+                id = new Id(prefix, parentId.GetComponents(componentIndex), sequence);
+            }
+            else
+            {
+                id = new Id(prefix, parentId, sequence);
+            }
+            
+            return id;
+        }
+
+        public override string generateID()
+        {
+            return GenerateId().ToString();
+        }
+    }
+
+    class CustomIdGenerator : IdGenerator
+    {
+        protected object[] parts;
+        protected bool isOnlyParts;
+
+
+        public CustomIdGenerator(string prefix, params object[] args) : base(prefix)
+        {
+            parts = args;
+        }
+
+        public CustomIdGenerator(bool onlyParts, params object[] args) : this(DEFAULT_PREFIX, args)
+        {
+            isOnlyParts = onlyParts;
+        }
+
+        public CustomIdGenerator(Id pId) : this(DEFAULT_PREFIX, pId) { }
+
+        public override Id GenerateId()
+        {
+            Id id;
+            if (isOnlyParts)
+            {
+                id = new Id(parts);
+            }
+            else
+            {
+                id = new Id(prefix, parts, sequence);
+            }
+            return id;
+        }
+
+        public override string generateID()
+        {
+            return GenerateId().ToString();
+        }
+    }
+
+#endregion
+}

http://git-wip-us.apache.org/repos/asf/activemq-nms-amqp/blob/432c9613/src/main/csharp/Util/LinkCache.cs
----------------------------------------------------------------------
diff --git a/src/main/csharp/Util/LinkCache.cs b/src/main/csharp/Util/LinkCache.cs
new file mode 100644
index 0000000..985f9e4
--- /dev/null
+++ b/src/main/csharp/Util/LinkCache.cs
@@ -0,0 +1,190 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+using System;
+using System.Collections;
+using System.Collections.Generic;
+using Apache.NMS;
+
+namespace Apache.NMS.AMQP.Util
+{
+    
+    #region Abstract Link Cache
+
+    internal abstract class LinkCache<TKey, TLink> : ICollection, IDisposable where TKey : class where TLink : MessageLink
+    {
+        protected readonly IDictionary<TKey, TLink> cachedLinks;
+
+        public LinkCache()
+        {
+            cachedLinks = CreateCache();
+        }
+
+        #region ICollection Properties
+
+        public int Count { get => cachedLinks.Count; }
+
+        public object SyncRoot { get => cachedLinks; }
+
+        public bool IsSynchronized { get => false; }
+
+        #endregion
+
+        #region ICollection Methods
+
+        public abstract void CopyTo(Array array, int index);
+        
+        public IEnumerator GetEnumerator()
+        {
+            return (cachedLinks as IEnumerable).GetEnumerator();
+        }
+
+        #endregion
+
+        #region Link Cache Properties
+
+        internal ICollection<TKey> Keys { get => cachedLinks.Keys; }
+
+        internal ICollection<TLink> Links { get => cachedLinks.Values; }
+
+        #endregion
+
+        #region Link Cache Methods
+
+        public TLink GetLink(TKey cacheId)
+        {
+            TLink link = null;
+            if (!IsValidKey(cacheId)) return link;
+            if(!cachedLinks.TryGetValue(cacheId, out link))
+            {
+                Tracer.InfoFormat("Failed to get Link for cache request id {0}", cacheId);
+            }
+            return link;
+        }
+
+        public void AddLink(TKey cacheId, TLink link)
+        {
+            if (HasLink(cacheId))
+            {
+                throw new NMSException("Cannot add link to cache with Id {0} which is already in use.");
+            }
+            cachedLinks.Add(cacheId, link);
+        }
+
+        public TLink RemoveLink(TKey cacheId)
+        {
+            TLink linkToRemove = null;
+            cachedLinks.TryGetValue(cacheId, out linkToRemove);
+            cachedLinks.Remove(cacheId);
+            return linkToRemove;
+        }
+
+        public bool HasLink(TKey cacheId)
+        {
+            return IsValidKey(cacheId) && cachedLinks.ContainsKey(cacheId);
+        }
+
+        public virtual void Close() { }
+
+        public virtual void Dispose()
+        {
+            Close();
+        }
+
+        #endregion
+
+        #region Abstract Link Cache Methods
+
+        protected abstract IDictionary<TKey, TLink> CreateCache();
+        protected abstract bool IsValidKey(TKey cacheId);
+        
+        #endregion
+    }
+
+    #endregion
+
+    #region Temporary Link Cache 
+
+    internal class TemporaryLinkCache : LinkCache<TemporaryDestination, TemporaryLink>
+    {
+        private Connection connection;
+        private Session tempSession;
+        internal TemporaryLinkCache(Connection connection) : base()
+        {
+            this.connection = connection;
+
+        }
+
+        internal Session Session
+        {
+            get
+            {
+                if(tempSession == null)
+                {
+                    tempSession = connection.CreateSession() as Session;
+                }
+                return tempSession;
+            }
+        }
+
+        protected override bool IsValidKey(TemporaryDestination cacheId)
+        {
+            return cacheId != null && cacheId.DestinationId != null && cacheId.DestinationId.Size > 0;
+        }
+
+        protected override IDictionary<TemporaryDestination, TemporaryLink> CreateCache()
+        {
+            return new Dictionary<TemporaryDestination, TemporaryLink>(new TemporaryDestinationComparer());
+        }
+
+        protected sealed class TemporaryDestinationComparer : IEqualityComparer<TemporaryDestination>
+        {
+            public bool Equals(TemporaryDestination x, TemporaryDestination y)
+            {
+                return x.Equals(y);
+            }
+
+            public int GetHashCode(TemporaryDestination obj)
+            {
+                return obj.GetHashCode();
+            }
+        }
+
+        public override void CopyTo(Array array, int index)
+        {
+            (this.cachedLinks as Dictionary<TemporaryDestination, TemporaryLink> as IDictionary).CopyTo(array, index);
+        }
+
+        public override void Close()
+        {
+            base.Close();
+            this.cachedLinks.Clear();
+            if(tempSession != null)
+            {
+                tempSession.Close();
+                tempSession = null;
+            }
+        }
+    }
+
+    #endregion
+    
+    #region Anonymous Link Cache
+
+    //TODO implement for Anonymous Fallback producer.
+
+    #endregion
+}

http://git-wip-us.apache.org/repos/asf/activemq-nms-amqp/blob/432c9613/src/main/csharp/Util/MessageSupport.cs
----------------------------------------------------------------------
diff --git a/src/main/csharp/Util/MessageSupport.cs b/src/main/csharp/Util/MessageSupport.cs
new file mode 100644
index 0000000..2941103
--- /dev/null
+++ b/src/main/csharp/Util/MessageSupport.cs
@@ -0,0 +1,397 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+using Apache.NMS;
+using Amqp.Framing;
+using Amqp.Types;
+using Apache.NMS.AMQP.Message;
+
+namespace Apache.NMS.AMQP.Util
+{
+    /// <summary>
+    /// Utility class containing constant values for NMS message fields, and values.
+    /// Also contains Utility methods for NMS messagId/correlationId and Destinations.
+    /// </summary>
+    class MessageSupport
+    {
+        // "x-opt-jms-msg-type" values
+        public const byte JMS_TYPE_MSG  = 0x00;
+        public const byte JMS_TYPE_OBJ  = 0x01;
+        public const byte JMS_TYPE_MAP  = 0x02;
+        public const byte JMS_TYPE_BYTE = 0x03;
+        public const byte JMS_TYPE_STRM = 0x04;
+        public const byte JMS_TYPE_TXT  = 0x05;
+
+        // "x-opt-jms-dest" and "x-opt-jms-reply-to" values
+        public const byte JMS_DEST_TYPE_QUEUE      = 0x00;
+        public const byte JMS_DEST_TYPE_TOPIC      = 0x01;
+        public const byte JMS_DEST_TYPE_TEMP_QUEUE = 0x02;
+        public const byte JMS_DEST_TYPE_TEMP_TOPIC = 0x03;
+
+        // Message Serialization ENCODING Annotation keys
+        public const string JMS_AMQP_TYPE_ENCODING = "JMS_AMQP_TYPE_ENCODING";
+        public const string JMS_JAVA_ENCODING = "JMS_JAVA_ENCODING";
+        public const string JMS_DONET_ENCODING = "JMS_DOTNET_ENCODING";
+
+        // Message Content-type values
+        public const string OCTET_STREAM_CONTENT_TYPE = "application/octet-stream";
+        public const string SERIALIZED_JAVA_OBJECT_CONTENT_TYPE = "application/x-java-serialized-object";
+
+        // Amqp.Message priority default value
+        public static readonly byte DEFAULT_PRIORITY_BYTE = Convert.ToByte((int)NMSConstants.defaultPriority);
+
+        public static readonly Data EMPTY_DATA = new Data() { Binary = new byte[] { } };
+        public static readonly AmqpValue NULL_AMQP_VALUE_BODY = new AmqpValue() { Value = null };
+
+        // Amqp Message Outcome instances
+        public static readonly Amqp.Framing.Accepted ACCEPTED_INSTANCE = new Amqp.Framing.Accepted();
+        public static readonly Amqp.Framing.Released RELEASED_INSTANCE = new Amqp.Framing.Released();
+        public static readonly Amqp.Framing.Rejected REJECTED_INSTANCE = new Amqp.Framing.Rejected();
+        public static readonly Amqp.Framing.Modified MODIFIED_INSTANCE = new Amqp.Framing.Modified();
+        public static readonly Amqp.Framing.Modified MODIFIED_FAILED_INSTANCE = new Amqp.Framing.Modified() { DeliveryFailed = true };
+        public static readonly AckType DEFAULT_ACK_TYPE = AckType.ACCEPTED;
+
+        // Message Id constants
+        public const string NMS_ID_PREFIX = "ID:";
+        public const string AMQP_STRING_PREFIX = "AMQP_STRING:";
+        public const string AMQP_ULONG_PREFIX = "AMQP_ULONG:";
+        public const string AMQP_BINARY_PREFIX = "AMQP_BINARY:";
+        public const string AMQP_UUID_PREFIX = "AMQP_UUID:";
+        public const string AMQP_NO_PREFIX = "AMQP_NO_PREFIX:";
+
+        private const string AMQP_TYPE = "AMQP_";
+        private static readonly int NMS_ID_PREFIX_LENGTH = NMS_ID_PREFIX.Length;
+        private static readonly int AMQP_TYPE_LENGTH = AMQP_TYPE.Length;
+        private static readonly int AMQP_STRING_PREFIX_LENGTH = AMQP_STRING_PREFIX.Length;
+        private static readonly int AMQP_BINARY_PREFIX_LENGTH = AMQP_BINARY_PREFIX.Length;
+        private static readonly int AMQP_ULONG_PREFIX_LENGTH = AMQP_ULONG_PREFIX.Length;
+        private static readonly int AMQP_UUID_PREFIX_LENGTH = AMQP_UUID_PREFIX.Length;
+        private static readonly int AMQP_NO_PREFIX_LENGTH = AMQP_NO_PREFIX.Length;
+        private static readonly char[] HEX_CHARS = "0123456789ABCDEF".ToCharArray();
+
+        public static IDestination CreateDestinationFromMessage(Connection source, Properties properties, byte type, bool replyTo = false)
+        {
+            IDestination dest = null;
+            if(properties==null || source == null) { return dest; }
+            bool isPropertyNull = (!replyTo) ? properties.To != null : properties.ReplyTo != null;
+            if (isPropertyNull)
+            {
+                string destname = (!replyTo) ? properties.To : properties.ReplyTo;
+                destname = UriUtil.GetDestinationName(destname, source);
+                switch (type)
+                {
+                    case JMS_DEST_TYPE_TEMP_QUEUE:
+                        dest = new TemporaryQueue(source, destname);
+                        break;
+                    case JMS_DEST_TYPE_QUEUE:
+                        dest = new Queue(source, destname);
+                        break;
+                    case JMS_DEST_TYPE_TEMP_TOPIC:
+                        dest = new TemporaryTopic(source, destname);
+                        break;
+                    case JMS_DEST_TYPE_TOPIC:
+                        dest = new Topic(source, destname);
+                        break;
+                }
+            }
+            return dest;
+        }
+
+        public static sbyte GetValueForDestination(IDestination destination)
+        {
+            sbyte b = 0x00; // same as queue.
+            if (destination != null)
+            {
+                if (destination.IsTopic)
+                {
+                    if (destination.IsTemporary)
+                    {
+                        return (sbyte)JMS_DEST_TYPE_TEMP_TOPIC;
+                    }
+                    else
+                    {
+                        return (sbyte)JMS_DEST_TYPE_TOPIC;
+                    }
+                }
+                else if (destination.IsQueue)
+                {
+                    if (destination.IsTemporary)
+                    {
+                        return (sbyte)JMS_DEST_TYPE_TEMP_QUEUE;
+                    }
+                    else
+                    {
+                        return (sbyte)JMS_DEST_TYPE_QUEUE;
+                    }
+                }
+            }
+            return b;
+        }
+
+        public static byte GetValueForPriority(MsgPriority mp)
+        {
+            return Convert.ToByte((int)mp);
+        }
+
+        public static MsgPriority GetPriorityFromValue(byte value)
+        {
+            MsgPriority result = NMSConstants.defaultPriority;
+
+            switch (value)
+            {
+                case 0x00:
+                    result = MsgPriority.Lowest;
+                    break;
+                case 0x01:
+                    result = MsgPriority.VeryLow;
+                    break;
+                case 0x02:
+                    result = MsgPriority.Low;
+                    break;
+                case 0x03:
+                    result = MsgPriority.AboveLow;
+                    break;
+                case 0x04:
+                    result = MsgPriority.BelowNormal;
+                    break;
+                case 0x05:
+                    result = MsgPriority.Normal;
+                    break;
+                case 0x06:
+                    result = MsgPriority.AboveNormal;
+                    break;
+                case 0x07:
+                    result = MsgPriority.High;
+                    break;
+                case 0x08:
+                    result = MsgPriority.VeryHigh;
+                    break;
+                case 0x09:
+                    result = MsgPriority.Highest;
+                    break;
+                default:
+                    break;
+            }
+            
+            return result;
+        }
+
+        public static object CreateAMQPMessageId(string nmsId)
+        {
+            if(nmsId == null)
+            {
+                return null;
+            }
+            if (!HasNMSIdPrefix(nmsId))
+            {
+                // application specific msg id return as is.
+                return nmsId;
+            }
+
+            try
+            {
+                if (HasAMQPNoPrefix(nmsId, NMS_ID_PREFIX_LENGTH))
+                {
+                    return nmsId.Substring(NMS_ID_PREFIX_LENGTH + AMQP_NO_PREFIX_LENGTH);
+                }
+                else if (HasAMQPStringPrefix(nmsId, NMS_ID_PREFIX_LENGTH))
+                {
+                    return nmsId.Substring(NMS_ID_PREFIX_LENGTH + AMQP_STRING_PREFIX_LENGTH);
+                }
+                else if (HasAMQPBinaryPrefix(nmsId, NMS_ID_PREFIX_LENGTH))
+                {
+                    string hexString = nmsId.Substring(NMS_ID_PREFIX_LENGTH + AMQP_BINARY_PREFIX_LENGTH).ToUpper();
+                    return ToByteArray(hexString, nmsId);
+                }
+                else if (HasAMQPULongPrefix(nmsId, NMS_ID_PREFIX_LENGTH))
+                {
+                    string ulongString = nmsId.Substring(NMS_ID_PREFIX_LENGTH + AMQP_ULONG_PREFIX_LENGTH);
+                    return Convert.ToUInt64(ulongString);
+                }
+                else if (HasAMQPUuidPrefix(nmsId, NMS_ID_PREFIX_LENGTH))
+                {
+                    string guidString = nmsId.Substring(NMS_ID_PREFIX_LENGTH + AMQP_UUID_PREFIX_LENGTH);
+                    return Guid.Parse(guidString);
+                }
+                else
+                {
+                    return nmsId;
+                }
+
+            }
+            catch (Exception e)
+            {
+                throw new NMSException("Id Conversion Failure. Provided Id: " + nmsId, e);
+            }
+        }
+
+        public static string CreateNMSMessageId(object amqpId)
+        {
+            if(null == amqpId)
+            {
+                return null;
+            }
+            if(amqpId is string)
+            {
+                string id = amqpId as string;
+                if (!HasNMSIdPrefix(id))
+                {
+                    return NMS_ID_PREFIX + AMQP_NO_PREFIX + id;
+                }
+                else if (HasEncodingTypePrefix(id, NMS_ID_PREFIX_LENGTH))
+                {
+                    return NMS_ID_PREFIX + AMQP_STRING_PREFIX + id;
+                }
+                else
+                {
+                    return id;
+                }
+            }
+            else if (amqpId is Guid)
+            {
+                return NMS_ID_PREFIX + AMQP_UUID_PREFIX + amqpId.ToString();
+            }
+            else if (amqpId is ulong)
+            {
+                return NMS_ID_PREFIX + AMQP_ULONG_PREFIX + amqpId.ToString();
+            }
+            else if (amqpId is byte[])
+            {
+                return NMS_ID_PREFIX + AMQP_BINARY_PREFIX + ToHexString(amqpId as byte[]);
+            }
+            else
+            {
+                throw new NMSException("Unsupported Id Type provided: ", amqpId.GetType().FullName);
+            }
+        }
+
+        private static bool HasNMSIdPrefix(string id)
+        {
+            if(id == null)
+            {
+                return false;
+            }
+            return id.StartsWith(NMS_ID_PREFIX);
+        }
+
+        private static bool HasAMQPNoPrefix(string id, int offset)
+        {
+            if (id.Length - offset < AMQP_NO_PREFIX_LENGTH)
+            {
+                return false;
+            }
+            return id.IndexOf(AMQP_NO_PREFIX, offset, AMQP_NO_PREFIX_LENGTH) - offset == 0;
+        }
+
+        private static bool HasAMQPBinaryPrefix(string id, int offset)
+        {
+            if (id.Length - offset < AMQP_BINARY_PREFIX_LENGTH)
+            {
+                return false;
+            }
+            return id.IndexOf(AMQP_BINARY_PREFIX, offset, AMQP_BINARY_PREFIX_LENGTH) - offset == 0;
+        }
+
+        private static bool HasAMQPStringPrefix(string id, int offset)
+        {
+            if (id.Length - offset < AMQP_STRING_PREFIX_LENGTH)
+            {
+                return false;
+            }
+            return id.IndexOf(AMQP_STRING_PREFIX, offset, AMQP_STRING_PREFIX_LENGTH) - offset == 0;
+        }
+
+        private static bool HasAMQPULongPrefix(string id, int offset)
+        {
+            if (id.Length - offset < AMQP_ULONG_PREFIX_LENGTH)
+            {
+                return false;
+            }
+            return id.IndexOf(AMQP_ULONG_PREFIX, offset, AMQP_ULONG_PREFIX_LENGTH) - offset == 0;
+        }
+
+        private static bool HasAMQPUuidPrefix(string id, int offset)
+        {
+            if (id.Length - offset < AMQP_UUID_PREFIX_LENGTH)
+            {
+                return false;
+            }
+            return id.IndexOf(AMQP_UUID_PREFIX, offset, AMQP_UUID_PREFIX_LENGTH) - offset == 0;
+        }
+
+        private static bool HasEncodingTypePrefix(string id, int offset)
+        {
+            if (id.Length - offset < AMQP_NO_PREFIX_LENGTH)
+            {
+                return false;
+            }
+            if (id.IndexOf(AMQP_TYPE,offset, AMQP_TYPE_LENGTH) != 0)
+            {
+                return false;
+            }
+            return HasAMQPBinaryPrefix(id, offset) ||
+                HasAMQPNoPrefix(id, offset) ||
+                HasAMQPStringPrefix(id, offset) ||
+                HasAMQPULongPrefix(id, offset) ||
+                HasAMQPUuidPrefix(id, offset);
+        } 
+
+        private static string ToHexString(byte[] bytes)
+        {
+            if(bytes == null)
+            {
+                return null;
+            }
+            StringBuilder sb = new StringBuilder(bytes.Length);
+            foreach(byte b in bytes)
+            {
+                int upper = (b >> 4) & 0x0F;
+                int lower = b & 0x0F;
+                sb.Append(HEX_CHARS[upper]);
+                sb.Append(HEX_CHARS[lower]);
+            }
+            return sb.ToString();
+        }
+
+        private static byte[] ToByteArray(string hex, string originalId)
+        {
+            if (hex == null || hex.Length % 2 != 0)
+            {
+                throw new NMSException("Invalid Binary MessageId " + originalId);
+            }
+            int size = hex.Length / 2;
+            int index = 0;
+            byte[] result = new byte[size];
+            for (int i=0; i<result.Length; i++)
+            {
+                char upper = hex[index];
+                index++;
+                char lower = hex[index];
+                index++;
+                char[] subchars = { upper, lower };
+                string substring = new string(subchars);
+                result[i] = Convert.ToByte(substring, 16);
+            }
+            return result;
+        }
+
+    }
+}

http://git-wip-us.apache.org/repos/asf/activemq-nms-amqp/blob/432c9613/src/main/csharp/Util/PropertyUtil.cs
----------------------------------------------------------------------
diff --git a/src/main/csharp/Util/PropertyUtil.cs b/src/main/csharp/Util/PropertyUtil.cs
new file mode 100644
index 0000000..7b68bd5
--- /dev/null
+++ b/src/main/csharp/Util/PropertyUtil.cs
@@ -0,0 +1,1294 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+using Apache.NMS;
+using System;
+using System.Collections;
+using System.Collections.Generic;
+using System.Collections.Specialized;
+using System.Linq;
+using System.Reflection;
+using System.Text;
+using System.Threading.Tasks;
+using System.Security.Authentication;
+
+using Apache.NMS.AMQP.Transport.Secure;
+using Apache.NMS.AMQP.Transport;
+
+namespace Apache.NMS.AMQP.Util
+{
+    class PropertyUtil
+    {
+        private const string PROPERTY_TERM_SEPARATOR = ".";
+        public const string PROPERTY_PREFIX = "NMS" + PROPERTY_TERM_SEPARATOR;
+        
+        public static string CreateProperty(string name, string subprefix = "", string prefix = PROPERTY_PREFIX)
+        {
+            string propertyPrefix = prefix +
+                (prefix.Length > 0 && !prefix.EndsWith(PROPERTY_TERM_SEPARATOR)
+                    ?
+                    PROPERTY_TERM_SEPARATOR
+                    :
+                    ""
+                 );
+
+            string subPropertyTerm = subprefix +
+                (subprefix.Length > 0 && !subprefix.EndsWith(PROPERTY_TERM_SEPARATOR)
+                    ?
+                    PROPERTY_TERM_SEPARATOR
+                    :
+                    ""
+                );
+            return propertyPrefix + subPropertyTerm + name;
+        }
+
+        public static void SetProperties(object obj, StringDictionary properties, string propertyPrefix = PROPERTY_PREFIX)
+        {
+            Dictionary<string, PropertyInfo> props = GetPropertiesForClass(obj);
+            foreach (string rawkey in properties.Keys)
+            {
+                string key = removePrefix(propertyPrefix, rawkey);
+                Tracer.DebugFormat("Searching for Property: \"{0}\"", key);
+                if (props.ContainsKey(key))
+                {
+                    Tracer.DebugFormat(
+                        "Assigning Property {0} to {1}.{2} with value {3}",
+                        key, obj.GetType().Namespace, obj.GetType().Name, properties[rawkey]
+                        );
+#if NET40
+                    if (props[key].GetSetMethod() != null)
+#else
+                    if(props[key].SetMethod!=null)
+#endif
+                        props[key].SetValue(obj, ConvertType(props[key].PropertyType, properties[rawkey]), null);
+                }
+
+            }
+        }
+
+        public static StringDictionary GetProperties(object obj, string propertyPrefix = PROPERTY_PREFIX)
+        {
+            StringDictionary result = new StringDictionary();
+            Dictionary<string, PropertyInfo> props = GetPropertiesForClass(obj);
+            string propsPrefix = propertyPrefix +
+                (
+                propertyPrefix.Length > 0 && !propertyPrefix.EndsWith(PROPERTY_TERM_SEPARATOR)
+                ?
+                    PROPERTY_TERM_SEPARATOR
+                :
+                    ""
+                );
+            foreach (string key in props.Keys)
+            {
+                object value = props[key].GetValue(obj, null);
+                if (value != null)
+                {
+                    result[propertyPrefix + key] = value.ToString();
+                }
+            }
+            return result;
+        }
+
+        public static object ConvertType(Type targetType, string value)
+        {
+            if (targetType.IsPrimitive)
+            {
+                return Convert.ChangeType(value, targetType);
+            }
+            else if (targetType.Equals(typeof(string)))
+            {
+                return value;
+            }
+            return null;
+        }
+
+        private static string removePrefix(string prefix, string propertyName)
+        {
+            if (propertyName.StartsWith(prefix, StringComparison.CurrentCultureIgnoreCase) && prefix.Length > 0)
+            {
+                return propertyName.Remove(0, prefix.Length);
+            }
+            else
+            {
+                return propertyName;
+            }
+        }
+
+        public static Dictionary<string, PropertyInfo> GetPropertiesForClass(object obj)
+        {
+            MemberInfo[] members = obj.GetType().GetMembers();
+            Dictionary<string, PropertyInfo> properties = new Dictionary<string, PropertyInfo>();
+            foreach (MemberInfo member in members)
+            {
+                string memberName = member.Name;
+                if (member != null && member is PropertyInfo)
+                {
+                    PropertyInfo prop = member as PropertyInfo;
+                    properties.Add(memberName.ToLower(), prop);
+                }
+            }
+            return properties;
+        }
+        
+        public static StringDictionary Clone(StringDictionary original)
+        {
+            StringDictionary clone = new StringDictionary();
+            foreach (string key in original.Keys)
+            {
+                clone.Add(key?.Clone() as string, original[key]?.Clone() as string);
+            }
+            return clone;
+        }
+
+        /// <summary>
+        /// See <see cref="Merge(StringDictionary, StringDictionary, out StringDictionary, string, string, string)"/>
+        /// </summary>
+        /// <param name="one"></param>
+        /// <param name="other"></param>
+        /// <param name="onePrefix"></param>
+        /// <param name="otherPrefix"></param>
+        /// <param name="mergePrefix"></param>
+        /// <returns></returns>
+        public static StringDictionary Merge(
+            StringDictionary one, 
+            StringDictionary other, 
+            string onePrefix = PROPERTY_PREFIX, 
+            string otherPrefix = PROPERTY_PREFIX,
+            string mergePrefix = PROPERTY_PREFIX
+            )
+        {
+            StringDictionary d;
+            return Merge(one, other, out d, onePrefix, otherPrefix, mergePrefix);
+        }
+
+
+        /// <summary>
+        /// Takes all properties from one StringDictionary and merges them with the other StringDictionary.
+        /// The properties in "one" are prefered over the "other".
+        /// 
+        /// </summary>
+        /// <param name="one">StringDictionary containing properties.</param>
+        /// <param name="other">Another StringDictionary containing properties.</param>
+        /// <param name="cross">Holds all the properties from the "other" StringDictionary that are not used because one has the properties.</param>
+        /// <param name="onePrefix">Optional string prefix for the properties in "one".</param>
+        /// <param name="otherPrefix">Optional string prefix for the properties in "other".</param>
+        /// <param name="mergePrefix">Optional string prefix for the properties in result.</param>
+        /// <returns>Merged StringDictionary with properties from both "one" and "other".</returns>
+        public static StringDictionary Merge(
+            StringDictionary one, 
+            StringDictionary other, 
+            out StringDictionary cross, 
+            string onePrefix = PROPERTY_PREFIX, 
+            string otherPrefix = PROPERTY_PREFIX,
+            string mergePrefix = PROPERTY_PREFIX
+            )
+        {
+            if (one == null && other != null)
+            {
+                cross = null;
+                return Clone(other);
+            }
+            else if (one!=null && other == null)
+            {
+                cross = null;
+                return Clone(one);
+            }
+            else if (one == null && other == null)
+            {
+                cross = null;
+                return new StringDictionary();
+            }
+            StringDictionary result = new StringDictionary();
+            StringDictionary dups = new StringDictionary();
+            
+            Array arr = new string[other.Keys.Count];
+            other.Keys.CopyTo(arr, 0);
+            ArrayList otherKeys = new ArrayList(arr); 
+
+            string mPre = mergePrefix +
+                (
+                mergePrefix.Length > 0 && !mergePrefix.EndsWith(PROPERTY_TERM_SEPARATOR)
+                ?
+                    PROPERTY_TERM_SEPARATOR
+                :
+                    ""
+                );
+            mergePrefix.ToLower();
+
+            string onePre = onePrefix +
+                (
+                onePrefix.Length > 0 && !onePrefix.EndsWith(PROPERTY_TERM_SEPARATOR)
+                ?
+                    PROPERTY_TERM_SEPARATOR
+                :
+                    ""
+                );
+            onePre.ToLower();
+
+            string otherPre = otherPrefix +
+                (
+                otherPrefix.Length > 0 && !otherPrefix.EndsWith(PROPERTY_TERM_SEPARATOR)
+                ?
+                    PROPERTY_TERM_SEPARATOR
+                :
+                    ""
+                );
+            otherPre.ToLower();
+
+            foreach (string rawkey in one.Keys)
+            {
+                string key = removePrefix(onePre, rawkey);
+                string otherkey = (otherPre + key).ToLower();
+                string mergekey = (mPre + key).ToLower();
+                if (!result.ContainsKey(mergekey))
+                {
+                    result.Add(mergekey, one[rawkey]);
+                }
+                if (other.ContainsKey(otherkey))
+                {
+                    otherKeys.Remove(otherkey);
+                    dups.Add(mergekey, other[otherkey]);
+                }
+            }
+
+            foreach (string rawkey in otherKeys)
+            {
+                string key = removePrefix(otherPre, rawkey);
+                result.Add(mPre + key, other[rawkey]);
+            }
+
+            cross = dups.Count == 0 ? null : dups;
+            return result;
+        }
+
+        public static string ToString(IList set)
+        {
+            if (set == null)
+            {
+                return "null";
+            }
+            if (set.Count == 0)
+            {
+                return "[]";
+            }
+            string result = "[";
+            foreach (object o in set)
+            {
+                result += o.ToString() + ",";
+            }
+            return result.Substring(0, result.Length - 1) + "]";
+        }
+
+        private static string ToString(ArrayList set)
+        {
+            if(set == null)
+            {
+                return "null";
+            }
+            if(set.Count == 0)
+            {
+                return "[]";
+            }
+            string result = "[";
+            foreach(object o in set)
+            {
+                result += o.ToString() + ",";
+            }
+            return result.Substring(0,result.Length - 1) + "]";
+        }
+
+        public static string ToString(StringDictionary properties)
+        {
+            if(properties == null)
+            {
+                return "null";
+            }
+            if (properties.Count == 0)
+            {
+                return "[]";
+            }
+            string result = "[\n";
+            foreach(string s in properties.Keys)
+            {
+                result += string.Format("{0} : {1},\n", s, properties[s]);
+            }
+            return result.Substring(0,result.Length-2) + "\n]";
+        }
+
+        public static IDictionary<K,V> Clone<K,V>(IDictionary<K,V> dict)
+        {
+            if (dict == null) return null;
+            Dictionary<K, V> clone = new Dictionary<K, V>(dict.Count);
+            dict.CopyTo(clone.ToArray(), 0);
+            return clone;
+        }
+    }
+
+#region NMS Resource Property Interceptor classes StringDictionary based
+
+#region abstract Property Interceptor classes
+
+    internal abstract class PropertyInterceptor<T> : StringDictionary where T : class
+    {
+        protected delegate void ApplyProperty(T instance, string key, string value);
+        protected delegate string GetProperty(T instance, string key);
+        protected delegate void ClearProperty(T instance);
+        protected delegate bool CheckProperty(T instance);
+
+        protected struct Interceptor
+        {
+            public ApplyProperty Setter;
+            public GetProperty Getter;
+            public ClearProperty Reset;
+            public CheckProperty Exists;
+        }
+
+
+        private readonly StringDictionary properties;
+        private readonly IDictionary<string, Interceptor> interceptors;
+        private readonly T instance;
+        protected PropertyInterceptor(T instance, StringDictionary properties, IDictionary<string, Interceptor> interceptors) : base()
+        {
+            this.properties = properties;
+            this.instance = instance;
+
+            // initialize interceptor map
+            this.interceptors = new Dictionary<string, Interceptor>();
+            foreach (string key in interceptors.Keys)
+            {
+                AddInterceptor(key, interceptors[key]);
+            }
+
+        }
+
+        protected T Instance { get { return instance; } }
+
+        protected StringDictionary Properties { get { return properties; } }
+
+        protected void AddInterceptor(string key, Interceptor interceptor)
+        {
+            bool updated = false;
+            // add new interceptor 
+            if (!interceptors.ContainsKey(key))
+            {
+                this.interceptors.Add(key, interceptor);
+            }
+            else
+            {
+                // update interceptor
+                // this allows subs classes to override base classes.
+                this.interceptors[key] = interceptor;
+                updated = true;
+            }
+            // Remove intercepted properties from base string dictionary
+            if (properties.ContainsKey(key) || updated)
+            {
+                SetProperty(key, properties[key]);
+                properties.Remove(key);
+            }
+        }
+
+        protected void AddProperty(string key, string value)
+        {
+            if (interceptors.ContainsKey(key))
+            {
+                interceptors[key].Setter(instance, key, value);
+            }
+            else
+            {
+                properties.Add(key, value);
+            }
+        }
+
+        protected void SetProperty(string key, string value)
+        {
+            if (interceptors.ContainsKey(key))
+            {
+                interceptors[key].Setter(instance, key, value);
+            }
+            else
+            {
+                properties[key] = value;
+            }
+        }
+
+        protected string GetValue(string key)
+        {
+            string value = null;
+            if (interceptors.ContainsKey(key))
+            {
+                if (interceptors[key].Exists(instance))
+                {
+                    value = interceptors[key].Getter(instance, key);
+                }
+            }
+            else
+            {
+                value = properties[key];
+            }
+            return value;
+        }
+
+        protected int InterceptorCount
+        {
+            get
+            {
+                int count = 0;
+                foreach (string key in interceptors.Keys)
+                {
+                    Interceptor i = interceptors[key];
+                    if (i.Exists(instance))
+                    {
+                        count++;
+                    }
+                }
+                return count;
+            }
+        }
+
+        #region IDictionary<> Methods
+
+        public override int Count => this.properties.Count + InterceptorCount;
+
+        public override void Add(string key, string value)
+        {
+            AddProperty(key, value);
+        }
+
+        public override string this[string key]
+        {
+            get
+            {
+                return GetValue(key);
+            }
+            set
+            {
+                SetProperty(key, value);
+            }
+        }
+
+        public override void Clear()
+        {
+            this.properties.Clear();
+            Interceptor[] set = interceptors.Values.ToArray();
+            foreach (Interceptor i in set)
+            {
+                i.Reset?.Invoke(Instance);
+            }
+        }
+
+        public override void Remove(string key)
+        {
+            if (this.properties.ContainsKey(key))
+            {
+                this.properties.Remove(key);
+            }
+            else if (this.interceptors.ContainsKey(key))
+            {
+                if (this.interceptors[key].Exists(Instance))
+                {
+                    this.interceptors[key].Reset(Instance);
+                }
+            }
+        }
+
+        public override bool ContainsKey(string key)
+        {
+            if (this.properties.ContainsKey(key))
+            {
+                return true;
+            }
+            else if (this.interceptors.ContainsKey(key))
+            {
+                return this.interceptors[key].Exists(Instance);
+            }
+            return false;
+        }
+
+        public override ICollection Keys
+        {
+            get
+            {
+                ISet<string> keys = new HashSet<string>();
+                foreach (string key in interceptors.Keys)
+                {
+                    Interceptor i = interceptors[key];
+                    if (i.Exists(instance))
+                    {
+                        keys.Add(key);
+                    }
+                }
+                foreach (string key in properties.Keys)
+                {
+                    keys.Add(key);
+                }
+
+                return keys.ToList();
+            }
+        }
+
+        public override ICollection Values
+        {
+            get
+            {
+                ISet<object> values = new HashSet<object>();
+                foreach (string key in interceptors.Keys)
+                {
+                    Interceptor i = interceptors[key];
+                    if (i.Exists(instance))
+                    {
+                        values.Add(i.Getter(instance, key));
+                    }
+                }
+                foreach (object value in properties.Values)
+                {
+                    values.Add(value);
+                }
+
+                return values.ToList();
+            }
+        }
+
+        #endregion
+        public override string ToString()
+        {
+            string result = base.ToString();
+            foreach (string key in Keys)
+            {
+                result += "\n" + key.ToString() + ": " + GetValue(key).ToString();
+            }
+            return result;
+        }
+
+    }
+
+    internal abstract class NMSResourcePropertyInterceptor<T, I> : PropertyInterceptor<T> where I : ResourceInfo where T : NMSResource<I>
+    {
+        protected NMSResourcePropertyInterceptor(T instance, StringDictionary properties, IDictionary<string, Interceptor> interceptors) : base(instance, properties, interceptors)
+        {
+
+        }
+    }
+
+    #region RelfectionPropertyInterceptor
+
+    internal abstract class ReflectionPropertyInterceptor<T> : PropertyInterceptor<T> where T : class
+    {
+        #region static methods
+
+        private static bool DefaultExists(T instance)
+        {
+            return true;
+        }
+        
+        private static void SetReflectedValue(PropertyInfo info, object instance, string value)
+        {
+            if (info.GetSetMethod() != null)
+            {
+                object objValue = ParseReflectedValue(info, value);
+                info.SetValue(instance, objValue, null);
+            }
+        }
+
+        private static object GetReflectedValue(PropertyInfo info, object instance)
+        {
+            object value = null;
+            if (info.GetGetMethod() != null)
+            {
+                value = info.GetValue(instance);
+            }
+            return value;
+        }
+
+        private static object ParseReflectedValue(PropertyInfo info, string value)
+        {
+            Type targetType = info.PropertyType;
+            return PropertyUtil.ConvertType(targetType, value);
+        }
+
+        #endregion
+
+        protected struct ReflectedInteceptor
+        {
+            public PropertyInfo ReflectedProperty;
+            public Interceptor BaseInterceptor;
+        }
+
+
+        private Dictionary<string, ReflectedInteceptor> autoInterceptors = null;
+
+        #region Contructor
+
+        protected ReflectionPropertyInterceptor(T instance, StringDictionary properties, IDictionary<string, Interceptor> interceptors ) : base(instance, properties, interceptors)
+        {
+            this.autoInterceptors = CreateReflectionInterceptors(instance);
+            if (this.autoInterceptors != null)
+            {
+                foreach (string propertyName in this.autoInterceptors.Keys)
+                {
+                    this.AddInterceptor(propertyName, this.autoInterceptors[propertyName].BaseInterceptor);
+                }
+
+                if (Tracer.IsDebugEnabled)
+                {
+                    StringBuilder sb = new StringBuilder();
+#if TRACE
+                    sb.AppendFormat("Generated {0} reflection properties, Properties = [", this.autoInterceptors.Keys.Count);
+                    foreach (string propertyName in this.autoInterceptors.Keys)
+                    {
+                        sb.AppendFormat("\n\t{0},\n", propertyName);
+                    }
+                    sb.AppendFormat("]");
+#else
+                    sb.AppendFormat("Generated {0} reflection properties", this.autoInterceptors.Keys.Count);
+#endif
+                    Tracer.DebugFormat(sb.ToString());
+                }
+                
+            }
+        }
+
+        #endregion
+
+        #region abstract Properties
+
+        protected abstract string PropertyPrefix { get; }
+
+        #endregion
+
+        protected abstract bool CanReflect(PropertyInfo reflectedProperty);
+
+        #region Private Methods
+
+        private Interceptor? CreateReflectedInterceptor(PropertyInfo reflectedProperty)
+        {
+            Interceptor? result = null;
+
+            if (reflectedProperty.GetSetMethod() == null)
+            {
+
+            }
+            else
+            {
+
+
+                ApplyProperty reflectedSetter = (inst, key, value) =>
+                {
+                    SetReflectedValue(reflectedProperty, inst, value);
+                };
+
+                GetProperty reflectedGetter = (inst, key) =>
+                {
+                    return GetReflectedValue(reflectedProperty, inst)?.ToString();
+                };
+
+                ClearProperty reflectedClear = (inst) =>
+                {
+                    SetReflectedValue(reflectedProperty, inst, null);
+                };
+
+                CheckProperty reflectedExists = DefaultExists;
+
+                result = new Interceptor()
+                {
+                    Getter = reflectedGetter,
+                    Setter = reflectedSetter,
+                    Reset = reflectedClear,
+                    Exists = reflectedExists
+                };
+            }
+
+            return result;
+        }
+
+        private Dictionary<string, ReflectedInteceptor> CreateReflectionInterceptors(T instance)
+        {
+            Dictionary<string, PropertyInfo> objProperties = PropertyUtil.GetPropertiesForClass(instance);
+
+            Dictionary<string, ReflectedInteceptor> result = new Dictionary<string, ReflectedInteceptor>();
+
+            if (Tracer.IsDebugEnabled)
+            {
+
+                List<string> stringPropertyNames = new List<string>(objProperties.Keys.Count);
+                foreach (string pName in objProperties.Keys)
+                {
+                    string propertyName = this.PropertyPrefix + pName;
+                    stringPropertyNames.Add(propertyName);
+                }
+
+                Tracer.DebugFormat("Creating reflection interceptors for Class instance {0}, Generating Properties = {1}", instance.GetType().Name, PropertyUtil.ToString(stringPropertyNames));
+            }
+
+            foreach (string key in objProperties.Keys)
+            {
+                string propertyName = this.PropertyPrefix + key;
+                PropertyInfo info = objProperties[key];
+                if (!CanReflect(info)) continue;
+                //MethodInfo propGetter = info.GetGetMethod();
+                Interceptor? reflectedInterceptor = CreateReflectedInterceptor(info);
+                if (reflectedInterceptor != null)
+                {
+                    Interceptor i = (Interceptor)reflectedInterceptor;
+                    ReflectedInteceptor ri = new ReflectedInteceptor()
+                    {
+                        ReflectedProperty = info,
+                        BaseInterceptor = i,
+                    };
+                    result.Add(propertyName, ri);
+                }
+
+            }
+
+            return result;
+        }
+
+        #endregion
+
+    }
+
+    #endregion // end abstract reflection interception
+
+    #endregion
+
+#region Transport Property Interceptor class 
+
+    internal class SecureTransportPropertyInterceptor : TransportPropertyInterceptor
+    {
+        internal const string SSL_PROTOCOLS_PROPERTY = ConnectionFactory.TransportPropertyPrefix + "SSLProtocol";
+        
+        private static bool ValidateProtocolString(string protocolString, out string cleanProtocols)
+        {
+            const string COMMA = ",";
+            cleanProtocols = protocolString;
+            if (protocolString != null)
+            {
+                string trim = protocolString.Trim();
+                if(trim.StartsWith(COMMA) || trim.EndsWith(COMMA))
+                {
+                    return false;
+                }
+                cleanProtocols = trim;
+            }
+            return true;
+        }
+
+        protected static Dictionary<string, Interceptor> secureTransportConextInterceptors = new Dictionary<string, Interceptor>()
+        {
+            {
+                SSL_PROTOCOLS_PROPERTY,
+                new Interceptor()
+                {
+                    Getter = (context, key) =>
+                    {
+                        return (context as IProviderSecureTransportContext).SSLProtocol;
+                    },
+                    Setter = (context, key, value) =>
+                    {
+                        string cleanValue;
+                        if(!ValidateProtocolString(value, out cleanValue))
+                        {
+                            throw new InvalidPropertyException(key, "Protocol string can not start or end with ','");
+                        }
+                        else
+                        {
+                            (context as IProviderSecureTransportContext).SSLProtocol = cleanValue;
+                        }
+                    },
+                    Exists = (context) => 
+                    {
+                        return true;
+                    },
+                    Reset = (context) =>
+                    {
+                        (context as IProviderSecureTransportContext).SSLProtocol = null;
+                    }
+                }
+
+            }
+        };
+        
+        
+        public SecureTransportPropertyInterceptor(IProviderSecureTransportContext context, StringDictionary props ) : base(context, props)
+        {
+
+
+            foreach(string key in secureTransportConextInterceptors.Keys)
+            {
+                this.AddInterceptor(key, secureTransportConextInterceptors[key]);
+            }
+        }
+
+        protected override bool CanReflect(PropertyInfo reflectedProperty)
+        {
+            Type TargetType = reflectedProperty.PropertyType;
+            return TargetType.IsPrimitive || TargetType.Equals(typeof(string));
+        }
+
+    }
+    
+    internal class TransportPropertyInterceptor : ReflectionPropertyInterceptor<IProviderTransportContext>
+    {
+        protected static Dictionary<string, Interceptor> transportContextInterceptors = new Dictionary<string, Interceptor>()
+        {
+
+        };
+        
+        public TransportPropertyInterceptor(IProviderTransportContext c, StringDictionary transportProperties) : base(c, transportProperties, transportContextInterceptors)
+        {
+        
+        }
+
+        protected override string PropertyPrefix => ConnectionFactory.TransportPropertyPrefix;
+
+        protected override bool CanReflect(PropertyInfo reflectedProperty)
+        {
+            return true;
+        }
+
+    }
+
+#endregion
+
+#region ConnectionFactory Property Interceptor Class
+
+    internal class ConnectionFactoryPropertyInterceptor : PropertyInterceptor<ConnectionFactory>
+    {
+
+#region Ignore Case Comparer
+        private class IgnoreCaseComparer : IEqualityComparer
+        {
+            public new bool Equals(object x, object y)
+            {
+                if(x==null || y == null)
+                {
+                    return x == null && y == null;
+                }
+                else if(!(x is string) || !(y is string))
+                {
+                    return false;
+                }
+                else
+                {
+                    string a = x as string;
+                    string b = y as string;
+                    return a.Equals(b, StringComparison.InvariantCultureIgnoreCase);
+                }
+
+            }
+
+            public int GetHashCode(object obj)
+            {
+                return obj.GetHashCode();
+            }
+        }
+
+#endregion
+
+        private readonly static IgnoreCaseComparer ComparerInstance = new IgnoreCaseComparer();
+        
+        private static Amqp.ConnectionFactory.SslSettings GetSSLSettings(Amqp.IConnectionFactory cf)
+        {
+            // TODO Create Provider AMQP Implementation hook to access Amqp.IConnectionFactory implementation.
+            return ((Amqp.ConnectionFactory)cf).SSL;
+        }
+
+        private static bool IsSecureConfiguration(ConnectionFactory cf)
+        {
+            return cf.Context != null && cf.Context is IProviderSecureTransportContext;
+        }
+
+#region Interceptors
+
+        protected static Dictionary<string, Interceptor> connFactoryInterceptors = new Dictionary<string, Interceptor>()
+        {
+            // TODO Add connection porperty interceptors. eg for username, password, requesttimeout, etc.
+            {
+                ConnectionFactory.CLIENT_ID_PROP,
+                new Interceptor()
+                {
+                    Getter = (cf, key) =>
+                    {
+                        return cf.ClientId;
+                    },
+                    Setter = (cf, key, value) =>
+                    {
+                        cf.ClientId = value;
+                    },
+                    Exists = (cf) =>
+                    {
+                        return !cf.IsClientIdSet;
+                    },
+                    Reset = (cf) =>
+                    {
+                        cf.ClientId = null;
+                    }
+                }
+            }
+        };
+
+#endregion
+
+        public ConnectionFactoryPropertyInterceptor(ConnectionFactory factory, StringDictionary properties) : base(factory, properties, connFactoryInterceptors)
+        {
+
+        }
+    }
+
+#endregion
+
+#region Connnection Property Interceptor Class
+
+    public class ConnectionPropertyConstants
+    {
+        public static readonly string REQUEST_TIMEOUT = PropertyUtil.CreateProperty("RequestTimeout", "Connection");
+        
+    }
+
+    internal class ConnectionPropertyInterceptor : NMSResourcePropertyInterceptor<Connection, ConnectionInfo>
+    {
+        // TODO add more properties.
+        protected static Dictionary<string, Interceptor> connInterceptors = new Dictionary<string, Interceptor>()
+        {
+            {
+                ConnectionPropertyConstants.REQUEST_TIMEOUT,
+                new Interceptor
+                {
+                    Setter = (c, key, value)=>
+                    {
+                        c.RequestTimeout = TimeSpan.FromMilliseconds(Convert.ToInt64(value));
+                    },
+                    Getter = (c, key) => { return Convert.ToInt64(c.RequestTimeout.TotalMilliseconds).ToString(); }
+                }
+            },
+        };
+
+        public ConnectionPropertyInterceptor(Connection connection, StringDictionary properties) : base(connection, properties, connInterceptors)
+        {
+
+        }
+    }
+
+#endregion
+
+#region Session Property Interceptor Class
+    //TODO Implement
+#endregion
+
+#region Producer Property Interceptor Class
+    //TODO Implement
+#endregion
+
+#region Consumer Property Interceptor Class
+    //TODO Implement
+#endregion
+
+#endregion
+
+#region NMS object Property Interceptor classes IPrimitiveMap based
+
+#region Abstract Property Interceptor Class
+    internal abstract class NMSPropertyInterceptor<T> : Types.Map.PrimitiveMapBase, IPrimitiveMap
+    {
+
+#region Generic delegates and Interceptor struct
+
+        protected delegate void ApplyProperty(T instance, object value);
+        protected delegate object GetProperty(T instance);
+        protected delegate void ClearProperty(T instance);
+        protected delegate bool CheckProperty(T instance);
+
+        // The Interceptor struct is a container of operation delegates 
+        // to be used on a specific property of instance T.
+        protected struct Interceptor
+        {
+            public ApplyProperty Setter;
+            public GetProperty Getter;
+            public ClearProperty Reset;
+            public CheckProperty Exists;
+        }
+
+#endregion
+
+        private readonly object SyncLock;
+        private readonly IPrimitiveMap properties;
+        private readonly IDictionary<string, Interceptor> interceptors;
+        private readonly T instance;
+        protected NMSPropertyInterceptor(T instance, IPrimitiveMap properties, IDictionary<string, Interceptor> interceptors) : base()
+        {
+            this.properties = properties ?? new Apache.NMS.Util.PrimitiveMap();
+            
+            this.instance = instance;
+            if (this.properties is Types.Map.PrimitiveMapBase)
+            {
+                SyncLock = (this.properties as Types.Map.PrimitiveMapBase).SyncRoot;
+            }
+            else
+            {
+                SyncLock = new object();
+            }
+
+            this.interceptors = new Dictionary<string, Interceptor>();
+            foreach(string key in interceptors.Keys)
+            {
+                AddInterceptor(key, interceptors[key]);
+            }
+        }
+
+#region Property Interceptor Methods
+
+        protected T Instance { get { return instance; } }
+
+        protected void AddInterceptor(string key, Interceptor interceptor)
+        {
+            bool updated = false;
+            if(!interceptors.ContainsKey(key))
+                this.interceptors.Add(key, interceptor);
+            else
+            {
+                // this allows subs classes to override base classes.
+                this.interceptors[key] = interceptor;
+                updated = true;
+            }
+            if (properties.Contains(key) || updated)
+            {
+                SetProperty(key, properties[key]);
+                properties.Remove(key);
+            }
+                
+        }
+
+        protected void SetProperty(string key, object value)
+        {
+            if (interceptors.ContainsKey(key))
+            {
+                interceptors[key].Setter(instance, value);
+            }
+            else
+            {
+                properties[key] = value;
+            }
+        }
+
+        protected object GetValue(string key)
+        {
+            object value = null;
+            if (interceptors.ContainsKey(key))
+            {
+                if(interceptors[key].Exists(instance))
+                    value = interceptors[key].Getter(instance);
+            }
+            else
+            {
+                value = properties[key];
+            }
+            return value;
+        }
+
+#endregion
+
+#region PrimitiveMapBase abstract override methods
+
+        internal override object SyncRoot { get { return SyncLock; } }
+
+        public override bool Contains(object key)
+        {
+            bool found = properties.Contains(key);
+            if (!found && interceptors.ContainsKey(key.ToString()))
+            {
+                string keystring = key.ToString();
+                found = interceptors[keystring].Exists(instance);
+            }
+            return found;
+        }
+
+        public override void Clear()
+        {
+            properties.Clear();
+            foreach(string key in interceptors.Keys)
+            {
+                interceptors[key].Reset(instance);
+            }
+        }
+
+        protected int InterceptorCount
+        {
+            get
+            {
+                int count = 0;
+                foreach(string key in interceptors.Keys)
+                {
+                    Interceptor i = interceptors[key];
+                    if(i.Exists(instance))
+                    {
+                        count++;
+                    }
+                }
+                return count;
+            }
+        }
+
+        public override int Count => this.properties.Count + InterceptorCount;
+
+        public override void Remove(object key)
+        {
+            if(properties.Contains(key))
+                properties.Remove(key);
+            else if(interceptors.ContainsKey(key.ToString()))
+            {
+                interceptors[key.ToString()].Reset(instance);
+            }
+        }
+
+        public override ICollection Keys
+        {
+            get
+            {
+                ISet<string> keys = new HashSet<string>();
+                foreach (string key in interceptors.Keys)
+                {
+                    Interceptor i = interceptors[key];
+                    if (i.Exists(instance))
+                    {
+                        keys.Add(key);
+                    }
+                }
+                foreach(string key in properties.Keys)
+                {
+                    keys.Add(key);
+                }
+                
+                return keys.ToList();
+            }
+        }
+
+        public override ICollection Values
+        {
+            get
+            {
+                ISet<object> values = new HashSet<object>();
+                foreach (string key in interceptors.Keys)
+                {
+                    Interceptor i = interceptors[key];
+                    if (i.Exists(instance))
+                    {
+                        values.Add(i.Getter(instance));
+                    }
+                }
+                foreach (object value in properties.Values)
+                {
+                    values.Add(value);
+                }
+
+                return values.ToList();
+            }
+        }
+ 
+        protected override void SetObjectProperty(string key, object value)
+        {
+            SetProperty(key, value);
+        }
+ 
+        protected override object GetObjectProperty(string key)
+        {
+            return GetValue(key);
+        }
+#endregion
+
+    }
+#endregion
+
+#region Message Property Interceptor Class
+    internal class NMSMessagePropertyInterceptor : NMSPropertyInterceptor<Message.Message>
+    {
+        protected static readonly Dictionary<string, Interceptor> messageInterceptors = new Dictionary<string, Interceptor>()
+        {
+            {
+                Message.Message.MESSAGE_VENDOR_ACK_PROP,
+                new Interceptor
+                {
+                    Setter = (m, value) => 
+                    {
+                        if(m.GetMessageCloak().AckHandler == null && m.GetMessageCloak().IsReceived)
+                        {
+                            throw new NMSException("Session Acknowledgement mode does not allow setting " + Message.Message.MESSAGE_VENDOR_ACK_PROP);
+                        }
+                        int ackType = -1;
+                        try
+                        {
+                            ackType = Types.ConversionSupport.ConvertNMSType<int>(value);
+                        }
+                        catch (Types.ConversionSupport.NMSTypeConversionException ce)
+                        {
+                            throw ExceptionSupport.Wrap(ce, "Property {0} cannot be set from a {1}", Message.Message.MESSAGE_VENDOR_ACK_PROP, value?.GetType()?.Name);
+                        }
+                        if (ackType != -1)
+                            m.GetMessageCloak().AckHandler.AcknowledgementType = (Message.AckType)ackType;
+
+                    },
+                    Getter = (m) => 
+                    {
+                        object acktype = null;
+                        if(m.GetMessageCloak().AckHandler != null)
+                        {
+                            acktype = m.GetMessageCloak().AckHandler.AcknowledgementType;
+                        }
+                        return acktype;
+                    },
+                    Exists = (m) =>
+                    {
+                        Message.Cloak.IMessageCloak cloak = m.GetMessageCloak();
+                        if (cloak.AckHandler != null)
+                        {
+                            return cloak.AckHandler.IsAckTypeSet;
+                        }
+                        return false;
+                    },
+                    Reset = (m) =>
+                    {
+                        Message.Cloak.IMessageCloak cloak = m.GetMessageCloak();
+                        if (cloak.AckHandler != null)
+                        {
+                            cloak.AckHandler.ClearAckType();
+                        }
+                    }
+
+                }
+            },
+        };
+
+
+        public NMSMessagePropertyInterceptor(Message.Message instance, IPrimitiveMap properties) : base (instance, properties, messageInterceptors)
+        {
+
+        }
+        public override string ToString()
+        {
+            string result = base.ToString();
+            foreach (string key in Keys)
+            {
+                result += "\n" + key.ToString() + ": " + GetObjectProperty(key).ToString();
+            }
+            return result;
+        }
+
+    }//*/
+
+#endregion
+
+#endregion
+
+}