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 2017/03/08 13:45:15 UTC

[09/13] activemq-nms-xms git commit: Initial check-in of new Apache.NMS.XMS provider implementation. Big thanks to Stéphane Ramet for the implementation! Fixes [AMQNET-185]. (See https://issues.apache.org/jira/browse/AMQNET-185)

http://git-wip-us.apache.org/repos/asf/activemq-nms-xms/blob/653d676d/src/main/csharp/MapMessage.cs
----------------------------------------------------------------------
diff --git a/src/main/csharp/MapMessage.cs b/src/main/csharp/MapMessage.cs
new file mode 100644
index 0000000..188e3d7
--- /dev/null
+++ b/src/main/csharp/MapMessage.cs
@@ -0,0 +1,719 @@
+/*
+ * 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 Apache.NMS;
+using Apache.NMS.Util;
+using Apache.NMS.XMS.Util;
+using IBM.XMS;
+
+namespace Apache.NMS.XMS
+{
+	/// <summary>
+	/// Represents a map message which contains key and value pairs which are
+	/// of primitive types.
+	/// </summary>
+	class MapMessage : Apache.NMS.XMS.Message, Apache.NMS.IMapMessage,
+		Apache.NMS.IPrimitiveMap
+	{
+		#region Constructors and access to internal map message
+
+		/// <summary>
+		/// Internal IBM XMS map message.
+		/// </summary>
+		public IBM.XMS.IMapMessage xmsMapMessage
+		{
+			get { return (IBM.XMS.IMapMessage)(this.xmsMessage); }
+			set { this.xmsMessage = value; }
+		}
+
+		/// <summary>
+		/// Constructs a <c>MapMessage</c> object.
+		/// </summary>
+		/// <param name="message">XMS map message.</param>
+		public MapMessage(IBM.XMS.IMapMessage message)
+			: base(message)
+		{
+		}
+
+		#endregion
+
+		#region IMapMessage Members
+
+		public Apache.NMS.IPrimitiveMap Body
+		{
+			get { return this; }
+		}
+
+		#endregion
+
+		#region IPrimitiveMap Members
+
+		#region General methods
+
+		/// <summary>
+		/// Clears the contents of the message body.
+		/// </summary>
+		public void Clear()
+		{
+			try
+			{
+				this.ReadOnlyBody = false;
+				this.xmsMapMessage.ClearBody();
+			}
+			catch(Exception ex)
+			{
+				ExceptionUtil.WrapAndThrowNMSException(ex);
+			}
+		}
+
+		/// <summary>
+		/// Checks if the body contains the specified item.
+		/// </summary>
+		/// <param name="key">Item key.</param>
+		public bool Contains(object key)
+		{
+			try
+			{
+				return this.xmsMapMessage.ItemExists(key.ToString());
+			}
+			catch(Exception ex)
+			{
+				ExceptionUtil.WrapAndThrowNMSException(ex);
+				return false;
+			}
+		}
+
+		/// <summary>
+		/// Removes an item from the map message body.
+		/// </summary>
+		/// <param name="key">Item key.</param>
+		public void Remove(object key)
+		{
+			try
+			{
+				// Best guess at equivalent implementation.
+				this.xmsMapMessage.SetObject(key.ToString(), null);
+			}
+			catch(Exception ex)
+			{
+				ExceptionUtil.WrapAndThrowNMSException(ex);
+			}
+		}
+
+		/// <summary>
+		/// Count of key/value pairs in the message body.
+		/// </summary>
+		public int Count
+		{
+			get
+			{
+				int count = 0;
+
+				try
+				{
+					IEnumerator mapNames = this.xmsMapMessage.MapNames;
+					while(mapNames.MoveNext())
+					{
+						count++;
+					}
+				}
+				catch(Exception ex)
+				{
+					ExceptionUtil.WrapAndThrowNMSException(ex);
+				}
+
+				return count;
+			}
+		}
+
+		/// <summary>
+		/// The collection of keys in the mep message body.
+		/// </summary>
+		public ICollection Keys
+		{
+			get
+			{
+				ArrayList keys = new ArrayList();
+
+				try
+				{
+					IEnumerator mapNames = this.xmsMapMessage.MapNames;
+					while(mapNames.MoveNext())
+					{
+						keys.Add(mapNames.Current);
+					}
+				}
+				catch(Exception ex)
+				{
+					ExceptionUtil.WrapAndThrowNMSException(ex);
+				}
+
+				return keys;
+			}
+		}
+
+		/// <summary>
+		/// The collection of values in the mep message body.
+		/// </summary>
+		public ICollection Values
+		{
+			get
+			{
+				ArrayList values = new ArrayList();
+
+				try
+				{
+					IEnumerator mapNames = this.xmsMapMessage.MapNames;
+					while(mapNames.MoveNext())
+					{
+						string key = (string)mapNames.Current;
+						values.Add(this.xmsMapMessage.GetObject(key));
+					}
+				}
+				catch(Exception ex)
+				{
+					ExceptionUtil.WrapAndThrowNMSException(ex);
+				}
+
+				return values;
+			}
+		}
+
+		/// <summary>
+		/// Accesses an item by its key.
+		/// </summary>
+		/// <param name="key">Item key.</param>
+		public object this[string key]
+		{
+			get
+			{
+				try
+				{
+					return this.xmsMapMessage.GetObject(key);
+				}
+				catch(Exception ex)
+				{
+					ExceptionUtil.WrapAndThrowNMSException(ex);
+					return null;
+				}
+			}
+			set
+			{
+				try
+				{
+					this.xmsMapMessage.SetObject(key, value);
+				}
+				catch(Exception ex)
+				{
+					ExceptionUtil.WrapAndThrowNMSException(ex);
+				}
+			}
+		}
+
+		#endregion
+
+		#region String items
+
+		/// <summary>
+		/// Gets the value of a <c>string</c> item.
+		/// </summary>
+		/// <param name="key">Item key.</param>
+		/// <returns>Item value.</returns>
+		public string GetString(string key)
+		{
+			try
+			{
+				return this.xmsMapMessage.GetString(key);
+			}
+			catch(Exception ex)
+			{
+				ExceptionUtil.WrapAndThrowNMSException(ex);
+				return null;
+			}
+		}
+
+		/// <summary>
+		/// Sets the value of a <c>string</c> item.
+		/// </summary>
+		/// <param name="key">Item key.</param>
+		/// <param name="value">Item value.</param>
+		public void SetString(string key, string value)
+		{
+			try
+			{
+				this.xmsMapMessage.SetString(key, value);
+			}
+			catch(Exception ex)
+			{
+				ExceptionUtil.WrapAndThrowNMSException(ex);
+			}
+		}
+
+		#endregion
+
+		#region Boolean items
+
+		/// <summary>
+		/// Gets the value of a <c>bool</c> item.
+		/// </summary>
+		/// <param name="key">Item key.</param>
+		/// <returns>Item value.</returns>
+		public bool GetBool(string key)
+		{
+			try
+			{
+				return this.xmsMapMessage.GetBoolean(key);
+			}
+			catch(Exception ex)
+			{
+				ExceptionUtil.WrapAndThrowNMSException(ex);
+				return false;
+			}
+		}
+
+		/// <summary>
+		/// Sets the value of a <c>bool</c> item.
+		/// </summary>
+		/// <param name="key">Item key.</param>
+		/// <param name="value">Item value.</param>
+		public void SetBool(string key, bool value)
+		{
+			try
+			{
+				this.xmsMapMessage.SetBoolean(key, value);
+			}
+			catch(Exception ex)
+			{
+				ExceptionUtil.WrapAndThrowNMSException(ex);
+			}
+		}
+
+		#endregion
+
+		#region Byte items
+
+		/// <summary>
+		/// Gets the value of a <c>byte</c> item.
+		/// </summary>
+		/// <param name="key">Item key.</param>
+		/// <returns>Item value.</returns>
+		public byte GetByte(string key)
+		{
+			try
+			{
+				return this.xmsMapMessage.GetByte(key);
+			}
+			catch(Exception ex)
+			{
+				ExceptionUtil.WrapAndThrowNMSException(ex);
+				return 0;
+			}
+		}
+
+		/// <summary>
+		/// Sets the value of a <c>byte</c> item.
+		/// </summary>
+		/// <param name="key">Item key.</param>
+		/// <param name="value">Item value.</param>
+		public void SetByte(string key, byte value)
+		{
+			try
+			{
+				this.xmsMapMessage.SetByte(key, value);
+			}
+			catch(Exception ex)
+			{
+				ExceptionUtil.WrapAndThrowNMSException(ex);
+			}
+		}
+
+		#endregion
+
+		#region Char items
+
+		/// <summary>
+		/// Gets the value of a <c>char</c> item.
+		/// </summary>
+		/// <param name="key">Item key.</param>
+		/// <returns>Item value.</returns>
+		public char GetChar(string key)
+		{
+			try
+			{
+				return this.xmsMapMessage.GetChar(key);
+			}
+			catch(Exception ex)
+			{
+				ExceptionUtil.WrapAndThrowNMSException(ex);
+				return (char) 0;
+			}
+		}
+
+		/// <summary>
+		/// Sets the value of a <c>char</c> item.
+		/// </summary>
+		/// <param name="key">Item key.</param>
+		/// <param name="value">Item value.</param>
+		public void SetChar(string key, char value)
+		{
+			try
+			{
+				this.xmsMapMessage.SetChar(key, value);
+			}
+			catch(Exception ex)
+			{
+				ExceptionUtil.WrapAndThrowNMSException(ex);
+			}
+		}
+
+		#endregion
+
+		#region Short items
+
+		/// <summary>
+		/// Gets the value of a 16 bits <c>short</c> integer item.
+		/// </summary>
+		/// <param name="key">Item key.</param>
+		/// <returns>Item value.</returns>
+		public short GetShort(string key)
+		{
+			try
+			{
+				return this.xmsMapMessage.GetShort(key);
+			}
+			catch(Exception ex)
+			{
+				ExceptionUtil.WrapAndThrowNMSException(ex);
+				return 0;
+			}
+		}
+
+		/// <summary>
+		/// Sets the value of a 16 bits <c>short</c> integer item.
+		/// </summary>
+		/// <param name="key">Item key.</param>
+		/// <param name="value">Item value.</param>
+		public void SetShort(string key, short value)
+		{
+			try
+			{
+				this.xmsMapMessage.SetShort(key, value);
+			}
+			catch(Exception ex)
+			{
+				ExceptionUtil.WrapAndThrowNMSException(ex);
+			}
+		}
+
+		#endregion
+
+		#region Int items
+
+		/// <summary>
+		/// Gets the value of a 32 bits <c>int</c> integer item.
+		/// </summary>
+		/// <param name="key">Item key.</param>
+		/// <returns>Item value.</returns>
+		public int GetInt(string key)
+		{
+			try
+			{
+				return this.xmsMapMessage.GetInt(key);
+			}
+			catch(Exception ex)
+			{
+				ExceptionUtil.WrapAndThrowNMSException(ex);
+				return 0;
+			}
+		}
+
+		/// <summary>
+		/// Sets the value of a 32 bits <c>int</c> integer item.
+		/// </summary>
+		/// <param name="key">Item key.</param>
+		/// <param name="value">Item value.</param>
+		public void SetInt(string key, int value)
+		{
+			try
+			{
+				this.xmsMapMessage.SetInt(key, value);
+			}
+			catch(Exception ex)
+			{
+				ExceptionUtil.WrapAndThrowNMSException(ex);
+			}
+		}
+
+		#endregion
+
+		#region Long items
+
+		/// <summary>
+		/// Gets the value of a 64 bits <c>long</c> integer item.
+		/// </summary>
+		/// <param name="key">Item key.</param>
+		/// <returns>Item value.</returns>
+		public long GetLong(string key)
+		{
+			try
+			{
+				return this.xmsMapMessage.GetLong(key);
+			}
+			catch(Exception ex)
+			{
+				ExceptionUtil.WrapAndThrowNMSException(ex);
+				return 0;
+			}
+		}
+
+		/// <summary>
+		/// Sets the value of a 64 bits <c>long</c> integer item.
+		/// </summary>
+		/// <param name="key">Item key.</param>
+		/// <param name="value">Item value.</param>
+		public void SetLong(string key, long value)
+		{
+			try
+			{
+				this.xmsMapMessage.SetLong(key, value);
+			}
+			catch(Exception ex)
+			{
+				ExceptionUtil.WrapAndThrowNMSException(ex);
+			}
+		}
+
+		#endregion
+
+		#region Float items
+
+		/// <summary>
+		/// Gets the value of a <c>float</c> item.
+		/// </summary>
+		/// <param name="key">Item key.</param>
+		/// <returns>Item value.</returns>
+		public float GetFloat(string key)
+		{
+			try
+			{
+				return this.xmsMapMessage.GetFloat(key);
+			}
+			catch(Exception ex)
+			{
+				ExceptionUtil.WrapAndThrowNMSException(ex);
+				return 0;
+			}
+		}
+
+		/// <summary>
+		/// Sets the value of a <c>float</c> item.
+		/// </summary>
+		/// <param name="key">Item key.</param>
+		/// <param name="value">Item value.</param>
+		public void SetFloat(string key, float value)
+		{
+			try
+			{
+				this.xmsMapMessage.SetFloat(key, value);
+			}
+			catch(Exception ex)
+			{
+				ExceptionUtil.WrapAndThrowNMSException(ex);
+			}
+		}
+
+		#endregion
+
+		#region Double items
+
+		/// <summary>
+		/// Gets the value of a <c>double</c> item.
+		/// </summary>
+		/// <param name="key">Item key.</param>
+		/// <returns>Item value.</returns>
+		public double GetDouble(string key)
+		{
+			try
+			{
+				return this.xmsMapMessage.GetDouble(key);
+			}
+			catch(Exception ex)
+			{
+				ExceptionUtil.WrapAndThrowNMSException(ex);
+				return 0;
+			}
+		}
+
+		/// <summary>
+		/// Sets the value of a <c>double</c> item.
+		/// </summary>
+		/// <param name="key">Item key.</param>
+		/// <param name="value">Item value.</param>
+		public void SetDouble(string key, double value)
+		{
+			try
+			{
+				this.xmsMapMessage.SetDouble(key, value);
+			}
+			catch(Exception ex)
+			{
+				ExceptionUtil.WrapAndThrowNMSException(ex);
+			}
+		}
+
+		#endregion
+
+		#region List items
+
+		/// <summary>
+		/// Gets the value of an <c>IList</c> item.
+		/// </summary>
+		/// <param name="key">Item key.</param>
+		/// <returns>Item value.</returns>
+		public IList GetList(string key)
+		{
+			try
+			{
+				return (IList) this.xmsMapMessage.GetObject(key);
+			}
+			catch(Exception ex)
+			{
+				ExceptionUtil.WrapAndThrowNMSException(ex);
+				return null;
+			}
+		}
+
+		/// <summary>
+		/// Sets the value of an <c>IList</c> item.
+		/// </summary>
+		/// <param name="key">Item key.</param>
+		/// <param name="list">Item value.</param>
+		public void SetList(string key, IList list)
+		{
+			try
+			{
+				this.xmsMapMessage.SetObject(key, list);
+			}
+			catch(Exception ex)
+			{
+				ExceptionUtil.WrapAndThrowNMSException(ex);
+			}
+		}
+
+		#endregion
+
+		#region Bytes array items
+
+		/// <summary>
+		/// Gets the value of a <c>byte[]</c> byte array item.
+		/// </summary>
+		/// <param name="key">Item key.</param>
+		/// <returns>Item value.</returns>
+		public byte[] GetBytes(string key)
+		{
+			try
+			{
+				return this.xmsMapMessage.GetBytes(key);
+			}
+			catch(Exception ex)
+			{
+				ExceptionUtil.WrapAndThrowNMSException(ex);
+				return null;
+			}
+		}
+
+		/// <summary>
+		/// Sets the value of a <c>byte[]</c> byte array item.
+		/// </summary>
+		/// <param name="key">Item key.</param>
+		/// <param name="value">Item value.</param>
+		public void SetBytes(string key, byte[] value)
+		{
+			try
+			{
+				this.xmsMapMessage.SetBytes(key, value);
+			}
+			catch(Exception ex)
+			{
+				ExceptionUtil.WrapAndThrowNMSException(ex);
+			}
+		}
+
+		/// <summary>
+		/// Sets the value of a <c>byte[]</c> byte array item.
+		/// </summary>
+		/// <param name="key">Item key.</param>
+		/// <param name="value">Byte array from which value is extracted.</param>
+		/// <param name="offset">Index of first byte to extract.</param>
+		/// <param name="length">Number of bytes to extract.</param>
+		public void SetBytes(string key, byte[] value, int offset, int length)
+		{
+			try
+			{
+				this.xmsMapMessage.SetBytes(key, value, offset, length);
+			}
+			catch(Exception ex)
+			{
+				ExceptionUtil.WrapAndThrowNMSException(ex);
+			}
+		}
+
+		#endregion
+
+		#region Dictionary items
+
+		/// <summary>
+		/// Gets the value of an <c>IDictionary</c> item.
+		/// </summary>
+		/// <param name="key">Item key.</param>
+		/// <returns>Item value.</returns>
+		public IDictionary GetDictionary(string key)
+		{
+			try
+			{
+				return (IDictionary) this.xmsMapMessage.GetObject(key);
+			}
+			catch(Exception ex)
+			{
+				ExceptionUtil.WrapAndThrowNMSException(ex);
+				return null;
+			}
+		}
+
+		/// <summary>
+		/// Sets the value of an <c>IDictionary</c> item.
+		/// </summary>
+		/// <param name="key">Item key.</param>
+		/// <param name="dictionary">Item value.</param>
+		public void SetDictionary(string key, IDictionary dictionary)
+		{
+			try
+			{
+				this.xmsMapMessage.SetObject(key, dictionary);
+			}
+			catch(Exception ex)
+			{
+				ExceptionUtil.WrapAndThrowNMSException(ex);
+			}
+		}
+
+		#endregion
+
+		#endregion
+	}
+}

http://git-wip-us.apache.org/repos/asf/activemq-nms-xms/blob/653d676d/src/main/csharp/Message.cs
----------------------------------------------------------------------
diff --git a/src/main/csharp/Message.cs b/src/main/csharp/Message.cs
new file mode 100644
index 0000000..278b73c
--- /dev/null
+++ b/src/main/csharp/Message.cs
@@ -0,0 +1,526 @@
+/*
+ * 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 Apache.NMS.Util;
+using Apache.NMS.XMS.Util;
+using IBM.XMS;
+
+namespace Apache.NMS.XMS
+{
+	/// <summary>
+	/// Represents a message either to be sent to a message broker or received
+	/// from a message broker.
+	/// </summary>
+	class Message : Apache.NMS.IMessage
+	{
+		public IBM.XMS.IMessage xmsMessage;
+
+		#region Constructors
+
+		/// <summary>
+		/// Constructs a <c>Message</c> object.
+		/// </summary>
+		/// <param name="message">XMS message.</param>
+		public Message(IBM.XMS.IMessage message)
+		{
+			this.xmsMessage = message;
+		}
+
+		#endregion
+
+		#region IMessage Members
+
+		#region Acknowledgement
+
+		/// <summary>
+		/// If using client acknowledgement mode on the session then this
+		/// method will acknowledge that the message has been processed
+		/// correctly.
+		/// </summary>
+		public void Acknowledge()
+		{
+			try
+			{
+				this.xmsMessage.Acknowledge();
+			}
+			catch(Exception ex)
+			{
+				ExceptionUtil.WrapAndThrowNMSException(ex);
+			}
+		}
+
+		#endregion
+
+		#region Message body
+
+		private bool readOnlyMsgBody = false;
+		/// <summary>
+		/// Whether the message body is read-only.
+		/// </summary>
+		public virtual bool ReadOnlyBody
+		{
+			get { return this.readOnlyMsgBody; }
+			set { this.readOnlyMsgBody = value; }
+		}
+
+		/// <summary>
+		/// Clears out the message body. Clearing a message's body does not
+		/// clear its header values or property entries.
+		/// If this message body was read-only, calling this method leaves
+		/// the message body in the same state as an empty body in a newly
+		/// created message.
+		/// </summary>
+		public void ClearBody()
+		{
+			try
+			{
+				this.ReadOnlyBody = false;
+				this.xmsMessage.ClearBody();
+			}
+			catch(Exception ex)
+			{
+				ExceptionUtil.WrapAndThrowNMSException(ex);
+			}
+		}
+
+		#endregion
+
+		#region Message properties
+
+		#region General comments
+
+		// https://docs.oracle.com/cd/E19798-01/821-1841/bnces/index.html
+		// A JMS message has three parts: a header, properties, and a body.
+		// A JMS message header contains a number of predefined fields that
+		// contain values that both clients and providers use to identify
+		// and to route messages:
+		//   Header Field     Set By 
+		//   JMSDestination   send or publish method
+		//   JMSDeliveryMode  send or publish method
+		//   JMSExpiration    send or publish method
+		//   JMSPriority      send or publish method
+		//   JMSMessageID     send or publish method
+		//   JMSTimestamp     send or publish method
+		//   JMSCorrelationID Client 
+		//   JMSReplyTo       Client 
+		//   JMSType          Client
+		//   JMSRedelivered   JMS provider 
+		// Properties can be created and set for messages if values are needed
+		// in addition to those provided by the header fields.
+		// The JMS API provides some predefined property names that a provider
+		// can support. The use either of these predefined properties or of
+		// user-defined properties is optional.
+		// The JMS API defines five message body formats:
+		//   Message Type   Body Contains
+		//   TextMessage    A java.lang.String object.
+		//   MapMessage     A set of name-value pairs, with names as String
+		//                  objects and values as primitive types.
+		//   BytesMessage   A stream of uninterpreted bytes.
+		//   StreamMessage  A stream of primitive values, filled and read
+		//                  sequentially. 
+		//   ObjectMessage  A Serializable object.
+		//   Message        Nothing. Composed of header fields and properties
+		//                  only.
+		//
+		// http://www-01.ibm.com/support/knowledgecenter/SSFKSJ_8.0.0/com.ibm.mq.msc.doc/xms_cmesmod.htm?lang=en
+		// The XMS message model is the same as the WebSphere� MQ classes for
+		// JMS message model.
+		// In particular, XMS implements the same message header fields and
+		// message properties that WebSphere MQ classes for JMS implements:
+		//   JMS header fields.       These fields have names that commence
+		//                            with the prefix JMS.
+		//   JMS defined properties.  These fields have properties whose names
+		//                            commence with the prefix JMSX.
+		//   IBM� defined properties. These fields have properties whose names
+		//                            commence with the prefix JMS_IBM_.
+		//
+		// Apache.NMS redefines JMS message header fields with an "NMS" prefix:
+		//   JMS                           NMS                               IBM.XMS
+		//   Destination JMSDestination    IDestination    NMSDestination    IDestination JMSDestination
+		//   int         JMSDeliveryMode   MsgDeliveryMode NMSDeliveryMode   DeliveryMode JMSDeliveryMode
+		//   long        JMSExpiration     [TimeSpan       NMSTimeToLive]    Int64        JMSExpiration
+		//   int         JMSPriority       MsgPriority     NMSPriority       Int32        JMSPriority
+		//   String      JMSMessageID      string          NMSMessageId      String       JMSMessageID
+		//   long        JMSTimestamp      DateTime        NMSTimestamp      Int64        JMSTimestamp
+		//   String      JMSCorrelationID  string          NMSCorrelationID  String       JMSCorrelationID
+		//   Destination JMSReplyTo        IDestination    NMSReplyTo        IDestination JMSReplyTo
+		//   String      JMSType           string          NMSType           String       JMSType
+		//   boolean     JMSRedelivered    bool            NMSRedelivered    Boolean      JMSRedelivered
+		// Properties are set and retrieved through typed SetXxxProperty and
+		// GetXxxProperty methods.
+		// Unlike JMS, Apache.NMS does not expose those methods in the
+		// IMessage interface, but through the IPrimitiveMap interface,
+		// implemented by the MessageProperties class, exposed through
+		// the IMessage.Properties property.
+		// The MessagePropertyIntercepter propertyHelper intercepts get and
+		// set invocations on properties whose name starts with "NMS", and
+		// maps them to the equivalent message header fields through
+		// reflection. Other invocations are routed to the
+		// MessageProperties.Get/SetObjetProperty methods, which in turn
+		// invokes xmsMessage.Get/SetObjectProperty.
+		//
+		// XMS message properties are:
+		//   XMSC.JMS_DESTINATION               = "JMSDestination"
+		//   XMSC.JMS_DELIVERY_MODE             = "JMSDeliveryMode"
+		//   XMSC.JMS_EXPIRATION                = "JMSExpiration"
+		//   XMSC.JMS_PRIORITY                  = "JMSPriority"
+		//   XMSC.JMS_MESSAGEID                 = "JMSMessageID"
+		//   XMSC.JMS_TIMESTAMP                 = "JMSTimestamp"
+		//   XMSC.JMS_CORRELATIONID             = "JMSCorrelationID"
+		//   XMSC.JMS_REPLYTO                   = "JMSReplyto"
+		//   XMSC.JMS_TYPE                      = "JMSType"
+		//   XMSC.JMS_REDELIVERED               = "JMSRedelivered"
+		//
+		//   XMSC.JMSX_USERID                   = "JMSXUserID"
+		//   XMSC.JMSX_APPID                    = "JMSXAppID"
+		//   XMSC.JMSX_DELIVERY_COUNT           = "JMSXDeliveryCount"
+		//   XMSC.JMSX_GROUPID                  = "JMSXGroupID"
+		//   XMSC.JMSX_GROUPSEQ                 = "JMSXGroupSeq"
+		//   XMSC.JMSX_STATE                    = "JMSXState"
+		//   XMSC.JMSX_PRODUCER_TXID            = "JMSXProducerTXID"
+		//   XMSC.JMSX_CONSUMER_TXID            = "JMSXConsumerTXID"
+		//   XMSC.JMSX_RCV_TIMESTAMP            = "JMSXRcvTimestamp"
+
+		//   XMSC.JMS_IBM_REPORT_EXCEPTION      = "JMS_IBM_Report_Exception"
+		//   XMSC.JMS_IBM_REPORT_EXPIRATION     = "JMS_IBM_Report_Expiration"
+		//   XMSC.JMS_IBM_REPORT_COA            = "JMS_IBM_Report_COA"
+		//   XMSC.JMS_IBM_REPORT_COD            = "JMS_IBM_Report_COD"
+		//   XMSC.JMS_IBM_REPORT_NAN            = "JMS_IBM_Report_NAN"
+		//   XMSC.JMS_IBM_REPORT_PAN            = "JMS_IBM_Report_PAN"
+		//   XMSC.JMS_IBM_REPORT_PASS_MSG_ID    = "JMS_IBM_Report_Pass_Msg_ID"
+		//   XMSC.JMS_IBM_REPORT_PASS_CORREL_ID = "JMS_IBM_Report_Pass_Correl_ID"
+		//   XMSC.JMS_IBM_REPORT_DISCARD_MSG    = "JMS_IBM_Report_Discard_Msg"
+		//   XMSC.JMS_IBM_MSGTYPE               = "JMS_IBM_MsgType"
+		//   XMSC.JMS_IBM_FEEDBACK              = "JMS_IBM_Feedback"
+		//   XMSC.JMS_IBM_FORMAT                = "JMS_IBM_Format"
+		//   XMSC.JMS_IBM_PUTAPPLTYPE           = "JMS_IBM_PutApplType"
+		//   XMSC.JMS_IBM_ENCODING              = "JMS_IBM_Encoding"
+		//   XMSC.JMS_IBM_CHARACTER_SET         = "JMS_IBM_Character_Set"
+		//   XMSC.JMS_IBM_PUTDATE               = "JMS_IBM_PutDate"
+		//   XMSC.JMS_IBM_PUTTIME               = "JMS_IBM_PutTime"
+		//   XMSC.JMS_IBM_LAST_MSG_IN_GROUP     = "JMS_IBM_Last_Msg_In_Group"
+		//   XMSC.JMS_IBM_EXCEPTIONREASON       = "JMS_IBM_ExceptionReason"
+		//   XMSC.JMS_IBM_EXCEPTIONTIMESTAMP    = "JMS_IBM_ExceptionTimestamp"
+		//   XMSC.JMS_IBM_EXCEPTIONMESSAGE      = "JMS_IBM_ExceptionMessage"
+		//   XMSC.JMS_IBM_SYSTEM_MESSAGEID      = "JMS_IBM_System_MessageID"
+		//   XMSC.JMS_IBM_EXCEPTIONPROBLEMDESTINATION = "JMS_IBM_ExceptionProblemDestination"
+		//   XMSC.JMS_IBM_ARM_CORRELATOR        = "JMS_IBM_ArmCorrelator"
+		//   XMSC.JMS_IBM_WAS_RM_CORRELATOR     = "JMS_IBM_RMCorrelator"
+		//   XMSC.JMS_IBM_CONNECTIONID          = "JMS_IBM_ConnectionID"
+		//   XMSC.JMS_IBM_RETAIN                = "JMS_IBM_Retain"
+		//   XMSC.JMS_IBM_MQMD_REPORT           = "JMS_IBM_MQMD_Report"
+		//   XMSC.JMS_IBM_MQMD_MSGTYPE          = "JMS_IBM_MQMD_MsgType"
+		//   XMSC.JMS_IBM_MQMD_EXPIRY           = "JMS_IBM_MQMD_Expiry"
+		//   XMSC.JMS_IBM_MQMD_FEEDBACK         = "JMS_IBM_MQMD_Feedback"
+		//   XMSC.JMS_IBM_MQMD_ENCODING         = "JMS_IBM_MQMD_Encoding"
+		//   XMSC.JMS_IBM_MQMD_CODEDCHARSETID   = "JMS_IBM_MQMD_CodedCharSetId"
+		//   XMSC.JMS_IBM_MQMD_FORMAT           = "JMS_IBM_MQMD_Format"
+		//   XMSC.JMS_IBM_MQMD_PRIORITY         = "JMS_IBM_MQMD_Priority"
+		//   XMSC.JMS_IBM_MQMD_PERSISTENCE      = "JMS_IBM_MQMD_Persistence"
+		//   XMSC.JMS_IBM_MQMD_MSGID            = "JMS_IBM_MQMD_MsgId"
+		//   XMSC.JMS_IBM_MQMD_CORRELID         = "JMS_IBM_MQMD_CorrelId"
+		//   XMSC.JMS_IBM_MQMD_BACKOUTCOUNT     = "JMS_IBM_MQMD_BackoutCount"
+		//   XMSC.JMS_IBM_MQMD_REPLYTOQ         = "JMS_IBM_MQMD_ReplyToQ"
+		//   XMSC.JMS_IBM_MQMD_REPLYTOQMGR      = "JMS_IBM_MQMD_ReplyToQMgr"
+		//   XMSC.JMS_IBM_MQMD_USERIDENTIFIER   = "JMS_IBM_MQMD_UserIdentifier"
+		//   XMSC.JMS_IBM_MQMD_ACCOUNTINGTOKEN  = "JMS_IBM_MQMD_AccountingToken"
+		//   XMSC.JMS_IBM_MQMD_APPLIDENTITYDATA = "JMS_IBM_MQMD_ApplIdentityData"
+		//   XMSC.JMS_IBM_MQMD_PUTAPPLTYPE      = "JMS_IBM_MQMD_PutApplType"
+		//   XMSC.JMS_IBM_MQMD_PUTAPPLNAME      = "JMS_IBM_MQMD_PutApplName"
+		//   XMSC.JMS_IBM_MQMD_PUTDATE          = "JMS_IBM_MQMD_PutDate"
+		//   XMSC.JMS_IBM_MQMD_PUTTIME          = "JMS_IBM_MQMD_PutTime"
+		//   XMSC.JMS_IBM_MQMD_APPLORIGINDATA   = "JMS_IBM_MQMD_ApplOriginData"
+		//   XMSC.JMS_IBM_MQMD_GROUPID          = "JMS_IBM_MQMD_GroupId"
+		//   XMSC.JMS_IBM_MQMD_MSGSEQNUMBER     = "JMS_IBM_MQMD_MsgSeqNumber"
+		//   XMSC.JMS_IBM_MQMD_OFFSET           = "JMS_IBM_MQMD_Offset"
+		//   XMSC.JMS_IBM_MQMD_MSGFLAGS         = "JMS_IBM_MQMD_MsgFlags"
+		//   XMSC.JMS_IBM_MQMD_ORIGINALLENGTH   = "JMS_IBM_MQMD_OriginalLength"
+		//   XMSC.JMS_TOG_ARM_CORRELATOR        = "JMS_TOG_ARM_Correlator"
+
+		#endregion
+
+		#region General methods
+
+		private bool readOnlyMsgProperties = false;
+		/// <summary>
+		/// Whether the message properties is read-only.
+		/// </summary>
+		public virtual bool ReadOnlyProperties
+		{
+			get { return this.readOnlyMsgProperties; }
+
+			set
+			{
+				if(this.propertyHelper != null)
+				{
+					this.propertyHelper.ReadOnly = value;
+				}
+				this.readOnlyMsgProperties = value;
+			}
+		}
+
+		/// <summary>
+		/// Clears a message's properties.
+		/// The message's header fields and body are not cleared.
+		/// </summary>
+		public void ClearProperties()
+		{
+			try
+			{
+				this.ReadOnlyProperties = false;
+				this.xmsMessage.ClearProperties();
+			}
+			catch(Exception ex)
+			{
+				ExceptionUtil.WrapAndThrowNMSException(ex);
+			}
+		}
+
+		private Apache.NMS.IPrimitiveMap properties = null;
+		private Apache.NMS.Util.MessagePropertyIntercepter propertyHelper;
+		/// <summary>
+		/// Provides access to the message properties (headers)
+		/// </summary>
+		public Apache.NMS.IPrimitiveMap Properties
+		{
+			get
+			{
+				if(properties == null)
+				{
+					properties = XMSConvert.ToMessageProperties(this.xmsMessage);
+					propertyHelper = new Apache.NMS.Util.MessagePropertyIntercepter(
+						this, properties, this.ReadOnlyProperties);
+				}
+
+				return propertyHelper;
+			}
+		}
+
+		#endregion
+
+		#region Message header fields
+
+		/// <summary>
+		/// The correlation ID used to correlate messages from conversations
+		/// or long running business processes.
+		/// </summary>
+		public string NMSCorrelationID
+		{
+			get
+			{
+				try
+				{
+					return this.xmsMessage.JMSCorrelationID;
+				}
+				catch(Exception ex)
+				{
+					ExceptionUtil.WrapAndThrowNMSException(ex);
+					return null;
+				}
+			}
+			set
+			{
+				try
+				{
+					this.xmsMessage.JMSCorrelationID = value;
+				}
+				catch(Exception ex)
+				{
+					ExceptionUtil.WrapAndThrowNMSException(ex);
+				}
+			}
+		}
+
+		/// <summary>
+		/// The destination of the message.
+		/// </summary>
+		public Apache.NMS.IDestination NMSDestination
+		{
+			get
+			{
+				return XMSConvert.ToNMSDestination(
+					this.xmsMessage.JMSDestination);
+			}
+			set
+			{
+				try
+				{
+					this.xmsMessage.JMSDestination =
+						XMSConvert.ToXMSDestination(value);
+				}
+				catch(Exception ex)
+				{
+					ExceptionUtil.WrapAndThrowNMSException(ex);
+				}
+			}
+		}
+
+		protected TimeSpan timeToLive;
+		/// <summary>
+		/// The amount of time that this message is valid for.
+		/// <c>null</c> if this message does not expire.
+		/// </summary>
+		public TimeSpan NMSTimeToLive
+		{
+			get { return this.timeToLive; }
+			set { this.timeToLive = value; }
+		}
+
+		/// <summary>
+		/// The message ID which is set by the provider.
+		/// </summary>
+		public string NMSMessageId
+		{
+			get { return this.xmsMessage.JMSMessageID; }
+			set { this.xmsMessage.JMSMessageID = value; }
+		}
+
+		/// <summary>
+		/// Whether or not this message is persistent.
+		/// </summary>
+		public MsgDeliveryMode NMSDeliveryMode
+		{
+			get
+			{
+				return XMSConvert.ToNMSMsgDeliveryMode(
+					this.xmsMessage.JMSDeliveryMode);
+			}
+			set
+			{
+				try
+				{
+					this.xmsMessage.JMSDeliveryMode =
+						XMSConvert.ToJMSDeliveryMode(value);
+				}
+				catch(Exception ex)
+				{
+					ExceptionUtil.WrapAndThrowNMSException(ex);
+				}
+			}
+		}
+
+		/// <summary>
+		/// The Priority on this message.
+		/// </summary>
+		public MsgPriority NMSPriority
+		{
+			get
+			{
+				return (MsgPriority)this.xmsMessage.JMSPriority;
+			}
+			set
+			{
+				try
+				{
+					this.xmsMessage.JMSPriority = (int)value;
+				}
+				catch(Exception ex)
+				{
+					ExceptionUtil.WrapAndThrowNMSException(ex);
+				}
+			}
+		}
+
+		/// <summary>
+		/// Returns true if this message has been redelivered to this or
+		/// another consumer before being acknowledged successfully.
+		/// </summary>
+		public bool NMSRedelivered
+		{
+			get { return this.xmsMessage.JMSRedelivered; }
+			set
+			{
+				throw new NMSException("JMSRedelivered cannot be set.");
+			}
+		}
+
+		/// <summary>
+		/// The destination that the consumer of this message should send
+		/// replies to.
+		/// </summary>
+		public Apache.NMS.IDestination NMSReplyTo
+		{
+			get
+			{
+				return XMSConvert.ToNMSDestination(
+					this.xmsMessage.JMSReplyTo);
+			}
+			set
+			{
+				try
+				{
+					this.xmsMessage.JMSReplyTo =
+						XMSConvert.ToXMSDestination(value);
+				}
+				catch(Exception ex)
+				{
+					ExceptionUtil.WrapAndThrowNMSException(ex);
+				}
+			}
+		}
+
+		/// <summary>
+		/// The timestamp of when the message was pubished in UTC time. If the
+		/// publisher disables setting the timestamp on the message, the time
+		/// will be set to the start of the UNIX epoch (1970-01-01 00:00:00).
+		/// </summary>
+		public DateTime NMSTimestamp
+		{
+			get { return DateUtils.ToDateTime(this.xmsMessage.JMSTimestamp); }
+			set { this.xmsMessage.JMSTimestamp = DateUtils.ToJavaTime(value); }
+		}
+
+		/// <summary>
+		/// The type name of this message.
+		/// </summary>
+		public string NMSType
+		{
+			get { return this.xmsMessage.JMSType; }
+			set
+			{
+				try
+				{
+					this.xmsMessage.JMSType = value;
+				}
+				catch(Exception ex)
+				{
+					ExceptionUtil.WrapAndThrowNMSException(ex);
+				}
+			}
+		}
+
+		#endregion
+
+		#endregion
+
+		#endregion
+
+		#region Event handlers
+
+		public virtual void OnSend()
+		{
+			this.ReadOnlyProperties = true;
+			this.ReadOnlyBody = true;
+		}
+
+		public virtual void OnMessageRollback()
+		{
+		}
+
+		#endregion
+	}
+}

http://git-wip-us.apache.org/repos/asf/activemq-nms-xms/blob/653d676d/src/main/csharp/MessageConsumer.cs
----------------------------------------------------------------------
diff --git a/src/main/csharp/MessageConsumer.cs b/src/main/csharp/MessageConsumer.cs
new file mode 100644
index 0000000..1ad2949
--- /dev/null
+++ b/src/main/csharp/MessageConsumer.cs
@@ -0,0 +1,201 @@
+/*
+ * 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 Apache.NMS;
+using Apache.NMS.Util;
+using Apache.NMS.XMS.Util;
+
+namespace Apache.NMS.XMS
+{
+	class MessageConsumer : Apache.NMS.IMessageConsumer
+	{
+		private readonly Apache.NMS.XMS.Util.Dispatcher dispatcher
+			= new Apache.NMS.XMS.Util.Dispatcher();
+		protected readonly Apache.NMS.XMS.Session nmsSession;
+		public IBM.XMS.IMessageConsumer xmsMessageConsumer;
+		private bool closed = false;
+		private bool disposed = false;
+
+		public MessageConsumer(Apache.NMS.XMS.Session session,
+			IBM.XMS.IMessageConsumer consumer)
+		{
+			this.nmsSession = session;
+			this.xmsMessageConsumer = consumer;
+			this.xmsMessageConsumer.MessageListener = this.HandleXmsMessage;
+		}
+
+		~MessageConsumer()
+		{
+			Dispose(false);
+		}
+
+		#region IMessageConsumer Members
+
+		private ConsumerTransformerDelegate consumerTransformer;
+		/// <summary>
+		/// A Delegate that is called each time a Message is dispatched to allow the client to do
+		/// any necessary transformations on the received message before it is delivered.
+		/// </summary>
+		public ConsumerTransformerDelegate ConsumerTransformer
+		{
+			get { return this.consumerTransformer; }
+			set { this.consumerTransformer = value; }
+		}
+
+		/// <summary>
+		/// Waits until a message is available and returns it
+		/// </summary>
+		public Apache.NMS.IMessage Receive()
+		{
+			return this.dispatcher.Dequeue();
+		}
+
+		/// <summary>
+		/// If a message is available within the timeout duration it is returned otherwise this method returns null
+		/// </summary>
+		public Apache.NMS.IMessage Receive(TimeSpan timeout)
+		{
+			return this.dispatcher.Dequeue(timeout);
+		}
+
+		/// <summary>
+		/// If a message is available immediately it is returned otherwise this method returns null
+		/// </summary>
+		public Apache.NMS.IMessage ReceiveNoWait()
+		{
+			return this.dispatcher.DequeueNoWait();
+		}
+
+		/// <summary>
+		/// An asynchronous listener which can be used to consume messages asynchronously
+		/// </summary>
+		public event Apache.NMS.MessageListener Listener;
+
+		/// <summary>
+		/// Closes the message consumer. 
+		/// </summary>
+		/// <remarks>
+		/// Clients should close message consumers them when they are not needed.
+		/// This call blocks until a receive or message listener in progress has completed.
+		/// A blocked message consumer receive call returns null when this message consumer is closed.
+		/// </remarks>
+		public void Close()
+		{
+			lock(this)
+			{
+				if(closed)
+				{
+					return;
+				}
+			}
+
+			// wake up any pending dequeue() call on the dispatcher
+			this.dispatcher.Close();
+
+			lock(this)
+			{
+				try
+				{
+					this.xmsMessageConsumer.MessageListener = null;
+					this.xmsMessageConsumer.Close();
+				}
+				catch(Exception ex)
+				{
+					ExceptionUtil.WrapAndThrowNMSException(ex);
+				}
+				finally
+				{
+					closed = true;
+				}
+			}
+		}
+
+		#endregion
+
+		#region IDisposable Members
+
+		///<summary>
+		/// Performs application-defined tasks associated with freeing, releasing, or resetting unmanaged resources.
+		///</summary>
+		///<filterpriority>2</filterpriority>
+		public void Dispose()
+		{
+			Dispose(true);
+			GC.SuppressFinalize(this);
+		}
+
+		protected void Dispose(bool disposing)
+		{
+			if(disposed)
+			{
+				return;
+			}
+
+			if(disposing)
+			{
+				// Dispose managed code here.
+			}
+
+			try
+			{
+				Close();
+			}
+			catch
+			{
+				// Ignore errors.
+			}
+
+			disposed = true;
+		}
+
+		#endregion
+
+		private void HandleXmsMessage(IBM.XMS.IMessage xmsMessage)
+		{
+			Apache.NMS.IMessage message = XMSConvert.ToNMSMessage(xmsMessage);
+
+			if(message != null)
+			{
+				if(this.ConsumerTransformer != null)
+				{
+					IMessage newMessage = ConsumerTransformer(this.nmsSession, this, message);
+
+					if(newMessage != null)
+					{
+						message = newMessage;
+					}
+				}
+
+				if(Listener != null)
+				{
+					try
+					{
+						Listener(message);
+					}
+					catch(Exception ex)
+					{
+						Apache.NMS.Tracer.Debug("Error handling message: " + ex.Message);
+					}
+				}
+				else
+				{
+					this.dispatcher.Enqueue(message);
+				}
+			}
+		}
+	}
+}

http://git-wip-us.apache.org/repos/asf/activemq-nms-xms/blob/653d676d/src/main/csharp/MessageProducer.cs
----------------------------------------------------------------------
diff --git a/src/main/csharp/MessageProducer.cs b/src/main/csharp/MessageProducer.cs
new file mode 100644
index 0000000..34da42c
--- /dev/null
+++ b/src/main/csharp/MessageProducer.cs
@@ -0,0 +1,416 @@
+/*
+ * 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.Threading;
+using Apache.NMS;
+using Apache.NMS.Util;
+using Apache.NMS.XMS.Util;
+
+namespace Apache.NMS.XMS
+{
+	class MessageProducer : Apache.NMS.IMessageProducer
+	{
+		protected readonly Apache.NMS.XMS.Session nmsSession;
+		public IBM.XMS.IMessageProducer xmsMessageProducer;
+		private TimeSpan requestTimeout = NMSConstants.defaultRequestTimeout;
+		private bool closed = false;
+		private bool disposed = false;
+
+		public MessageProducer(Apache.NMS.XMS.Session session,
+			IBM.XMS.IMessageProducer producer)
+		{
+			this.nmsSession = session;
+			this.xmsMessageProducer = producer;
+			this.RequestTimeout = session.RequestTimeout;
+		}
+
+		~MessageProducer()
+		{
+			Dispose(false);
+		}
+
+		private Apache.NMS.XMS.Message GetXMSMessage(Apache.NMS.IMessage message)
+		{
+			Apache.NMS.XMS.Message msg = (Apache.NMS.XMS.Message) message;
+
+			if(this.ProducerTransformer != null)
+			{
+				IMessage transformed = this.ProducerTransformer(this.nmsSession, this, message);
+				if(transformed != null)
+				{
+					msg = (Apache.NMS.XMS.Message) transformed;
+				}
+			}
+
+			return msg;
+		}
+
+		#region IMessageProducer Members
+
+		/// <summary>
+		/// Sends the message to the default destination for this producer.
+		/// </summary>
+		public void Send(Apache.NMS.IMessage message)
+		{
+			Apache.NMS.XMS.Message msg = GetXMSMessage(message);
+			long timeToLive = (long) message.NMSTimeToLive.TotalMilliseconds;
+
+			if(0 == timeToLive)
+			{
+				timeToLive = this.xmsMessageProducer.TimeToLive;
+			}
+
+			try
+			{
+				msg.OnSend();
+				this.xmsMessageProducer.Send(
+							msg.xmsMessage,
+							this.xmsMessageProducer.DeliveryMode,
+							this.xmsMessageProducer.Priority,
+							timeToLive);
+			}
+			catch(Exception ex)
+			{
+				ExceptionUtil.WrapAndThrowNMSException(ex);
+			}
+		}
+
+		/// <summary>
+		/// Sends the message to the default destination with the explicit QoS
+		/// configuration.
+		/// </summary>
+		public void Send(Apache.NMS.IMessage message,
+			MsgDeliveryMode deliveryMode, MsgPriority priority,
+			TimeSpan timeToLive)
+		{
+			Apache.NMS.XMS.Message msg = GetXMSMessage(message);
+
+			try
+			{
+				this.xmsMessageProducer.Send(
+							msg.xmsMessage,
+							XMSConvert.ToJMSDeliveryMode(deliveryMode),
+							(int)priority,
+							(long)timeToLive.TotalMilliseconds);
+			}
+			catch(Exception ex)
+			{
+				ExceptionUtil.WrapAndThrowNMSException(ex);
+			}
+		}
+
+		/// <summary>
+		/// Sends the message to the given destination.
+		/// </summary>
+		public void Send(Apache.NMS.IDestination destination,
+			Apache.NMS.IMessage message)
+		{
+			Apache.NMS.XMS.Destination dest =
+				(Apache.NMS.XMS.Destination)destination;
+
+			Apache.NMS.XMS.Message msg = GetXMSMessage(message);
+			long timeToLive = (long)message.NMSTimeToLive.TotalMilliseconds;
+
+			if(0 == timeToLive)
+			{
+				timeToLive = this.xmsMessageProducer.TimeToLive;
+			}
+
+			try
+			{
+				this.xmsMessageProducer.Send(
+							dest.xmsDestination,
+							msg.xmsMessage,
+							this.xmsMessageProducer.DeliveryMode,
+							this.xmsMessageProducer.Priority,
+							timeToLive);
+			}
+			catch(Exception ex)
+			{
+				ExceptionUtil.WrapAndThrowNMSException(ex);
+			}
+		}
+
+		/// <summary>
+		/// Sends the message to the given destination with the explicit QoS
+		/// configuration.
+		/// </summary>
+		public void Send(Apache.NMS.IDestination destination,
+			Apache.NMS.IMessage message, MsgDeliveryMode deliveryMode,
+			MsgPriority priority, TimeSpan timeToLive)
+		{
+			Apache.NMS.XMS.Destination dest =
+				(Apache.NMS.XMS.Destination)destination;
+
+			Apache.NMS.XMS.Message msg = GetXMSMessage(message);
+
+			try
+			{
+				this.xmsMessageProducer.Send(
+							dest.xmsDestination,
+							msg.xmsMessage,
+							XMSConvert.ToJMSDeliveryMode(deliveryMode),
+							(int)priority,
+							(long)timeToLive.TotalMilliseconds);
+			}
+			catch(Exception ex)
+			{
+				ExceptionUtil.WrapAndThrowNMSException(ex);
+			}
+		}
+
+		private ProducerTransformerDelegate producerTransformer;
+		/// <summary>
+		/// A delegate that is called each time a Message is sent from this
+		/// Producer which allows the application to perform any needed
+		/// transformations on the Message before it is sent.
+		/// </summary>
+		public ProducerTransformerDelegate ProducerTransformer
+		{
+			get { return this.producerTransformer; }
+			set { this.producerTransformer = value; }
+		}
+
+		public MsgDeliveryMode DeliveryMode
+		{
+			get
+			{
+				return XMSConvert.ToNMSMsgDeliveryMode(
+					this.xmsMessageProducer.DeliveryMode);
+			}
+			set
+			{
+				try
+				{
+					this.xmsMessageProducer.DeliveryMode =
+						XMSConvert.ToJMSDeliveryMode(value);
+				}
+				catch(Exception ex)
+				{
+					ExceptionUtil.WrapAndThrowNMSException(ex);
+				}
+			}
+		}
+
+		public TimeSpan TimeToLive
+		{
+			get
+			{
+				return TimeSpan.FromMilliseconds(
+					this.xmsMessageProducer.TimeToLive);
+			}
+			set
+			{
+				try
+				{
+					this.xmsMessageProducer.TimeToLive =
+						(long)value.TotalMilliseconds;
+				}
+				catch(Exception ex)
+				{
+					ExceptionUtil.WrapAndThrowNMSException(ex);
+				}
+			}
+		}
+
+		/// <summary>
+		/// The default timeout for network requests.
+		/// </summary>
+		public TimeSpan RequestTimeout
+		{
+			get { return requestTimeout; }
+			set { this.requestTimeout = value; }
+		}
+
+		public MsgPriority Priority
+		{
+			get { return (MsgPriority) this.xmsMessageProducer.Priority; }
+			set
+			{
+				try
+				{
+					this.xmsMessageProducer.Priority = (int) value;
+				}
+				catch(Exception ex)
+				{
+					ExceptionUtil.WrapAndThrowNMSException(ex);
+				}
+			}
+		}
+
+		public bool DisableMessageID
+		{
+			get { return this.xmsMessageProducer.DisableMessageID; }
+			set
+			{
+				try
+				{
+					this.xmsMessageProducer.DisableMessageID = value;
+				}
+				catch(Exception ex)
+				{
+					ExceptionUtil.WrapAndThrowNMSException(ex);
+				}
+			}
+		}
+
+		public bool DisableMessageTimestamp
+		{
+			get { return this.xmsMessageProducer.DisableMessageTimestamp; }
+			set
+			{
+				try
+				{
+					this.xmsMessageProducer.DisableMessageTimestamp = value;
+				}
+				catch(Exception ex)
+				{
+					ExceptionUtil.WrapAndThrowNMSException(ex);
+				}
+			}
+		}
+
+		/// <summary>
+		/// Creates a new message with an empty body
+		/// </summary>
+		public Apache.NMS.IMessage CreateMessage()
+		{
+			return this.nmsSession.CreateMessage();
+		}
+
+		/// <summary>
+		/// Creates a new text message with an empty body.
+		/// </summary>
+		public Apache.NMS.ITextMessage CreateTextMessage()
+		{
+			return this.nmsSession.CreateTextMessage();
+		}
+
+		/// <summary>
+		/// Creates a new text message with the given body.
+		/// </summary>
+		public Apache.NMS.ITextMessage CreateTextMessage(string text)
+		{
+			return this.nmsSession.CreateTextMessage(text);
+		}
+
+		/// <summary>
+		/// Creates a new Map message which contains primitive key and value
+		/// pairs.
+		/// </summary>
+		public Apache.NMS.IMapMessage CreateMapMessage()
+		{
+			return this.nmsSession.CreateMapMessage();
+		}
+
+		/// <summary>
+		/// Creates a new object message containing the given .NET object as
+		/// the body.
+		/// </summary>
+		public Apache.NMS.IObjectMessage CreateObjectMessage(object body)
+		{
+			return this.nmsSession.CreateObjectMessage(body);
+		}
+
+		/// <summary>
+		/// Creates a new binary message.
+		/// </summary>
+		public Apache.NMS.IBytesMessage CreateBytesMessage()
+		{
+			return this.nmsSession.CreateBytesMessage();
+		}
+
+		/// <summary>
+		/// Creates a new binary message with the given body.
+		/// </summary>
+		public Apache.NMS.IBytesMessage CreateBytesMessage(byte[] body)
+		{
+			return this.nmsSession.CreateBytesMessage(body);
+		}
+
+		/// <summary>
+		/// Creates a new stream message.
+		/// </summary>
+		public Apache.NMS.IStreamMessage CreateStreamMessage()
+		{
+			return this.nmsSession.CreateStreamMessage();
+		}
+
+		#endregion
+
+		#region IDisposable Members
+
+		public void Close()
+		{
+			lock(this)
+			{
+				if(closed)
+				{
+					return;
+				}
+
+				try
+				{
+					this.xmsMessageProducer.Close();
+				}
+				catch(Exception ex)
+				{
+					ExceptionUtil.WrapAndThrowNMSException(ex);
+				}
+				finally
+				{
+					closed = true;
+				}
+			}
+		}
+		///<summary>
+		///Performs application-defined tasks associated with freeing, releasing, or resetting unmanaged resources.
+		///</summary>
+		///<filterpriority>2</filterpriority>
+		public void Dispose()
+		{
+			Dispose(true);
+			GC.SuppressFinalize(this);
+		}
+
+		protected void Dispose(bool disposing)
+		{
+			if(disposed)
+			{
+				return;
+			}
+
+			if(disposing)
+			{
+				// Dispose managed code here.
+			}
+
+			try
+			{
+				Close();
+			}
+			catch
+			{
+				// Ignore errors.
+			}
+
+			disposed = true;
+		}
+
+		#endregion
+	}
+}

http://git-wip-us.apache.org/repos/asf/activemq-nms-xms/blob/653d676d/src/main/csharp/MessageProperties.cs
----------------------------------------------------------------------
diff --git a/src/main/csharp/MessageProperties.cs b/src/main/csharp/MessageProperties.cs
new file mode 100644
index 0000000..3edd086
--- /dev/null
+++ b/src/main/csharp/MessageProperties.cs
@@ -0,0 +1,485 @@
+/*
+ * 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 Apache.NMS;
+using Apache.NMS.Util;
+using Apache.NMS.XMS.Util;
+
+namespace Apache.NMS.XMS
+{
+	public class MessageProperties : Apache.NMS.IPrimitiveMap
+	{
+		public IBM.XMS.IMessage xmsMessage;
+
+		public MessageProperties(IBM.XMS.IMessage message)
+		{
+			this.xmsMessage = message;
+		}
+
+		#region IPrimitiveMap Members
+
+		public void Clear()
+		{
+			try
+			{
+				this.xmsMessage.ClearProperties();
+			}
+			catch(Exception ex)
+			{
+				ExceptionUtil.WrapAndThrowNMSException(ex);
+			}
+		}
+
+		public bool Contains(object key)
+		{
+			return this.xmsMessage.PropertyExists(key.ToString());
+		}
+
+		public void Remove(object key)
+		{
+			try
+			{
+				// Best guess at equivalent implementation.
+				this.xmsMessage.SetObjectProperty(key.ToString(), null);
+			}
+			catch(Exception ex)
+			{
+				ExceptionUtil.WrapAndThrowNMSException(ex);
+			}
+		}
+
+		public int Count
+		{
+			get
+			{
+				int count = 0;
+				try
+				{
+					IEnumerator propertyNamesEnumerator =
+						this.xmsMessage.PropertyNames;
+
+					if(null != propertyNamesEnumerator)
+					{
+						while(propertyNamesEnumerator.MoveNext())
+						{
+							count++;
+						}
+					}
+				}
+				catch(Exception ex)
+				{
+					ExceptionUtil.WrapAndThrowNMSException(ex);
+				}
+
+				return count;
+			}
+		}
+
+		public ICollection Keys
+		{
+			get
+			{
+				ArrayList keys = new ArrayList();
+
+				try
+				{
+					foreach(string propertyName in XMSConvert.ToEnumerable(this.xmsMessage.PropertyNames))
+					{
+						keys.Add(propertyName);
+					}
+				}
+				catch(Exception ex)
+				{
+					ExceptionUtil.WrapAndThrowNMSException(ex);
+				}
+
+				return keys;
+			}
+		}
+
+		public ICollection Values
+		{
+			get
+			{
+				ArrayList values = new ArrayList();
+
+				try
+				{
+					foreach(string propertyName in XMSConvert.ToEnumerable(this.xmsMessage.PropertyNames))
+					{
+						values.Add(this.xmsMessage.GetObjectProperty(propertyName));
+					}
+				}
+				catch(Exception ex)
+				{
+					ExceptionUtil.WrapAndThrowNMSException(ex);
+				}
+
+				return values;
+			}
+		}
+
+		public object this[string key]
+		{
+			get
+			{
+				try
+				{
+					return this.xmsMessage.GetObjectProperty(key);
+				}
+				catch(Exception ex)
+				{
+					ExceptionUtil.WrapAndThrowNMSException(ex);
+					return null;
+				}
+			}
+			set
+			{
+				try
+				{
+					this.xmsMessage.SetObjectProperty(key, value);
+				}
+				catch(Exception ex)
+				{
+					ExceptionUtil.WrapAndThrowNMSException(ex);
+				}
+			}
+		}
+
+		public string GetString(string key)
+		{
+			try
+			{
+				return this.xmsMessage.GetStringProperty(key);
+			}
+			catch(Exception ex)
+			{
+				ExceptionUtil.WrapAndThrowNMSException(ex);
+				return null;
+			}
+		}
+
+		public void SetString(string key, string value)
+		{
+			try
+			{
+				this.xmsMessage.SetStringProperty(key, value);
+			}
+			catch(Exception ex)
+			{
+				ExceptionUtil.WrapAndThrowNMSException(ex);
+			}
+		}
+
+		public bool GetBool(string key)
+		{
+			try
+			{
+				return this.xmsMessage.GetBooleanProperty(key);
+			}
+			catch(Exception ex)
+			{
+				ExceptionUtil.WrapAndThrowNMSException(ex);
+				return false;
+			}
+		}
+
+		public void SetBool(string key, bool value)
+		{
+			try
+			{
+				this.xmsMessage.SetBooleanProperty(key, value);
+			}
+			catch(Exception ex)
+			{
+				ExceptionUtil.WrapAndThrowNMSException(ex);
+			}
+		}
+
+		public byte GetByte(string key)
+		{
+			try
+			{
+				return this.xmsMessage.GetByteProperty(key);
+			}
+			catch(Exception ex)
+			{
+				ExceptionUtil.WrapAndThrowNMSException(ex);
+				return 0;
+			}
+		}
+
+		public void SetByte(string key, byte value)
+		{
+			try
+			{
+				this.xmsMessage.SetByteProperty(key, value);
+			}
+			catch(Exception ex)
+			{
+				ExceptionUtil.WrapAndThrowNMSException(ex);
+			}
+		}
+
+		public char GetChar(string key)
+		{
+			try
+			{
+				return this.xmsMessage.GetCharProperty(key);
+			}
+			catch(Exception ex)
+			{
+				ExceptionUtil.WrapAndThrowNMSException(ex);
+				return (char) 0;
+			}
+		}
+
+		public void SetChar(string key, char value)
+		{
+			try
+			{
+				this.xmsMessage.SetCharProperty(key, value);
+			}
+			catch(Exception ex)
+			{
+				ExceptionUtil.WrapAndThrowNMSException(ex);
+			}
+		}
+
+		public short GetShort(string key)
+		{
+			try
+			{
+				return this.xmsMessage.GetShortProperty(key);
+			}
+			catch(Exception ex)
+			{
+				ExceptionUtil.WrapAndThrowNMSException(ex);
+				return 0;
+			}
+		}
+
+		public void SetShort(string key, short value)
+		{
+			try
+			{
+				this.xmsMessage.SetShortProperty(key, value);
+			}
+			catch(Exception ex)
+			{
+				ExceptionUtil.WrapAndThrowNMSException(ex);
+			}
+		}
+
+		public int GetInt(string key)
+		{
+			try
+			{
+				return this.xmsMessage.GetIntProperty(key);
+			}
+			catch(Exception ex)
+			{
+				ExceptionUtil.WrapAndThrowNMSException(ex);
+				return 0;
+			}
+		}
+
+		public void SetInt(string key, int value)
+		{
+			try
+			{
+				this.xmsMessage.SetIntProperty(key, value);
+			}
+			catch(Exception ex)
+			{
+				ExceptionUtil.WrapAndThrowNMSException(ex);
+			}
+		}
+
+		public long GetLong(string key)
+		{
+			try
+			{
+				return this.xmsMessage.GetLongProperty(key);
+			}
+			catch(Exception ex)
+			{
+				ExceptionUtil.WrapAndThrowNMSException(ex);
+				return 0;
+			}
+		}
+
+		public void SetLong(string key, long value)
+		{
+			try
+			{
+				this.xmsMessage.SetLongProperty(key, value);
+			}
+			catch(Exception ex)
+			{
+				ExceptionUtil.WrapAndThrowNMSException(ex);
+			}
+		}
+
+		public float GetFloat(string key)
+		{
+			try
+			{
+				return this.xmsMessage.GetFloatProperty(key);
+			}
+			catch(Exception ex)
+			{
+				ExceptionUtil.WrapAndThrowNMSException(ex);
+				return 0;
+			}
+		}
+
+		public void SetFloat(string key, float value)
+		{
+			try
+			{
+				this.xmsMessage.SetFloatProperty(key, value);
+			}
+			catch(Exception ex)
+			{
+				ExceptionUtil.WrapAndThrowNMSException(ex);
+			}
+		}
+
+		public double GetDouble(string key)
+		{
+			try
+			{
+				return this.xmsMessage.GetDoubleProperty(key);
+			}
+			catch(Exception ex)
+			{
+				ExceptionUtil.WrapAndThrowNMSException(ex);
+				return 0;
+			}
+		}
+
+		public void SetDouble(string key, double value)
+		{
+			try
+			{
+				this.xmsMessage.SetDoubleProperty(key, value);
+			}
+			catch(Exception ex)
+			{
+				ExceptionUtil.WrapAndThrowNMSException(ex);
+			}
+		}
+
+		public IList GetList(string key)
+		{
+			try
+			{
+				return (IList) this.xmsMessage.GetObjectProperty(key);
+			}
+			catch(Exception ex)
+			{
+				ExceptionUtil.WrapAndThrowNMSException(ex);
+				return null;
+			}
+		}
+
+		public void SetList(string key, IList list)
+		{
+			try
+			{
+				this.xmsMessage.SetObjectProperty(key, list);
+			}
+			catch(Exception ex)
+			{
+				ExceptionUtil.WrapAndThrowNMSException(ex);
+			}
+		}
+
+		public void SetBytes(string key, byte[] value)
+		{
+			try
+			{
+				this.xmsMessage.SetBytesProperty(key, value);
+			}
+			catch(Exception ex)
+			{
+				ExceptionUtil.WrapAndThrowNMSException(ex);
+			}
+		}
+
+		public void SetBytes(string key, byte[] value, int offset, int length)
+		{
+			try
+			{
+				byte[] byteSection = new byte[length];
+
+				for(int srcIndex = offset, destIndex = 0; srcIndex < (offset + length); srcIndex++, destIndex++)
+				{
+					byteSection[destIndex] = value[srcIndex];
+				}
+
+				this.xmsMessage.SetBytesProperty(key, byteSection);
+			}
+			catch(Exception ex)
+			{
+				ExceptionUtil.WrapAndThrowNMSException(ex);
+			}
+		}
+
+		public byte[] GetBytes(string key)
+		{
+			try
+			{
+				return (byte[]) this.xmsMessage.GetBytesProperty(key);
+			}
+			catch(Exception ex)
+			{
+				ExceptionUtil.WrapAndThrowNMSException(ex);
+				return null;
+			}
+		}
+
+		public IDictionary GetDictionary(string key)
+		{
+			try
+			{
+				return (IDictionary) this.xmsMessage.GetObjectProperty(key);
+			}
+			catch(Exception ex)
+			{
+				ExceptionUtil.WrapAndThrowNMSException(ex);
+				return null;
+			}
+		}
+
+		public void SetDictionary(string key, IDictionary dictionary)
+		{
+			try
+			{
+				this.xmsMessage.SetObjectProperty(key, dictionary);
+			}
+			catch(Exception ex)
+			{
+				ExceptionUtil.WrapAndThrowNMSException(ex);
+			}
+		}
+
+		#endregion
+	}
+}

http://git-wip-us.apache.org/repos/asf/activemq-nms-xms/blob/653d676d/src/main/csharp/ObjectMessage.cs
----------------------------------------------------------------------
diff --git a/src/main/csharp/ObjectMessage.cs b/src/main/csharp/ObjectMessage.cs
new file mode 100644
index 0000000..b777674
--- /dev/null
+++ b/src/main/csharp/ObjectMessage.cs
@@ -0,0 +1,65 @@
+/*
+ * 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 Apache.NMS;
+using Apache.NMS.Util;
+using Apache.NMS.XMS.Util;
+using IBM.XMS;
+
+namespace Apache.NMS.XMS
+{
+	/// <summary>
+	/// Represents an object message which contains a serializable .NET object.
+	/// </summary>
+	class ObjectMessage : Apache.NMS.XMS.Message, Apache.NMS.IObjectMessage
+	{
+		#region Constructors and access to internal map message
+
+		/// <summary>
+		/// Internal IBM XMS object message.
+		/// </summary>
+		public IBM.XMS.IObjectMessage xmsObjectMessage
+		{
+			get { return (IBM.XMS.IObjectMessage)this.xmsMessage; }
+			set { this.xmsMessage = value; }
+		}
+
+		/// <summary>
+		/// Constructs a <c>MapMessage</c> object.
+		/// </summary>
+		/// <param name="message">XMS map message.</param>
+		public ObjectMessage(IBM.XMS.IObjectMessage message)
+			: base(message)
+		{
+		}
+
+		#endregion
+
+		#region IObjectMessage Members
+
+		/// <summary>
+		/// Object message body.
+		/// </summary>
+		public object Body
+		{
+			get { return this.xmsObjectMessage.Object; }
+			set { this.xmsObjectMessage.Object = value; }
+		}
+
+		#endregion
+	}
+}

http://git-wip-us.apache.org/repos/asf/activemq-nms-xms/blob/653d676d/src/main/csharp/Queue.cs
----------------------------------------------------------------------
diff --git a/src/main/csharp/Queue.cs b/src/main/csharp/Queue.cs
new file mode 100644
index 0000000..579a65a
--- /dev/null
+++ b/src/main/csharp/Queue.cs
@@ -0,0 +1,75 @@
+/*
+ * 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 Apache.NMS;
+using Apache.NMS.Util;
+using Apache.NMS.XMS.Util;
+using IBM.XMS;
+
+namespace Apache.NMS.XMS
+{
+	public class Queue : Apache.NMS.XMS.Destination, Apache.NMS.IQueue
+	{
+		#region Constructors and destructors
+
+		/// <summary>
+		/// Constructs a <c>Queue</c> object.
+		/// </summary>
+		/// <param name="queue">IBM XMS queue</param>
+		public Queue(IBM.XMS.IDestination queue)
+			: base(queue)
+		{
+		}
+
+		/// <summary>
+		/// Constructs a <c>Queue</c> object.
+		/// </summary>
+		/// <param name="queue">IBM XMS queue</param>
+		/// <param name="isTemporary">Whether the queue is temporary</param>
+		public Queue(IBM.XMS.IDestination queue, bool isTemporary)
+			: base(queue, isTemporary)
+		{
+		}
+
+		#endregion
+        
+        #region IQueue Members
+
+		/// <summary>
+		/// Queue name.
+		/// </summary>
+		public string QueueName
+		{
+			get { return this.xmsDestination.Name; }
+		}
+
+		#endregion
+
+		#region ToString
+
+		/// <summary>
+		/// Returns a string representation of this instance.
+		/// </summary>
+		/// <returns>String representation of this instance</returns>
+		public override System.String ToString()
+		{
+			return "queue://" + QueueName;
+		}
+
+		#endregion
+	}
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/activemq-nms-xms/blob/653d676d/src/main/csharp/QueueBrowser.cs
----------------------------------------------------------------------
diff --git a/src/main/csharp/QueueBrowser.cs b/src/main/csharp/QueueBrowser.cs
new file mode 100644
index 0000000..2ef3690
--- /dev/null
+++ b/src/main/csharp/QueueBrowser.cs
@@ -0,0 +1,145 @@
+/*
+ * 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 Apache.NMS;
+using Apache.NMS.Util;
+using Apache.NMS.XMS.Util;
+
+namespace Apache.NMS.XMS
+{
+	public class QueueBrowser : Apache.NMS.IQueueBrowser
+	{
+		public IBM.XMS.IQueueBrowser xmsQueueBrowser;
+		private bool closed = false;
+		private bool disposed = false;
+
+		public QueueBrowser(IBM.XMS.IQueueBrowser queueBrowser)
+		{
+			this.xmsQueueBrowser = queueBrowser;
+		}
+
+		~QueueBrowser()
+		{
+			Dispose(false);
+		}
+
+		#region IDisposable Members
+
+		///<summary>
+		/// Performs application-defined tasks associated with freeing, releasing, or resetting unmanaged resources.
+		///</summary>
+		public void Dispose()
+		{
+			Dispose(true);
+			GC.SuppressFinalize(this);
+		}
+
+		protected void Dispose(bool disposing)
+		{
+			if(disposed)
+			{
+				return;
+			}
+
+			if(disposing)
+			{
+				// Dispose managed code here.
+			}
+
+			try
+			{
+				Close();
+			}
+			catch
+			{
+				// Ignore errors.
+			}
+
+			disposed = true;
+		}
+
+		#endregion
+
+		public void  Close()
+		{
+			lock(this)
+			{
+				if(closed)
+				{
+					return;
+				}
+
+				try
+				{
+					this.xmsQueueBrowser.Close();
+				}
+				catch(Exception ex)
+				{
+					ExceptionUtil.WrapAndThrowNMSException(ex);
+				}
+				finally
+				{
+					closed = true;
+				}
+			}
+		}
+
+		public string MessageSelector
+		{
+			get { return this.xmsQueueBrowser.MessageSelector; }
+		}
+
+		public IQueue Queue
+		{
+			get { return XMSConvert.ToNMSQueue(this.xmsQueueBrowser.Queue); }
+		}
+
+		internal class Enumerator : IEnumerator
+		{
+			private IEnumerator innerEnumerator;
+
+			public Enumerator(IEnumerator innerEnumerator)
+			{
+				this.innerEnumerator = innerEnumerator;
+			}
+
+			public object Current
+			{
+				get
+				{
+					return XMSConvert.ToNMSMessage((IBM.XMS.IMessage)this.innerEnumerator.Current);
+				}
+			}
+
+			public bool MoveNext()
+			{
+				return this.innerEnumerator.MoveNext();
+			}
+
+			public void Reset()
+			{
+				this.innerEnumerator.Reset();
+			}
+		}
+
+		public IEnumerator GetEnumerator()
+		{
+			return new Enumerator(this.xmsQueueBrowser.GetEnumerator());
+		}
+	}
+}

http://git-wip-us.apache.org/repos/asf/activemq-nms-xms/blob/653d676d/src/main/csharp/Session.cs
----------------------------------------------------------------------
diff --git a/src/main/csharp/Session.cs b/src/main/csharp/Session.cs
new file mode 100644
index 0000000..8e01827
--- /dev/null
+++ b/src/main/csharp/Session.cs
@@ -0,0 +1,551 @@
+/*
+ * 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 Apache.NMS;
+using Apache.NMS.Util;
+using Apache.NMS.XMS.Util;
+using IBM.XMS;
+
+namespace Apache.NMS.XMS
+{
+	/// <summary>
+	/// Represents a NMS session to IBM XMS.
+	/// </summary>
+	public class Session : Apache.NMS.ISession
+	{
+		public readonly IBM.XMS.ISession xmsSession;
+		private bool closed = false;
+		private bool disposed = false;
+		
+		public Session(IBM.XMS.ISession session)
+		{
+			this.xmsSession = session;
+		}
+		
+		~Session()
+		{
+			Dispose(false);
+		}
+		
+		#region ISession Members
+		
+		public Apache.NMS.IMessageProducer CreateProducer()
+		{
+			return CreateProducer(null);
+		}
+		
+		public Apache.NMS.IMessageProducer CreateProducer(
+			Apache.NMS.IDestination destination)
+		{
+			Apache.NMS.XMS.Destination destinationObj =
+				(Apache.NMS.XMS.Destination)destination;
+		
+			try
+			{
+				Apache.NMS.IMessageProducer producer =
+					XMSConvert.ToNMSMessageProducer(this,
+						this.xmsSession.CreateProducer(
+							destinationObj.xmsDestination));
+				ConfigureProducer(producer);
+				return producer;
+			}
+			catch(Exception ex)
+			{
+				ExceptionUtil.WrapAndThrowNMSException(ex);
+				return null;
+			}
+		}
+		
+		public Apache.NMS.IMessageConsumer CreateConsumer(
+			Apache.NMS.IDestination destination)
+		{
+			Apache.NMS.XMS.Destination destinationObj =
+				(Apache.NMS.XMS.Destination)destination;
+		
+			try
+			{
+				Apache.NMS.IMessageConsumer consumer =
+					XMSConvert.ToNMSMessageConsumer(this,
+						this.xmsSession.CreateConsumer(
+							destinationObj.xmsDestination));
+				ConfigureConsumer(consumer);
+				return consumer;
+			}
+			catch(Exception ex)
+			{
+				ExceptionUtil.WrapAndThrowNMSException(ex);
+				return null;
+			}
+		}
+		
+		public Apache.NMS.IMessageConsumer CreateConsumer(
+			Apache.NMS.IDestination destination, string selector)
+		{
+			Apache.NMS.XMS.Destination destinationObj =
+				(Apache.NMS.XMS.Destination)destination;
+		
+			try
+			{
+				Apache.NMS.IMessageConsumer consumer =
+					XMSConvert.ToNMSMessageConsumer(this,
+						this.xmsSession.CreateConsumer(
+							destinationObj.xmsDestination, selector));
+				ConfigureConsumer(consumer);
+				return consumer;
+			}
+			catch(Exception ex)
+			{
+				ExceptionUtil.WrapAndThrowNMSException(ex);
+				return null;
+			}
+		}
+		
+		public Apache.NMS.IMessageConsumer CreateConsumer(
+			Apache.NMS.IDestination destination, string selector, bool noLocal)
+		{
+			Apache.NMS.XMS.Destination destinationObj = 
+				(Apache.NMS.XMS.Destination)destination;
+		
+			try
+			{
+				Apache.NMS.IMessageConsumer consumer =
+					XMSConvert.ToNMSMessageConsumer(this,
+						this.xmsSession.CreateConsumer(
+							destinationObj.xmsDestination, selector, noLocal));
+				ConfigureConsumer(consumer);
+				return consumer;
+			}
+			catch(Exception ex)
+			{
+				ExceptionUtil.WrapAndThrowNMSException(ex);
+				return null;
+			}
+		}
+		
+		public Apache.NMS.IMessageConsumer CreateDurableConsumer(
+			Apache.NMS.ITopic destination, string name, string selector,
+			bool noLocal)
+		{
+			Apache.NMS.XMS.Topic topicObj = (Apache.NMS.XMS.Topic)destination;
+		
+			try
+			{
+				Apache.NMS.IMessageConsumer consumer =
+					XMSConvert.ToNMSMessageConsumer(this,
+						this.xmsSession.CreateDurableSubscriber(
+							topicObj.xmsDestination, name, selector, noLocal));
+				ConfigureConsumer(consumer);
+				return consumer;
+			}
+			catch(Exception ex)
+			{
+				ExceptionUtil.WrapAndThrowNMSException(ex);
+				return null;
+			}
+		}
+		
+		private void ConfigureProducer(Apache.NMS.IMessageProducer producer)
+		{
+			producer.ProducerTransformer = this.ProducerTransformer;
+		}
+		
+		private void ConfigureConsumer(Apache.NMS.IMessageConsumer consumer)
+		{
+			consumer.ConsumerTransformer = this.ConsumerTransformer;
+		}
+		
+		public void DeleteDurableConsumer(string name)
+		{
+			try
+			{
+				this.xmsSession.Unsubscribe(name);
+			}
+			catch(Exception ex)
+			{
+				ExceptionUtil.WrapAndThrowNMSException(ex);
+			}
+		}
+		
+		public IQueueBrowser CreateBrowser(IQueue queue)
+		{
+			Apache.NMS.XMS.Queue queueObj = (Apache.NMS.XMS.Queue)queue;
+		
+			try
+			{
+				return XMSConvert.ToNMSQueueBrowser(this.xmsSession.CreateBrowser(
+					queueObj.xmsDestination));
+			}
+			catch(Exception ex)
+			{
+				ExceptionUtil.WrapAndThrowNMSException(ex);
+				return null;
+			}
+		}
+		
+		public IQueueBrowser CreateBrowser(IQueue queue, string selector)
+		{
+			Apache.NMS.XMS.Queue queueObj = (Apache.NMS.XMS.Queue) queue;
+		
+			try
+			{
+				return XMSConvert.ToNMSQueueBrowser(this.xmsSession.CreateBrowser(
+					queueObj.xmsDestination, selector));
+			}
+			catch(Exception ex)
+			{
+				ExceptionUtil.WrapAndThrowNMSException(ex);
+				return null;
+			}
+		}
+		
+		public Apache.NMS.IQueue GetQueue(string name)
+		{
+			try
+			{
+				return XMSConvert.ToNMSQueue(this.xmsSession.CreateQueue(name));
+			}
+			catch(Exception ex)
+			{
+				ExceptionUtil.WrapAndThrowNMSException(ex);
+				return null;
+			}
+		}
+		
+		public Apache.NMS.ITopic GetTopic(string name)
+		{
+			try
+			{
+				return XMSConvert.ToNMSTopic(this.xmsSession.CreateTopic(name));
+			}
+			catch(Exception ex)
+			{
+				ExceptionUtil.WrapAndThrowNMSException(ex);
+				return null;
+			}
+		}
+		
+		public Apache.NMS.ITemporaryQueue CreateTemporaryQueue()
+		{
+			try
+			{
+				return XMSConvert.ToNMSTemporaryQueue(
+					this.xmsSession.CreateTemporaryQueue());
+			}
+			catch(Exception ex)
+			{
+				ExceptionUtil.WrapAndThrowNMSException(ex);
+				return null;
+			}
+		}
+		
+		public Apache.NMS.ITemporaryTopic CreateTemporaryTopic()
+		{
+			try
+			{
+				return XMSConvert.ToNMSTemporaryTopic(
+					this.xmsSession.CreateTemporaryTopic());
+			}
+			catch(Exception ex)
+			{
+				ExceptionUtil.WrapAndThrowNMSException(ex);
+				return null;
+			}
+		}
+		
+		/// <summary>
+		/// Delete a destination (Queue, Topic, Temp Queue, Temp Topic).
+		/// </summary>
+		public void DeleteDestination(IDestination destination)
+		{
+			// The IBM.XMS API does not support destination deletion
+			throw new NotSupportedException();
+		}
+		
+		public Apache.NMS.IMessage CreateMessage()
+		{
+			try
+			{
+				return XMSConvert.ToNMSMessage(
+					this.xmsSession.CreateMessage());
+			}
+			catch(Exception ex)
+			{
+				ExceptionUtil.WrapAndThrowNMSException(ex);
+				return null;
+			}
+		}
+		
+		public Apache.NMS.ITextMessage CreateTextMessage()
+		{
+			try
+			{
+				return XMSConvert.ToNMSTextMessage(
+					this.xmsSession.CreateTextMessage());
+			}
+			catch(Exception ex)
+			{
+				ExceptionUtil.WrapAndThrowNMSException(ex);
+				return null;
+			}
+		}
+		
+		public Apache.NMS.ITextMessage CreateTextMessage(string text)
+		{
+			try
+			{
+				return XMSConvert.ToNMSTextMessage(
+					this.xmsSession.CreateTextMessage(text));
+			}
+			catch(Exception ex)
+			{
+				ExceptionUtil.WrapAndThrowNMSException(ex);
+				return null;
+			}
+		}
+		
+		public Apache.NMS.IMapMessage CreateMapMessage()
+		{
+			try
+			{
+				return XMSConvert.ToNMSMapMessage(
+					this.xmsSession.CreateMapMessage());
+			}
+			catch(Exception ex)
+			{
+				ExceptionUtil.WrapAndThrowNMSException(ex);
+				return null;
+			}
+		}
+		
+		public Apache.NMS.IBytesMessage CreateBytesMessage()
+		{
+			try
+			{
+				return XMSConvert.ToNMSBytesMessage(
+					this.xmsSession.CreateBytesMessage());
+			}
+			catch(Exception ex)
+			{
+				ExceptionUtil.WrapAndThrowNMSException(ex);
+				return null;
+			}
+		}
+		
+		public Apache.NMS.IBytesMessage CreateBytesMessage(byte[] body)
+		{
+			try
+			{
+				Apache.NMS.IBytesMessage bytesMessage = CreateBytesMessage();
+		
+				if(null != bytesMessage)
+				{
+					bytesMessage.Content = body;
+				}
+		
+				return bytesMessage;
+			}
+			catch(Exception ex)
+			{
+				ExceptionUtil.WrapAndThrowNMSException(ex);
+				return null;
+			}
+		}
+		
+		public Apache.NMS.IStreamMessage CreateStreamMessage()
+		{
+			try
+			{
+				return XMSConvert.ToNMSStreamMessage(
+					this.xmsSession.CreateStreamMessage());
+			}
+			catch(Exception ex)
+			{
+				ExceptionUtil.WrapAndThrowNMSException(ex);
+				return null;
+			}
+		}
+		
+		public Apache.NMS.IObjectMessage CreateObjectMessage(Object body)
+		{
+			try
+			{
+				IBM.XMS.IObjectMessage xmsObjectMessage =
+					this.xmsSession.CreateObjectMessage();
+				xmsObjectMessage.Object = body;
+				return XMSConvert.ToNMSObjectMessage(xmsObjectMessage);
+			}
+			catch(Exception ex)
+			{
+				ExceptionUtil.WrapAndThrowNMSException(ex);
+				return null;
+			}
+		}
+		
+		public void Commit()
+		{
+			try
+			{
+				this.xmsSession.Commit();
+			}
+			catch(Exception ex)
+			{
+				ExceptionUtil.WrapAndThrowNMSException(ex);
+			}
+		}
+		
+		public void Rollback()
+		{
+			try
+			{
+				this.xmsSession.Rollback();
+			}
+			catch(Exception ex)
+			{
+				ExceptionUtil.WrapAndThrowNMSException(ex);
+			}
+		}
+		
+		public void Recover()
+		{
+			throw new NotSupportedException();
+		}
+		
+		private ConsumerTransformerDelegate consumerTransformer;
+		/// <summary>
+		/// A Delegate that is called each time a Message is dispatched to
+		/// allow the client to do any necessary transformations on the
+		/// received message before it is delivered. The Session instance
+		/// sets the delegate on each Consumer it creates.
+		/// </summary>
+		public ConsumerTransformerDelegate ConsumerTransformer
+		{
+			get { return this.consumerTransformer; }
+			set { this.consumerTransformer = value; }
+		}
+		
+		private ProducerTransformerDelegate producerTransformer;
+		/// <summary>
+		/// A delegate that is called each time a Message is sent from this
+		/// Producer which allows the application to perform any needed
+		/// transformations on the Message before it is sent. The Session
+		/// instance sets the delegate on each Producer it creates.
+		/// </summary>
+		public ProducerTransformerDelegate ProducerTransformer
+		{
+			get { return this.producerTransformer; }
+			set { this.producerTransformer = value; }
+		}
+		
+		#region Transaction State Events
+		
+		#pragma warning disable 0067
+		public event SessionTxEventDelegate TransactionStartedListener;
+		public event SessionTxEventDelegate TransactionCommittedListener;
+		public event SessionTxEventDelegate TransactionRolledBackListener;
+		#pragma warning restore 0067
+		
+		#endregion
+		
+		// Properties
+		
+		/// <summary>
+		/// The default timeout for network requests.
+		/// </summary>
+		private TimeSpan requestTimeout =
+			Apache.NMS.NMSConstants.defaultRequestTimeout;
+		public TimeSpan RequestTimeout
+		{
+			get { return this.requestTimeout; }
+			set { this.requestTimeout = value; }
+		}
+		
+		public bool Transacted
+		{
+			get { return this.xmsSession.Transacted; }
+		}
+		
+		public Apache.NMS.AcknowledgementMode AcknowledgementMode
+		{
+			get { return XMSConvert.ToAcknowledgementMode(this.xmsSession.AcknowledgeMode); }
+		}
+		
+		public void Close()
+		{
+			lock(this)
+			{
+				if(closed)
+				{
+					return;
+				}
+		
+				try
+				{
+					this.xmsSession.Close();
+				}
+				catch(Exception ex)
+				{
+					ExceptionUtil.WrapAndThrowNMSException(ex);
+				}
+				finally
+				{
+					closed = true;
+				}
+			}
+		}
+		
+		#endregion
+		
+		#region IDisposable Members
+		
+		///<summary>
+		/// Performs application-defined tasks associated with freeing,
+		/// releasing, or resetting unmanaged resources.
+		///</summary>
+		///<filterpriority>2</filterpriority>
+		public void Dispose()
+		{
+			Dispose(true);
+			GC.SuppressFinalize(this);
+		}
+		
+		protected void Dispose(bool disposing)
+		{
+			if(disposed)
+			{
+				return;
+			}
+		
+			if(disposing)
+			{
+				// Dispose managed code here.
+			}
+		
+			try
+			{
+				Close();
+			}
+			catch
+			{
+				// Ignore errors.
+			}
+		
+			disposed = true;
+		}
+		
+		#endregion
+	}
+}