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)

diff --git a/Apache.NMS.XMS.Test.nunit b/Apache.NMS.XMS.Test.nunit
new file mode 100644
index 0000000..54bccec
--- /dev/null
+++ b/Apache.NMS.XMS.Test.nunit
@@ -0,0 +1,7 @@
+<NUnitProject>

+  <Settings activeconfig="Default" />

+  <Config name="Default" binpathtype="Auto">

+    <!--<assembly path="Apache.NMS.Test.dll" />-->

+    <assembly path="Apache.NMS.XMS.Test.dll" />

+  </Config>

+</NUnitProject>
\ No newline at end of file
diff --git a/LICENSE.txt b/LICENSE.txt
new file mode 100644
index 0000000..6f22588
--- /dev/null
+++ b/LICENSE.txt
@@ -0,0 +1,764 @@
+

+                                 Apache License

+                           Version 2.0, January 2004

+                        http://www.apache.org/licenses/

+

+   TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION

+

+   1. Definitions.

+

+      "License" shall mean the terms and conditions for use, reproduction,

+      and distribution as defined by Sections 1 through 9 of this document.

+

+      "Licensor" shall mean the copyright owner or entity authorized by

+      the copyright owner that is granting the License.

+

+      "Legal Entity" shall mean the union of the acting entity and all

+      other entities that control, are controlled by, or are under common

+      control with that entity. For the purposes of this definition,

+      "control" means (i) the power, direct or indirect, to cause the

+      direction or management of such entity, whether by contract or

+      otherwise, or (ii) ownership of fifty percent (50%) or more of the

+      outstanding shares, or (iii) beneficial ownership of such entity.

+

+      "You" (or "Your") shall mean an individual or Legal Entity

+      exercising permissions granted by this License.

+

+      "Source" form shall mean the preferred form for making modifications,

+      including but not limited to software source code, documentation

+      source, and configuration files.

+

+      "Object" form shall mean any form resulting from mechanical

+      transformation or translation of a Source form, including but

+      not limited to compiled object code, generated documentation,

+      and conversions to other media types.

+

+      "Work" shall mean the work of authorship, whether in Source or

+      Object form, made available under the License, as indicated by a

+      copyright notice that is included in or attached to the work

+      (an example is provided in the Appendix below).

+

+      "Derivative Works" shall mean any work, whether in Source or Object

+      form, that is based on (or derived from) the Work and for which the

+      editorial revisions, annotations, elaborations, or other modifications

+      represent, as a whole, an original work of authorship. For the purposes

+      of this License, Derivative Works shall not include works that remain

+      separable from, or merely link (or bind by name) to the interfaces of,

+      the Work and Derivative Works thereof.

+

+      "Contribution" shall mean any work of authorship, including

+      the original version of the Work and any modifications or additions

+      to that Work or Derivative Works thereof, that is intentionally

+      submitted to Licensor for inclusion in the Work by the copyright owner

+      or by an individual or Legal Entity authorized to submit on behalf of

+      the copyright owner. For the purposes of this definition, "submitted"

+      means any form of electronic, verbal, or written communication sent

+      to the Licensor or its representatives, including but not limited to

+      communication on electronic mailing lists, source code control systems,

+      and issue tracking systems that are managed by, or on behalf of, the

+      Licensor for the purpose of discussing and improving the Work, but

+      excluding communication that is conspicuously marked or otherwise

+      designated in writing by the copyright owner as "Not a Contribution."

+

+      "Contributor" shall mean Licensor and any individual or Legal Entity

+      on behalf of whom a Contribution has been received by Licensor and

+      subsequently incorporated within the Work.

+

+   2. Grant of Copyright License. Subject to the terms and conditions of

+      this License, each Contributor hereby grants to You a perpetual,

+      worldwide, non-exclusive, no-charge, royalty-free, irrevocable

+      copyright license to reproduce, prepare Derivative Works of,

+      publicly display, publicly perform, sublicense, and distribute the

+      Work and such Derivative Works in Source or Object form.

+

+   3. Grant of Patent License. Subject to the terms and conditions of

+      this License, each Contributor hereby grants to You a perpetual,

+      worldwide, non-exclusive, no-charge, royalty-free, irrevocable

+      (except as stated in this section) patent license to make, have made,

+      use, offer to sell, sell, import, and otherwise transfer the Work,

+      where such license applies only to those patent claims licensable

+      by such Contributor that are necessarily infringed by their

+      Contribution(s) alone or by combination of their Contribution(s)

+      with the Work to which such Contribution(s) was submitted. If You

+      institute patent litigation against any entity (including a

+      cross-claim or counterclaim in a lawsuit) alleging that the Work

+      or a Contribution incorporated within the Work constitutes direct

+      or contributory patent infringement, then any patent licenses

+      granted to You under this License for that Work shall terminate

+      as of the date such litigation is filed.

+

+   4. Redistribution. You may reproduce and distribute copies of the

+      Work or Derivative Works thereof in any medium, with or without

+      modifications, and in Source or Object form, provided that You

+      meet the following conditions:

+

+      (a) You must give any other recipients of the Work or

+          Derivative Works a copy of this License; and

+

+      (b) You must cause any modified files to carry prominent notices

+          stating that You changed the files; and

+

+      (c) You must retain, in the Source form of any Derivative Works

+          that You distribute, all copyright, patent, trademark, and

+          attribution notices from the Source form of the Work,

+          excluding those notices that do not pertain to any part of

+          the Derivative Works; and

+

+      (d) If the Work includes a "NOTICE" text file as part of its

+          distribution, then any Derivative Works that You distribute must

+          include a readable copy of the attribution notices contained

+          within such NOTICE file, excluding those notices that do not

+          pertain to any part of the Derivative Works, in at least one

+          of the following places: within a NOTICE text file distributed

+          as part of the Derivative Works; within the Source form or

+          documentation, if provided along with the Derivative Works; or,

+          within a display generated by the Derivative Works, if and

+          wherever such third-party notices normally appear. The contents

+          of the NOTICE file are for informational purposes only and

+          do not modify the License. You may add Your own attribution

+          notices within Derivative Works that You distribute, alongside

+          or as an addendum to the NOTICE text from the Work, provided

+          that such additional attribution notices cannot be construed

+          as modifying the License.

+

+      You may add Your own copyright statement to Your modifications and

+      may provide additional or different license terms and conditions

+      for use, reproduction, or distribution of Your modifications, or

+      for any such Derivative Works as a whole, provided Your use,

+      reproduction, and distribution of the Work otherwise complies with

+      the conditions stated in this License.

+

+   5. Submission of Contributions. Unless You explicitly state otherwise,

+      any Contribution intentionally submitted for inclusion in the Work

+      by You to the Licensor shall be under the terms and conditions of

+      this License, without any additional terms or conditions.

+      Notwithstanding the above, nothing herein shall supersede or modify

+      the terms of any separate license agreement you may have executed

+      with Licensor regarding such Contributions.

+

+   6. Trademarks. This License does not grant permission to use the trade

+      names, trademarks, service marks, or product names of the Licensor,

+      except as required for reasonable and customary use in describing the

+      origin of the Work and reproducing the content of the NOTICE file.

+

+   7. Disclaimer of Warranty. Unless required by applicable law or

+      agreed to in writing, Licensor provides the Work (and each

+      Contributor provides its Contributions) on an "AS IS" BASIS,

+      WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or

+      implied, including, without limitation, any warranties or conditions

+      of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A

+      PARTICULAR PURPOSE. You are solely responsible for determining the

+      appropriateness of using or redistributing the Work and assume any

+      risks associated with Your exercise of permissions under this License.

+

+   8. Limitation of Liability. In no event and under no legal theory,

+      whether in tort (including negligence), contract, or otherwise,

+      unless required by applicable law (such as deliberate and grossly

+      negligent acts) or agreed to in writing, shall any Contributor be

+      liable to You for damages, including any direct, indirect, special,

+      incidental, or consequential damages of any character arising as a

+      result of this License or out of the use or inability to use the

+      Work (including but not limited to damages for loss of goodwill,

+      work stoppage, computer failure or malfunction, or any and all

+      other commercial damages or losses), even if such Contributor

+      has been advised of the possibility of such damages.

+

+   9. Accepting Warranty or Additional Liability. While redistributing

+      the Work or Derivative Works thereof, You may choose to offer,

+      and charge a fee for, acceptance of support, warranty, indemnity,

+      or other liability obligations and/or rights consistent with this

+      License. However, in accepting such obligations, You may act only

+      on Your own behalf and on Your sole responsibility, not on behalf

+      of any other Contributor, and only if You agree to indemnify,

+      defend, and hold each Contributor harmless for any liability

+      incurred by, or claims asserted against, such Contributor by reason

+      of your accepting any such warranty or additional liability.

+

+   END OF TERMS AND CONDITIONS

+

+   APPENDIX: How to apply the Apache License to your work.

+

+      To apply the Apache License to your work, attach the following

+      boilerplate notice, with the fields enclosed by brackets "[]"

+      replaced with your own identifying information. (Don't include

+      the brackets!)  The text should be enclosed in the appropriate

+      comment syntax for the file format. We also recommend that a

+      file or class name and description of purpose be included on the

+      same "printed page" as the copyright notice for easier

+      identification within third-party archives.

+

+   Copyright [yyyy] [name of copyright owner]

+

+   Licensed 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.

+

+APACHE ACTIVEMQ DEPENDENCIES:

+

+The Apache ActiveMQ message broker includes a number of dependencies, many 

+of them optional, with separate copyright notices and license terms. Your 

+use of the source code for the these subcomponents is subject to the terms 

+and conditions of the following licenses. 

+

+For the backport-util-concurrent library:

+

+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "DTD/xhtml1-transitional.dtd">

+<html><head><title>Creative Commons Public Domain</title>

+

+<body>

+

+<p align="center"><em>Copyright-Only Dedication (based on United States law) or Public Domain Certification</em></p>

+

+        <p>The

+person or persons who have associated work with this document (the

+"Dedicator" or "Certifier") hereby either (a) certifies that, to the

+best of his knowledge, the work of authorship identified is in the

+public domain of the country from which the work is published, or (b)

+hereby dedicates whatever copyright the dedicators holds in the work of

+authorship identified below (the "Work") to the public domain. A

+certifier, morever, dedicates any copyright interest he may have in the

+associated work, and for these purposes, is described as a "dedicator"

+below.</p>

+

+        <p>A certifier has taken reasonable steps to verify

+the copyright status of this work. Certifier recognizes that his good

+faith efforts may not shield him from liability if in fact the work

+certified is not in the public domain.</p>

+

+        <p>Dedicator makes

+this dedication for the benefit of the public at large and to the

+detriment of the Dedicator's heirs and successors. Dedicator intends

+this dedication to be an overt act of relinquishment in perpetuity of

+all present and future rights under copyright law, whether vested or

+contingent, in the Work. Dedicator understands that such relinquishment

+of all rights includes the relinquishment of all rights to enforce (by

+lawsuit or otherwise) those copyrights in the Work.</p>

+

+        <p>Dedicator

+recognizes that, once placed in the public domain, the Work may be

+freely reproduced, distributed, transmitted, used, modified, built

+upon, or otherwise exploited by anyone for any purpose, commercial or

+non-commercial, and in any way, including by methods that have not yet

+been invented or conceived.</p>

+    </div>

+</div>

+</body></html>

+

+For the mx4j, mx4j-remote, and mx4j-tools library:

+

+         The MX4J License, Version 1.0

+

+         Copyright (c) 2001-2004 by the MX4J contributors.  All rights reserved.

+

+         Redistribution and use in source and binary forms, with or without

+         modification, are permitted provided that the following conditions

+         are met:

+

+         1. Redistributions of source code must retain the above copyright

+            notice, this list of conditions and the following disclaimer.

+

+         2. Redistributions in binary form must reproduce the above copyright

+            notice, this list of conditions and the following disclaimer in

+            the documentation and/or other materials provided with the

+            distribution.

+

+         3. The end-user documentation included with the redistribution,

+            if any, must include the following acknowledgment:

+               "This product includes software developed by the

+                MX4J project (http://mx4j.sourceforge.net)."

+            Alternately, this acknowledgment may appear in the software itself,

+            if and wherever such third-party acknowledgments normally appear.

+

+         4. The name "MX4J" must not be used to endorse or promote

+            products derived from this software without prior written

+            permission.

+            For written permission, please contact

+            biorn_steedom [at] users [dot] sourceforge [dot] net

+

+         5. Products derived from this software may not be called "MX4J",

+            nor may "MX4J" appear in their name, without prior written

+            permission of Simone Bordet.

+

+         THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED

+         WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES

+         OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE

+         DISCLAIMED.  IN NO EVENT SHALL THE MX4J CONTRIBUTORS

+         BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,

+         SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT

+         LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF

+         USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND

+         ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,

+         OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT

+         OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF

+         SUCH DAMAGE.

+         ====================================================================

+

+         This software consists of voluntary contributions made by many

+         individuals on behalf of the MX4J project.  For more information on

+         MX4J, please see

+         <a href="http://mx4j.sourceforge.net" target="_top">the MX4J website</a>.

+

+For the jetty and jetty-util library:

+

+

+                                 Apache License

+                           Version 2.0, January 2004

+                        http://www.apache.org/licenses/

+

+   TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION

+

+   1. Definitions.

+

+      "License" shall mean the terms and conditions for use, reproduction,

+      and distribution as defined by Sections 1 through 9 of this document.

+

+      "Licensor" shall mean the copyright owner or entity authorized by

+      the copyright owner that is granting the License.

+

+      "Legal Entity" shall mean the union of the acting entity and all

+      other entities that control, are controlled by, or are under common

+      control with that entity. For the purposes of this definition,

+      "control" means (i) the power, direct or indirect, to cause the

+      direction or management of such entity, whether by contract or

+      otherwise, or (ii) ownership of fifty percent (50%) or more of the

+      outstanding shares, or (iii) beneficial ownership of such entity.

+

+      "You" (or "Your") shall mean an individual or Legal Entity

+      exercising permissions granted by this License.

+

+      "Source" form shall mean the preferred form for making modifications,

+      including but not limited to software source code, documentation

+      source, and configuration files.

+

+      "Object" form shall mean any form resulting from mechanical

+      transformation or translation of a Source form, including but

+      not limited to compiled object code, generated documentation,

+      and conversions to other media types.

+

+      "Work" shall mean the work of authorship, whether in Source or

+      Object form, made available under the License, as indicated by a

+      copyright notice that is included in or attached to the work

+      (an example is provided in the Appendix below).

+

+      "Derivative Works" shall mean any work, whether in Source or Object

+      form, that is based on (or derived from) the Work and for which the

+      editorial revisions, annotations, elaborations, or other modifications

+      represent, as a whole, an original work of authorship. For the purposes

+      of this License, Derivative Works shall not include works that remain

+      separable from, or merely link (or bind by name) to the interfaces of,

+      the Work and Derivative Works thereof.

+

+      "Contribution" shall mean any work of authorship, including

+      the original version of the Work and any modifications or additions

+      to that Work or Derivative Works thereof, that is intentionally

+      submitted to Licensor for inclusion in the Work by the copyright owner

+      or by an individual or Legal Entity authorized to submit on behalf of

+      the copyright owner. For the purposes of this definition, "submitted"

+      means any form of electronic, verbal, or written communication sent

+      to the Licensor or its representatives, including but not limited to

+      communication on electronic mailing lists, source code control systems,

+      and issue tracking systems that are managed by, or on behalf of, the

+      Licensor for the purpose of discussing and improving the Work, but

+      excluding communication that is conspicuously marked or otherwise

+      designated in writing by the copyright owner as "Not a Contribution."

+

+      "Contributor" shall mean Licensor and any individual or Legal Entity

+      on behalf of whom a Contribution has been received by Licensor and

+      subsequently incorporated within the Work.

+

+   2. Grant of Copyright License. Subject to the terms and conditions of

+      this License, each Contributor hereby grants to You a perpetual,

+      worldwide, non-exclusive, no-charge, royalty-free, irrevocable

+      copyright license to reproduce, prepare Derivative Works of,

+      publicly display, publicly perform, sublicense, and distribute the

+      Work and such Derivative Works in Source or Object form.

+

+   3. Grant of Patent License. Subject to the terms and conditions of

+      this License, each Contributor hereby grants to You a perpetual,

+      worldwide, non-exclusive, no-charge, royalty-free, irrevocable

+      (except as stated in this section) patent license to make, have made,

+      use, offer to sell, sell, import, and otherwise transfer the Work,

+      where such license applies only to those patent claims licensable

+      by such Contributor that are necessarily infringed by their

+      Contribution(s) alone or by combination of their Contribution(s)

+      with the Work to which such Contribution(s) was submitted. If You

+      institute patent litigation against any entity (including a

+      cross-claim or counterclaim in a lawsuit) alleging that the Work

+      or a Contribution incorporated within the Work constitutes direct

+      or contributory patent infringement, then any patent licenses

+      granted to You under this License for that Work shall terminate

+      as of the date such litigation is filed.

+

+   4. Redistribution. You may reproduce and distribute copies of the

+      Work or Derivative Works thereof in any medium, with or without

+      modifications, and in Source or Object form, provided that You

+      meet the following conditions:

+

+      (a) You must give any other recipients of the Work or

+          Derivative Works a copy of this License; and

+

+      (b) You must cause any modified files to carry prominent notices

+          stating that You changed the files; and

+

+      (c) You must retain, in the Source form of any Derivative Works

+          that You distribute, all copyright, patent, trademark, and

+          attribution notices from the Source form of the Work,

+          excluding those notices that do not pertain to any part of

+          the Derivative Works; and

+

+      (d) If the Work includes a "NOTICE" text file as part of its

+          distribution, then any Derivative Works that You distribute must

+          include a readable copy of the attribution notices contained

+          within such NOTICE file, excluding those notices that do not

+          pertain to any part of the Derivative Works, in at least one

+          of the following places: within a NOTICE text file distributed

+          as part of the Derivative Works; within the Source form or

+          documentation, if provided along with the Derivative Works; or,

+          within a display generated by the Derivative Works, if and

+          wherever such third-party notices normally appear. The contents

+          of the NOTICE file are for informational purposes only and

+          do not modify the License. You may add Your own attribution

+          notices within Derivative Works that You distribute, alongside

+          or as an addendum to the NOTICE text from the Work, provided

+          that such additional attribution notices cannot be construed

+          as modifying the License.

+

+      You may add Your own copyright statement to Your modifications and

+      may provide additional or different license terms and conditions

+      for use, reproduction, or distribution of Your modifications, or

+      for any such Derivative Works as a whole, provided Your use,

+      reproduction, and distribution of the Work otherwise complies with

+      the conditions stated in this License.

+

+   5. Submission of Contributions. Unless You explicitly state otherwise,

+      any Contribution intentionally submitted for inclusion in the Work

+      by You to the Licensor shall be under the terms and conditions of

+      this License, without any additional terms or conditions.

+      Notwithstanding the above, nothing herein shall supersede or modify

+      the terms of any separate license agreement you may have executed

+      with Licensor regarding such Contributions.

+

+   6. Trademarks. This License does not grant permission to use the trade

+      names, trademarks, service marks, or product names of the Licensor,

+      except as required for reasonable and customary use in describing the

+      origin of the Work and reproducing the content of the NOTICE file.

+

+   7. Disclaimer of Warranty. Unless required by applicable law or

+      agreed to in writing, Licensor provides the Work (and each

+      Contributor provides its Contributions) on an "AS IS" BASIS,

+      WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or

+      implied, including, without limitation, any warranties or conditions

+      of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A

+      PARTICULAR PURPOSE. You are solely responsible for determining the

+      appropriateness of using or redistributing the Work and assume any

+      risks associated with Your exercise of permissions under this License.

+

+   8. Limitation of Liability. In no event and under no legal theory,

+      whether in tort (including negligence), contract, or otherwise,

+      unless required by applicable law (such as deliberate and grossly

+      negligent acts) or agreed to in writing, shall any Contributor be

+      liable to You for damages, including any direct, indirect, special,

+      incidental, or consequential damages of any character arising as a

+      result of this License or out of the use or inability to use the

+      Work (including but not limited to damages for loss of goodwill,

+      work stoppage, computer failure or malfunction, or any and all

+      other commercial damages or losses), even if such Contributor

+      has been advised of the possibility of such damages.

+

+   9. Accepting Warranty or Additional Liability. While redistributing

+      the Work or Derivative Works thereof, You may choose to offer,

+      and charge a fee for, acceptance of support, warranty, indemnity,

+      or other liability obligations and/or rights consistent with this

+      License. However, in accepting such obligations, You may act only

+      on Your own behalf and on Your sole responsibility, not on behalf

+      of any other Contributor, and only if You agree to indemnify,

+      defend, and hold each Contributor harmless for any liability

+      incurred by, or claims asserted against, such Contributor by reason

+      of your accepting any such warranty or additional liability.

+

+   END OF TERMS AND CONDITIONS

+

+   APPENDIX: How to apply the Apache License to your work.

+

+      To apply the Apache License to your work, attach the following

+      boilerplate notice, with the fields enclosed by brackets "[]"

+      replaced with your own identifying information. (Don't include

+      the brackets!)  The text should be enclosed in the appropriate

+      comment syntax for the file format. We also recommend that a

+      file or class name and description of purpose be included on the

+      same "printed page" as the copyright notice for easier

+      identification within third-party archives.

+

+   Copyright [yyyy] [name of copyright owner]

+

+   Licensed 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.

+

+For the xmlpull library:

+

+XMLPULL API IS FREE

+-------------------

+

+All of the XMLPULL API source code, compiled code, and documentation 

+contained in this distribution *except* for tests (see separate LICENSE_TESTS.txt)

+are in the Public Domain.

+

+XMLPULL API comes with NO WARRANTY or guarantee of fitness for any purpose.

+

+Initial authors:

+

+  Stefan Haustein

+  Aleksander Slominski

+

+2001-12-12

+

+For the spring library:

+

+                                 Apache License

+                           Version 2.0, January 2004

+                        http://www.apache.org/licenses/

+

+   TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION

+

+   1. Definitions.

+

+      "License" shall mean the terms and conditions for use, reproduction,

+      and distribution as defined by Sections 1 through 9 of this document.

+

+      "Licensor" shall mean the copyright owner or entity authorized by

+      the copyright owner that is granting the License.

+

+      "Legal Entity" shall mean the union of the acting entity and all

+      other entities that control, are controlled by, or are under common

+      control with that entity. For the purposes of this definition,

+      "control" means (i) the power, direct or indirect, to cause the

+      direction or management of such entity, whether by contract or

+      otherwise, or (ii) ownership of fifty percent (50%) or more of the

+      outstanding shares, or (iii) beneficial ownership of such entity.

+

+      "You" (or "Your") shall mean an individual or Legal Entity

+      exercising permissions granted by this License.

+

+      "Source" form shall mean the preferred form for making modifications,

+      including but not limited to software source code, documentation

+      source, and configuration files.

+

+      "Object" form shall mean any form resulting from mechanical

+      transformation or translation of a Source form, including but

+      not limited to compiled object code, generated documentation,

+      and conversions to other media types.

+

+      "Work" shall mean the work of authorship, whether in Source or

+      Object form, made available under the License, as indicated by a

+      copyright notice that is included in or attached to the work

+      (an example is provided in the Appendix below).

+

+      "Derivative Works" shall mean any work, whether in Source or Object

+      form, that is based on (or derived from) the Work and for which the

+      editorial revisions, annotations, elaborations, or other modifications

+      represent, as a whole, an original work of authorship. For the purposes

+      of this License, Derivative Works shall not include works that remain

+      separable from, or merely link (or bind by name) to the interfaces of,

+      the Work and Derivative Works thereof.

+

+      "Contribution" shall mean any work of authorship, including

+      the original version of the Work and any modifications or additions

+      to that Work or Derivative Works thereof, that is intentionally

+      submitted to Licensor for inclusion in the Work by the copyright owner

+      or by an individual or Legal Entity authorized to submit on behalf of

+      the copyright owner. For the purposes of this definition, "submitted"

+      means any form of electronic, verbal, or written communication sent

+      to the Licensor or its representatives, including but not limited to

+      communication on electronic mailing lists, source code control systems,

+      and issue tracking systems that are managed by, or on behalf of, the

+      Licensor for the purpose of discussing and improving the Work, but

+      excluding communication that is conspicuously marked or otherwise

+      designated in writing by the copyright owner as "Not a Contribution."

+

+      "Contributor" shall mean Licensor and any individual or Legal Entity

+      on behalf of whom a Contribution has been received by Licensor and

+      subsequently incorporated within the Work.

+

+   2. Grant of Copyright License. Subject to the terms and conditions of

+      this License, each Contributor hereby grants to You a perpetual,

+      worldwide, non-exclusive, no-charge, royalty-free, irrevocable

+      copyright license to reproduce, prepare Derivative Works of,

+      publicly display, publicly perform, sublicense, and distribute the

+      Work and such Derivative Works in Source or Object form.

+

+   3. Grant of Patent License. Subject to the terms and conditions of

+      this License, each Contributor hereby grants to You a perpetual,

+      worldwide, non-exclusive, no-charge, royalty-free, irrevocable

+      (except as stated in this section) patent license to make, have made,

+      use, offer to sell, sell, import, and otherwise transfer the Work,

+      where such license applies only to those patent claims licensable

+      by such Contributor that are necessarily infringed by their

+      Contribution(s) alone or by combination of their Contribution(s)

+      with the Work to which such Contribution(s) was submitted. If You

+      institute patent litigation against any entity (including a

+      cross-claim or counterclaim in a lawsuit) alleging that the Work

+      or a Contribution incorporated within the Work constitutes direct

+      or contributory patent infringement, then any patent licenses

+      granted to You under this License for that Work shall terminate

+      as of the date such litigation is filed.

+

+   4. Redistribution. You may reproduce and distribute copies of the

+      Work or Derivative Works thereof in any medium, with or without

+      modifications, and in Source or Object form, provided that You

+      meet the following conditions:

+

+      (a) You must give any other recipients of the Work or

+          Derivative Works a copy of this License; and

+

+      (b) You must cause any modified files to carry prominent notices

+          stating that You changed the files; and

+

+      (c) You must retain, in the Source form of any Derivative Works

+          that You distribute, all copyright, patent, trademark, and

+          attribution notices from the Source form of the Work,

+          excluding those notices that do not pertain to any part of

+          the Derivative Works; and

+

+      (d) If the Work includes a "NOTICE" text file as part of its

+          distribution, then any Derivative Works that You distribute must

+          include a readable copy of the attribution notices contained

+          within such NOTICE file, excluding those notices that do not

+          pertain to any part of the Derivative Works, in at least one

+          of the following places: within a NOTICE text file distributed

+          as part of the Derivative Works; within the Source form or

+          documentation, if provided along with the Derivative Works; or,

+          within a display generated by the Derivative Works, if and

+          wherever such third-party notices normally appear. The contents

+          of the NOTICE file are for informational purposes only and

+          do not modify the License. You may add Your own attribution

+          notices within Derivative Works that You distribute, alongside

+          or as an addendum to the NOTICE text from the Work, provided

+          that such additional attribution notices cannot be construed

+          as modifying the License.

+

+      You may add Your own copyright statement to Your modifications and

+      may provide additional or different license terms and conditions

+      for use, reproduction, or distribution of Your modifications, or

+      for any such Derivative Works as a whole, provided Your use,

+      reproduction, and distribution of the Work otherwise complies with

+      the conditions stated in this License.

+

+   5. Submission of Contributions. Unless You explicitly state otherwise,

+      any Contribution intentionally submitted for inclusion in the Work

+      by You to the Licensor shall be under the terms and conditions of

+      this License, without any additional terms or conditions.

+      Notwithstanding the above, nothing herein shall supersede or modify

+      the terms of any separate license agreement you may have executed

+      with Licensor regarding such Contributions.

+

+   6. Trademarks. This License does not grant permission to use the trade

+      names, trademarks, service marks, or product names of the Licensor,

+      except as required for reasonable and customary use in describing the

+      origin of the Work and reproducing the content of the NOTICE file.

+

+   7. Disclaimer of Warranty. Unless required by applicable law or

+      agreed to in writing, Licensor provides the Work (and each

+      Contributor provides its Contributions) on an "AS IS" BASIS,

+      WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or

+      implied, including, without limitation, any warranties or conditions

+      of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A

+      PARTICULAR PURPOSE. You are solely responsible for determining the

+      appropriateness of using or redistributing the Work and assume any

+      risks associated with Your exercise of permissions under this License.

+

+   8. Limitation of Liability. In no event and under no legal theory,

+      whether in tort (including negligence), contract, or otherwise,

+      unless required by applicable law (such as deliberate and grossly

+      negligent acts) or agreed to in writing, shall any Contributor be

+      liable to You for damages, including any direct, indirect, special,

+      incidental, or consequential damages of any character arising as a

+      result of this License or out of the use or inability to use the

+      Work (including but not limited to damages for loss of goodwill,

+      work stoppage, computer failure or malfunction, or any and all

+      other commercial damages or losses), even if such Contributor

+      has been advised of the possibility of such damages.

+

+   9. Accepting Warranty or Additional Liability. While redistributing

+      the Work or Derivative Works thereof, You may choose to offer,

+      and charge a fee for, acceptance of support, warranty, indemnity,

+      or other liability obligations and/or rights consistent with this

+      License. However, in accepting such obligations, You may act only

+      on Your own behalf and on Your sole responsibility, not on behalf

+      of any other Contributor, and only if You agree to indemnify,

+      defend, and hold each Contributor harmless for any liability

+      incurred by, or claims asserted against, such Contributor by reason

+      of your accepting any such warranty or additional liability.

+

+   END OF TERMS AND CONDITIONS

+

+   APPENDIX: How to apply the Apache License to your work.

+

+      To apply the Apache License to your work, attach the following

+      boilerplate notice, with the fields enclosed by brackets "[]"

+      replaced with your own identifying information. (Don't include

+      the brackets!)  The text should be enclosed in the appropriate

+      comment syntax for the file format. We also recommend that a

+      file or class name and description of purpose be included on the

+      same "printed page" as the copyright notice for easier

+      identification within third-party archives.

+

+   Copyright [yyyy] [name of copyright owner]

+

+   Licensed 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.

+

+For the xstream library:

+

+(BSD Style License)

+

+Copyright (c) 2003-2004, Joe Walnes

+All rights reserved.

+

+Redistribution and use in source and binary forms, with or without

+modification, are permitted provided that the following conditions are met:

+

+Redistributions of source code must retain the above copyright notice, this list of

+conditions and the following disclaimer. Redistributions in binary form must reproduce

+the above copyright notice, this list of conditions and the following disclaimer in

+the documentation and/or other materials provided with the distribution.

+

+Neither the name of XStream nor the names of its contributors may be used to endorse

+or promote products derived from this software without specific prior written

+permission.

+

+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY

+EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES

+OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT

+SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,

+INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED

+TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR

+BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN

+CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY

+WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH

+DAMAGE.

diff --git a/NOTICE.txt b/NOTICE.txt
new file mode 100644
index 0000000..d8ded15
--- /dev/null
+++ b/NOTICE.txt
@@ -0,0 +1,12 @@
+=========================================================================

+==  NOTICE file corresponding to the section 4 d of                    ==

+==  the Apache License, Version 2.0,                                   ==

+==  in this case for the Apache ActiveMQ distribution.                 ==

+=========================================================================

+

+Apache ActiveMQ

+Copyright 2005-2006 The Apache Software Foundation

+

+This product includes software developed by

+The Apache Software Foundation (http://www.apache.org/).

+

diff --git a/README.txt b/README.txt
new file mode 100644
index 0000000..6c5d2cf
--- /dev/null
+++ b/README.txt
@@ -0,0 +1,47 @@
+=======================================================================

+Welcome to:

+ * Apache.NMS.XMS : Apache NMS for IBM XMS Client Library

+=======================================================================

+

+For more information see http://activemq.apache.org/nms

+

+=======================================================================

+Building With NAnt 0.86 see http://nant.sourceforge.net/

+=======================================================================

+

+NAnt version 0.86 or newer is required to build Apache.NMS.XMS.  Version 0.90

+or newer is highly recommended.

+To build the code using NAnt, run:

+

+  nant

+

+The NMS documentation can be generated into three different formats using

+Microsoft's Sandcastle open source product. The Sandcastle Styles project

+was used to enhance the output generated from the current release of Sandcastle.

+

+The Sandcastle project is located here:

+

+http://sandcastle.codeplex.com/

+

+The Sandcastle Styles project is located here:

+

+http://sandcastlestyles.codeplex.com/

+

+To generate the documentation, run:

+

+  nant sandcastle-all

+

+=======================================================================

+Building With Visual Studio 2013

+=======================================================================

+

+First build the project with nant, this will download and install 

+all the 3rd party dependencies for you.

+

+Open the solution File.  Build using "Build"->"Build Solution" 

+menu option.

+

+The resulting DLLs will be in build\${framework}\debug or the 

+build\${framework}\release directories depending on your settings 

+under "Build"->"Configuration Manager"

+

diff --git a/keyfile/NMSKey.snk b/keyfile/NMSKey.snk
new file mode 100644
index 0000000..fdd5b24
--- /dev/null
+++ b/keyfile/NMSKey.snk
Binary files differ
diff --git a/nant-common.xml b/nant-common.xml
new file mode 100644
index 0000000..3e5a8fc
--- /dev/null
+++ b/nant-common.xml
@@ -0,0 +1,658 @@
+<?xml version="1.0"?>

+<!--

+    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.

+-->

+<project xmlns="http://nant.sourceforge.net/release/0.85/nant.xsd">

+

+    <!-- ============================================================================================ -->

+    <!--    P R O P E R T Y    D E F I N I T I O N S                                                  -->

+    <!-- ============================================================================================ -->

+

+    <!-- global project settings -->

+    <property name="project.cls.compliant"   value="true" unless="${property::exists('project.cls.compliant')}" />

+    <property name="project.release.type"    value="SNAPSHOT" unless="${property::exists('project.release.type')}" />

+    <property name="project.version.full"    value="${project.version + if(project.release.type == 'snapshot', '-' + project.release.type, '')}" dynamic="true" />

+    <property name="project.startyear"       value="2005" />

+    <property name="build.dir"               value="${basedir}/build" />

+    <property name="doc.dir"                 value="${build.dir}/doc" />

+    <property name="lib.dir"                 value="${path::combine(basedir, 'lib')}" dynamic="true" />

+    <property name="lib.family.dir"          value="${path::combine(lib.dir, framework::get-family(framework::get-target-framework()))}" dynamic="true" />

+    <property name="lib.framework.dir"       value="${path::combine(lib.family.dir, version::to-string(framework::get-version(framework::get-target-framework())))}" dynamic="true" />

+    <property name="package.dir"             value="${basedir}/package" />

+    <property name="src.package.name"        value="${project.name + '-' + project.version + if(project.release.type == 'SNAPSHOT', '-' + project.release.type, '') + '-src.zip'}" />

+    <property name="bin.package.name"        value="${project.name + '-' + project.version + if(project.release.type == 'SNAPSHOT', '-' + project.release.type, '') + '-bin.zip'}" />

+

+    <!-- default configuration -->

+    <property name="build.defines"           value="" />

+    <property name="build.noskip"            value="false" />

+    <property name="build.skip"              value="false" />

+    <property name="build.skip.release"      value="false" unless="${property::exists('build.skip.release')}" />

+    <property name="download.skip"           value="false" unless="${property::exists('download.skip')}"/>

+    <property name="install.skip"            value="false" unless="${property::exists('install.skip')}"/>

+    <property name="compile.skip"            value="false" unless="${property::exists('compile.skip')}" />

+    <property name="current.build.config"    value="${if(project.release.type == 'release', 'release', 'debug')}" overwrite="false" />

+    <property name="current.build.framework" value="${framework::get-target-framework()}" overwrite="false" />

+    <property name="current.build.defines"   value="${build.defines}" />

+    <property name="build.framework.strings" value="net-2.0,net-3.5,net-4.0,mono-2.0,mono-4.0,netcf-2.0,netcf-3.5" unless="${property::exists('build.framework.strings')}"/>

+    <property name="current.build.framework.assembly.dir" value="${framework::get-assembly-directory(framework::get-target-framework())}" dynamic="true" />

+

+    <property name="build.config.strings"    value="${if(property::exists('configuration'), configuration, if(build.skip.release == 'true', 'debug', 'debug,release'))}" dynamic="true" />

+

+    <!-- Figure out the user's HOME directory -->

+    <property name="user.home" value="${environment::get-variable('HOME')}"

+            if="${environment::variable-exists('HOME') and platform::is-unix()}"

+            unless="${property::exists('user.home')}" />

+    <property name="user.home" value="${environment::get-variable('USERPROFILE')}"

+            if="${environment::variable-exists('USERPROFILE') and platform::is-windows()}"

+            unless="${property::exists('user.home')}" />

+    <fail message="The HOME environment variable is not defined.  Please set it to your home directory."

+            unless="${property::exists('user.home')}" if="${platform::is-unix()}" />

+    <fail message="The USERPROFILE environment variable is not defined.  Please set it to your home directory."

+            unless="${property::exists('user.home')}" if="${platform::is-windows()}" />

+

+    <!-- Figure out the NANT repositories -->

+    <property name="nant.remote.repo" value="${environment::get-variable('NANT_REMOTE_REPO')}"

+            if="${environment::variable-exists('NANT_REMOTE_REPO')}"

+            unless="${property::exists('nant.remote.repo')}" />

+    <property name="nant.local.repo" value="${environment::get-variable('NANT_REPO')}/local"

+            if="${environment::variable-exists('NANT_REPO')}"

+            unless="${property::exists('nant.local.repo')}" />

+    <property name="nant.local.repo" value="${user.home}/.nant/repository/local"

+            unless="${property::exists('nant.local.repo')}" />

+

+    <!-- Figure out the keyfile location -->

+    <property name="snk.file" value="${environment::get-variable('ACTIVEMQ_DOTNET_SNK')}"

+            if="${environment::variable-exists('ACTIVEMQ_DOTNET_SNK')}"

+            unless="${property::exists('snk.file')}" />

+    <property name="snk.file" value="${basedir}/keyfile/NMSKey.snk"

+            if="${not property::exists('snk.file')}" />

+

+    <!-- ============================================================================================ -->

+    <!--      I N I T I A L I Z A T I O N     T A R G E T S                                           -->

+    <!-- ============================================================================================ -->

+

+    <target name="init" description="Initializes build properties">

+        <!-- enabled the release or debug configuration -->

+        <call target="set-${current.build.config}-configuration" />

+

+        <!-- Check to see if our build setup for the target framework -->

+        <if test="${not(target::exists('set-'+current.build.framework+'-framework-configuration'))}">

+            <fail message="The '${current.build.framework}' framework is not supported by this version of ActiveMQ .NET" />

+        </if>

+        <call target="set-${current.build.framework}-framework-configuration" />

+

+        <!-- Check to see current platform supports the target framework -->

+        <if test="${framework::exists(current.build.framework)}">

+            <property name="build.skip" value="false" />

+        </if>

+        <if test="${not framework::exists(current.build.framework)}">

+            <if test="${build.noskip}">

+                <fail message="${current.build.framework.name} is not available." />

+            </if>

+            <if test="${not(build.noskip)}">

+                <echo message="${current.build.framework.name} is not available. Build skipped." />

+                <property name="build.skip" value="true" />

+            </if>

+        </if>

+

+        <!-- Check to see if we should skip this build framework. -->

+        <if test="${not(build.skip)}">

+            <if test="${property::exists('build.'+current.build.framework+'.skip')}">

+                <property name="build.skip" value="true" />

+                <echo message="The '${current.build.framework}' framework is not supported by this version of ActiveMQ .NET" />

+            </if>

+        </if>

+

+        <property name="current.build.keysign" value="${current.build.framework.sign}" />

+        <property name="build.bin.dir" value="${build.dir}/${current.build.framework}/${current.build.config}" />

+        <if test="${not(build.skip)}">

+            <echo message="Doing ${if(current.build.keysign,'a signed','an unsigned')} ${current.build.config} build for the ${current.build.framework.name} framework" />

+            <mkdir dir="${build.bin.dir}" />

+        </if>

+        <call target="dependency-init" />

+    </target>

+

+    <!-- Generate four-digit build number -->

+    <target name="generate-build-number">

+        <if test="${not property::exists('project.version.numeric')}">

+            <script language="C#">

+                <imports>

+                    <import namespace="System.Globalization" />

+                    <import namespace="System.Threading" />

+                </imports>

+                <code>

+                    <!-- Format for assembly revision is the number of days from the year the project 'started', property project.startyear.  -->

+                    <![CDATA[

+                        public static void ScriptMain(Project project)

+                        {

+                            int startYear = Convert.ToInt32(project.Properties["project.startyear"]);

+                            DateTime start = new DateTime(startYear, 1, 1);

+                            TimeSpan ts = DateTime.Now - start;

+                            project.Properties["project.version.numeric"] = project.Properties["project.version"].ToString() + "." + ts.Days.ToString();

+                        }

+                    ]]>

+                </code>

+            </script>

+        </if>

+    </target>

+

+    <!-- Generate assemblyinfo.cs files -->

+    <target name="generate-assemblyinfo" depends="generate-build-number" description="Generate the assembly info for the path in assemblyinfo.filename">

+        <asminfo output="${assemblyinfo.filename}" language="CSharp">

+            <imports>

+                <import namespace="System" />

+                <import namespace="System.Reflection" />

+                <import namespace="System.Runtime.InteropServices" />

+            </imports>

+            <attributes>

+                <attribute type="ComVisibleAttribute" value="false" />

+                <attribute type="CLSCompliantAttribute" value="${project.cls.compliant}" />

+                <attribute type="AssemblyTitleAttribute" value="${project.short_description}" />

+                <attribute type="AssemblyDescriptionAttribute" value="${project.description}" />

+                <attribute type="AssemblyConfigurationAttribute" value="${project.release.type}" />

+                <attribute type="AssemblyCompanyAttribute" value="http://activemq.apache.org/nms" />

+                <attribute type="AssemblyProductAttribute" value="${project.short_description}" />

+                <attribute type="AssemblyCopyrightAttribute" value="Copyright (C) ${project.startyear}-${datetime::get-year(datetime::now())} Apache Software Foundation" />

+                <attribute type="AssemblyTrademarkAttribute" value="" />

+                <attribute type="AssemblyCultureAttribute" value="" />

+                <attribute type="AssemblyVersionAttribute" value="${project.version.numeric}" />

+                <attribute type="AssemblyInformationalVersionAttribute" value="${project.version}" />

+            </attributes>

+        </asminfo>

+    </target>

+

+    <!-- ============================================================================================ -->

+    <!--    C O N F I G U R A T I O N     T A R G E T S                                               -->

+    <!-- ============================================================================================ -->

+

+    <target name="set-noskip-configuration" description="Disable skipping builds">

+        <property name="project.noskip" value="true" />

+    </target>

+

+    <target name="set-debug-configuration" description="Enabled 'debug' builds">

+        <property name="current.build.config" value="debug" />

+        <property name="current.build.config.debug" value="true" />

+        <property name="current.build.config.release" value="false" />

+        <property name="current.build.defines" value="${build.defines}DEBUG,TRACE," dynamic="true" />

+        <property name="csc.debug" value="Full" />

+        <property name="csc.optimize" value="false" />

+    </target>

+

+    <target name="set-release-configuration" description="Enabled 'release' builds">

+        <property name="current.build.config" value="release" />

+        <property name="current.build.config.release" value="true" />

+        <property name="current.build.config.debug" value="false" />

+        <property name="csc.debug" value="Full" />

+        <property name="csc.optimize" value="true" />

+    </target>

+

+    <target name="set-net-2.0-framework-configuration">

+        <property name="current.build.framework" value="net-2.0" />

+        <property name="current.build.framework.name" value=".NET 2.0" />

+        <property name="current.build.defines" value="${build.defines}NET,NET_2_0" dynamic="true" />

+        <property name="current.build.framework.sign" value="true" />

+        <property name="link.sdkdoc.version" value="SDK_v2_0" />

+        <property name="link.sdkdoc.web" value="true" />

+        <if test="${framework::exists(current.build.framework)}">

+            <property name="nant.settings.currentframework" value="${current.build.framework}" />

+        </if>

+        <!-- Use the .NET 3.5 compiler for improved language features.  Still targets same runtime. -->

+        <if test="${framework::exists('net-3.5')}">

+            <property name="nant.settings.currentframework" value="net-3.5" />

+        </if>

+    </target>

+

+    <target name="set-net-3.5-framework-configuration">

+        <property name="current.build.framework" value="net-3.5" />

+        <property name="current.build.framework.name" value=".NET 3.5" />

+        <property name="current.build.defines" value="${build.defines}NET,NET_2_0,NET_3_5" dynamic="true" />

+        <property name="current.build.framework.sign" value="true" />

+        <property name="link.sdkdoc.version" value="SDK_v6_1" />

+        <property name="link.sdkdoc.web" value="true" />

+        <if test="${framework::exists(current.build.framework)}">

+            <property name="nant.settings.currentframework" value="${current.build.framework}" />

+        </if>

+    </target>

+

+    <target name="set-net-4.0-framework-configuration">

+        <property name="current.build.framework" value="net-4.0" />

+        <property name="current.build.framework.name" value=".NET 4.0" />

+        <property name="current.build.defines" value="${build.defines}NET,NET_2_0,NET_3_5,NET_4_0" dynamic="true" />

+        <property name="current.build.framework.sign" value="true" />

+        <property name="link.sdkdoc.version" value="SDK_v7_0" />

+        <property name="link.sdkdoc.web" value="true" />

+        <if test="${framework::exists(current.build.framework)}">

+            <property name="nant.settings.currentframework" value="${current.build.framework}" />

+        </if>

+    </target>

+

+    <target name="set-netcf-2.0-framework-configuration">

+        <property name="current.build.framework" value="netcf-2.0" />

+        <property name="current.build.framework.name" value=".NET Compact Framework 2.0" />

+        <property name="current.build.defines" value="${build.defines}PocketPC,NETCF,NETCF_2_0" dynamic="true" />

+        <property name="current.build.framework.sign" value="true" />

+        <property name="link.sdkdoc.version" value="SDK_v1_1" />

+        <property name="link.sdkdoc.web" value="true" />

+        <if test="${framework::exists(current.build.framework)}">

+            <property name="nant.settings.currentframework" value="${current.build.framework}" />

+        </if>

+    </target>

+

+    <target name="set-netcf-3.5-framework-configuration">

+        <property name="current.build.framework" value="netcf-3.5" />

+        <property name="current.build.framework.name" value=".NET Compact Framework 3.5" />

+        <property name="current.build.defines" value="${build.defines}PocketPC,NETCF,NETCF_3_5" dynamic="true" />

+        <property name="current.build.framework.sign" value="true" />

+        <property name="link.sdkdoc.version" value="SDK_v3_5" />

+        <property name="link.sdkdoc.web" value="true" />

+        <if test="${framework::exists(current.build.framework)}">

+            <property name="nant.settings.currentframework" value="${current.build.framework}" />

+        </if>

+    </target>

+

+    <target name="set-mono-2.0-framework-configuration">

+        <property name="current.build.framework" value="mono-2.0" />

+        <property name="current.build.framework.name" value="Mono 2.0" />

+        <property name="current.build.defines" value="${build.defines}MONO,MONO_2_0" dynamic="true" />

+        <property name="current.build.framework.sign" value="true" />

+        <property name="link.sdkdoc.version" value="SDK_v1_1" />

+        <property name="link.sdkdoc.web" value="true" />

+        <if test="${framework::exists(current.build.framework)}">

+            <property name="nant.settings.currentframework" value="${current.build.framework}" />

+        </if>

+    </target>

+

+    <target name="set-mono-4.0-framework-configuration">

+        <property name="current.build.framework" value="mono-4.0" />

+        <property name="current.build.framework.name" value="Mono 4.0" />

+        <property name="current.build.defines" value="${build.defines}MONO,MONO_4_0" dynamic="true" />

+        <property name="current.build.framework.sign" value="true" />

+        <property name="link.sdkdoc.version" value="SDK_v1_1" />

+        <property name="link.sdkdoc.web" value="true" />

+        <if test="${framework::exists(current.build.framework)}">

+            <property name="nant.settings.currentframework" value="${current.build.framework}" />

+        </if>

+    </target>

+

+    <!-- ============================================================================================ -->

+    <!--     C O M P I L E    T A R G E T S                                                           -->

+    <!-- ============================================================================================ -->

+

+    <target name="compile-all" description="Compile all build configurations for all runtime configurations">

+        <echo message="Compiling all build configurations for all runtime configurations." />

+        <foreach item="String" in="${build.framework.strings}" delim="," property="current.build.framework">

+            <foreach item="String" in="${build.config.strings}" delim="," property="current.build.config">

+                <call target="compile-target" />

+            </foreach>

+        </foreach>

+    </target>

+

+    <target name="compile-target" depends="init, download-vendor, conditional-compile" />

+

+    <target name="conditional-compile" depends="init" unless="${build.skip or compile.skip}"

+            description="Conditionaly compiles all the modules if build framework and type are supported">

+        <call target="compile" />

+    </target>

+

+    <target name="compile" description="Compile everything">

+        <call target="compile-main" cascade="false" />

+        <call target="compile-test" cascade="false" />

+    </target>

+

+    <target name="compile-main" depends="init" description="Build the main library">

+        <echo message="Building the ${project.name} library" />

+        <property name="assemblyinfo.filename" value="src/main/csharp/CommonAssemblyInfo.cs" />

+        <call target="generate-assemblyinfo" />

+

+        <csc if="${current.build.keysign}" keyfile="${snk.file}" target="library"

+                define="${current.build.defines}" warnaserror="false" debug="${csc.debug}" optimize="${csc.optimize}"

+                output="${build.bin.dir}/${project.name}.dll" doc="${build.bin.dir}/${project.name}.xml">

+            <nowarn>

+                <warning number="1591" /> <!-- do not report warnings for missing XML comments -->

+            </nowarn>

+            <sources failonempty="true">

+                <include name="src/main/csharp/**.cs" />

+            </sources>

+            <references refid="dependencies" />

+        </csc>

+        <csc if="${not current.build.keysign}" target="library"

+                define="${current.build.defines}" warnaserror="false" debug="${csc.debug}" optimize="${csc.optimize}"

+                output="${build.bin.dir}/${project.name}.dll" doc="${build.bin.dir}/${project.name}.xml">

+            <nowarn>

+                <warning number="1591" /> <!-- do not report warnings for missing XML comments -->

+            </nowarn>

+            <sources failonempty="true">

+                <include name="src/main/csharp/**.cs" />

+            </sources>

+            <references refid="dependencies" />

+        </csc>

+        <call target="copy-content" />

+    </target>

+

+    <!-- Compile the nms-test module -->

+    <target name="compile-test" depends="compile-main" description="Build the test library">

+        <echo message="Building the ${project.name}.Test library" />

+        <property name="assemblyinfo.filename" value="src/test/csharp/CommonAssemblyInfo.cs" />

+        <call target="generate-assemblyinfo" />

+

+        <csc if="${current.build.keysign}" keyfile="${snk.file}" target="library"

+                define="${current.build.defines}" warnaserror="false" debug="${csc.debug}" optimize="${csc.optimize}"

+                output="${build.bin.dir}/${project.name}.Test.dll" doc="${build.bin.dir}/${project.name}.Test.xml">

+            <nowarn>

+                <warning number="1591" /> <!-- do not report warnings for missing XML comments -->

+                <warning number="3016" /> <!-- do not report warnings for array parameters  -->

+            </nowarn>

+            <sources failonempty="true">

+                <include name="src/test/csharp/**.cs" />

+            </sources>

+            <references refid="test.dependencies" />

+        </csc>

+        <csc if="${not current.build.keysign}" target="library"

+                define="${current.build.defines}" warnaserror="false" debug="${csc.debug}" optimize="${csc.optimize}"

+                output="${build.bin.dir}/${project.name}.Test.dll" doc="${build.bin.dir}/${project.name}.Test.xml">

+            <nowarn>

+                <warning number="1591" /> <!-- do not report warnings for missing XML comments -->

+                <warning number="3016" /> <!-- do not report warnings for array parameters  -->

+            </nowarn>

+            <sources failonempty="true">

+                <include name="src/test/csharp/**.cs" />

+            </sources>

+            <references refid="test.dependencies" />

+        </csc>

+        <call target="copy-content" />

+    </target>

+

+    <target name="copy-content">

+        <foreach item="File" property="content.filename">

+            <in>

+                <items refid="content.filenames" />

+            </in>

+            <do>

+                <copy todir="${build.bin.dir}" file="${content.filename}" if="${not file::up-to-date(content.filename, '${build.bin.dir}/${content.filename}')}" />

+            </do>

+        </foreach>

+    </target>

+

+    <!-- ============================================================================================ -->

+    <!--      I N S T A L L     T A R G E T S                                                         -->

+    <!-- ============================================================================================ -->

+

+    <target name="install-all" description="Install all build configurations for all runtime configurations">

+        <echo message="Installing all build configurations for all runtime configurations." />

+        <foreach item="String" in="${build.framework.strings}" delim="," property="current.build.framework">

+            <foreach item="String" in="${build.config.strings}" delim="," property="current.build.config">

+                <call target="install" />

+            </foreach>

+        </foreach>

+    </target>

+

+    <!-- Install the modules to the local repo -->

+    <target name="install" depends="init, compile-target, conditional-install"

+            description="Install the artifacts into the nant repo" />

+

+    <target name="conditional-install" unless="${build.skip or install.skip}"

+            description="Install the artifacts into the nant repo">

+        <property name="path" value="${project.group}/${project.name}/${project.version.full}/${current.build.framework}/${current.build.config}" />

+        <foreach item="File" property="install.filename">

+            <in>

+                <items refid="install.filenames" />

+            </in>

+            <do>

+                <property name="repo.task.artifact" value="${path}/${path::get-file-name(install.filename)}" />

+                <property name="repo.task.src" value="${install.filename}" />

+                <property name="repo.task.dest" value="${nant.local.repo}/${repo.task.artifact}" />

+                <mkdir dir="${directory::get-parent-directory(repo.task.dest)}" />

+                <copy file="${repo.task.src}" tofile="${repo.task.dest}" />

+            </do>

+        </foreach>

+    </target>

+

+    <!-- ============================================================================================ -->

+    <!--      R E P O    D O W N L O A D     T A R G E T S                                            -->

+    <!-- ============================================================================================ -->

+

+    <target name="download-vendor-all" description="Download vendor files for all runtime configurations">

+        <echo message="Downloading vendor files for all runtime configurations." />

+        <property name="current.build.config" value="release" />

+        <foreach item="String" in="${build.framework.strings}" delim="," property="current.build.framework">

+            <call target="download-vendor" />

+        </foreach>

+    </target>

+

+    <target name="download-vendor" depends="vendor-init, conditional-download"

+                description="Download the vendor artifacts from the nant repo" />

+

+    <target name="conditional-download" unless="${build.skip or download.skip}"

+                description="Download the artifacts from the nant repo">

+        <!-- Iterate over the defined vendor filesets. -->

+        <foreach item="String" in="${vendor.fileset.names}" delim="," property="current.vendor">

+            <property name="vendor.name" value="${property::get-value(current.vendor + '.name')}" />

+            <property name="vendor.group" value="${property::get-value(current.vendor + '.group')}" />

+            <property name="vendor.version" value="${property::get-value(current.vendor + '.version')}" />

+            <property name="vendor.filenames" value="${property::get-value(current.vendor + '.filenames')}" />

+            <property name="local.repo.vendor.path" value="${nant.local.repo}/${vendor.group}/${vendor.name}/${vendor.version}/${current.build.framework}/${current.build.config}" />

+            <property name="lib.path" value="lib/${vendor.name}/${current.build.framework}" />

+            <!--

+            Update the LIB folder with the latest version of the file.  If there is a newer version

+            installed in the local repository, then that version will be copied into the LIB folder.

+            -->

+            <foreach item="String" in="${vendor.filenames}" delim="," property="repo.task.artifact">

+                <property name="lib.task.dest" value="${lib.path}/${repo.task.artifact}" />

+                <mkdir dir="${directory::get-parent-directory(lib.task.dest)}" />

+                <property name="repo.task.src" value="${local.repo.vendor.path}/${repo.task.artifact}" />

+                <copy file="${repo.task.src}" tofile="${lib.task.dest}" if="${file::exists(repo.task.src)}" />

+                <if test="${not file::exists(lib.task.dest)}">

+                    <echo message="Required dependent assembly ${repo.task.artifact} from ${vendor.name} for ${current.build.framework} is not available. Build skipped." />

+                    <property name="build.skip" value="true" />

+                </if>

+            </foreach>

+        </foreach>

+    </target>

+

+    <!-- ============================================================================================ -->

+    <!--      T E S T     T A R G E T S                                                               -->

+    <!-- ============================================================================================ -->

+

+    <target name="test" depends="test-debug" description="Alias test target to test-debug" />

+

+    <target name="test-all" depends="test-debug, test-release" description="Test all build configurations for all runtime configurations" />

+

+    <target name="test-debug" depends="" description="Test debug build configurations for all runtime configurations">

+        <property name="current.build.config" value="debug" />

+        <call target="test-frameworks" />

+    </target>

+

+    <target name="test-release" depends="" description="Test release build configurations for all runtime configurations">

+        <property name="current.build.config" value="release" />

+        <call target="test-frameworks" />

+    </target>

+

+    <target name="test-frameworks">

+        <foreach item="String" in="${build.framework.strings}" delim="," property="current.build.framework">

+            <call target="init" />

+            <if test="${not build.skip}">

+                <exec program="nunit-console" failonerror="true" workingdir="build/${current.build.framework}/${current.build.config}">

+                    <arg value="${NUnit.Projectfile}" />

+                    <arg value="-labels" />

+                    <arg value="-exclude=Manual,LongRunning" />

+                    <arg value="-xml=Nunit.TestOutput.xml" />

+                </exec>

+            </if>

+        </foreach>

+    </target>

+

+    <!-- ============================================================================================ -->

+    <!--      M I S C E L L A N E O U S    T A R G E T S                                              -->

+    <!-- ============================================================================================ -->

+

+    <target name="build" depends="default" description="Build the project." />

+

+    <target name="rebuild" depends="clean,build" description="Rebuild the project." />

+

+    <target name="clean" description="Deletes build">

+        <if test="${target::exists('clean-init')}">

+            <call target="clean-init" />

+        </if>

+        <foreach item="String" in="${build.framework.strings}" delim="," property="current.build.framework">

+            <foreach item="String" in="${build.config.strings}" delim="," property="current.build.config">

+                <call target="clean-proj" />

+            </foreach>

+        </foreach>

+    </target>

+

+    <target name="clean-proj" depends="init" description="Deletes specific project build">

+        <property name="clean.dir" value="build/${current.build.framework}/${current.build.config}" />

+        <delete dir="${clean.dir}" if="${directory::exists(clean.dir)}" />

+        <property name="clean.dir" value="package/${current.build.config}" />

+        <delete dir="${clean.dir}" if="${directory::exists(clean.dir)}" />

+    </target>

+

+    <target name="package" description="Bundle the source and binary distributions.">

+        <mkdir dir="${package.dir}"

+                if="${not directory::exists(package.dir)}" />

+        <zip zipfile="${package.dir}/${bin.package.name}">

+            <fileset refid="bin.package.contents"/>

+        </zip>

+        <zip zipfile="${package.dir}/${src.package.name}">

+            <fileset refid="src.package.contents"/>

+        </zip>

+    </target>

+

+    <target name="doc" depends="build">

+        <mkdir dir="${doc.dir}" />

+        <ndoc failonerror="false">

+            <assemblies basedir="${build.bin.dir}">

+                <include name="${project.name}.dll" />

+            </assemblies>

+            <summaries basedir="${basedir}/src/main/ndoc">

+                <include name="NamespaceSummary.xml" />

+            </summaries>

+            <documenters>

+                <documenter name="MSDN">

+                    <property name="OutputDirectory" value="${doc.dir}" />

+                    <property name="HtmlHelpName" value="${project.name}" />

+                    <property name="HtmlHelpCompilerFilename" value="hhc.exe" />

+                    <property name="IncludeFavorites" value="False" />

+                    <property name="Title" value="${project.short_description}" />

+                    <property name="SplitTOCs" value="False" />

+                    <property name="DefaulTOC" value="" />

+                    <!--

+                    <property name="ShowVisualBasic" value="True" />

+                    <property name="ShowMissingSummaries" value="True" />

+                    <property name="ShowMissingRemarks" value="True" />

+                    <property name="ShowMissingParams" value="True" />

+                    <property name="ShowMissingReturns" value="True" />

+                    <property name="ShowMissingValues" value="True" />

+                    -->

+                    <property name="DocumentInternals" value="False" />

+                    <property name="DocumentProtected" value="True" />

+                    <property name="DocumentPrivates" value="False" />

+                    <property name="DocumentEmptyNamespaces" value="False" />

+                    <property name="IncludeAssemblyVersion" value="True" />

+                    <property name="CopyrightText" value="" />

+                    <property name="CopyrightHref" value="" />

+                </documenter>

+            </documenters>

+        </ndoc>

+    </target>

+

+    <target name="sandcastle" depends="set-release-configuration, init, conditional-compile">

+        <!-- Directories -->

+        <property name="sandcastle.style" value="vs2005" unless="${property::exists('sandcastle.style')}" />

+        <property name="documentation.dir" value="${build.bin.dir}" />

+        <property name="bin.intern.dir" value="${build.bin.dir}" />

+        <property name="bin.extern.dir" value="${basedir}\lib\NUnit\net-2.0" />

+        <property name="sandcastle.dir" value="${environment::get-variable('DXROOT')}" />

+        <property name="sandcastle.workingdir" value="${build.dir}\doc\${sandcastle.style}" />

+        <property name="sandcastle.output.dir" value="${sandcastle.workingdir}\Output" />

+

+        <!-- Executables -->

+        <property name="sandcastle.mrefbuilder.exe" value="${sandcastle.dir}\productiontools\mrefbuilder.exe" />

+        <property name="sandcastle.buildassembler.exe" value="${sandcastle.dir}\productiontools\buildassembler.exe" />

+        <property name="sandcastle.xsltransform.exe" value="${sandcastle.dir}\productiontools\xsltransform.exe" />

+        <property name="sandcastle.productiontransforms.dir" value="${sandcastle.dir}\ProductionTransforms" />

+

+        <!-- Create or Cleanup Working Directory -->

+        <mkdir dir="${sandcastle.workingdir}"

+                if="${not directory::exists(sandcastle.workingdir)}" />

+        <delete>

+            <fileset basedir="${sandcastle.workingdir}">

+                <include name="**\*" />

+            </fileset>

+        </delete>

+

+        <!-- Copy configuration file, and hard code references -->

+        <copy file="${sandcastle.dir}/Presentation/${sandcastle.style}/Configuration/Sandcastle.config"

+                tofile="${sandcastle.workingdir}/Sandcastle.config">

+            <filterchain>

+                <replacestring from="&quot;..\..\" to="&quot;${sandcastle.dir}\" />

+                <replacestring from="&quot;..\" to="&quot;${sandcastle.dir}\Examples\" />

+                <replacestring from="&quot;.\comments.xml" to="&quot;${documentation.dir}\${project.name}.xml" />

+                <replacestring from="&quot;%DXROOT%\Presentation\${sandcastle.style}\content\feedback_content.xml&quot;" to="&quot;${basedir}/src/main/sandcastle/feedback_content.xml&quot;" />

+            </filterchain>

+        </copy>

+

+        <!-- Run MRefBuilder (introspection on assemblies) to create basic Reflection XML -->

+        <exec program="${sandcastle.mrefbuilder.exe}" workingdir="${sandcastle.workingdir}">

+            <arg value="${bin.intern.dir}/${project.name}.dll" />

+            <arg value="/out:reflection.int.xml" />

+            <arg value="/dep:${bin.extern.dir}\*.dll" />

+        </exec>

+

+        <!-- Create Reflection XML -->

+        <exec program="${sandcastle.xsltransform.exe}" workingdir="${sandcastle.workingdir}">

+            <arg value="/xsl:&quot;${sandcastle.productiontransforms.dir}\ApplyVSDocModel.xsl&quot;" if="${sandcastle.style != 'prototype'}" />

+            <arg value="/xsl:&quot;${sandcastle.productiontransforms.dir}\ApplyPrototypeDocModel.xsl&quot;" if="${sandcastle.style == 'prototype'}" />

+            <arg value="/xsl:&quot;${sandcastle.productiontransforms.dir}\AddFriendlyFilenames.xsl&quot;" /> <!-- if="${sandcastle.style != 'prototype'}" /> -->

+            <arg value="/xsl:&quot;${sandcastle.productiontransforms.dir}\AddGuidFilenames.xsl&quot;" if="${sandcastle.style == 'disabled'}" />

+            <arg value="reflection.int.xml" />

+            <arg value="/out:reflection.xml" />

+            <arg value="/arg:IncludeAllMembersTopic=true" />

+            <arg value="/arg:IncludeInheritedOverloadTopics=true" />

+        </exec>

+

+        <!-- Create Manifest (list of Topics) -->

+        <exec program="${sandcastle.xsltransform.exe}" workingdir="${sandcastle.workingdir}">

+            <arg value="/xsl:&quot;${sandcastle.productiontransforms.dir}\ReflectionToManifest.xsl&quot;" />

+            <arg value="reflection.xml" />

+            <arg value="/out:manifest.xml" />

+        </exec>

+

+        <!-- Create Output Environment -->

+        <mkdir dir="${sandcastle.output.dir}" />

+        <mkdir dir="${sandcastle.output.dir}/html" />

+        <copy todir="${sandcastle.output.dir}">

+            <fileset basedir="${sandcastle.dir}/Presentation/${sandcastle.style}">

+                <include name="icons/*" />

+                <include name="media/*" />

+                <include name="scripts/*" />

+                <include name="styles/*" />

+            </fileset>

+        </copy>

+

+        <!-- Run BuildAssembler (create html topic files) -->

+        <exec program="${sandcastle.buildassembler.exe}" workingdir="${sandcastle.workingdir}">

+            <arg value="/config:Sandcastle.config" />

+            <arg value="manifest.xml" />

+        </exec>

+    </target>

+

+    <target name="sandcastle-all" description="Generate all formats of the Sandcastle documentation files.">

+        <foreach item="String" in="vs2005,prototype,hana" delim="," property="sandcastle.style">

+            <call target="sandcastle" />

+        </foreach>

+    </target>

+</project>

diff --git a/nant.build b/nant.build
new file mode 100644
index 0000000..0912aa5
--- /dev/null
+++ b/nant.build
@@ -0,0 +1,189 @@
+<?xml version="1.0"?>

+<!--

+    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.

+-->

+<project name="Apache.NMS.XMS" default="default" xmlns="http://nant.sourceforge.net/release/0.85/nant.xsd">

+	<!-- ============================================================================================ -->

+	<!--      I N I T I A L I Z A T I O N                                                             -->

+	<!-- ============================================================================================ -->

+	<property name="basedir" value="${project::get-base-directory()}" />

+	<property name="project.name" value="Apache.NMS.XMS" />

+	<property name="project.group" value="org.apache.activemq" />

+	<property name="project.version" value="1.8.0" unless="${property::exists('project.version')}" />

+	<property name="project.release.type" value="SNAPSHOT" unless="${property::exists('project.release.type')}" />

+	<property name="project.short_description" value="Apache NMS for XMS Class Library" />

+	<property name="project.description" value="Apache NMS for XMS Class Library (.Net Messaging Library Implementation): An implementation of the NMS API for XMS" />

+	<!-- The XMS module is not CLS compliant yet -->

+	<property name="project.cls.compliant" value="false" />

+	<!-- Repository organized as: organization/module/version/plaform/artifact, platform might be something like 'all' or 'net-4.0/release' -->

+	<property name="nunit.dll" value="${basedir}/lib/NUnit/${current.build.framework}/nunit.framework.dll" dynamic="true" />

+	<property name="Apache.NMS.dll" value="${basedir}/lib/Apache.NMS/${current.build.framework}/Apache.NMS.dll" dynamic="true" />

+	<property name="Apache.NMS.pdb" value="${basedir}/lib/Apache.NMS/${current.build.framework}/Apache.NMS.pdb" dynamic="true" />

+	<!--<property name="Apache.NMS.Test.dll" value="${basedir}/lib/Apache.NMS/${current.build.framework}//Apache.NMS.Test.dll" dynamic="true" />-->

+	<!--<property name="Apache.NMS.Test.pdb" value="${basedir}/lib/Apache.NMS/${current.build.framework}/Apache.NMS.Test.pdb" dynamic="true" />-->

+	<property name="IBM.XMS.dll" value="${basedir}/lib/IBM.XMS/${current.build.framework}/IBM.XMS.dll" dynamic="true" />

+	<property name="IBM.XMS.Impl.dll" value="${basedir}/lib/IBM.XMS/${current.build.framework}/IBM.XMS.Impl.dll" dynamic="true" />

+	<property name="IBM.XMS.Core.dll" value="${basedir}/lib/IBM.XMS/${current.build.framework}/IBM.XMS.Core.dll" dynamic="true" />

+	<property name="IBM.XMS.Util.dll" value="${basedir}/lib/IBM.XMS/${current.build.framework}/IBM.XMS.Util.dll" dynamic="true" />

+	<property name="IBM.XMS.NLS.dll" value="${basedir}/lib/IBM.XMS/${current.build.framework}/IBM.XMS.NLS.dll" dynamic="true" />

+	<property name="IBM.XMS.Provider.dll" value="${basedir}/lib/IBM.XMS/${current.build.framework}/IBM.XMS.Provider.dll" dynamic="true" />

+	<property name="IBM.XMS.Client.Impl.dll" value="${basedir}/lib/IBM.XMS/${current.build.framework}/IBM.XMS.Client.Impl.dll" dynamic="true" />

+	<property name="IBM.XMS.Client.WMQ.dll" value="${basedir}/lib/IBM.XMS/${current.build.framework}/IBM.XMS.Client.WMQ.dll" dynamic="true" />

+	<property name="IBM.XMS.Admin.dll" value="${basedir}/lib/IBM.XMS/${current.build.framework}/IBM.XMS.Admin.dll" dynamic="true" />

+	<property name="IBM.XMS.Admin.Objects.dll" value="${basedir}/lib/IBM.XMS/${current.build.framework}/IBM.XMS.Admin.Objects.dll" dynamic="true" />

+	<property name="IBM.XMS.Comms.dll" value="${basedir}/lib/IBM.XMS/${current.build.framework}/IBM.XMS.Comms.dll" dynamic="true" />

+	<property name="IBM.XMS.Comms.RMM.dll" value="${basedir}/lib/IBM.XMS/${current.build.framework}/IBM.XMS.Comms.RMM.dll" dynamic="true" />

+	<property name="IBM.XMS.Comms.SSL.dll" value="${basedir}/lib/IBM.XMS/${current.build.framework}/IBM.XMS.Comms.SSL.dll" dynamic="true" />

+	<property name="IBM.XMS.Formats.JMF.dll" value="${basedir}/lib/IBM.XMS/${current.build.framework}/IBM.XMS.Formats.JMF.dll" dynamic="true" />

+	<property name="IBM.XMS.Formats.MFP.dll" value="${basedir}/lib/IBM.XMS/${current.build.framework}/IBM.XMS.Formats.MFP.dll" dynamic="true" />

+	<property name="IBM.XMS.Match.dll" value="${basedir}/lib/IBM.XMS/${current.build.framework}/IBM.XMS.Match.dll" dynamic="true" />

+	<property name="IBM.XMS.SIB.dll" value="${basedir}/lib/IBM.XMS/${current.build.framework}/IBM.XMS.SIB.dll" dynamic="true" />

+	<property name="IBM.XMS.WCF.dll" value="${basedir}/lib/IBM.XMS/${current.build.framework}/IBM.XMS.WCF.dll" dynamic="true" />

+	<property name="IBM.XMS.WCF.NLS.dll" value="${basedir}/lib/IBM.XMS/${current.build.framework}/IBM.XMS.WCF.NLS.dll" dynamic="true" />

+	<property name="IBM.XMS.WMQI.dll" value="${basedir}/lib/IBM.XMS/${current.build.framework}/IBM.XMS.WMQI.dll" dynamic="true" />

+	<property name="NUnit.Projectfile" value="Apache.NMS.XMS.Test.nunit" />

+	<!-- Skip certain frameworks, since IBM XMS client is not supported on those platforms. -->

+	<property name="build.netcf-2.0.skip" value="true" />

+	<property name="build.netcf-3.5.skip" value="true" />

+	<property name="build.mono-2.0.skip" value="true" />

+	<!-- Possibly supported (cf. http://stackoverflow.com/questions/10138267/ibm-mqs-net-xms-and-mono) but not tested -->

+	<property name="build.mono-4.0.skip" value="true" />

+	<!-- Possibly supported (cf. http://stackoverflow.com/questions/10138267/ibm-mqs-net-xms-and-mono) but not tested -->

+	<property name="build.net-2.0.skip" value="true" />

+	<!-- Possibly supported but not tested -->

+	<property name="build.net-3.5.skip" value="true" />

+	<!-- Possibly supported but not tested -->

+	<target name="vendor-init" description="Initializes Vendor library from local repository.">

+		<!--

+		   Vendor specific info.  The prefix of 'vendor.apache.org' is taken from the property

+		   'vendor.fileset.names'.  This comma-delimited list is iterated, and properties with

+		   well-known suffixes are used to access and copy down vendor file dependencies.

+		-->

+		<property name="vendor.fileset.names" value="vendor.apache.org,vendor.nunit.org,vendor.ibm.org" />

+		<!-- Property grouping for 'vendor.apache.org' -->

+		<property name="vendor.apache.org.name" value="Apache.NMS" />

+		<property name="vendor.apache.org.group" value="org.apache.activemq" />

+		<property name="vendor.apache.org.version" value="1.8.0" />

+		<property name="vendor.apache.org.filenames" value="Apache.NMS.dll,Apache.NMS.pdb,Apache.NMS.Test.dll,Apache.NMS.Test.pdb" />

+		<!-- Property grouping for 'vendor.nunit.org' -->

+		<property name="vendor.nunit.org.name" value="NUnit" />

+		<property name="vendor.nunit.org.group" value="org.nunit" />

+		<property name="vendor.nunit.org.version" value="2.5.8" />

+		<property name="vendor.nunit.org.filenames" value="nunit.framework.dll" />

+		<!-- Property grouping for 'vendor.ibm.org' -->

+		<property name="vendor.ibm.org.name" value="IBM.XMS" />

+		<property name="vendor.ibm.org.group" value="org.ibm.xms" />

+		<property name="vendor.ibm.org.version" value="8.0.0" />

+		<property name="vendor.ibm.org.filenames" value="IBM.XMS.dll,IBM.XMS.Impl.dll,IBM.XMS.Core.dll,IBM.XMS.Util.dll,IBM.XMS.NLS.dll,IBM.XMS.Provider.dll,IBM.XMS.Client.Impl.dll,IBM.XMS.Client.WMQ.dll,IBM.XMS.Admin.dll,IBM.XMS.Admin.Objects.dll,IBM.XMS.Comms.dll,IBM.XMS.Comms.RMM.dll,IBM.XMS.Comms.SSL.dll,IBM.XMS.Formats.JMF.dll,IBM.XMS.Formats.MFP.dll,IBM.XMS.Match.dll,IBM.XMS.SIB.dll,IBM.XMS.WCF.dll,IBM.XMS.WCF.NLS.dll,IBM.XMS.WMQI.dll" />

+	</target>

+	<target name="dependency-init" description="Initializes build dependencies">

+		<assemblyfileset failonempty="true" id="dependencies">

+			<include name="${current.build.framework.assembly.dir}/mscorlib.dll" />

+			<include name="${current.build.framework.assembly.dir}/System.dll" />

+			<include name="${current.build.framework.assembly.dir}/System.Xml.dll" />

+			<include name="${IBM.XMS.dll}" />

+			<include name="${IBM.XMS.Impl.dll}" />

+			<include name="${IBM.XMS.Core.dll}" />

+			<include name="${IBM.XMS.Util.dll}" />

+			<include name="${IBM.XMS.NLS.dll}" />

+			<include name="${IBM.XMS.Provider.dll}" />

+			<include name="${IBM.XMS.Client.Impl.dll}" />

+			<include name="${IBM.XMS.Client.WMQ.dll}" />

+			<include name="${IBM.XMS.Admin.dll}" />

+			<include name="${IBM.XMS.Admin.Objects.dll}" />

+			<include name="${IBM.XMS.Comms.dll}" />

+			<include name="${IBM.XMS.Comms.RMM.dll}" />

+			<include name="${IBM.XMS.Comms.SSL.dll}" />

+			<include name="${IBM.XMS.Formats.JMF.dll}" />

+			<include name="${IBM.XMS.Formats.MFP.dll}" />

+			<include name="${IBM.XMS.Match.dll}" />

+			<include name="${IBM.XMS.SIB.dll}" />

+			<include name="${IBM.XMS.WCF.dll}" />

+			<include name="${IBM.XMS.WCF.NLS.dll}" />

+			<include name="${IBM.XMS.WMQI.dll}" />

+			<include name="${Apache.NMS.dll}" />

+		</assemblyfileset>

+		<assemblyfileset failonempty="true" id="test.dependencies">

+			<include name="${current.build.framework.assembly.dir}/mscorlib.dll" />

+			<include name="${current.build.framework.assembly.dir}/System.dll" />

+			<include name="${current.build.framework.assembly.dir}/System.Xml.dll" />

+			<include name="${IBM.XMS.dll}" />

+			<include name="${IBM.XMS.Impl.dll}" />

+			<include name="${IBM.XMS.Core.dll}" />

+			<include name="${IBM.XMS.Util.dll}" />

+			<include name="${IBM.XMS.NLS.dll}" />

+			<include name="${IBM.XMS.Provider.dll}" />

+			<include name="${IBM.XMS.Client.Impl.dll}" />

+			<include name="${IBM.XMS.Client.WMQ.dll}" />

+			<include name="${IBM.XMS.Admin.dll}" />

+			<include name="${IBM.XMS.Admin.Objects.dll}" />

+			<include name="${IBM.XMS.Comms.dll}" />

+			<include name="${IBM.XMS.Comms.RMM.dll}" />

+			<include name="${IBM.XMS.Comms.SSL.dll}" />

+			<include name="${IBM.XMS.Formats.JMF.dll}" />

+			<include name="${IBM.XMS.Formats.MFP.dll}" />

+			<include name="${IBM.XMS.Match.dll}" />

+			<include name="${IBM.XMS.SIB.dll}" />

+			<include name="${IBM.XMS.WCF.dll}" />

+			<include name="${IBM.XMS.WCF.NLS.dll}" />

+			<include name="${IBM.XMS.WMQI.dll}" />

+			<include name="${Apache.NMS.dll}" />

+			<!--<include name="${Apache.NMS.Test.dll}" />-->

+			<include name="${build.bin.dir}/${project.name}.dll" />

+			<include name="${nunit.dll}" />

+		</assemblyfileset>

+		<fileset id="content.filenames">

+			<include name="LICENSE.txt" />

+			<include name="NOTICE.txt" />

+			<include name="nmsprovider-*.config" />

+			<include name="${IBM.XMS.dll}" />

+			<include name="${IBM.XMS.Impl.dll}" />

+			<include name="${IBM.XMS.Core.dll}" />

+			<include name="${IBM.XMS.Util.dll}" />

+			<include name="${IBM.XMS.NLS.dll}" />

+			<include name="${IBM.XMS.Provider.dll}" />

+			<include name="${IBM.XMS.Client.Impl.dll}" />

+			<include name="${IBM.XMS.Client.WMQ.dll}" />

+			<include name="${IBM.XMS.Admin.dll}" />

+			<include name="${IBM.XMS.Admin.Objects.dll}" />

+			<include name="${IBM.XMS.Comms.dll}" />

+			<include name="${IBM.XMS.Comms.RMM.dll}" />

+			<include name="${IBM.XMS.Comms.SSL.dll}" />

+			<include name="${IBM.XMS.Formats.JMF.dll}" />

+			<include name="${IBM.XMS.Formats.MFP.dll}" />

+			<include name="${IBM.XMS.Match.dll}" />

+			<include name="${IBM.XMS.SIB.dll}" />

+			<include name="${IBM.XMS.WCF.dll}" />

+			<include name="${IBM.XMS.WCF.NLS.dll}" />

+			<include name="${IBM.XMS.WMQI.dll}" />

+			<include name="${Apache.NMS.dll}" />

+			<include name="${Apache.NMS.pdb}" />

+			<!--<include name="${Apache.NMS.Test.dll}" />-->

+			<!--<include name="${Apache.NMS.Test.pdb}" />-->

+			<include name="${nunit.dll}" />

+			<include name="${NUnit.Projectfile}" />

+		</fileset>

+		<fileset id="install.filenames">

+			<include name="LICENSE.txt" />

+			<include name="NOTICE.txt" />

+			<include name="${build.bin.dir}/${project.name}.dll" />

+			<include name="${build.bin.dir}/${project.name}.pdb" />

+		</fileset>

+	</target>

+	<target name="default" depends="install-all" />

+	<!-- Load the common target definitions  -->

+	<include buildfile="${basedir}/nant-common.xml" />

+</project>

diff --git a/package.ps1 b/package.ps1
new file mode 100644
index 0000000..6fbb79b
--- /dev/null
+++ b/package.ps1
@@ -0,0 +1,61 @@
+# 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.

+

+$pkgname = "Apache.NMS.XMS"

+$pkgver = "1.8-SNAPSHOT"

+$configurations = "release", "debug"

+$frameworks = "net-4.0"

+

+write-progress "Creating package directory." "Initializing..."

+if(!(test-path package))

+{

+	md package

+}

+

+if(test-path build)

+{

+	pushd build

+

+	$pkgdir = "..\package"

+

+	write-progress "Packaging Application files." "Scanning..."

+	$zipfile = "$pkgdir\$pkgname-$pkgver-bin.zip"

+	zip -9 -u -j "$zipfile" ..\LICENSE.txt

+	zip -9 -u -j "$zipfile" ..\NOTICE.txt

+	foreach($configuration in $configurations)

+	{

+		foreach($framework in $frameworks)

+		{

+			zip -9 -u "$zipfile" "$framework\$configuration\$pkgname.dll"

+			zip -9 -u "$zipfile" "$framework\$configuration\$pkgname.xml"

+			zip -9 -u "$zipfile" "$framework\$configuration\xmsprovider*.config"

+			zip -9 -u "$zipfile" "$framework\$configuration\$pkgname.Test.dll"

+			zip -9 -u "$zipfile" "$framework\$configuration\$pkgname.Test.xml"

+			zip -9 -u "$zipfile" "$framework\$configuration\$pkgname.pdb"

+			zip -9 -u "$zipfile" "$framework\$configuration\$pkgname.Test.pdb"

+		}

+	}

+

+	popd

+}

+

+write-progress "Packaging Source code files." "Scanning..."

+$pkgdir = "package"

+$zipfile = "$pkgdir\$pkgname-$pkgver-src.zip"

+

+zip -9 -u "$zipfile" LICENSE.txt NOTICE.txt nant-common.xml nant.build package.ps1 vs2013-xms-test.csproj vs2013-xms.csproj vs2013-xms.sln

+zip -9 -u -r "$zipfile" keyfile src

+

+write-progress -Completed "Packaging" "Complete."

diff --git a/src/main/csharp/BytesMessage.cs b/src/main/csharp/BytesMessage.cs
new file mode 100644
index 0000000..bddfb0f
--- /dev/null
+++ b/src/main/csharp/BytesMessage.cs
@@ -0,0 +1,187 @@
+/*

+ * 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

+{

+	class BytesMessage : Apache.NMS.XMS.Message, Apache.NMS.IBytesMessage

+	{

+		public IBM.XMS.IBytesMessage xmsBytesMessage

+		{

+			get { return (IBM.XMS.IBytesMessage)this.xmsMessage; }

+			set { this.xmsMessage = value; }

+		}

+

+		public BytesMessage(IBM.XMS.IBytesMessage message)

+			: base(message)

+		{

+		}

+

+		#region IBytesMessage Members

+

+		public byte[] Content

+		{

+			get

+			{

+				int contentLength = (int) this.xmsBytesMessage.BodyLength;

+				byte[] msgContent = new byte[contentLength];

+

+				this.xmsBytesMessage.Reset();

+				this.xmsBytesMessage.ReadBytes(msgContent, contentLength);

+				return msgContent;

+			}

+

+			set

+			{

+				this.ReadOnlyBody = false;

+				this.xmsBytesMessage.ClearBody();

+				this.xmsBytesMessage.WriteBytes(value, 0, value.Length);

+			}

+		}

+

+		public long BodyLength

+		{

+			get { return this.xmsBytesMessage.BodyLength; }

+		}

+

+		public bool ReadBoolean()

+		{

+			return this.xmsBytesMessage.ReadBoolean();

+		}

+

+		public byte ReadByte()

+		{

+			return (byte) this.xmsBytesMessage.ReadByte();

+		}

+

+		public int ReadBytes(byte[] value, int length)

+		{

+			return this.xmsBytesMessage.ReadBytes(value, length);

+		}

+

+		public int ReadBytes(byte[] value)

+		{

+			return this.xmsBytesMessage.ReadBytes(value);

+		}

+

+		public char ReadChar()

+		{

+			return this.xmsBytesMessage.ReadChar();

+		}

+

+		public double ReadDouble()

+		{

+			return this.xmsBytesMessage.ReadDouble();

+		}

+

+		public short ReadInt16()

+		{

+			return this.xmsBytesMessage.ReadShort();

+		}

+

+		public int ReadInt32()

+		{

+			return this.xmsBytesMessage.ReadInt();

+		}

+

+		public long ReadInt64()

+		{

+			return this.xmsBytesMessage.ReadLong();

+		}

+

+		public float ReadSingle()

+		{

+			return this.xmsBytesMessage.ReadFloat();

+		}

+

+		public string ReadString()

+		{

+			return this.xmsBytesMessage.ReadUTF();

+		}

+

+		public void Reset()

+		{

+			this.xmsBytesMessage.Reset();

+		}

+

+		public void WriteBoolean(bool value)

+		{

+			this.xmsBytesMessage.WriteBoolean(value);

+		}

+

+		public void WriteByte(byte value)

+		{

+			this.xmsBytesMessage.WriteByte(value);

+		}

+

+		public void WriteBytes(byte[] value, int offset, int length)

+		{

+			this.xmsBytesMessage.WriteBytes(value, offset, length);

+		}

+

+		public void WriteBytes(byte[] value)

+		{

+			this.xmsBytesMessage.WriteBytes(value);

+		}

+

+		public void WriteChar(char value)

+		{

+			this.xmsBytesMessage.WriteChar(value);

+		}

+

+		public void WriteDouble(double value)

+		{

+			this.xmsBytesMessage.WriteDouble(value);

+		}

+

+		public void WriteInt16(short value)

+		{

+			this.xmsBytesMessage.WriteShort(value);

+		}

+

+		public void WriteInt32(int value)

+		{

+			this.xmsBytesMessage.WriteInt(value);

+		}

+

+		public void WriteInt64(long value)

+		{

+			this.xmsBytesMessage.WriteLong(value);

+		}

+

+		public void WriteObject(object value)

+		{

+			this.xmsBytesMessage.WriteObject(value);

+		}

+

+		public void WriteSingle(float value)

+		{

+			this.xmsBytesMessage.WriteFloat(value);

+		}

+

+		public void WriteString(string value)

+		{

+			this.xmsBytesMessage.WriteUTF(value);

+		}

+

+		#endregion

+	}

+}

diff --git a/src/main/csharp/Connection.cs b/src/main/csharp/Connection.cs
new file mode 100644
index 0000000..07ba2fd
--- /dev/null
+++ b/src/main/csharp/Connection.cs
@@ -0,0 +1,461 @@
+/*

+ * 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 NMS connection to IBM MQ.

+	/// </summary>

+	///

+	public class Connection : Apache.NMS.IConnection

+	{

+		private Apache.NMS.AcknowledgementMode acknowledgementMode;

+		public readonly IBM.XMS.IConnection xmsConnection;

+		private IRedeliveryPolicy redeliveryPolicy;

+		private ConnectionMetaData metaData = null;

+		private readonly Atomic<bool> started = new Atomic<bool>(false);

+		private bool closed = false;

+		private bool disposed = false;

+		

+		#region Constructors

+		

+		/// <summary>

+		/// Constructs a connection object.

+		/// </summary>

+		public Connection(IBM.XMS.IConnection xmsConnection)

+		{

+			this.xmsConnection = xmsConnection;

+			this.xmsConnection.ExceptionListener = this.HandleXmsException;

+		}

+		

+		/// <summary>

+		/// "Destructs" or "finalizes" a connection object.

+		/// </summary>

+		~Connection()

+		{

+			Dispose(false);

+		}

+		

+		#endregion

+		

+		#region IStartable Members

+		

+		/// <summary>

+		/// Starts message delivery for this connection.

+		/// </summary>

+		public void Start()

+		{

+			if(started.CompareAndSet(false, true))

+			{

+				try

+				{

+					this.xmsConnection.Start();

+				}

+				catch(Exception ex)

+				{

+					ExceptionUtil.WrapAndThrowNMSException(ex);

+				}

+			}

+		}

+		

+		public bool IsStarted

+		{

+			get { return this.started.Value; }

+		}

+		

+		#endregion

+		

+		#region IStoppable Members

+		

+		/// <summary>

+		/// Stop message delivery for this connection.

+		/// </summary>

+		public void Stop()

+		{

+			try

+			{

+				if(started.CompareAndSet(true, false))

+				{

+					this.xmsConnection.Stop();

+				}

+			}

+			catch(Exception ex)

+			{

+				ExceptionUtil.WrapAndThrowNMSException(ex);

+			}

+		}

+		

+		#endregion

+		

+		#region IConnection Members

+		

+		/// <summary>

+		/// Creates a new session to work on this connection

+		/// </summary>

+		public Apache.NMS.ISession CreateSession()

+		{

+			return CreateSession(acknowledgementMode);

+		}

+		

+		/// <summary>

+		/// Creates a new session to work on this connection

+		/// </summary>

+		public Apache.NMS.ISession CreateSession(

+			Apache.NMS.AcknowledgementMode mode)

+		{

+			try

+			{

+				bool isTransacted =

+					(mode == Apache.NMS.AcknowledgementMode.Transactional);

+				return XMSConvert.ToNMSSession(

+					this.xmsConnection.CreateSession(

+						isTransacted, XMSConvert.ToAcknowledgeMode(mode)));

+			}

+			catch(Exception ex)

+			{

+				ExceptionUtil.WrapAndThrowNMSException(ex);

+				return null;

+			}

+		}

+		

+		public void Close()

+		{

+			lock(this)

+			{

+				if(closed)

+				{

+					return;

+				}

+		

+				try

+				{

+					this.xmsConnection.ExceptionListener = null;

+					this.xmsConnection.Stop();

+					this.xmsConnection.Close();

+				}

+				catch(Exception ex)

+				{

+					ExceptionUtil.WrapAndThrowNMSException(ex);

+				}

+				finally

+				{

+					closed = true;

+				}

+			}

+		}

+		

+		public void PurgeTempDestinations()

+		{

+		}

+		

+		#endregion

+		

+		#region IDisposable Members

+		

+		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

+		

+		#region Attributes

+		

+		/// <summary>

+		/// The default timeout for network requests.

+		/// </summary>

+		public TimeSpan RequestTimeout

+		{

+			get { return Apache.NMS.NMSConstants.defaultRequestTimeout; }

+			set { }

+		}

+		

+		public Apache.NMS.AcknowledgementMode AcknowledgementMode

+		{

+			get { return acknowledgementMode; }

+			set { acknowledgementMode = value; }

+		}

+		

+		public string ClientId

+		{

+			get

+			{

+				try

+				{

+					return this.xmsConnection.ClientID;

+				}

+				catch(Exception ex)

+				{

+					ExceptionUtil.WrapAndThrowNMSException(ex);

+					return null;

+				}

+			}

+			set

+			{

+				try

+				{

+					this.xmsConnection.ClientID = value;

+				}

+				catch(Exception ex)

+				{

+					ExceptionUtil.WrapAndThrowNMSException(ex);

+				}

+			}

+		}

+		

+		/// <summary>

+		/// Get/or set the redelivery policy for this connection.

+		/// </summary>

+		public IRedeliveryPolicy RedeliveryPolicy

+		{

+			get { return this.redeliveryPolicy; }

+			set { this.redeliveryPolicy = value; }

+		}

+		

+		/// <summary>

+		/// Gets the Meta Data for the NMS Connection instance.

+		/// </summary>

+		public IConnectionMetaData MetaData

+		{

+			get { return this.metaData ?? (this.metaData = new ConnectionMetaData()); }

+		}

+		

+		#endregion

+		

+		#region Properties

+		

+		// http://www-01.ibm.com/support/knowledgecenter/SSFKSJ_8.0.0/com.ibm.mq.msc.doc/props_conn.htm?lang=en

+		

+		#region Common properties

+		

+		/// <summary>

+		/// This property is used to obtain the name of the queue manager

+		/// to which it is connected.

+		/// </summary>

+		public string ResolvedQueueManagerName

+		{

+			get { return this.xmsConnection.GetStringProperty(XMSC.WMQ_RESOLVED_QUEUE_MANAGER); }

+			set { this.xmsConnection.SetStringProperty(XMSC.WMQ_RESOLVED_QUEUE_MANAGER, value); }

+		}

+		

+		/// <summary>

+		/// This property is populated with the ID of the queue manager

+		/// after the connection.

+		/// </summary>

+		public string ResolvedQueueManagerId

+		{

+			get { return this.xmsConnection.GetStringProperty(XMSC.WMQ_RESOLVED_QUEUE_MANAGER_ID); }

+			set { this.xmsConnection.SetStringProperty(XMSC.WMQ_RESOLVED_QUEUE_MANAGER_ID, value); }

+		}

+		

+		#endregion

+		

+		#region WPM-specific properties

+		

+		/// <summary>

+		/// The communications protocol used for the connection to the

+		/// messaging engine. This property is read-only.

+		/// </summary>

+		public Int32 XMSConnectionProtocol

+		{

+			get { return this.xmsConnection.GetIntProperty(XMSC.WPM_CONNECTION_PROTOCOL); }

+		}

+		

+		/// <summary>

+		/// The communications protocol used for the connection to the

+		/// messaging engine. This property is read-only.

+		/// </summary>

+		public WPMConnectionProtocol ConnectionProtocol

+		{

+			get { return XMSConvert.ToWPMConnectionProtocol(this.XMSConnectionProtocol); }

+		}

+		

+		/// <summary>

+		/// The host name or IP address of the system that contains the

+		/// messaging engine to which the application is connected. This

+		/// property is read-only.

+		/// </summary>

+		public string HostName

+		{

+			get { return this.xmsConnection.GetStringProperty(XMSC.WPM_HOST_NAME); }

+		}

+		

+		/// <summary>

+		/// The name of the messaging engine to which the application is

+		/// connected. This property is read-only.

+		/// </summary>

+		public string MessagingEngineName

+		{

+			get { return this.xmsConnection.GetStringProperty(XMSC.WPM_ME_NAME); }

+		}

+		

+		/// <summary>

+		/// The number of the port listened on by the messaging engine to

+		/// which the application is connected. This property is read-only.

+		/// </summary>

+		public Int32 Port

+		{

+			get { return this.xmsConnection.GetIntProperty(XMSC.WPM_PORT); }

+		}

+		

+		#endregion

+		

+		#endregion

+		

+		#region Event Listeners, Handlers and Delegates

+		

+		/// <summary>

+		/// A delegate that can receive transport level exceptions.

+		/// </summary>

+		public event ExceptionListener ExceptionListener;

+		

+		/// <summary>

+		/// Handles XMS connection exceptions.

+		/// </summary>

+		private void HandleXmsException(Exception exception)

+		{

+			if(ExceptionListener != null)

+			{

+				// Return codes MQRC_RECONNECTING and MQRC_RECONNECTED

+				// are not defined in XMS.

+				// const int MQRC_RECONNECTING = 2544;

+				// const int MQRC_RECONNECTED = 2545;

+				// According to http://www-01.ibm.com/support/knowledgecenter/#!/SSFKSJ_8.0.0/com.ibm.mq.con.doc/q017800_.htm

+				// Except for JMS and XMS clients, if a client application has

+				// access to reconnection options, it can also create an event

+				// handler to handle reconnection events.

+				ExceptionListener(exception);

+			}

+			else

+			{

+				Apache.NMS.Tracer.Error(exception);

+			}

+		}

+		

+		/// <summary>

+		/// An asynchronous listener that is notified when a fault tolerant

+		/// connection has been interrupted.

+		/// </summary>

+		/// <remarks>

+		/// IBM XMS does not handle disconnection / reconnection notifications.

+		/// This delegate will never be called.

+		/// </remarks>

+		public event ConnectionInterruptedListener ConnectionInterruptedListener;

+		

+		private void HandleTransportInterrupted()

+		{

+			Tracer.Debug("Transport has been interrupted.");

+		

+			if(this.ConnectionInterruptedListener != null && !this.closed)

+			{

+				try

+				{

+					this.ConnectionInterruptedListener();

+				}

+				catch

+				{

+				}

+			}

+		}

+		

+		/// <summary>

+		/// An asynchronous listener that is notified when a fault tolerant

+		/// connection has been resumed.

+		/// </summary>

+		/// <remarks>

+		/// IBM XMS does not handle disconnection / reconnection notifications.

+		/// This delegate will never be called.

+		/// </remarks>

+		public event ConnectionResumedListener ConnectionResumedListener;

+		

+		private void HandleTransportResumed()

+		{

+			Tracer.Debug("Transport has resumed normal operation.");

+		

+			if(this.ConnectionResumedListener != null && !this.closed)

+			{

+				try

+				{

+					this.ConnectionResumedListener();

+				}

+				catch

+				{

+				}

+			}

+		}

+		

+		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

+		/// ConnectionFactory sets the provided delegate instance on each Connection instance that

+		/// is created from this factory, each connection in turn passes the delegate along to each

+		/// Session it creates which then passes that along to the Consumers 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 ConnectionFactory sets the provided delegate instance on each Connection instance that

+		/// is created from this factory, each connection in turn passes the delegate along to each

+		/// Session it creates which then passes that along to the Producers it creates.

+		/// </summary>

+		public ProducerTransformerDelegate ProducerTransformer

+		{

+			get { return this.producerTransformer; }

+			set { this.producerTransformer = value; }

+		}

+		

+		#endregion

+	}

+}

diff --git a/src/main/csharp/ConnectionFactory.cs b/src/main/csharp/ConnectionFactory.cs
new file mode 100644
index 0000000..35863bb
--- /dev/null
+++ b/src/main/csharp/ConnectionFactory.cs
@@ -0,0 +1,1502 @@
+/*

+ * 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.Specialized;

+using Apache.NMS.XMS.Util;

+using Apache.NMS.Policies;

+using Apache.NMS.Util;

+using IBM.XMS;

+

+namespace Apache.NMS.XMS

+{

+	/// <summary>

+	/// A Factory that can establish NMS connections to IBM MQ.

+	/// </summary>

+	/// <remarks>

+	/// XMS connection factories can either be created from definitions

+	/// administered in a repository ("administered object"), or created

+	/// from an <c>XMSFactoryFactory</c>.

+	///

+	/// Addressable repositories for administered objects are:

+	/// - file system context

+	///   (URL format: "file://Path").

+	/// - LDAP context

+	///   (URL format: "ldap:[Hostname][:Port]["/"[DistinguishedName]]").

+	/// - WSS context:

+	///   (URL format: "http://Url", "cosnaming://Url" or "wsvc://Url").

+	///

+	/// A non-administered object is instanciated for a specific protocol:

+	/// - WebSphere Application Server Service Integration Bus

+	///   (protocol prefix: <c>"wpm:"</c>; XMS key: <c>XMSC.CT_WPM</c>).

+	/// - IBM Integration Bus using WebSphere MQ Real-Time Transport

+	///   (protocol prefix: <c>"rtt:"</c>; XMS key: <c>XMSC.CT_RTT</c>).

+	/// - WebSphere MQ queue manager

+	///   (protocol prefix: <c>"wmq:"</c>; XMS key: <c>XMSC.CT_WMQ</c>).

+	/// </remarks>

+	public class ConnectionFactory : Apache.NMS.IConnectionFactory

+	{

+		public IBM.XMS.IConnectionFactory xmsConnectionFactory = null;

+

+		private Uri brokerUri = null;

+		private IRedeliveryPolicy redeliveryPolicy = new RedeliveryPolicy();

+

+		#region Constructors

+

+		/// <summary>

+		/// Constructs a <c>ConnectionFactory</c> object using default values.

+		/// </summary>

+		public ConnectionFactory()

+			: this(new Uri("xms:wmq:"))

+		{

+		}

+

+		/// <summary>

+		/// Constructs a <c>ConnectionFactory</c> object.

+		/// </summary>

+		/// <param name="brokerUri">Factory URI.</param>

+		public ConnectionFactory(Uri brokerUri)

+		{

+			try

+			{

+				// BrokerUri will construct the xmsConnectionFactory

+				this.BrokerUri = brokerUri;

+			}

+			catch(Exception ex)

+			{

+				Apache.NMS.Tracer.DebugFormat(

+					"Exception instantiating IBM.XMS.ConnectionFactory: {0}",

+					ex.Message);

+				ExceptionUtil.WrapAndThrowNMSException(ex);

+			}

+			// In case WrapAndThrowNMSException masks the exception

+			if(this.xmsConnectionFactory == null)

+			{

+				throw new Apache.NMS.NMSException(

+					"Error instantiating XMS connection factory object.");

+			}

+		}

+

+		/// <summary>

+		/// Constructs the internal <c>ConnectionFactory</c> object from the

+		/// parameters specified in the input URI.

+		/// </summary>

+		/// <param name="factoryUri">Factory URI.</param>

+		/// <returns>URI stripped out from overridable property values.

+		/// </returns>

+		private Uri CreateConnectionFactoryFromURI(Uri factoryUri)

+		{

+			try

+			{

+				// Remove "xms:" scheme prefix

+				string originalString = factoryUri.OriginalString;

+				factoryUri = new Uri(originalString.Substring(

+					originalString.IndexOf(":") + 1));

+

+				// Parse URI properties

+				StringDictionary properties = URISupport.ParseQuery(

+					factoryUri.Query);

+

+				// The URI scheme specifies either the repository of

+				// administered objects where the ConnectionFactory object

+				// is defined, or the target connection type for

+				// non-administered objects.

+				switch(factoryUri.Scheme.ToLower())

+				{

+				case "rtt":

+				case "wmq":

+				case "wpm":

+					CreateNonAdministeredConnectionFactory(

+						factoryUri, properties);

+					break;

+				case "http":

+				case "ldap":

+				case "cosnaming":

+				case "wsvc":

+				default:

+					CreateAdministeredConnectionFactory(

+						factoryUri, properties);

+					break;

+				}

+

+				// Configure the instanciated connection factory

+				ConfigureConnectionFactory(factoryUri, properties);

+

+				return new Uri("xms:" + factoryUri.Scheme);

+			}

+			catch(Exception ex)

+			{

+				ExceptionUtil.WrapAndThrowNMSException(ex);

+				return null;

+			}

+		}

+

+		/// <summary>

+		/// Creates a connection factory from the object definition retrieved

+		/// from a repository of administered objects.

+		/// </summary>

+		/// <param name="factoryUri">Factory URI.</param>

+		/// <param name="properties">URI properties.</param>

+		private void CreateAdministeredConnectionFactory(

+			Uri factoryUri, StringDictionary properties)

+		{

+			// The initial context URL is the non-query part of the factory URI

+			string icUrl = factoryUri.OriginalString.Substring(0,

+				factoryUri.OriginalString.IndexOf('?'));

+

+			// Extract other InitialContext property values from URI

+			string icPrefix = "ic.";

+			StringDictionary icProperties = URISupport.ExtractProperties(

+				properties, icPrefix);

+

+			// Initialize environment Hashtable

+			Hashtable environment = new Hashtable();

+			environment[XMSC.IC_URL] = icUrl;

+			foreach(DictionaryEntry de in icProperties)

+			{

+				string key = ((string)de.Key).Substring(icPrefix.Length);

+				//TODO: convert "environment." attribute types.

+				environment[key] = de.Value;

+			}

+

+			// Create an InitialContext

+			InitialContext ic = new InitialContext(environment);

+

+			// Extract administered object name

+			string objectNameKey = "object.Name";

+			if(!properties.ContainsKey(objectNameKey))

+			{

+				throw new NMSException(string.Format(

+					"URI attribute {0} must be specified.", objectNameKey));

+			}

+            string objectName = properties[objectNameKey];

+			properties.Remove(objectNameKey);

+

+			// Lookup for object

+			this.xmsConnectionFactory =

+				(IBM.XMS.IConnectionFactory)ic.Lookup(objectName);

+		}

+

+		/// <summary>

+		/// Creates a non-administered connection factory.

+		/// </summary>

+		/// <param name="factoryUri">Factory URI.</param>

+		/// <param name="properties">URI properties.</param>

+		private void CreateNonAdministeredConnectionFactory(

+			Uri factoryUri, StringDictionary properties)

+		{

+			// Get an XMS factory factory for the requested protocol

+			IBM.XMS.XMSFactoryFactory xmsFactoryFactory = null;

+			string scheme = factoryUri.Scheme.ToLower();

+			switch(scheme)

+			{

+			case "rtt":

+				xmsFactoryFactory =

+					IBM.XMS.XMSFactoryFactory.GetInstance(IBM.XMS.XMSC.CT_RTT);

+

+				if(!string.IsNullOrEmpty(factoryUri.Host))

+				{

+					this.RTTHostName = factoryUri.Host;

+				}

+

+				if(factoryUri.Port != -1)

+				{

+					this.RTTPort = factoryUri.Port;

+				}

+				break;

+

+			case "wmq":

+				xmsFactoryFactory =

+					IBM.XMS.XMSFactoryFactory.GetInstance(IBM.XMS.XMSC.CT_WMQ);

+				break;

+

+			case "wpm":

+				xmsFactoryFactory =

+					IBM.XMS.XMSFactoryFactory.GetInstance(IBM.XMS.XMSC.CT_WPM);

+				break;

+			}

+

+			// Create the connection factory

+			this.xmsConnectionFactory =

+				xmsFactoryFactory.CreateConnectionFactory();

+

+			// For RTT and WMQ protocols, set the host name and port if

+			// they are specified

+			switch(scheme)

+			{

+				case "rtt":

+					if(!string.IsNullOrEmpty(factoryUri.Host))

+					{

+						this.RTTHostName = factoryUri.Host;

+					}

+

+					if(factoryUri.Port != -1)

+					{

+						this.RTTPort = factoryUri.Port;

+					}

+					break;

+

+				case "wmq":

+					if(!string.IsNullOrEmpty(factoryUri.Host))

+					{

+						this.WMQHostName = factoryUri.Host;

+					}

+

+					if(factoryUri.Port != -1)

+					{

+						this.WMQPort = factoryUri.Port;

+					}

+					break;

+			}

+		}

+

+		/// <summary>

+		/// Configures the connection factory.

+		/// </summary>

+		/// <param name="factoryUri">Factory URI.</param>

+		/// <param name="properties">URI properties.</param>

+		private void ConfigureConnectionFactory(

+			Uri factoryUri, StringDictionary properties)

+		{

+			if(properties != null && properties.Count > 0)

+			{

+				IntrospectionSupport.SetProperties(this, properties);

+			}

+		}

+

+		#endregion

+

+		#region Redelivery Policy

+

+		/// <summary>

+		/// Get/or set the redelivery policy that new IConnection objects are

+		/// assigned upon creation.

+		/// </summary>

+		public IRedeliveryPolicy RedeliveryPolicy

+		{

+			get { return this.redeliveryPolicy; }

+			set

+			{

+				if(value != null)

+				{

+					this.redeliveryPolicy = value;

+				}

+			}

+		}

+

+		#endregion

+

+		#region Properties (configure via URL parameters)

+

+		// http://www-01.ibm.com/support/knowledgecenter/?lang=en#!/SSFKSJ_8.0.0/com.ibm.mq.msc.doc/props_connf.htm

+

+		#region Connection Factory Properties common to all protocols

+

+		/// <summary>

+		/// The client identifier for a connection.

+		/// </summary>

+		[UriAttribute("factory.ClientId")]

+		public string ClientId

+		{

+			get { return this.xmsConnectionFactory.GetStringProperty(XMSC.CLIENT_ID); }

+			set { this.xmsConnectionFactory.SetStringProperty(XMSC.CLIENT_ID, value); }

+		}

+

+		/// <summary>

+		/// The type of messaging server to which an application connects.

+		/// </summary>

+		[UriAttribute("factory.XMSConnectionType")]

+		public Int32 XMSConnectionType

+		{

+			get { return this.xmsConnectionFactory.GetIntProperty(XMSC.CONNECTION_TYPE); }

+			set { this.xmsConnectionFactory.SetIntProperty(XMSC.CONNECTION_TYPE, value); }

+		}

+

+		/// <summary>

+		/// The type of messaging server to which an application connects.

+		/// </summary>

+		[UriAttribute("factory.ConnectionType")]

+		public ConnectionType ConnectionType

+		{

+			get { return XMSConvert.ToConnectionType(this.XMSConnectionType); }

+			set { this.XMSConnectionType = XMSConvert.ToXMSConnectionType(value); }

+		}

+

+		/// <summary>

+		/// A user identifier that can be used to authenticate the application

+		/// when it attempts to connect to a messaging server.

+		/// </summary>

+		[UriAttribute("factory.UserId")]

+		public string UserId

+		{

+			get { return this.xmsConnectionFactory.GetStringProperty(XMSC.USERID); }

+			set { this.xmsConnectionFactory.SetStringProperty(XMSC.USERID, value); }

+		}

+

+		/// <summary>

+		/// A password that can be used to authenticate the application when it

+		/// attempts to connect to a messaging server.

+		/// </summary>

+		[UriAttribute("factory.XMSPassword")]

+		public byte[] XMSPassword

+		{

+			get { return this.xmsConnectionFactory.GetBytesProperty(XMSC.PASSWORD); }

+			set { this.xmsConnectionFactory.SetBytesProperty(XMSC.PASSWORD, value); }

+		}

+

+		/// <summary>

+		/// A password that can be used to authenticate the application when it

+		/// attempts to connect to a messaging server, specified as a string.

+		/// </summary>

+		[UriAttribute("factory.Password")]

+		public string Password

+		{

+			get { return Convert.ToBase64String(this.XMSPassword); }

+			set { this.XMSPassword = Convert.FromBase64String(value); }

+		}

+

+		/// <summary>

+		/// This property determines whether XMS informs an ExceptionListener

+		/// only when a connection is broken, or when any exception occurs

+		/// asynchronously to an XMS API call.

+		/// </summary>

+		/// <remarks>

+		/// This property applies to all Connections created from this

+		/// ConnectionFactory that have an ExceptionListener registered.

+		/// </remarks>

+		[UriAttribute("factory.XMSAsynchronousExceptions")]

+		public Int32 XMSAsynchronousExceptions

+		{

+			get { return this.xmsConnectionFactory.GetIntProperty(XMSC.ASYNC_EXCEPTIONS); }

+			set { this.xmsConnectionFactory.SetIntProperty(XMSC.ASYNC_EXCEPTIONS, value); }

+		}

+

+		/// <summary>

+		/// This property determines whether XMS informs an

+		/// <c>ExceptionListener</c> only when a connection is broken, or when

+		/// any exception occurs asynchronously to an XMS API call.

+		/// </summary>

+		[UriAttribute("factory.AsynchronousExceptions")]

+		public AsynchronousExceptions AsynchronousExceptions

+		{

+			get { return XMSConvert.ToAsynchronousExceptions(this.XMSAsynchronousExceptions); }

+			set { this.XMSAsynchronousExceptions = XMSConvert.ToXMSAsynchronousExceptions(value); }

+		}

+

+		#endregion

+

+		#region RTT-specific properties

+

+		/// <summary>

+		/// The communications protocol used for a real-time connection to a broker.

+		/// </summary>

+		[UriAttribute("rtt.XMSConnectionProtocol")]

+		public Int32 XMSConnectionProtocol

+		{

+			get { return this.xmsConnectionFactory.GetIntProperty(XMSC.RTT_CONNECTION_PROTOCOL); }

+			set { this.xmsConnectionFactory.SetIntProperty(XMSC.RTT_CONNECTION_PROTOCOL, value); }

+		}

+

+		/// <summary>

+		/// The communications protocol used for a real-time connection to a broker.

+		/// </summary>

+		[UriAttribute("rtt.ConnectionProtocol")]

+		public RTTConnectionProtocol ConnectionProtocol

+		{

+			get { return XMSConvert.ToRTTConnectionProtocol(this.XMSConnectionProtocol); }

+			set { this.XMSConnectionProtocol = XMSConvert.ToXMSRTTConnectionProtocol(value); }

+		}

+

+		/// <summary>

+		/// The host name or IP address of the system on which a broker runs.

+		/// </summary>

+		[UriAttribute("rtt.HostName")]

+		public string RTTHostName

+		{

+			get { return this.xmsConnectionFactory.GetStringProperty(XMSC.RTT_HOST_NAME); }

+			set { this.xmsConnectionFactory.SetStringProperty(XMSC.RTT_HOST_NAME, value); }

+		}

+

+		/// <summary>

+		/// The number of the port on which a broker listens for incoming requests.

+		/// </summary>

+		[UriAttribute("rtt.Port")]

+		public Int32 RTTPort

+		{

+			get { return this.xmsConnectionFactory.GetIntProperty(XMSC.RTT_PORT); }

+			set { this.xmsConnectionFactory.SetIntProperty(XMSC.RTT_PORT, value); }

+		}

+

+		/// <summary>

+		/// The host name or IP address of the local network interface to be

+		/// used for a real-time connection to a broker.

+		/// </summary>

+		[UriAttribute("rtt.LocalAddress")]

+		public string RTTLocalAddress

+		{

+			get { return this.xmsConnectionFactory.GetStringProperty(XMSC.RTT_LOCAL_ADDRESS); }

+			set { this.xmsConnectionFactory.SetStringProperty(XMSC.RTT_LOCAL_ADDRESS, value); }

+		}

+

+		/// <summary>

+		/// The multicast setting for the connection factory.

+		/// </summary>

+		[UriAttribute("rtt.XMSMulticast")]

+		public Int32 XMSMulticast

+		{

+			get { return this.xmsConnectionFactory.GetIntProperty(XMSC.RTT_MULTICAST); }

+			set { this.xmsConnectionFactory.SetIntProperty(XMSC.RTT_MULTICAST, value); }

+		}

+

+		/// <summary>

+		/// The multicast setting for a connection factory or destination.

+		/// </summary>

+		[UriAttribute("rtt.Multicast")]

+		public Multicast Multicast

+		{

+			get { return XMSConvert.ToMulticast(this.XMSMulticast); }

+			set { this.XMSMulticast = XMSConvert.ToXMSMulticast(value); }

+		}

+

+		/// <summary>

+		/// The time interval, in milliseconds, after which XMS .NET checks the

+		/// connection to a Real Time messaging server to detect any activity.

+		/// </summary>

+		[UriAttribute("rtt.BrokerPingInterval")]

+		public Int32 BrokerPingInterval

+		{

+			get { return this.xmsConnectionFactory.GetIntProperty(XMSC.RTT_BROKER_PING_INTERVAL); }

+			set { this.xmsConnectionFactory.SetIntProperty(XMSC.RTT_BROKER_PING_INTERVAL, value); }

+		}

+

+		#endregion

+

+		#region WMQ-specific properties

+

+		/// <summary>

+		/// The host name or IP address of the system on which a queue manager

+		/// runs.

+		/// </summary>

+		[UriAttribute("wmq.HostName")]

+		public string WMQHostName

+		{

+			get { return this.xmsConnectionFactory.GetStringProperty(XMSC.WMQ_HOST_NAME); }

+			set { this.xmsConnectionFactory.SetStringProperty(XMSC.WMQ_HOST_NAME, value); }

+		}

+

+		/// <summary>

+		/// The number of the port on which a queue manager listens for

+		/// incoming requests.

+		/// </summary>

+		[UriAttribute("wmq.Port")]

+		public Int32 WMQPort

+		{

+			get { return this.xmsConnectionFactory.GetIntProperty(XMSC.WMQ_PORT); }

+			set { this.xmsConnectionFactory.SetIntProperty(XMSC.WMQ_PORT, value); }

+		}

+

+		/// <summary>

+		/// For a connection to a queue manager, this property specifies the

+		/// local network interface to be used, or the local port or range of

+		/// local ports to be used, or both.

+		/// </summary>

+		[UriAttribute("wmq.LocalAddress")]

+		public string WMQLocalAddress

+		{

+			get { return this.xmsConnectionFactory.GetStringProperty(XMSC.WMQ_LOCAL_ADDRESS); }

+			set { this.xmsConnectionFactory.SetStringProperty(XMSC.WMQ_LOCAL_ADDRESS, value); }

+		}

+

+		/// <summary>

+		/// The name of the queue manager to connect to.

+		/// </summary>

+		[UriAttribute("wmq.QueueManagerName")]

+		public string QueueManagerName

+		{

+			get { return this.xmsConnectionFactory.GetStringProperty(XMSC.WMQ_QUEUE_MANAGER); }

+			set { this.xmsConnectionFactory.SetStringProperty(XMSC.WMQ_QUEUE_MANAGER, value); }

+		}

+

+		/// <summary>

+		/// The version, release, modification level and fix pack of the queue

+		/// manager to which the application intends to connect.

+		/// </summary>

+		[UriAttribute("wmq.ProviderVersion")]

+		public string ProviderVersion

+		{

+			get { return this.xmsConnectionFactory.GetStringProperty(XMSC.WMQ_PROVIDER_VERSION); }

+			set { this.xmsConnectionFactory.SetStringProperty(XMSC.WMQ_PROVIDER_VERSION, value); }

+		}

+

+		/// <summary>

+		/// The name of the channel to be used for a connection.

+		/// </summary>

+		[UriAttribute("wmq.ChannelName")]

+		public string ChannelName

+		{

+			get { return this.xmsConnectionFactory.GetStringProperty(XMSC.WMQ_CHANNEL); }

+			set { this.xmsConnectionFactory.SetStringProperty(XMSC.WMQ_CHANNEL, value); }

+		}

+

+		/// <summary>

+		/// A Uniform Resource Locator (URL) that identifies the name and

+		/// location of the file that contains the client channel definition

+		/// table and also specifies how the file can be accessed.

+		/// </summary>

+		[UriAttribute("wmq.ClientChannelDefinitionTableURL")]

+		public string ClientChannelDefinitionTableURL

+		{

+			get { return this.xmsConnectionFactory.GetStringProperty(XMSC.WMQ_CCDTURL); }

+			set { this.xmsConnectionFactory.SetStringProperty(XMSC.WMQ_CCDTURL, value); }

+		}

+

+		/// <summary>

+		/// The mode by which an application connects to a queue manager.

+		/// </summary>

+		[UriAttribute("wmq.XMSConnectionMode")]

+		public Int32 XMSConnectionMode

+		{

+			get { return this.xmsConnectionFactory.GetIntProperty(XMSC.WMQ_CONNECTION_MODE); }

+			set { this.xmsConnectionFactory.SetIntProperty(XMSC.WMQ_CONNECTION_MODE, value); }

+		}

+

+		/// <summary>

+		/// The mode by which an application connects to a queue manager,

+		/// specified as a string.

+		/// </summary>

+		[UriAttribute("wmq.ConnectionMode")]

+		public ConnectionMode ConnectionMode

+		{

+			get { return XMSConvert.ToConnectionMode(this.XMSConnectionMode); }

+			set { this.XMSConnectionMode = XMSConvert.ToXMSConnectionMode(value); }

+		}

+

+		/// <summary>

+		/// This property specifies the client reconnect options for new

+		/// connections created by this factory.

+		/// </summary>

+		[UriAttribute("wmq.ClientReconnectOptions")]

+		public string ClientReconnectOptions

+		{

+			get { return this.xmsConnectionFactory.GetStringProperty(XMSC.WMQ_CLIENT_RECONNECT_OPTIONS); }

+			set { this.xmsConnectionFactory.SetStringProperty(XMSC.WMQ_CLIENT_RECONNECT_OPTIONS, value); }

+		}

+

+		/// <summary>

+		/// This property specifies the duration of time, in seconds, that a

+		/// client connection attempts to reconnect.

+		/// </summary>

+		[UriAttribute("wmq.ClientReconnectTimeout")]

+		public string ClientReconnectTimeout

+		{

+			get { return this.xmsConnectionFactory.GetStringProperty(XMSC.WMQ_CLIENT_RECONNECT_TIMEOUT); }

+			set { this.xmsConnectionFactory.SetStringProperty(XMSC.WMQ_CLIENT_RECONNECT_TIMEOUT, value); }

+		}

+

+		/// <summary>

+		/// This property specifies the hosts to which the client attempts to

+		/// reconnect to after its connection are broken.

+		/// </summary>

+		[UriAttribute("wmq.ConnectionNameList")]

+		public string ConnectionNameList

+		{

+			get { return this.xmsConnectionFactory.GetStringProperty(XMSC.WMQ_CONNECTION_NAME_LIST); }

+			set { this.xmsConnectionFactory.SetStringProperty(XMSC.WMQ_CONNECTION_NAME_LIST, value); }

+		}

+

+		/// <summary>

+		/// Whether calls to certain methods fail if the queue manager to which

+		/// the application is connected is in a quiescing state.

+		/// </summary>

+		[UriAttribute("wmq.XMSFailIfQuiesce")]

+		public Int32 XMSFailIfQuiesce

+		{

+			get { return this.xmsConnectionFactory.GetIntProperty(XMSC.WMQ_FAIL_IF_QUIESCE); }

+			set { this.xmsConnectionFactory.SetIntProperty(XMSC.WMQ_FAIL_IF_QUIESCE, value); }

+		}

+

+		/// <summary>

+		/// Whether calls to certain methods fail if the queue manager to which

+		/// the application is connected is in a quiescing state.

+		/// </summary>

+		[UriAttribute("wmq.FailIfQuiesce")]

+		public bool FailIfQuiesce

+		{

+			get { return XMSConvert.ToFailIfQuiesce(this.XMSFailIfQuiesce); }

+			set { this.XMSFailIfQuiesce = XMSConvert.ToXMSFailIfQuiesce(value); }

+		}

+

+		/// <summary>

+		/// The type of broker used by the application for a connection or for

+		/// the destination.

+		/// </summary>

+		[UriAttribute("wmq.XMSBrokerVersion")]

+		public Int32 XMSBrokerVersion

+		{

+			get { return this.xmsConnectionFactory.GetIntProperty(XMSC.WMQ_BROKER_VERSION); }

+			set { this.xmsConnectionFactory.SetIntProperty(XMSC.WMQ_BROKER_VERSION, value); }

+		}

+

+		/// <summary>

+		/// The type of broker used by the application for a connection or for

+		/// the destination.

+		/// </summary>

+		[UriAttribute("wmq.BrokerVersion")]

+		public BrokerVersion BrokerVersion

+		{

+			get { return XMSConvert.ToBrokerVersion(this.XMSBrokerVersion); }

+			set { this.XMSBrokerVersion = XMSConvert.ToXMSBrokerVersion(value); }

+		}

+

+		/// <summary>

+		/// The name of the queue manager to which a broker is connected.

+		/// </summary>

+		[UriAttribute("wmq.BrokerQueueManagerName")]

+		public string BrokerQueueManagerName

+		{

+			get { return this.xmsConnectionFactory.GetStringProperty(XMSC.WMQ_BROKER_QMGR); }

+			set { this.xmsConnectionFactory.SetStringProperty(XMSC.WMQ_BROKER_QMGR, value); }

+		}

+

+		/// <summary>

+		/// The name of the control queue used by a broker.

+		/// </summary>

+		[UriAttribute("wmq.BrokerControlQueueName")]

+		public string BrokerControlQueueName

+		{

+			get { return this.xmsConnectionFactory.GetStringProperty(XMSC.WMQ_BROKER_CONTROLQ); }

+			set { this.xmsConnectionFactory.SetStringProperty(XMSC.WMQ_BROKER_CONTROLQ, value); }

+		}

+

+		/// <summary>

+		/// The name of the queue monitored by a broker where applications send

+		/// messages that they publish.

+		/// </summary>

+		[UriAttribute("wmq.BrokerPublishQueueName")]

+		public string BrokerPublishQueueName

+		{

+			get { return this.xmsConnectionFactory.GetStringProperty(XMSC.WMQ_BROKER_PUBQ); }

+			set { this.xmsConnectionFactory.SetStringProperty(XMSC.WMQ_BROKER_PUBQ, value); }

+		}

+

+		/// <summary>

+		/// The name of the subscriber queue for a nondurable message consumer.

+		/// </summary>

+		[UriAttribute("wmq.BrokerSubscriberQueueName")]

+		public string BrokerSubscriberQueueName

+		{

+			get { return this.xmsConnectionFactory.GetStringProperty(XMSC.WMQ_BROKER_SUBQ); }

+			set { this.xmsConnectionFactory.SetStringProperty(XMSC.WMQ_BROKER_SUBQ, value); }

+		}

+

+		/// <summary>

+		/// Determines whether message selection is done by the XMS client or

+		/// by the broker.

+		/// </summary>

+		[UriAttribute("wmq.XMSMessageSelection")]

+		public Int32 XMSMessageSelection

+		{

+			get { return this.xmsConnectionFactory.GetIntProperty(XMSC.WMQ_MESSAGE_SELECTION); }

+			set { this.xmsConnectionFactory.SetIntProperty(XMSC.WMQ_MESSAGE_SELECTION, value); }

+		}

+

+		/// <summary>

+		/// Determines whether message selection is done by the XMS client or

+		/// by the broker.

+		/// </summary>

+		[UriAttribute("wmq.MessageSelection")]

+		public MessageSelection MessageSelection

+		{

+			get { return XMSConvert.ToMessageSelection(this.XMSMessageSelection); }

+			set { this.XMSMessageSelection = XMSConvert.ToXMSMessageSelection(value); }

+		}

+

+		/// <summary>

+		/// The maximum number of messages to be retrieved from a queue in one

+		/// batch when using asynchronous message delivery.

+		/// </summary>

+		[UriAttribute("wmq.MessageBatchSize")]

+		public Int32 MessageBatchSize

+		{

+			get { return this.xmsConnectionFactory.GetIntProperty(XMSC.WMQ_MSG_BATCH_SIZE); }

+			set { this.xmsConnectionFactory.SetIntProperty(XMSC.WMQ_MSG_BATCH_SIZE, value); }

+		}

+

+		/// <summary>

+		/// If each message listener within a session has no suitable message

+		/// on its queue, this value is the maximum interval, in milliseconds,

+		/// that elapses before each message listener tries again to get a

+		/// message from its queue.

+		/// </summary>

+		[UriAttribute("wmq.PollingInterval")]

+		public Int32 PollingInterval

+		{

+			get { return this.xmsConnectionFactory.GetIntProperty(XMSC.WMQ_POLLING_INTERVAL); }

+			set { this.xmsConnectionFactory.SetIntProperty(XMSC.WMQ_POLLING_INTERVAL, value); }

+		}

+

+		/// <summary>

+		/// The number of messages published by a publisher before the XMS

+		/// client requests an acknowledgement from the broker.

+		/// </summary>

+		[UriAttribute("wmq.PublishAcknowledgementInterval")]

+		public Int32 PublishAcknowledgementInterval

+		{

+			get { return this.xmsConnectionFactory.GetIntProperty(XMSC.WMQ_PUB_ACK_INTERVAL); }

+			set { this.xmsConnectionFactory.SetIntProperty(XMSC.WMQ_PUB_ACK_INTERVAL, value); }

+		}

+

+		/// <summary>

+		/// This property determines whether message producers are allowed to

+		/// use asynchronous puts to send messages to this destination.

+		/// </summary>

+		[UriAttribute("wmq.XMSAsynchronousPutsAllowed")]

+		public Int32 XMSAsynchronousPutsAllowed

+		{

+			get { return this.xmsConnectionFactory.GetIntProperty(XMSC.WMQ_PUT_ASYNC_ALLOWED); }

+			set { this.xmsConnectionFactory.SetIntProperty(XMSC.WMQ_PUT_ASYNC_ALLOWED, value); }

+		}

+

+		/// <summary>

+		/// This property determines whether message producers are allowed to

+		/// use asynchronous puts to send messages to this destination.

+		/// </summary>

+		[UriAttribute("wmq.AsynchronousPutsAllowed")]

+		public AsynchronousPutsAllowed AsynchronousPutsAllowed

+		{

+			get { return XMSConvert.ToAsynchronousPutsAllowed(this.XMSAsynchronousPutsAllowed); }

+			set { this.XMSAsynchronousPutsAllowed = XMSConvert.ToXMSAsynchronousPutsAllowed(value); }

+		}

+

+		/// <summary>

+		/// The identifier (CCSID) of the coded character set, or code page,

+		/// in which fields of character data defined in the Message Queue

+		/// Interface (MQI) are exchanged between the XMS client and the

+		/// WebSphere MQ client.

+		/// </summary>

+		[UriAttribute("wmq.QueueManagerCCSID")]

+		public string QueueManagerCCSID

+		{

+			get { return this.xmsConnectionFactory.GetStringProperty(XMSC.WMQ_QMGR_CCSID); }

+			set { this.xmsConnectionFactory.SetStringProperty(XMSC.WMQ_QMGR_CCSID, value); }

+		}

+

+		/// <summary>

+		/// Identifies a channel receive exit to be run.

+		/// </summary>

+		[UriAttribute("wmq.ReceiveExit")]

+		public string ReceiveExit

+		{

+			get { return this.xmsConnectionFactory.GetStringProperty(XMSC.WMQ_RECEIVE_EXIT); }

+			set { this.xmsConnectionFactory.SetStringProperty(XMSC.WMQ_RECEIVE_EXIT, value); }

+		}

+

+		/// <summary>

+		/// The user data that is passed to a channel receive exit when it

+		/// is called.

+		/// </summary>

+		[UriAttribute("wmq.ReceiveExitInit")]

+		public string ReceiveExitInit

+		{

+			get { return this.xmsConnectionFactory.GetStringProperty(XMSC.WMQ_RECEIVE_EXIT_INIT); }

+			set { this.xmsConnectionFactory.SetStringProperty(XMSC.WMQ_RECEIVE_EXIT_INIT, value); }

+		}

+

+		/// <summary>

+		/// Identifies a channel security exit.

+		/// </summary>

+		[UriAttribute("wmq.SecurityExit")]

+		public string SecurityExit

+		{

+			get { return this.xmsConnectionFactory.GetStringProperty(XMSC.WMQ_SECURITY_EXIT); }

+			set { this.xmsConnectionFactory.SetStringProperty(XMSC.WMQ_SECURITY_EXIT, value); }

+		}

+

+		/// <summary>

+		/// The user data that is passed to a channel security exit when it

+		/// is called.

+		/// </summary>

+		[UriAttribute("wmq.SecurityExitInit")]

+		public string SecurityExitInit

+		{

+			get { return this.xmsConnectionFactory.GetStringProperty(XMSC.WMQ_SECURITY_EXIT_INIT); }

+			set { this.xmsConnectionFactory.SetStringProperty(XMSC.WMQ_SECURITY_EXIT_INIT, value); }

+		}

+

+		/// <summary>

+		/// Identifies a channel send exit.

+		/// </summary>

+		[UriAttribute("wmq.SendExit")]

+		public string SendExit

+		{

+			get { return this.xmsConnectionFactory.GetStringProperty(XMSC.WMQ_SEND_EXIT); }

+			set { this.xmsConnectionFactory.SetStringProperty(XMSC.WMQ_SEND_EXIT, value); }

+		}

+

+		/// <summary>

+		/// The user data that is passed to channel send exits when they

+		/// are called.

+		/// </summary>

+		[UriAttribute("wmq.SendExitInit")]

+		public string SendExitInit

+		{

+			get { return this.xmsConnectionFactory.GetStringProperty(XMSC.WMQ_SEND_EXIT_INIT); }

+			set { this.xmsConnectionFactory.SetStringProperty(XMSC.WMQ_SEND_EXIT_INIT, value); }

+		}

+

+		/// <summary>

+		/// The number of send calls to allow between checking for asynchronous

+		/// put errors, within a single non-transacted XMS session.

+		/// </summary>

+		[UriAttribute("wmq.SendCheckCount")]

+		public Int32 SendCheckCount

+		{

+			get { return this.xmsConnectionFactory.GetIntProperty(XMSC.WMQ_SEND_CHECK_COUNT); }

+			set { this.xmsConnectionFactory.SetIntProperty(XMSC.WMQ_SEND_CHECK_COUNT, value); }

+		}

+

+		/// <summary>

+		/// Whether a client connection can share its socket with other

+		/// top-level XMS connections from the same process to the same queue

+		/// manager, if the channel definitions match.

+		/// </summary>

+		[UriAttribute("wmq.XMSShareSocketAllowed")]

+		public Int32 XMSShareSocketAllowed

+		{

+			get { return this.xmsConnectionFactory.GetIntProperty(XMSC.WMQ_SHARE_CONV_ALLOWED); }

+			set { this.xmsConnectionFactory.SetIntProperty(XMSC.WMQ_SHARE_CONV_ALLOWED, value); }

+		}

+

+		/// <summary>

+		/// Whether a client connection can share its socket with other

+		/// top-level XMS connections from the same process to the same queue

+		/// manager, if the channel definitions match.

+		/// </summary>

+		[UriAttribute("wmq.ShareSocketAllowed")]

+		public bool ShareSocketAllowed

+		{

+			get { return XMSConvert.ToShareSocketAllowed(this.XMSShareSocketAllowed); }

+			set { this.XMSShareSocketAllowed = XMSConvert.ToXMSShareSocketAllowed(value); }

+		}

+

+		/// <summary>

+		/// The locations of the servers that hold the certificate revocation

+		/// lists (CRLs) to be used on an SSL connection to a queue manager.

+		/// </summary>

+		[UriAttribute("wmq.SSLCertificateStores")]

+		public string SSLCertificateStores

+		{

+			get { return this.xmsConnectionFactory.GetStringProperty(XMSC.WMQ_SSL_CERT_STORES); }

+			set { this.xmsConnectionFactory.SetStringProperty(XMSC.WMQ_SSL_CERT_STORES, value); }

+		}

+

+		/// <summary>

+		/// The name of the CipherSpec to be used on a secure connection to

+		/// a queue manager.

+		/// </summary>

+		[UriAttribute("wmq.SSLCipherSpec")]

+		public string SSLCipherSpec

+		{

+			get { return this.xmsConnectionFactory.GetStringProperty(XMSC.WMQ_SSL_CIPHER_SPEC); }

+			set { this.xmsConnectionFactory.SetStringProperty(XMSC.WMQ_SSL_CIPHER_SPEC, value); }

+		}

+

+		/// <summary>

+		/// The name of the CipherSuite to be used on an SSL or TLS connection

+		/// to a queue manager. The protocol used in negotiating the secure

+		/// connection depends on the specified CipherSuite.

+		/// </summary>

+		[UriAttribute("wmq.SSLCipherSuite")]

+		public string SSLCipherSuite

+		{

+			get { return this.xmsConnectionFactory.GetStringProperty(XMSC.WMQ_SSL_CIPHER_SUITE); }

+			set { this.xmsConnectionFactory.SetStringProperty(XMSC.WMQ_SSL_CIPHER_SUITE, value); }

+		}

+

+		/// <summary>

+		/// Configuration details for the cryptographic hardware connected

+		/// to the client system.

+		/// </summary>

+		[UriAttribute("wmq.SSLCryptoHardware")]

+		public string SSLCryptoHardware

+		{

+			get { return this.xmsConnectionFactory.GetStringProperty(XMSC.WMQ_SSL_CRYPTO_HW); }

+			set { this.xmsConnectionFactory.SetStringProperty(XMSC.WMQ_SSL_CRYPTO_HW, value); }

+		}

+

+		/// <summary>

+		/// The value of this property determines whether an application can

+		/// or cannot use non-FIPS compliant cipher suites. If this property

+		/// is set to true, only FIPS algorithms are used for the client-server

+		/// connection.

+		/// </summary>

+		[UriAttribute("wmq.SSLFipsRequired")]

+		public bool SSLFipsRequired

+		{

+			get { return this.xmsConnectionFactory.GetBooleanProperty(XMSC.WMQ_SSL_FIPS_REQUIRED); }

+			set { this.xmsConnectionFactory.SetBooleanProperty(XMSC.WMQ_SSL_FIPS_REQUIRED, value); }

+		}

+

+		/// <summary>

+		/// The location of the key database file in which keys and

+		/// certificates are stored.

+		/// </summary>

+		[UriAttribute("wmq.SSLKeyRepository")]

+		public string SSLKeyRepository

+		{

+			get { return this.xmsConnectionFactory.GetStringProperty(XMSC.WMQ_SSL_KEY_REPOSITORY); }

+			set { this.xmsConnectionFactory.SetStringProperty(XMSC.WMQ_SSL_KEY_REPOSITORY, value); }

+		}

+

+		/// <summary>

+		/// The KeyResetCount represents the total number of unencrypted bytes

+		/// sent and received within an SSL conversation before the secret key

+		/// is renegotiated.

+		/// </summary>

+		[UriAttribute("wmq.SSLKeyResetCount")]

+		public Int32 SSLKeyResetCount

+		{

+			get { return this.xmsConnectionFactory.GetIntProperty(XMSC.WMQ_SSL_KEY_RESETCOUNT); }

+			set { this.xmsConnectionFactory.SetIntProperty(XMSC.WMQ_SSL_KEY_RESETCOUNT, value); }

+		}

+

+		/// <summary>

+		/// The peer name to be used on an SSL connection to a queue manager.

+		/// </summary>

+		[UriAttribute("wmq.SSLPeerName")]

+		public string SSLPeerName

+		{

+			get { return this.xmsConnectionFactory.GetStringProperty(XMSC.WMQ_SSL_PEER_NAME); }

+			set { this.xmsConnectionFactory.SetStringProperty(XMSC.WMQ_SSL_PEER_NAME, value); }

+		}

+

+		/// <summary>

+		/// Whether all messages must be retrieved from queues within sync point control.

+		/// </summary>

+		[UriAttribute("wmq.SyncpointAllGets")]

+		public bool SyncpointAllGets

+		{

+			get { return this.xmsConnectionFactory.GetBooleanProperty(XMSC.WMQ_SYNCPOINT_ALL_GETS); }

+			set { this.xmsConnectionFactory.SetBooleanProperty(XMSC.WMQ_SYNCPOINT_ALL_GETS, value); }

+		}

+

+		/// <summary>

+		/// Whether messages sent to the destination contain an MQRFH2 header.

+		/// </summary>

+		[UriAttribute("wmq.XMSTargetClient")]

+		public Int32 XMSTargetClient

+		{

+			get { return this.xmsConnectionFactory.GetIntProperty(XMSC.WMQ_TARGET_CLIENT); }

+			set { this.xmsConnectionFactory.SetIntProperty(XMSC.WMQ_TARGET_CLIENT, value); }

+		}

+

+		/// <summary>

+		/// Whether messages sent to the destination contain an <c>MQRFH2</c>

+		/// header.

+		/// </summary>

+		[UriAttribute("wmq.TargetClient")]

+		public TargetClient TargetClient

+		{

+			get { return XMSConvert.ToTargetClient(this.XMSTargetClient); }

+			set { this.XMSTargetClient = XMSConvert.ToXMSTargetClient(value); }

+		}

+

+		/// <summary>

+		/// The prefix used to form the name of the WebSphere MQ dynamic queue

+		/// that is created when the application creates an XMS temporary queue.

+		/// </summary>

+		[UriAttribute("wmq.TemporaryQueuePrefix")]

+		public string WMQTemporaryQueuePrefix

+		{

+			get { return this.xmsConnectionFactory.GetStringProperty(XMSC.WMQ_TEMP_Q_PREFIX); }

+			set { this.xmsConnectionFactory.SetStringProperty(XMSC.WMQ_TEMP_Q_PREFIX, value); }

+		}

+

+		/// <summary>

+		/// When creating temporary topics, XMS generates a topic string of

+		/// the form "TEMP/TEMPTOPICPREFIX/unique_id", or if this property

+		/// contains the default value, then this string, "TEMP/unique_id", is

+		/// generated. Specifying a non-empty value allows specific model

+		/// queues to be defined for creating the managed queues for subscribers

+		/// to temporary topics created under this connection.

+		/// </summary>

+		[UriAttribute("wmq.TemporaryTopicPrefix")]

+		public string WMQTemporaryTopicPrefix

+		{

+			get { return this.xmsConnectionFactory.GetStringProperty(XMSC.WMQ_TEMP_TOPIC_PREFIX); }

+			set { this.xmsConnectionFactory.SetStringProperty(XMSC.WMQ_TEMP_TOPIC_PREFIX, value); }

+		}

+

+		/// <summary>

+		/// The name of the WebSphere MQ model queue from which a dynamic

+		/// queue is created when the application creates an XMS temporary

+		/// queue.

+		/// </summary>

+		[UriAttribute("wmq.TemporaryModel")]

+		public string WMQTemporaryModel

+		{

+			get { return this.xmsConnectionFactory.GetStringProperty(XMSC.WMQ_TEMP_TOPIC_PREFIX); }

+			set { this.xmsConnectionFactory.SetStringProperty(XMSC.WMQ_TEMP_TOPIC_PREFIX, value); }

+		}

+

+		#endregion

+

+		#region WPM-specific properties

+

+		/// <summary>

+		/// For a connection to a service integration bus, this property

+		/// specifies the local network interface to be used, or the local

+		/// port or range of local ports to be used, or both.

+		/// </summary>

+		[UriAttribute("wpm.LocalAddress")]

+		public string WPMLocalAddress

+		{

+			get { return this.xmsConnectionFactory.GetStringProperty(XMSC.WPM_LOCAL_ADDRESS); }

+			set { this.xmsConnectionFactory.SetStringProperty(XMSC.WPM_LOCAL_ADDRESS, value); }

+		}

+

+		/// <summary>

+		/// The name of the service integration bus that the application

+		/// connects to.

+		/// </summary>

+		[UriAttribute("wpm.BusName")]

+		public string BusName

+		{

+			get { return this.xmsConnectionFactory.GetStringProperty(XMSC.WPM_BUS_NAME); }

+			set { this.xmsConnectionFactory.SetStringProperty(XMSC.WPM_BUS_NAME, value); }

+		}

+

+		/// <summary>

+		/// The connection proximity setting for the connection.

+		/// </summary>

+		[UriAttribute("wpm.XMSConnectionProximity")]

+		public Int32 XMSConnectionProximity

+		{

+			get { return this.xmsConnectionFactory.GetIntProperty(XMSC.WPM_CONNECTION_PROXIMITY); }

+			set { this.xmsConnectionFactory.SetIntProperty(XMSC.WPM_CONNECTION_PROXIMITY, value); }

+		}

+

+		/// <summary>

+		/// The connection proximity setting for the connection.

+		/// </summary>

+		[UriAttribute("wpm.ConnectionProximity")]

+		public ConnectionProximity ConnectionProximity

+		{

+			get { return XMSConvert.ToConnectionProximity(this.XMSConnectionProximity); }

+			set { this.XMSConnectionProximity = XMSConvert.ToXMSConnectionProximity(value); }

+		}

+

+		/// <summary>

+		/// The name of the messaging engine where all durable subscriptions

+		/// for a connection or a destination are managed.

+		/// </summary>

+		[UriAttribute("wpm.DurableSubscriptionHome")]

+		public string DurableSubscriptionHome

+		{

+			get { return this.xmsConnectionFactory.GetStringProperty(XMSC.WPM_DUR_SUB_HOME); }

+			set { this.xmsConnectionFactory.SetStringProperty(XMSC.WPM_DUR_SUB_HOME, value); }

+		}

+

+		/// <summary>

+		/// The reliability level of nonpersistent messages that are sent

+		/// using the connection.

+		/// </summary>

+		[UriAttribute("wpm.XMSNonPersistentMap")]

+		public Int32 XMSNonPersistentMap

+		{

+			get { return this.xmsConnectionFactory.GetIntProperty(XMSC.WPM_NON_PERSISTENT_MAP); }

+			set { this.xmsConnectionFactory.SetIntProperty(XMSC.WPM_NON_PERSISTENT_MAP, value); }

+		}

+

+		/// <summary>

+		/// The reliability level of nonpersistent messages that are sent

+		/// using the connection.

+		/// </summary>

+		[UriAttribute("wpm.NonPersistentMap")]

+		public Mapping NonPersistentMap

+		{

+			get { return XMSConvert.ToMapping(this.XMSNonPersistentMap); }

+			set { this.XMSNonPersistentMap = XMSConvert.ToXMSMapping(value); }

+		}

+

+		/// <summary>

+		/// The reliability level of persistent messages that are sent

+		/// using the connection.

+		/// </summary>

+		[UriAttribute("wpm.XMSPersistentMap")]

+		public Int32 XMSPersistentMap

+		{

+			get { return this.xmsConnectionFactory.GetIntProperty(XMSC.WPM_PERSISTENT_MAP); }

+			set { this.xmsConnectionFactory.SetIntProperty(XMSC.WPM_PERSISTENT_MAP, value); }

+		}

+

+		/// <summary>

+		/// The reliability level of persistent messages that are sent

+		/// using the connection.

+		/// </summary>

+		[UriAttribute("wpm.PersistentMap")]

+		public Mapping PersistentMap

+		{

+			get { return XMSConvert.ToMapping(this.XMSPersistentMap); }

+			set { this.XMSPersistentMap = XMSConvert.ToXMSMapping(value); }

+		}

+

+		/// <summary>

+		/// A sequence of one or more endpoint addresses of bootstrap servers.

+		/// </summary>

+		[UriAttribute("wpm.ProviderEndpoints")]

+		public string ProviderEndpoints

+		{

+			get { return this.xmsConnectionFactory.GetStringProperty(XMSC.WPM_PROVIDER_ENDPOINTS); }

+			set { this.xmsConnectionFactory.SetStringProperty(XMSC.WPM_PROVIDER_ENDPOINTS, value); }

+		}

+

+		/// <summary>

+		/// The name of a target group of messaging engines.

+		/// </summary>

+		[UriAttribute("wpm.TargetGroup")]

+		public string TargetGroup

+		{

+			get { return this.xmsConnectionFactory.GetStringProperty(XMSC.WPM_TARGET_GROUP); }

+			set { this.xmsConnectionFactory.SetStringProperty(XMSC.WPM_TARGET_GROUP, value); }

+		}

+

+		/// <summary>

+		/// The significance of the target group of messaging engines.

+		/// </summary>

+		[UriAttribute("wpm.XMSTargetSignificance")]

+		public Int32 XMSTargetSignificance

+		{

+			get { return this.xmsConnectionFactory.GetIntProperty(XMSC.WPM_TARGET_SIGNIFICANCE); }

+			set { this.xmsConnectionFactory.SetIntProperty(XMSC.WPM_TARGET_SIGNIFICANCE, value); }

+		}

+

+		/// <summary>

+		/// The significance of the target group of messaging engines.

+		/// </summary>

+		[UriAttribute("wpm.TargetSignificance")]

+		public TargetSignificance TargetSignificance

+		{

+			get { return XMSConvert.ToTargetSignificance(this.XMSTargetSignificance); }

+			set { this.XMSTargetSignificance = XMSConvert.ToXMSTargetSignificance(value); }

+		}

+

+		/// <summary>

+		/// The name of the inbound transport chain that the application must

+		/// use to connect to a messaging engine.

+		/// </summary>

+		[UriAttribute("wpm.TargetTransportChain")]

+		public string TargetTransportChain

+		{

+			get { return this.xmsConnectionFactory.GetStringProperty(XMSC.WPM_TARGET_TRANSPORT_CHAIN); }

+			set { this.xmsConnectionFactory.SetStringProperty(XMSC.WPM_TARGET_TRANSPORT_CHAIN, value); }

+		}

+

+		/// <summary>

+		/// The type of the target group of messaging engines.

+		/// </summary>

+		[UriAttribute("wpm.XMSTargetType")]

+		public Int32 XMSTargetType

+		{

+			get { return this.xmsConnectionFactory.GetIntProperty(XMSC.WPM_TARGET_TYPE); }

+			set { this.xmsConnectionFactory.SetIntProperty(XMSC.WPM_TARGET_TYPE, value); }

+		}

+

+		/// <summary>

+		/// The type of the target group of messaging engines.

+		/// </summary>

+		[UriAttribute("wpm.TargetType")]

+		public TargetType TargetType

+		{

+			get { return XMSConvert.ToTargetType(this.XMSTargetType); }

+			set { this.XMSTargetType = XMSConvert.ToXMSTargetType(value); }

+		}

+

+		/// <summary>

+		/// The prefix used to form the name of the temporary queue that is

+		/// created in the service integration bus when the application creates

+		/// an XMS temporary queue.

+		/// </summary>

+		[UriAttribute("wpm.TemporaryQueuePrefix")]

+		public string WPMTemporaryQueuePrefix

+		{

+			get { return this.xmsConnectionFactory.GetStringProperty(XMSC.WMQ_TEMP_Q_PREFIX); }

+			set { this.xmsConnectionFactory.SetStringProperty(XMSC.WMQ_TEMP_Q_PREFIX, value); }

+		}

+

+		/// <summary>

+		/// The prefix used to form the name of a temporary topic that is

+		/// created by the application.

+		/// </summary>

+		[UriAttribute("wpm.TemporaryTopicPrefix")]

+		public string WPMTemporaryTopicPrefix

+		{

+			get { return this.xmsConnectionFactory.GetStringProperty(XMSC.WMQ_TEMP_TOPIC_PREFIX); }

+			set { this.xmsConnectionFactory.SetStringProperty(XMSC.WMQ_TEMP_TOPIC_PREFIX, value); }

+		}

+

+		#endregion

+

+		#region Common properties having protocol-specific keys

+

+		/// <summary>

+		/// The host name or IP address of the system on which a broker (RTT)

+		/// or queue manager (WMQ) runs.

+		/// </summary>

+		public string HostName

+		{

+			get

+			{

+				switch(this.XMSConnectionType)

+				{

+					case XMSC.CT_RTT: return this.RTTHostName;

+					case XMSC.CT_WMQ: return this.WMQHostName;

+					case XMSC.CT_WPM: return null;

+					default         : return null;

+				}

+			}

+			set

+			{

+				switch(this.XMSConnectionType)

+				{

+					case XMSC.CT_RTT: this.RTTHostName = value; break;

+					case XMSC.CT_WMQ: this.WMQHostName = value; break;

+					case XMSC.CT_WPM: break;

+					default         : break;

+				}

+			}

+		}

+

+		/// <summary>

+		/// The number of the port on which a broker (RTT) or queue manager

+		/// (WMQ) listens for incoming requests.

+		/// </summary>

+		public Int32 Port

+		{

+			get

+			{

+				switch(this.XMSConnectionType)

+				{

+					case IBM.XMS.XMSC.CT_RTT: return this.RTTPort;

+					case IBM.XMS.XMSC.CT_WMQ: return this.WMQPort;

+					case IBM.XMS.XMSC.CT_WPM: return 0;

+					default         : return 0;

+				}

+			}

+			set

+			{

+				switch(this.XMSConnectionType)

+				{

+					case IBM.XMS.XMSC.CT_RTT: this.RTTPort = value; break;

+					case IBM.XMS.XMSC.CT_WMQ: this.WMQPort = value; break;

+					case IBM.XMS.XMSC.CT_WPM: break;

+					default         : break;

+				}

+			}

+		}

+

+		/// <summary>

+		/// The host name or IP address of the local network interface to be

+		/// used for a RTT real-time connection to a broker.

+		/// For a WMQ connection to a queue manager, this property specifies

+		/// the local network interface to be used, or the local port or range

+		/// of local ports to be used, or both.

+		/// For a WPM connection to a service integration bus, this property

+		/// specifies the local network interface to be used, or the local

+		/// port or range of local ports to be used, or both.

+		/// </summary>

+		public string LocalAddress

+		{

+			get

+			{

+				switch(this.XMSConnectionType)

+				{

+					case IBM.XMS.XMSC.CT_RTT: return this.RTTLocalAddress;

+					case IBM.XMS.XMSC.CT_WMQ: return this.WMQLocalAddress;

+					case IBM.XMS.XMSC.CT_WPM: return this.WPMLocalAddress;

+					default         : return null;

+				}

+			}

+			set

+			{

+				switch(this.XMSConnectionType)

+				{

+					case IBM.XMS.XMSC.CT_RTT: this.RTTLocalAddress = value; break;

+					case IBM.XMS.XMSC.CT_WMQ: this.WMQLocalAddress = value; break;

+					case IBM.XMS.XMSC.CT_WPM: this.WPMLocalAddress = value; break;

+					default         : break;

+				}

+			}

+		}

+

+		/// <summary>

+		/// The prefix used to form the name of the WebSphere MQ dynamic queue

+		/// that is created (WMQ), or the name of the temporary queue that is

+		/// created in the service integration bus (WPM) when the application

+		/// creates an XMS temporary queue.

+		/// </summary>

+		public string TemporaryQueuePrefix

+		{

+			get

+			{

+				switch(this.XMSConnectionType)

+				{

+					case IBM.XMS.XMSC.CT_RTT: return null;

+					case IBM.XMS.XMSC.CT_WMQ: return this.WMQTemporaryQueuePrefix;

+					case IBM.XMS.XMSC.CT_WPM: return this.WPMTemporaryQueuePrefix;

+					default         : return null;

+				}

+			}

+			set

+			{

+				switch(this.XMSConnectionType)

+				{

+					case IBM.XMS.XMSC.CT_RTT: break;

+					case IBM.XMS.XMSC.CT_WMQ: this.WMQTemporaryQueuePrefix = value; break;

+					case IBM.XMS.XMSC.CT_WPM: this.WPMTemporaryQueuePrefix = value; break;

+					default         : break;

+				}

+			}

+		}

+

+		/// <summary>

+		/// The prefix used to form the name of a temporary topic that is

+		/// created by the application (WMQ and WPM).

+		/// </summary>

+		public string TemporaryTopicPrefix

+		{

+			get

+			{

+				switch(this.XMSConnectionType)

+				{

+					case IBM.XMS.XMSC.CT_RTT: return null;

+					case IBM.XMS.XMSC.CT_WMQ: return this.WMQTemporaryTopicPrefix;

+					case IBM.XMS.XMSC.CT_WPM: return this.WPMTemporaryTopicPrefix;

+					default         : return null;

+				}

+			}

+			set

+			{

+				switch(this.XMSConnectionType)

+				{

+					case IBM.XMS.XMSC.CT_RTT: break;

+					case IBM.XMS.XMSC.CT_WMQ: this.WMQTemporaryTopicPrefix = value; break;

+					case IBM.XMS.XMSC.CT_WPM: this.WPMTemporaryTopicPrefix = value; break;

+					default         : break;

+				}

+			}

+		}

+

+		#endregion

+

+		#endregion

+

+		#region IConnectionFactory Members

+

+		/// <summary>

+		/// Creates a new connection to IBM MQ with the default properties.

+		/// </summary>

+		public Apache.NMS.IConnection CreateConnection()

+		{

+			Apache.NMS.IConnection connection = null;

+			try

+			{

+				connection = new Apache.NMS.XMS.Connection(

+					this.xmsConnectionFactory.CreateConnection());

+				ConfigureConnection(connection);

+			}

+			catch(Exception ex)

+			{

+				ExceptionUtil.WrapAndThrowNMSException(ex);

+			}

+			return connection;

+		}

+

+		/// <summary>

+		/// Creates a new connection to IBM MQ using a specified user identity.

+		/// </summary>

+		/// <param name="userName">User name.</param>

+		/// <param name="password">Password.</param>

+		public Apache.NMS.IConnection CreateConnection(

+					string userName, string password)

+		{

+			Apache.NMS.IConnection connection = null;

+			try

+			{

+				connection = new Apache.NMS.XMS.Connection(

+					this.xmsConnectionFactory.CreateConnection(

+						userName, password));

+				ConfigureConnection(connection);

+			}

+			catch(Exception ex)

+			{

+				ExceptionUtil.WrapAndThrowNMSException(ex);

+			}

+			return connection;

+		}

+

+		/// <summary>

+		/// Configure the newly created connection.

+		/// </summary>

+		/// <param name="connection">Connection.</param>

+		private void ConfigureConnection(IConnection connection)

+		{

+			connection.RedeliveryPolicy = this.redeliveryPolicy.Clone() as IRedeliveryPolicy;

+			connection.ConsumerTransformer = this.consumerTransformer;

+			connection.ProducerTransformer = this.producerTransformer;

+		}

+

+		/// <summary>

+		/// Get or set the broker URI.

+		/// </summary>

+		public Uri BrokerUri

+		{

+			get { return this.brokerUri; }

+			set { this.brokerUri = CreateConnectionFactoryFromURI(value); }

+		}

+

+		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

+		/// ConnectionFactory sets the provided delegate instance on each Connection instance that

+		/// is created from this factory, each connection in turn passes the delegate along to each

+		/// Session it creates which then passes that along to the Consumers 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 ConnectionFactory sets the provided delegate instance on each Connection instance that

+		/// is created from this factory, each connection in turn passes the delegate along to each

+		/// Session it creates which then passes that along to the Producers it creates.

+		/// </summary>

+		public ProducerTransformerDelegate ProducerTransformer

+		{

+			get { return this.producerTransformer; }

+			set { this.producerTransformer = value; }

+		}

+

+		#endregion

+	}

+}

diff --git a/src/main/csharp/ConnectionMetaData.cs b/src/main/csharp/ConnectionMetaData.cs
new file mode 100644
index 0000000..27ffce3
--- /dev/null
+++ b/src/main/csharp/ConnectionMetaData.cs
@@ -0,0 +1,106 @@
+/*

+ * 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.Reflection;

+

+namespace Apache.NMS.XMS

+{

+	/// <summary>

+	/// Implements the Connection Meta-Data feature for Apache.NMS.EMS

+	/// </summary>

+	public class ConnectionMetaData : IConnectionMetaData

+	{

+		private int nmsMajorVersion;

+		private int nmsMinorVersion;

+

+		private string nmsProviderName;

+		private string nmsVersion;

+

+		private int providerMajorVersion;

+		private int providerMinorVersion;

+		private string providerVersion;

+

+		private string[] nmsxProperties;

+

+		public ConnectionMetaData()

+		{

+			Assembly self = Assembly.GetExecutingAssembly();

+			AssemblyName asmName = self.GetName();

+

+			this.nmsProviderName = asmName.Name;

+			this.providerMajorVersion = asmName.Version.Major;

+			this.providerMinorVersion = asmName.Version.Minor;

+			this.providerVersion = asmName.Version.ToString();

+

+			this.nmsxProperties = new String[] { };

+

+			foreach(AssemblyName name in self.GetReferencedAssemblies())

+			{

+				if(0 == string.Compare(name.Name, "Apache.NMS", true))

+				{

+					this.nmsMajorVersion = name.Version.Major;

+					this.nmsMinorVersion = name.Version.Minor;

+					this.nmsVersion = name.Version.ToString();

+

+					return;

+				}

+			}

+

+			throw new NMSException("Could not find a reference to the Apache.NMS Assembly.");

+		}

+

+		public int NMSMajorVersion

+		{

+			get { return this.nmsMajorVersion; }

+		}

+

+		public int NMSMinorVersion

+		{

+			get { return this.nmsMinorVersion; }

+		}

+

+		public string NMSProviderName

+		{

+			get { return this.nmsProviderName; }

+		}

+

+		public string NMSVersion

+		{

+			get { return this.nmsVersion; }

+		}

+

+		public string[] NMSXPropertyNames

+		{

+			get { return this.nmsxProperties; }

+		}

+

+		public int ProviderMajorVersion

+		{

+			get { return this.providerMajorVersion; }

+		}

+

+		public int ProviderMinorVersion

+		{

+			get { return this.providerMinorVersion; }

+		}

+

+		public string ProviderVersion

+		{

+			get { return this.providerVersion; }

+		}

+	}

+}

diff --git a/src/main/csharp/Destination.cs b/src/main/csharp/Destination.cs
new file mode 100644
index 0000000..d3848b2
--- /dev/null
+++ b/src/main/csharp/Destination.cs
@@ -0,0 +1,524 @@
+/*

+ * 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 Destination : IDestination

+	{

+		public IBM.XMS.IDestination xmsDestination;

+

+		#region Constructors

+

+		/// <summary>

+		/// Constructs a destination object.

+		/// </summary>

+		/// <param name="destination">IBM XMS destination.</param>

+		public Destination(IBM.XMS.IDestination destination)

+		{

+			this.xmsDestination = destination;

+		}

+

+		/// <summary>

+		/// Constructs a destination object specifying if the destination is

+		/// temporary.

+		/// </summary>

+		/// <param name="destination">IBM XMS destination.</param>

+		/// <param name="isTemporary">Whether the destination is temporary.

+		/// </param>

+		public Destination(IBM.XMS.IDestination destination, bool isTemporary)

+		{

+			this.xmsDestination = destination;

+			this.isTemporary = isTemporary;

+		}

+

+		#endregion

+

+		#region IDestination implementation

+

+		/// <summary>

+		/// Destination type.

+		/// </summary>

+		public DestinationType DestinationType

+		{

+			get

+			{

+				return XMSConvert.ToDestinationType(

+					this.xmsDestination.TypeId,

+					this.isTemporary);

+			}

+		}

+

+		/// <summary>

+		/// Checks if destination is a topic.

+		/// </summary>

+		public bool IsTopic

+		{

+			get

+			{

+				return (this.xmsDestination.TypeId

+					== IBM.XMS.DestinationType.Topic);

+			}

+		}

+

+		/// <summary>

+		/// Checks if destination is a queue.

+		/// </summary>

+		public bool IsQueue

+		{

+			get

+			{

+				return (this.xmsDestination.TypeId

+					== IBM.XMS.DestinationType.Queue);

+			}

+		}

+

+		private readonly bool isTemporary;

+		/// <summary>

+		/// Checks if destination is temporary.

+		/// </summary>

+		public bool IsTemporary

+		{

+			get { return this.isTemporary; }

+		}

+

+		#endregion

+

+		#region XMS IDestination properties

+

+		// http://www-01.ibm.com/support/knowledgecenter/SSFKSJ_8.0.0/com.ibm.mq.msc.doc/props_dest.htm?lang=en

+

+		#region Common properties

+

+		/// <summary>

+		/// Destination name.

+		/// </summary>

+		public string Name

+		{

+			get { return this.xmsDestination.Name; }

+		}

+

+		/// <summary>

+		/// The delivery mode of messages sent to the destination.

+		/// </summary>

+		public Int32 XMSDeliveryMode

+		{

+			get { return this.xmsDestination.GetIntProperty(XMSC.DELIVERY_MODE); }

+			set { this.xmsDestination.SetIntProperty(XMSC.DELIVERY_MODE, value); }

+		}

+

+		/// <summary>

+		/// The delivery mode of messages sent to the destination.

+		/// </summary>

+		public Apache.NMS.XMS.Util.DeliveryMode DeliveryMode

+		{

+			get { return XMSConvert.ToDeliveryMode(this.XMSDeliveryMode); }

+			set { this.XMSDeliveryMode = XMSConvert.ToXMSDeliveryMode(value); }

+		}

+

+		/// <summary>

+		/// The priority of messages sent to the destination.

+		/// </summary>

+		public Int32 Priority

+		{

+			get { return this.xmsDestination.GetIntProperty(XMSC.PRIORITY); }

+			set { this.xmsDestination.SetIntProperty(XMSC.PRIORITY, value); }

+		}

+

+		/// <summary>

+		/// The time to live in milliseconds for messages sent to the

+		/// destination.

+		/// </summary>

+		public Int32 TimeToLive

+		{

+			get { return this.xmsDestination.GetIntProperty(XMSC.TIME_TO_LIVE); }

+			set { this.xmsDestination.SetIntProperty(XMSC.TIME_TO_LIVE, value); }

+		}

+

+		#endregion

+

+		#region RTT-specific properties

+

+		/// <summary>

+		/// The multicast setting for the destination.

+		/// </summary>

+		[UriAttribute("rtt.XMSMulticast")]

+		public Int32 XMSMulticast

+		{

+			get { return this.xmsDestination.GetIntProperty(XMSC.RTT_MULTICAST); }

+			set { this.xmsDestination.SetIntProperty(XMSC.RTT_MULTICAST, value); }

+		}

+

+		/// <summary>

+		/// The multicast setting for the destination.

+		/// </summary>

+		[UriAttribute("rtt.Multicast")]

+		public Multicast Multicast

+		{

+			get { return XMSConvert.ToMulticast(this.XMSMulticast); }

+			set { this.XMSMulticast = XMSConvert.ToXMSMulticast(value); }

+		}

+

+		#endregion

+

+		#region WMQ-specific properties

+

+		/// <summary>

+		/// The type of broker used by the application for the destination.

+		/// </summary>

+		[UriAttribute("wmq.XMSBrokerVersion")]

+		public Int32 XMSBrokerVersion

+		{

+			get { return this.xmsDestination.GetIntProperty(XMSC.WMQ_BROKER_VERSION); }

+			set { this.xmsDestination.SetIntProperty(XMSC.WMQ_BROKER_VERSION, value); }

+		}

+

+		/// <summary>

+		/// The type of broker used by the application for the destination.

+		/// </summary>

+		[UriAttribute("wmq.BrokerVersion")]

+		public BrokerVersion BrokerVersion

+		{

+			get { return XMSConvert.ToBrokerVersion(this.XMSBrokerVersion); }

+			set { this.XMSBrokerVersion = XMSConvert.ToXMSBrokerVersion(value); }

+		}

+

+		/// <summary>

+		/// The identifier (CCSID) of the coded character set, or code page,

+		/// that the strings of character data in the body of a message are in

+		/// when the XMS client forwards the message to the destination.

+		/// </summary>

+		[UriAttribute("wmq.DestinationCCSID")]

+		public Int32 DestinationCCSID

+		{

+			get { return this.xmsDestination.GetIntProperty(XMSC.WMQ_CCSID); }

+			set { this.xmsDestination.SetIntProperty(XMSC.WMQ_CCSID, value); }

+		}

+

+		/// <summary>

+		/// The name of the subscriber queue for a durable subscriber that is

+		/// receiving messages from the destination.

+		/// </summary>

+		[UriAttribute("wmq.SubscriberQueueName")]

+		public string SubscriberQueueName

+		{

+			get { return this.xmsDestination.GetStringProperty(XMSC.WMQ_DUR_SUBQ); }

+			set { this.xmsDestination.SetStringProperty(XMSC.WMQ_DUR_SUBQ, value); }

+		}

+

+		/// <summary>

+		/// How numerical data in the body of a message is represented when

+		/// the XMS client forwards the message to the destination.

+		/// </summary>

+		[UriAttribute("wmq.XMSEncoding")]

+		public Int32 XMSEncoding

+		{

+			get { return this.xmsDestination.GetIntProperty(XMSC.WMQ_ENCODING); }

+			set { this.xmsDestination.SetIntProperty(XMSC.WMQ_ENCODING, value); }

+		}

+

+		/// <summary>

+		/// How numerical data in the body of a message is represented when

+		/// the XMS client forwards the message to the destination.

+		/// </summary>

+		[UriAttribute("wmq.Encoding")]

+		public Encoding Encoding

+		{

+			get { return XMSConvert.ToEncoding(this.XMSEncoding); }

+			set { this.XMSEncoding = XMSConvert.ToXMSEncoding(value); }

+		}

+

+		/// <summary>

+		/// Whether calls to certain methods fail if the queue manager to which

+		/// the application is connected is in a quiescing state.

+		/// </summary>

+		[UriAttribute("wmq.XMSFailIfQuiesce")]

+		public Int32 XMSFailIfQuiesce

+		{

+			get { return this.xmsDestination.GetIntProperty(XMSC.WMQ_FAIL_IF_QUIESCE); }

+			set { this.xmsDestination.SetIntProperty(XMSC.WMQ_FAIL_IF_QUIESCE, value); }

+		}

+

+		/// <summary>

+		/// Whether calls to certain methods fail if the queue manager to which

+		/// the application is connected is in a quiescing state.

+		/// </summary>

+		[UriAttribute("wmq.FailIfQuiesce")]

+		public bool FailIfQuiesce

+		{

+			get { return XMSConvert.ToFailIfQuiesce(this.XMSFailIfQuiesce); }

+			set { this.XMSFailIfQuiesce = XMSConvert.ToXMSFailIfQuiesce(value); }

+		}

+

+		/// <summary>

+		/// This property determines whether an XMS application processes the

+		/// <c>MQRFH2</c> of a WebSphere MQ message as part of the message

+		/// payload (that is, as part of the message body).

+		/// </summary>

+		[UriAttribute("wmq.XMSMessageBody")]

+		public Int32 XMSMessageBody

+		{

+			get { return this.xmsDestination.GetIntProperty(XMSC.WMQ_MESSAGE_BODY); }

+			set { this.xmsDestination.SetIntProperty(XMSC.WMQ_MESSAGE_BODY, value); }

+		}

+

+		/// <summary>

+		/// This property determines whether an XMS application processes the

+		/// <c>MQRFH2</c> of a WebSphere MQ message as part of the message

+		/// payload (that is, as part of the message body).

+		/// </summary>

+		[UriAttribute("wmq.MessageBody")]

+		public MessageBody MessageBody

+		{

+			get { return XMSConvert.ToMessageBody(this.XMSMessageBody); }

+			set { this.XMSMessageBody = XMSConvert.ToXMSMessageBody(value); }

+		}

+

+		/// <summary>

+		/// Determines what level of message context is to be set by the XMS

+		/// application. The application must be running with appropriate

+		/// context authority for this property to take effect.

+		/// </summary>

+		[UriAttribute("wmq.XMSMessageContext")]

+		public Int32 XMSMessageContext

+		{

+			get { return this.xmsDestination.GetIntProperty(XMSC.WMQ_MQMD_MESSAGE_CONTEXT); }

+			set { this.xmsDestination.SetIntProperty(XMSC.WMQ_MQMD_MESSAGE_CONTEXT, value); }

+		}

+

+		/// <summary>

+		/// Determines what level of message context is to be set by the XMS

+		/// application. The application must be running with appropriate

+		/// context authority for this property to take effect.

+		/// </summary>

+		[UriAttribute("wmq.MessageContext")]

+		public MessageContext MessageContext

+		{

+			get { return XMSConvert.ToMessageContext(this.XMSMessageContext); }

+			set { this.XMSMessageContext = XMSConvert.ToXMSMessageContext(value); }

+		}

+

+		/// <summary>

+		/// This property determines whether an XMS application can extract

+		/// the values of MQMD fields or not.

+		/// </summary>

+		[UriAttribute("wmq.XMSMQMDReadEnabled")]

+		public Int32 XMSMQMDReadEnabled

+		{

+			get { return this.xmsDestination.GetIntProperty(XMSC.WMQ_MQMD_READ_ENABLED); }

+			set { this.xmsDestination.SetIntProperty(XMSC.WMQ_MQMD_READ_ENABLED, value); }

+		}

+

+		/// <summary>

+		/// This property determines whether an XMS application can extract

+		/// the values of MQMD fields or not.

+		/// </summary>

+		[UriAttribute("wmq.MQMDReadEnabled")]

+		public bool MQMDReadEnabled

+		{

+			get { return XMSConvert.ToMQMDReadEnabled(this.XMSMQMDReadEnabled); }

+			set { this.XMSMQMDReadEnabled = XMSConvert.ToXMSMQMDReadEnabled(value); }

+		}

+

+		/// <summary>

+		/// This property determines whether an XMS application can set

+		/// the values of MQMD fields or not.

+		/// </summary>

+		[UriAttribute("wmq.XMSMQMDWriteEnabled")]

+		public Int32 XMSMQMDWriteEnabled

+		{

+			get { return this.xmsDestination.GetIntProperty(XMSC.WMQ_MQMD_WRITE_ENABLED); }

+			set { this.xmsDestination.SetIntProperty(XMSC.WMQ_MQMD_WRITE_ENABLED, value); }

+		}

+

+		/// <summary>

+		/// This property determines whether an XMS application can set

+		/// the values of MQMD fields or not.

+		/// </summary>

+		[UriAttribute("wmq.MQMDWriteEnabled")]

+		public bool MQMDWriteEnabled

+		{

+			get { return XMSConvert.ToMQMDWriteEnabled(this.XMSMQMDWriteEnabled); }

+			set { this.XMSMQMDWriteEnabled = XMSConvert.ToXMSMQMDWriteEnabled(value); }

+		}

+

+		/// <summary>

+		/// This property determines whether message consumers and queue

+		/// browsers are allowed to use read ahead to get non-persistent,

+		/// non-transactional messages from this destination into an internal

+		/// buffer before receiving them.

+		/// </summary>

+		[UriAttribute("wmq.XMSReadAheadAllowed")]

+		public Int32 XMSReadAheadAllowed

+		{

+			get { return this.xmsDestination.GetIntProperty(XMSC.WMQ_READ_AHEAD_ALLOWED); }

+			set { this.xmsDestination.SetIntProperty(XMSC.WMQ_READ_AHEAD_ALLOWED, value); }

+		}

+

+		/// <summary>

+		/// This property determines whether message consumers and queue

+		/// browsers are allowed to use read ahead to get non-persistent,

+		/// non-transactional messages from this destination into an internal

+		/// buffer before receiving them.

+		/// </summary>

+		[UriAttribute("wmq.ReadAheadAllowed")]

+		public ReadAheadAllowed ReadAheadAllowed

+		{

+			get { return XMSConvert.ToReadAheadAllowed(this.XMSReadAheadAllowed); }

+			set { this.XMSReadAheadAllowed = XMSConvert.ToXMSReadAheadAllowed(value); }

+		}

+

+

+		/// <summary>

+		/// This property determines, for messages being delivered to an

+		/// asynchronous message listener, what happens to messages in the

+		/// internal read ahead buffer when the message consumer is closed.

+		/// </summary>

+		[UriAttribute("wmq.XMSReadAheadClosePolicy")]

+		public Int32 XMSReadAheadClosePolicy

+		{

+			get { return this.xmsDestination.GetIntProperty(XMSC.WMQ_READ_AHEAD_CLOSE_POLICY); }

+			set { this.xmsDestination.SetIntProperty(XMSC.WMQ_READ_AHEAD_CLOSE_POLICY, value); }

+		}

+

+		/// <summary>

+		/// This property determines, for messages being delivered to an

+		/// asynchronous message listener, what happens to messages in the

+		/// internal read ahead buffer when the message consumer is closed.

+		/// </summary>

+		[UriAttribute("wmq.ReadAheadClosePolicy")]

+		public ReadAheadClosePolicy ReadAheadClosePolicy

+		{

+			get { return XMSConvert.ToReadAheadClosePolicy(this.XMSReadAheadClosePolicy); }

+			set { this.XMSReadAheadClosePolicy = XMSConvert.ToXMSReadAheadClosePolicy(value); }

+		}

+

+		/// <summary>

+		/// Destination property that sets the target CCSID for queue manager

+		/// message conversion. The value is ignored unless

+		/// <c>XMSC.WMQ_RECEIVE_CONVERSION</c> is set to

+		/// <c>WMQ_RECEIVE_CONVERSION_QMGR</c>.

+		/// </summary>

+		[UriAttribute("wmq.ReceiveCCSID")]

+		public Int32 ReceiveCCSID

+		{

+			get { return this.xmsDestination.GetIntProperty(XMSC.WMQ_RECEIVE_CCSID); }

+			set { this.xmsDestination.SetIntProperty(XMSC.WMQ_RECEIVE_CCSID, value); }

+		}

+

+		/// <summary>

+		/// Destination property that determines whether data conversion is

+		/// going to be performed by the queue manager.

+		/// </summary>

+		[UriAttribute("wmq.XMSReceiveConversion")]

+		public Int32 XMSReceiveConversion

+		{

+			get { return this.xmsDestination.GetIntProperty(XMSC.WMQ_RECEIVE_CONVERSION); }

+			set { this.xmsDestination.SetIntProperty(XMSC.WMQ_RECEIVE_CONVERSION, value); }

+		}

+

+		/// <summary>

+		/// Destination property that determines whether data conversion is

+		/// going to be performed by the queue manager.

+		/// </summary>

+		[UriAttribute("wmq.ReceiveConversion")]

+		public ReceiveConversion ReceiveConversion

+		{

+			get { return XMSConvert.ToReceiveConversion(this.XMSReceiveConversion); }

+			set { this.XMSReceiveConversion = XMSConvert.ToXMSReceiveConversion(value); }

+		}

+

+		/// <summary>

+		/// Whether messages sent to the destination contain an <c>MQRFH2</c>

+		/// header.

+		/// </summary>

+		[UriAttribute("wmq.XMSTargetClient")]

+		public Int32 XMSTargetClient

+		{

+			get { return this.xmsDestination.GetIntProperty(XMSC.WMQ_TARGET_CLIENT); }

+			set { this.xmsDestination.SetIntProperty(XMSC.WMQ_TARGET_CLIENT, value); }

+		}

+

+		/// <summary>

+		/// Whether messages sent to the destination contain an <c>MQRFH2</c>

+		/// header.

+		/// </summary>

+		[UriAttribute("wmq.TargetClient")]

+		public TargetClient TargetClient

+		{

+			get { return XMSConvert.ToTargetClient(this.XMSTargetClient); }

+			set { this.XMSTargetClient = XMSConvert.ToXMSTargetClient(value); }

+		}

+

+		/// <summary>

+		/// When creating temporary topics, XMS generates a topic string of

+		/// the form "TEMP/TEMPTOPICPREFIX/unique_id", or if this property

+		/// contains the default value, then this string, "TEMP/unique_id",

+		/// is generated. Specifying a non-empty value allows specific model

+		/// queues to be defined for creating the managed queues for subscribers

+		/// to temporary topics created under this connection.

+		/// </summary>

+		[UriAttribute("wmq.TemporaryTopicPrefix")]

+		public string WMQTemporaryTopicPrefix

+		{

+			get { return this.xmsDestination.GetStringProperty(XMSC.WMQ_TEMP_TOPIC_PREFIX); }

+			set { this.xmsDestination.SetStringProperty(XMSC.WMQ_TEMP_TOPIC_PREFIX, value); }

+		}

+

+		#endregion

+

+		#region WPM-specific properties

+

+		/// <summary>

+		/// The name of the service integration bus in which the destination

+		/// exists.

+		/// </summary>

+		[UriAttribute("wpm.BusName")]

+		public string BusName

+		{

+			get { return this.xmsDestination.GetStringProperty(XMSC.WPM_BUS_NAME); }

+			set { this.xmsDestination.SetStringProperty(XMSC.WPM_BUS_NAME, value); }

+		}

+

+

+		/// <summary>

+		/// The name of the topic space that contains the topic.

+		/// </summary>

+		[UriAttribute("wpm.TopicSpace")]

+		public string TopicSpace

+		{

+			get { return this.xmsDestination.GetStringProperty(XMSC.WPM_TOPIC_SPACE); }

+			set { this.xmsDestination.SetStringProperty(XMSC.WPM_TOPIC_SPACE, value); }

+		}

+

+		#endregion

+

+		#endregion

+

+		#region IDisposable implementation

+

+		public void Dispose()

+		{

+		}

+

+		#endregion

+	}

+}

diff --git a/src/main/csharp/InitialContext.cs b/src/main/csharp/InitialContext.cs
new file mode 100644
index 0000000..3b9ed83
--- /dev/null
+++ b/src/main/csharp/InitialContext.cs
@@ -0,0 +1,174 @@
+/*

+ * 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.Specialized;

+using Apache.NMS.XMS.Util;

+using Apache.NMS.Policies;

+using Apache.NMS.Util;

+using IBM.XMS;

+

+namespace Apache.NMS.XMS

+{

+	/// <summary>

+	/// An Initial Context for querying object repositories for object

+    /// definitions.

+	/// </summary>

+	public class InitialContext : IDisposable

+	{

+        public IBM.XMS.InitialContext xmsInitialContext;

+

+        #region Constructors

+

+        /// <summary>

+        /// Constructs an <c>InitialContext</c> object.

+        /// </summary>

+        /// <param name="environment">Environment settings.</param>

+		public InitialContext(Hashtable environment)

+		{

+            this.xmsInitialContext = new IBM.XMS.InitialContext(environment);

+		}

+

+        /// <summary>

+        /// Constructs an <c>InitialContext</c> object specifying the

+        /// repository URL.

+        /// </summary>

+        /// <param name="environment">Environment settings.</param>

+        /// <param name="repositoryURL">Repository URL.</param>

+		public InitialContext(Hashtable environment, string repositoryURL)

+		{

+            this.xmsInitialContext = new IBM.XMS.InitialContext(environment);

+            this.RepositoryURL = repositoryURL;

+		}

+

+		#endregion

+

+		#region Initial Context Properties (configure via ConnectionFactory URL parameters)

+

+        // http://www-01.ibm.com/support/knowledgecenter/SSFKSJ_8.0.0/com.ibm.mq.msc.doc/props_inctx.htm?lang=en

+

+        /// <summary>

+        /// Repository URL.

+        /// </summary>

+		[UriAttribute("ic.RepositoryURL")]

+        public string RepositoryURL

+        {

+            get { return (string)this.xmsInitialContext.Environment[XMSC.IC_URL]; }

+            set { this.xmsInitialContext.Environment[XMSC.IC_URL] = value; }

+        }

+

+        /// <summary>

+        /// Initial context provider URL.

+        /// </summary>

+		[UriAttribute("ic.ProviderURL")]

+        public string ProviderURL

+        {

+            get { return (string)this.xmsInitialContext.Environment[XMSC.IC_PROVIDER_URL]; }

+            set { this.xmsInitialContext.Environment[XMSC.IC_PROVIDER_URL] = value; }

+        }

+

+        /// <summary>

+        /// Initial context security protocol.

+        /// </summary>

+		[UriAttribute("ic.SecurityProtocol")]

+        public string SecurityProtocol

+        {

+            get { return (string)this.xmsInitialContext.Environment[XMSC.IC_SECURITY_PROTOCOL]; }

+            set { this.xmsInitialContext.Environment[XMSC.IC_SECURITY_PROTOCOL] = value; }

+        }

+

+        /// <summary>

+        /// Initial context security authentication.

+        /// </summary>

+		[UriAttribute("ic.SecurityAuthentication")]

+        public string SecurityAuthentication

+        {

+            get { return (string)this.xmsInitialContext.Environment[XMSC.IC_SECURITY_AUTHENTICATION]; }

+            set { this.xmsInitialContext.Environment[XMSC.IC_SECURITY_AUTHENTICATION] = value; }

+        }

+

+        /// <summary>

+        /// Initial context security principal.

+        /// </summary>

+		[UriAttribute("ic.SecurityPrincipal")]

+        public string SecurityPrincipal

+        {

+            get { return (string)this.xmsInitialContext.Environment[XMSC.IC_SECURITY_PRINCIPAL]; }

+            set { this.xmsInitialContext.Environment[XMSC.IC_SECURITY_PRINCIPAL] = value; }

+        }

+

+        /// <summary>

+        /// Initial context security credentials.

+        /// </summary>

+		[UriAttribute("ic.SecurityCredentials")]

+        public string SecurityCredentials

+        {

+            get { return (string)this.xmsInitialContext.Environment[XMSC.IC_SECURITY_CREDENTIALS]; }

+            set { this.xmsInitialContext.Environment[XMSC.IC_SECURITY_CREDENTIALS] = value; }

+        }

+

+        #endregion

+

+        #region InitialContext Methods

+

+        /// <summary>

+        /// Create an object from an object definition that is retrieved from

+        /// the repository of administered objects.

+        /// </summary>

+        /// <param name="objectName">Requested object name.</param>

+        /// <returns>Requested object, or null if the requested object is

+        /// not found.</returns>

+        public object Lookup(string objectName)

+        {

+            return this.xmsInitialContext.Lookup(objectName);

+        }

+

+        /// <summary>

+        /// Add a new property to the environment.

+        /// </summary>

+        /// <param name="propertyName">Property name.</param>

+        /// <param name="propertyValue">Property value.</param>

+        /// <returns>Old property value.</returns>

+        public object AddToEnvironment(

+            string propertyName, object propertyValue)

+        {

+            return this.xmsInitialContext.AddToEnvironment(

+                propertyName, propertyValue);

+        }

+

+        /// <summary>

+        /// Remove a property from the environment.

+        /// </summary>

+        /// <param name="propertyName">Property name.</param>

+        /// <returns>Old property value.</returns>

+        public object RemoveFromEnvironment(string propertyName)

+        {

+            return this.xmsInitialContext.RemoveFromEnvironment(propertyName);

+        }

+

+        #endregion

+

+        #region IDisposable

+

+        public void Dispose()

+        {

+            this.xmsInitialContext.Close();

+        }

+

+        #endregion

+	}

+}

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

+	}

+}

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

+	}

+}

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);

+				}

+			}

+		}

+	}

+}

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

+	}

+}

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

+	}

+}

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

+	}

+}

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
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());

+		}

+	}

+}

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

+	}

+}

diff --git a/src/main/csharp/StreamMessage.cs b/src/main/csharp/StreamMessage.cs
new file mode 100644
index 0000000..b25579b
--- /dev/null
+++ b/src/main/csharp/StreamMessage.cs
@@ -0,0 +1,480 @@
+/*

+ * 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>

+    /// A StreamMessage object is used to send a stream of primitive types in the 

+    /// .NET programming language. It is filled and read sequentially. It inherits 

+    /// from the Message interface and adds a stream message body.

+    /// </summary>

+	class StreamMessage : Apache.NMS.XMS.Message, Apache.NMS.IStreamMessage

+	{

+		#region Constructors and access to internal stream message

+

+		/// <summary>

+		/// Internal IBM XMS stream message.

+		/// </summary>

+		public IBM.XMS.IStreamMessage xmsStreamMessage

+		{

+			get { return (IBM.XMS.IStreamMessage)this.xmsMessage; }

+			set { this.xmsMessage = value; }

+		}

+

+		/// <summary>

+		/// Constructs a <c>StreamMessage</c> object.

+		/// </summary>

+		/// <param name="message">XMS stream message.</param>

+		public StreamMessage(IBM.XMS.IStreamMessage message)

+			: base(message)

+		{

+		}

+

+		#endregion

+

+		#region IStreamMessage Members

+

+		#region Reset method

+

+		/// <summary>

+		/// Resets the contents of the stream message body.

+		/// </summary>

+		public void Reset()

+		{

+			try

+			{

+				this.xmsStreamMessage.Reset();

+			}

+			catch(Exception ex)

+			{

+				ExceptionUtil.WrapAndThrowNMSException(ex);

+			}

+		}

+

+		#endregion

+

+		#region Read methods

+

+		/// <summary>

+		/// Reads a boolean from the stream message.

+		/// </summary>

+		/// <returns>A <see cref="System.Boolean"/></returns>

+		public bool ReadBoolean()

+		{

+			try

+			{

+				return this.xmsStreamMessage.ReadBoolean();

+			}

+			catch(Exception ex)

+			{

+				ExceptionUtil.WrapAndThrowNMSException(ex);

+				return false;

+			}

+		}

+

+		/// <summary>

+		/// Reads a byte from the stream message.

+		/// </summary>

+		/// <returns>A <see cref="System.Byte"/></returns>

+		public byte ReadByte()

+		{

+			try

+			{

+				return this.xmsStreamMessage.ReadByte();

+			}

+			catch(Exception ex)

+			{

+				ExceptionUtil.WrapAndThrowNMSException(ex);

+				return 0;

+			}

+		}

+

+		/// <summary>

+		/// Reads a byte array from the stream message.

+		/// </summary>

+		/// <param name="value">A <see cref="System.Byte"/> array</param>

+		/// <returns>The total number of bytes read into the buffer, or -1 if

+		/// there is no more data because the end of the byte field has been

+		/// reached</returns>

+		public int ReadBytes(byte[] value)

+		{

+			try

+			{

+				return this.xmsStreamMessage.ReadBytes(value);

+			}

+			catch(Exception ex)

+			{

+				ExceptionUtil.WrapAndThrowNMSException(ex);

+				return 0;

+			}

+		}

+

+		/// <summary>

+		/// Reads a character from the stream message.

+		/// </summary>

+		/// <returns>A <see cref="System.Char"/></returns>

+		public char ReadChar()

+		{

+			try

+			{

+				return this.xmsStreamMessage.ReadChar();

+			}

+			catch(Exception ex)

+			{

+				ExceptionUtil.WrapAndThrowNMSException(ex);

+				return (char) 0;

+			}

+		}

+

+		/// <summary>

+		/// Reads a 16 bits (short) integer number from the stream message.

+		/// </summary>

+		/// <returns>A <see cref="System.Int16"/></returns>

+		public short ReadInt16()

+		{

+			try

+			{

+				return this.xmsStreamMessage.ReadShort();

+			}

+			catch(Exception ex)

+			{

+				ExceptionUtil.WrapAndThrowNMSException(ex);

+				return 0;

+			}

+		}

+

+		/// <summary>

+		/// Reads a 32 bits (int) integer number from the stream message.

+		/// </summary>

+		/// <returns>A <see cref="System.Int32"/></returns>

+		public int ReadInt32()

+		{

+			try

+			{

+				return this.xmsStreamMessage.ReadInt();

+			}

+			catch(Exception ex)

+			{

+				ExceptionUtil.WrapAndThrowNMSException(ex);

+				return 0;

+			}

+		}

+

+		/// <summary>

+		/// Reads a 64 bits (long) integer number from the stream message.

+		/// </summary>

+		/// <returns>A <see cref="System.Int64"/></returns>

+		public long ReadInt64()

+		{

+			try

+			{

+				return this.xmsStreamMessage.ReadLong();

+			}

+			catch(Exception ex)

+			{

+				ExceptionUtil.WrapAndThrowNMSException(ex);

+				return 0;

+			}

+		}

+

+		/// <summary>

+		/// Reads a single precision floating point number from the stream

+		/// message.

+		/// </summary>

+		/// <returns>A <see cref="System.Single"/></returns>

+		public float ReadSingle()

+		{

+			try

+			{

+				return this.xmsStreamMessage.ReadFloat();

+			}

+			catch(Exception ex)

+			{

+				ExceptionUtil.WrapAndThrowNMSException(ex);

+				return 0;

+			}

+		}

+

+		/// <summary>

+		/// Reads a double precision floating point number from the stream

+		/// message.

+		/// </summary>

+		/// <returns>A <see cref="System.Double"/></returns>

+		public double ReadDouble()

+		{

+			try

+			{

+				return this.xmsStreamMessage.ReadDouble();

+			}

+			catch(Exception ex)

+			{

+				ExceptionUtil.WrapAndThrowNMSException(ex);

+				return 0;

+			}

+		}

+

+		/// <summary>

+		/// Reads a character string from the stream message.

+		/// </summary>

+		/// <returns>A <see cref="System.String"/></returns>

+		public string ReadString()

+		{

+			try

+			{

+				return this.xmsStreamMessage.ReadString();

+			}

+			catch(Exception ex)

+			{

+				ExceptionUtil.WrapAndThrowNMSException(ex);

+				return null;

+			}

+		}

+

+		/// <summary>

+		/// Reads an object from the stream message.

+		/// </summary>

+		/// <returns>A <see cref="System.Object"/></returns>

+		public object ReadObject()

+		{

+			try

+			{

+				return this.xmsStreamMessage.ReadObject();

+			}

+			catch(Exception ex)

+			{

+				ExceptionUtil.WrapAndThrowNMSException(ex);

+				return 0;

+			}

+		}

+

+		#endregion

+

+		#region Write methods

+

+		/// <summary>

+		/// Writes a boolean to the stream message.

+		/// </summary>

+		/// <param name="value">A <see cref="System.Boolean"/></param>

+		public void WriteBoolean(bool value)

+		{

+			try

+			{

+				this.xmsStreamMessage.WriteBoolean(value);

+			}

+			catch(Exception ex)

+			{

+				ExceptionUtil.WrapAndThrowNMSException(ex);

+			}

+		}

+

+		/// <summary>

+		/// Writes a byte to the stream message.

+		/// </summary>

+		/// <param name="value">A <see cref="System.Byte"/></param>

+		public void WriteByte(byte value)

+		{

+			try

+			{

+				this.xmsStreamMessage.WriteByte(value);

+			}

+			catch(Exception ex)

+			{

+				ExceptionUtil.WrapAndThrowNMSException(ex);

+			}

+		}

+

+		/// <summary>

+		/// Writes a byte array to the stream message.

+		/// </summary>

+		/// <param name="value">A <see cref="System.Byte"/> array</param>

+		public void WriteBytes(byte[] value)

+		{

+			try

+			{

+				this.xmsStreamMessage.WriteBytes(value);

+			}

+			catch(Exception ex)

+			{

+				ExceptionUtil.WrapAndThrowNMSException(ex);

+			}

+		}

+

+		/// <summary>

+		/// Writes a portion of a byte array as a byte array field to the

+		/// stream message.

+		/// </summary>

+		/// <param name="value">A <see cref="System.Byte"/> array</param>

+		/// <param name="offset">A <see cref="System.Int32"/> value that

+		/// indicates the point in the buffer to begin writing to the stream

+		/// message.</param>

+		/// <param name="length">A <see cref="System.Int32"/> value that

+		/// indicates how many bytes in the buffer to write to the stream

+		/// message.</param>

+		public void WriteBytes(byte[] value, int offset, int length)

+		{

+			try

+			{

+				this.xmsStreamMessage.WriteBytes(value, offset, length);

+			}

+			catch(Exception ex)

+			{

+				ExceptionUtil.WrapAndThrowNMSException(ex);

+			}

+		}

+

+		/// <summary>

+		/// Writes a character to the stream message.

+		/// </summary>

+		/// <param name="value">A <see cref="System.Char"/></param>

+		public void WriteChar(char value)

+		{

+			try

+			{

+				this.xmsStreamMessage.WriteChar(value);

+			}

+			catch(Exception ex)

+			{

+				ExceptionUtil.WrapAndThrowNMSException(ex);

+			}

+		}

+

+		/// <summary>

+		/// Writes a 16 bts (short) integer to the stream message.

+		/// </summary>

+		/// <param name="value">A <see cref="System.Int16"/></param>

+		public void WriteInt16(short value)

+		{

+			try

+			{

+				this.xmsStreamMessage.WriteShort(value);

+			}

+			catch(Exception ex)

+			{

+				ExceptionUtil.WrapAndThrowNMSException(ex);

+			}

+		}

+

+		/// <summary>

+		/// Writes a 32 bts (int) integer to the stream message.

+		/// </summary>

+		/// <param name="value">A <see cref="System.Int32"/></param>

+		public void WriteInt32(int value)

+		{

+			try

+			{

+				this.xmsStreamMessage.WriteInt(value);

+			}

+			catch(Exception ex)

+			{

+				ExceptionUtil.WrapAndThrowNMSException(ex);

+			}

+		}

+

+		/// <summary>

+		/// Writes a 64 bts (long) integer to the stream message.

+		/// </summary>

+		/// <param name="value">A <see cref="System.Int64"/></param>

+		public void WriteInt64(long value)

+		{

+			try

+			{

+				this.xmsStreamMessage.WriteLong(value);

+			}

+			catch(Exception ex)

+			{

+				ExceptionUtil.WrapAndThrowNMSException(ex);

+			}

+		}

+

+		/// <summary>

+		/// Writes a single precision floating point number to the stream

+		/// message.

+		/// </summary>

+		/// <param name="value">A <see cref="System.Single"/></param>

+		public void WriteSingle(float value)

+		{

+			try

+			{

+				this.xmsStreamMessage.WriteFloat(value);

+			}

+			catch(Exception ex)

+			{

+				ExceptionUtil.WrapAndThrowNMSException(ex);

+			}

+		}

+

+		/// <summary>

+		/// Writes a double precision floating point number to the stream

+		/// message.

+		/// </summary>

+		/// <param name="value">A <see cref="System.Double"/></param>

+		public void WriteDouble(double value)

+		{

+			try

+			{

+				this.xmsStreamMessage.WriteDouble(value);

+			}

+			catch(Exception ex)

+			{

+				ExceptionUtil.WrapAndThrowNMSException(ex);

+			}

+		}

+

+		/// <summary>

+		/// Writes a character string to the stream

+		/// message.

+		/// </summary>

+		/// <param name="value">A <see cref="System.String"/></param>

+		public void WriteString(string value)

+		{

+			try

+			{

+				this.xmsStreamMessage.WriteString(value);

+			}

+			catch(Exception ex)

+			{

+				ExceptionUtil.WrapAndThrowNMSException(ex);

+			}

+		}

+

+		/// <summary>

+		/// Writes an object to the stream

+		/// message.

+		/// </summary>

+		/// <param name="value">A <see cref="System.Object"/></param>

+		public void WriteObject(object value)

+		{

+			try

+			{

+				this.xmsStreamMessage.WriteObject(value);

+			}

+			catch(Exception ex)

+			{

+				ExceptionUtil.WrapAndThrowNMSException(ex);

+			}

+		}

+

+		#endregion

+

+		#endregion

+	}

+}

diff --git a/src/main/csharp/TemporaryQueue.cs b/src/main/csharp/TemporaryQueue.cs
new file mode 100644
index 0000000..4d896c5
--- /dev/null
+++ b/src/main/csharp/TemporaryQueue.cs
@@ -0,0 +1,62 @@
+/*

+ * 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.

+ */

+

+namespace Apache.NMS.XMS

+{

+	class TemporaryQueue : Apache.NMS.XMS.Queue, Apache.NMS.ITemporaryQueue

+	{

+		#region Constructors and destructors

+

+		/// <summary>

+		/// Constructs a <c>TemporaryQueue</c> object.

+		/// </summary>

+		/// <param name="temporaryQueue">IBM XMS queue</param>

+		public TemporaryQueue(IBM.XMS.IDestination temporaryQueue)

+			: base(temporaryQueue, true)

+		{

+		}

+

+		#endregion

+

+		#region ITemporaryQueue Members

+

+		/// <summary>

+		/// Deletes the temporary queue.

+		/// </summary>

+		public void Delete()

+		{

+			// IBM.XMS does not provide a method for deleting a destination.

+			// Should we throw an exception or ignore the request ?

+			//this.xmsDestination.Delete();

+		}

+

+		#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 "temp-queue://" + QueueName;

+		}

+

+		#endregion

+	}

+}

diff --git a/src/main/csharp/TemporaryTopic.cs b/src/main/csharp/TemporaryTopic.cs
new file mode 100644
index 0000000..374b528
--- /dev/null
+++ b/src/main/csharp/TemporaryTopic.cs
@@ -0,0 +1,62 @@
+/*

+ * 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.

+ */

+

+namespace Apache.NMS.XMS

+{

+	class TemporaryTopic : Apache.NMS.XMS.Topic, Apache.NMS.ITemporaryTopic

+	{

+		#region Constructors and destructors

+

+		/// <summary>

+		/// Constructs a <c>TemporaryTopic</c> object.

+		/// </summary>

+		/// <param name="temporaryTopic">IBM XMS queue</param>

+		public TemporaryTopic(IBM.XMS.IDestination temporaryTopic)

+			: base(temporaryTopic, true)

+		{

+		}

+

+		#endregion

+

+		#region ITemporaryTopic Members

+

+		/// <summary>

+		/// Deletes the temporary topic.

+		/// </summary>

+		public void Delete()

+		{

+			// IBM.XMS does not provide a method for deleting a destination.

+			// Should we throw an exception or ignore the request ?

+			//this.xmsDestination.Delete();

+		}

+

+		#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 "temp-topic://" + TopicName;

+		}

+

+		#endregion

+	}

+}

diff --git a/src/main/csharp/TextMessage.cs b/src/main/csharp/TextMessage.cs
new file mode 100644
index 0000000..d98cd03
--- /dev/null
+++ b/src/main/csharp/TextMessage.cs
@@ -0,0 +1,86 @@
+/*

+ * 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 text based message.

+	/// </summary>

+	class TextMessage : Apache.NMS.XMS.Message, Apache.NMS.ITextMessage

+	{

+		#region Constructors and access to internal stream message

+

+		/// <summary>

+		/// Internal IBM XMS text message.

+		/// </summary>

+		public IBM.XMS.ITextMessage xmsTextMessage

+		{

+			get { return (IBM.XMS.ITextMessage)this.xmsMessage; }

+			set { this.xmsMessage = value; }

+		}

+

+		/// <summary>

+		/// Constructs a <c>TextMessage</c> object.

+		/// </summary>

+		/// <param name="message">XMS text message.</param>

+		public TextMessage(IBM.XMS.ITextMessage message)

+			: base(message)

+		{

+		}

+

+		#endregion

+

+		#region ITextMessage Members

+

+		/// <summary>

+		/// The text contents of the message body.

+		/// </summary>

+		public string Text

+		{

+			get

+			{

+				try

+				{

+					return this.xmsTextMessage.Text;

+				}

+				catch(Exception ex)

+				{

+					ExceptionUtil.WrapAndThrowNMSException(ex);

+					return null;

+				}

+			}

+			set

+			{

+				try

+				{

+					this.xmsTextMessage.Text = value;

+				}

+				catch(Exception ex)

+				{

+					ExceptionUtil.WrapAndThrowNMSException(ex);

+				}

+			}

+		}

+

+		#endregion

+	}

+}

diff --git a/src/main/csharp/Topic.cs b/src/main/csharp/Topic.cs
new file mode 100644
index 0000000..c4cc4c2
--- /dev/null
+++ b/src/main/csharp/Topic.cs
@@ -0,0 +1,72 @@
+/*

+ * 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 Topic : Apache.NMS.XMS.Destination, Apache.NMS.ITopic

+	{

+		#region Constructors and destructors

+

+		/// <summary>

+		/// Constructs a <c>Topic</c> object.

+		/// </summary>

+		/// <param name="topic">IBM XMS topic</param>

+		public Topic(IBM.XMS.IDestination topic)

+			: base(topic)

+		{

+		}

+

+		/// <summary>

+		/// Constructs a <c>Topic</c> object.

+		/// </summary>

+		/// <param name="topic">IBM XMS topic</param>

+		/// <param name="isTemporary">Whether the topic is temporary</param>

+		public Topic(IBM.XMS.IDestination topic, bool isTemporary)

+			: base(topic, isTemporary)

+		{

+		}

+

+		#endregion

+

+        #region ITopic Members

+

+		public string TopicName

+		{

+			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 "topic://" + TopicName;

+		}

+

+		#endregion

+	}

+}
\ No newline at end of file
diff --git a/src/main/csharp/Util/Dispatcher.cs b/src/main/csharp/Util/Dispatcher.cs
new file mode 100644
index 0000000..d036cb3
--- /dev/null
+++ b/src/main/csharp/Util/Dispatcher.cs
@@ -0,0 +1,173 @@
+/*

+ * 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.Threading;

+

+namespace Apache.NMS.XMS.Util

+{

+	/// <summary>

+	/// Handles the multi-threaded dispatching between the transport and the consumers

+	/// </summary>

+	public class Dispatcher

+    {

+		System.Collections.Queue queue = new System.Collections.Queue();

+		readonly Object semaphore = new Object();

+		readonly ArrayList messagesToRedeliver = new ArrayList();

+        

+        // TODO can't use EventWaitHandle on MONO 1.0

+        AutoResetEvent messageReceivedEventHandle = new AutoResetEvent(false);

+        bool m_bAsyncDelivery = false;

+        bool m_bClosed = false;

+

+		public void SetAsyncDelivery(AutoResetEvent eventHandle)

+		{

+			lock (semaphore)

+			{

+				messageReceivedEventHandle = eventHandle;

+				m_bAsyncDelivery = true;

+				if (queue.Count > 0)

+				{

+					messageReceivedEventHandle.Set();

+				}

+			}

+		}

+

+        /// <summary>

+        /// Whem we start a transaction we must redeliver any rolled back messages

+        /// </summary>

+        public void RedeliverRolledBackMessages()

+		{

+            lock (semaphore)

+            {

+				System.Collections.Queue replacement = new System.Collections.Queue(queue.Count + messagesToRedeliver.Count);

+                foreach (Apache.NMS.IMessage element in messagesToRedeliver)

+                {

+                    replacement.Enqueue(element);

+                }

+                messagesToRedeliver.Clear();

+                

+                while (queue.Count > 0)

+                {

+					Apache.NMS.IMessage element = (Apache.NMS.IMessage) queue.Dequeue();

+                    replacement.Enqueue(element);

+                }

+

+				queue = replacement;

+                if (queue.Count > 0)

+                {

+                	messageReceivedEventHandle.Set();

+                }

+            }

+        }

+        

+        /// <summary>

+        /// Redeliver the given message, putting it at the head of the queue

+        /// </summary>

+		public void Redeliver(Apache.NMS.IMessage message)

+        {

+            lock (semaphore)

+			{

+				messagesToRedeliver.Add(message);

+            }

+        }

+        

+        /// <summary>

+        /// Method Enqueue

+        /// </summary>

+		public void Enqueue(Apache.NMS.IMessage message)

+        {

+            lock (semaphore)

+            {

+                queue.Enqueue(message);

+                messageReceivedEventHandle.Set();

+            }

+        }

+        

+        /// <summary>

+        /// Method DequeueNoWait

+        /// </summary>

+		public Apache.NMS.IMessage DequeueNoWait()

+        {

+			Apache.NMS.XMS.Message rc = null;

+            lock (semaphore)

+            {

+                if (!m_bClosed && queue.Count > 0)

+                {

+					rc = (Apache.NMS.XMS.Message) queue.Dequeue();

+					if(null != rc)

+					{

+						rc.ReadOnlyBody = true;

+						rc.ReadOnlyProperties = true;

+					}

+                } 

+            }

+            return rc;

+        }

+

+        /// <summary>

+        /// Method Dequeue

+        /// </summary>

+		public Apache.NMS.IMessage Dequeue(TimeSpan timeout)

+        {

+			Apache.NMS.IMessage rc;

+			bool bClosed = false;

+			lock (semaphore)

+			{

+				bClosed = m_bClosed;

+				rc = DequeueNoWait();

+			}

+

+            while (!bClosed && rc == null)

+            {

+                if( !messageReceivedEventHandle.WaitOne(timeout, false))

+                {

+                    break;

+                }

+

+				lock (semaphore)

+				{

+					rc = DequeueNoWait();

+					bClosed = m_bClosed;

+				}

+            }

+            return rc;

+        }

+        

+        /// <summary>

+        /// Method Dequeue

+        /// </summary>

+		public Apache.NMS.IMessage Dequeue()

+        {

+			TimeSpan indefiniteWait = TimeSpan.FromMilliseconds(Timeout.Infinite);

+			return Dequeue(indefiniteWait);

+        }

+

+		public void Close()

+		{

+			lock (semaphore)

+			{

+				m_bClosed = true;

+				queue.Clear();

+				if(m_bAsyncDelivery)

+				{

+					messageReceivedEventHandle.Set();

+				}

+			}

+		}

+	}

+}

diff --git a/src/main/csharp/Util/ExceptionUtil.cs b/src/main/csharp/Util/ExceptionUtil.cs
new file mode 100644
index 0000000..14ee5d1
--- /dev/null
+++ b/src/main/csharp/Util/ExceptionUtil.cs
@@ -0,0 +1,147 @@
+/*

+ * 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.Text;

+using System.Collections.Generic;

+using IBM.XMS;

+

+namespace Apache.NMS.XMS.Util

+{

+	class ExceptionUtil

+	{

+		/// <summary>

+		/// Wrap the provider specific exception inside an NMS exception to

+		/// more tightly integrate the provider extensions into the NMS API.

+		/// </summary>

+		/// <param name="ex">Original exception.</param>

+		public static void WrapAndThrowNMSException(Exception ex)

+		{

+			if(ex is Apache.NMS.NMSException)

+			{

+				// Already derived from NMSException

+				throw ex;

+			}

+

+			if(ex is IBM.XMS.IllegalStateException)

+			{

+				IBM.XMS.IllegalStateException xmsEx =

+					(IBM.XMS.IllegalStateException)ex;

+				throw new Apache.NMS.IllegalStateException(

+					xmsEx.Message, xmsEx.ErrorCode, xmsEx);

+			}

+

+			if(ex is IBM.XMS.InvalidClientIDException)

+			{

+				IBM.XMS.InvalidClientIDException xmsEx =

+					(IBM.XMS.InvalidClientIDException)ex;

+				throw new Apache.NMS.InvalidClientIDException(

+					xmsEx.Message, xmsEx.ErrorCode, xmsEx);

+			}

+

+			if(ex is IBM.XMS.InvalidDestinationException)

+			{

+				IBM.XMS.InvalidDestinationException xmsEx =

+					(IBM.XMS.InvalidDestinationException)ex;

+				throw new Apache.NMS.InvalidDestinationException(

+					xmsEx.Message, xmsEx.ErrorCode, xmsEx);

+			}

+

+			if(ex is IBM.XMS.InvalidSelectorException)

+			{

+				IBM.XMS.InvalidSelectorException xmsEx =

+					(IBM.XMS.InvalidSelectorException)ex;

+				throw new Apache.NMS.InvalidSelectorException(

+					xmsEx.Message, xmsEx.ErrorCode, xmsEx);

+			}

+

+			if(ex is IBM.XMS.MessageEOFException)

+			{

+				IBM.XMS.MessageEOFException xmsEx =

+					(IBM.XMS.MessageEOFException)ex;

+				throw new Apache.NMS.MessageEOFException(

+					xmsEx.Message, xmsEx.ErrorCode, xmsEx);

+			}

+

+			if(ex is IBM.XMS.MessageFormatException)

+			{

+				IBM.XMS.MessageFormatException xmsEx =

+					(IBM.XMS.MessageFormatException)ex;

+				throw new Apache.NMS.MessageFormatException(

+					xmsEx.Message, xmsEx.ErrorCode, xmsEx);

+			}

+

+			if(ex is IBM.XMS.MessageNotReadableException)

+			{

+				IBM.XMS.MessageNotReadableException xmsEx =

+					(IBM.XMS.MessageNotReadableException)ex;

+				throw new Apache.NMS.MessageNotReadableException(

+					xmsEx.Message, xmsEx.ErrorCode, xmsEx);

+			}

+

+			if(ex is IBM.XMS.MessageNotWriteableException)

+			{

+				IBM.XMS.MessageNotWriteableException xmsEx =

+					(IBM.XMS.MessageNotWriteableException)ex;

+				throw new Apache.NMS.MessageNotWriteableException(

+					xmsEx.Message, xmsEx.ErrorCode, xmsEx);

+			}

+

+			if(ex is IBM.XMS.ResourceAllocationException)

+			{

+				IBM.XMS.ResourceAllocationException xmsEx =

+					(IBM.XMS.ResourceAllocationException)ex;

+				throw new Apache.NMS.ResourceAllocationException(

+					xmsEx.Message, xmsEx.ErrorCode, xmsEx);

+			}

+

+			if(ex is IBM.XMS.SecurityException)

+			{

+				IBM.XMS.SecurityException xmsEx =

+					(IBM.XMS.SecurityException)ex;

+				throw new Apache.NMS.NMSSecurityException(

+					xmsEx.Message, xmsEx.ErrorCode, xmsEx);

+			}

+

+			if(ex is IBM.XMS.TransactionInProgressException)

+			{

+				IBM.XMS.TransactionInProgressException xmsEx =

+					(IBM.XMS.TransactionInProgressException)ex;

+				throw new Apache.NMS.TransactionInProgressException(

+					xmsEx.Message, xmsEx.ErrorCode, xmsEx);

+			}

+

+			if(ex is IBM.XMS.TransactionRolledBackException)

+			{

+				IBM.XMS.TransactionRolledBackException xmsEx =

+					(IBM.XMS.TransactionRolledBackException)ex;

+				throw new Apache.NMS.TransactionRolledBackException(

+					xmsEx.Message, xmsEx.ErrorCode, xmsEx);

+			}

+

+			if(ex is IBM.XMS.XMSException)

+			{

+				IBM.XMS.XMSException xmsEx =

+					(IBM.XMS.XMSException)ex;

+				throw new Apache.NMS.NMSException(

+					xmsEx.Message, xmsEx.ErrorCode, xmsEx);

+			}

+

+			// Not an EMS exception that should be wrapped.

+			throw ex;

+		}

+	}

+}

diff --git a/src/main/csharp/Util/IntrospectionSupport.cs b/src/main/csharp/Util/IntrospectionSupport.cs
new file mode 100644
index 0000000..175135f
--- /dev/null
+++ b/src/main/csharp/Util/IntrospectionSupport.cs
@@ -0,0 +1,434 @@
+/*

+ * 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.Reflection;

+using System.Globalization;

+using System.Collections.Generic;

+using System.Collections.Specialized;

+using Apache.NMS;

+using Apache.NMS.Util;

+

+namespace Apache.NMS.XMS.Util

+{

+	/// <summary>

+	/// Utility class used to provide convenience methods that apply named

+	/// property settings to objects.

+	/// </summary>

+	public class IntrospectionSupport

+	{

+        #region Manage maps of member names and URI aliases

+

+		private static Dictionary<Type, StringDictionary> nameMaps =

+			new Dictionary<Type, StringDictionary>();

+		private static readonly object nameMapsLock = new object();

+

+		/// <summary>

+		/// Gets the member names map for the specified type.

+		/// </summary>

+		/// <param name="type">Type whose names map is requested.</param>

+		/// <returns>Names map for the specified type.</returns>

+        /// <remarks>

+		/// The map is created and registered if it is not found in the

+		/// <c>nameMaps</c> registry.

+        /// </remarks>

+		public static StringDictionary GetNameMap(Type type)

+		{

+			StringDictionary nameMap;

+			lock(IntrospectionSupport.nameMapsLock)

+			{

+				if(!IntrospectionSupport.nameMaps.TryGetValue(

+					type, out nameMap))

+				{

+					nameMap = CreateNameMap(type);

+					IntrospectionSupport.nameMaps.Add(type, nameMap);

+				}

+			}

+			return nameMap;

+		}

+

+		/// <summary>

+		/// Creates a dictionary of public property and attribute names,

+        /// indexed by themselves plus all URI attribute keys associated

+		/// to them.

+		/// </summary>

+		/// <param name="type">Type whose names map is requested.</param>

+		/// <returns>Names map for the specified type.</returns>

+		/// <remarks>

+		/// Applied to this property:

+		/// <code>

+		///   [UriAttribute("My.Test", "MyTest")]

+		///   public string Test

+		///   { get { return(_test); }

+		///     set { _test = value; }

+		///   }

+		/// </code>

+		/// the method returns a dictionary containing

+		/// ("test" -> "Test"), ("my.test" -> "Test"), ("mytest" -> "Test").

+		/// Note that <c>StringDictionary</c> converts keys to lowercase but

+		/// keeps values untouched.

+		/// </remarks>

+		public static StringDictionary CreateNameMap(Type type)

+		{

+			StringDictionary nameMap = new StringDictionary();

+			BindingFlags flags = BindingFlags.FlattenHierarchy

+							| BindingFlags.Public

+							| BindingFlags.Instance;

+

+			// Process public instance self or inherited property

+			foreach(PropertyInfo propertyInfo in type.GetProperties(flags))

+		    {

+				AddToNameMap(nameMap, propertyInfo);

+			}

+

+			// Process public instance self or inherited fields

+			foreach(FieldInfo fieldInfo in type.GetFields(flags))

+		    {

+				AddToNameMap(nameMap, fieldInfo);

+			}

+

+			return(nameMap);

+		}

+

+		/// <summary>

+		/// Adds a property or field name and URI attribute keys to the

+		/// specified name map.

+		/// </summary>

+		/// <param name="nameMap">Name map.</param>

+		/// <param name="memberInfo">Member information for the property

+		/// or field.</param>

+		private static void AddToNameMap(StringDictionary nameMap,

+			MemberInfo memberInfo)

+		{

+			// Add member name mapped to itself

+			nameMap.Add(memberInfo.Name, memberInfo.Name);

+

+			// For each UriAttribute custom attribute

+			foreach(Attribute attr in memberInfo.GetCustomAttributes(

+				typeof(UriAttributeAttribute), true))

+			{

+				// For each URI attribute key

+				foreach(string key in

+					((UriAttributeAttribute)attr).AttributeKeys)

+				{

+					// Index property name by URI attribute key

+					if(!nameMap.ContainsKey(key))

+					{

+						nameMap.Add(key, memberInfo.Name);

+					}

+				}

+			}

+

+			return;

+		}

+

+        #endregion

+

+		#region Set properties

+

+		/// <summary>

+		/// Sets the public properties of a target object using a string map.

+		/// This method uses .Net reflection to identify public properties of

+		/// the target object matching the keys from the passed map.

+		/// </summary>

+		/// <param name="target">Object whose properties will be set.</param>

+		/// <param name="valueMap">Map of key/value pairs.</param>

+		public static void SetProperties(object target,

+			StringDictionary valueMap)

+		{

+			SetProperties(target, valueMap, GetNameMap(target.GetType()));

+		}

+

+        /// <summary>

+        /// Sets the public properties of a target object using a string map.

+        /// This method uses .Net reflection to access public properties of

+        /// the target object matching the keys from the passed map.

+        /// </summary>

+        /// <param name="target">The object whose properties will be set.</param>

+        /// <param name="valueMap">Map of key/value pairs.</param>

+        /// <param name="nameMap">Map of key/property name pairs.</param>

+        public static void SetProperties(object target,

+            StringDictionary valueMap,

+			StringDictionary nameMap)

+        {

+			Tracer.DebugFormat("SetProperties called with target: {0}",

+				target.GetType().Name);

+

+			// Application of specified values is recursive. If a key does not

+			// correspond to a member of the current target object, it is

+			// supposed to refer to a sub-member of such a member. Since member

+			// keys can contain dot characters, an attempt is made to find the

+			// "longest" key corresponding to a member of the current object

+			// (this identifies the "sub-target"), and extract the remaining

+			// key characters as a sub-key to sub-members.

+			// The following dictionary indexes keys to "sub-targets", and

+			// "sub-key"/value pairs to assign to "sub-targets".

+			Dictionary<string, StringDictionary> subTargetMap = null;

+

+			foreach(string key in valueMap.Keys)

+			{

+				if(nameMap.ContainsKey(key))

+				{

+					// Key refers to a member of the current target

+					string memberName = nameMap[key];

+					MemberInfo member = FindMemberInfo(target, memberName);

+					if(member == null)

+					{

+						// Should not happen if the nameMap was indeed created

+						// for the current target object...

+						throw new NMSException(string.Format(

+							"No such property or field: {0} on class: {1}",

+							memberName, target.GetType().Name));

+					}

+

+					// Set value

+					try

+					{

+						if(member.MemberType == MemberTypes.Property)

+						{

+							PropertyInfo property = (PropertyInfo)member;

+							object value = ConvertValue(valueMap[key],

+								property.PropertyType);

+							property.SetValue(target, value, null);

+						}

+						else

+						{

+							FieldInfo field = (FieldInfo)member;

+							object value = ConvertValue(valueMap[key],

+								field.FieldType);

+							field.SetValue(target, value);

+						}

+					}

+					catch(Exception ex)

+					{

+						throw NMSExceptionSupport.Create(

+							"Error while attempting to apply option.", ex);

+					}

+                }

+				else

+				{

+					// Key does NOT refers to a member of the current target

+					// Extract maximal member key + subkeys

+					string memberKey = key;

+					int dotPos = memberKey.LastIndexOf('.');

+					bool memberFound = false;

+					while(!memberFound && dotPos > 0)

+					{

+						memberKey = memberKey.Substring(0, dotPos);

+						if(nameMap.ContainsKey(memberKey))

+						{

+							memberKey = nameMap[memberKey];

+							memberFound = true;

+						}

+						else

+						{

+							dotPos = memberKey.LastIndexOf('.');

+						}

+					}

+

+					if(!memberFound)

+					{

+						throw new NMSException(string.Format(

+							"Unknown property or field: {0} on class: {1}",

+							key, target.GetType().Name));

+					}

+

+					// Register memberKey, subKey and value for further processing

+					string subKey = key.Substring(dotPos + 1);

+					StringDictionary subValueMap;

+

+					if(subTargetMap == null)

+					{

+						subTargetMap = new Dictionary<string, StringDictionary>();

+					}

+

+					if(!subTargetMap.TryGetValue(memberKey, out subValueMap))

+					{

+						subValueMap = new StringDictionary();

+						subTargetMap.Add(memberKey, subValueMap);

+					}

+

+					// In theory, we can't have the same subkey twice, since

+					// they were unique subkeys from another dictionary.

+					// Therefore, no need to check for subValueMap.ContainsKey.

+					subValueMap.Add(subKey, valueMap[key]);

+				}

+            }

+

+			// Now process any compound assignments.

+			if(subTargetMap != null)

+			{

+				foreach(string subTargetKey in subTargetMap.Keys)

+				{

+					MemberInfo member = FindMemberInfo(target, subTargetKey);

+					object subTarget = GetUnderlyingObject(member, target);

+					SetProperties(subTarget, subTargetMap[subTargetKey]);

+				}

+			}

+        }

+

+		/// <summary>

+		/// Converts the specified string value to the type of the target

+		/// member.

+		/// </summary>

+		private static object ConvertValue(string inputString, Type targetType)

+		{

+			// If the target member is an enumeration, get the enumeration

+			// value or combined (or-ed) values

+			object value;

+			if(targetType.IsEnum)

+			{

+				if(inputString.Contains("+"))

+				{

+					string[] inputValues = inputString.Split('+');

+

+					FieldInfo fieldInfo = targetType.GetField(inputValues[0],

+						BindingFlags.Public

+						| BindingFlags.Static

+						| BindingFlags.IgnoreCase);

+					if(fieldInfo == null)

+					{

+						throw new NMSException(string.Format(

+							"Invalid {0} value \"{1}\"", targetType.Name,

+							inputValues[0]));

+					}

+					dynamic val = fieldInfo.GetValue(null);

+

+					for(int v = 1; v < inputValues.Length; v++)

+					{

+						fieldInfo = targetType.GetField(inputValues[v],

+							BindingFlags.Public

+							| BindingFlags.Static

+							| BindingFlags.IgnoreCase);

+						if(fieldInfo == null)

+						{

+							throw new NMSException(string.Format(

+								"Invalid {0} value \"{1}\"", targetType.Name,

+								inputValues[v]));

+						}

+						val = (dynamic)val | (dynamic)fieldInfo.GetValue(null);

+					}

+

+					value = Convert.ChangeType(val, targetType);

+				}

+				else

+				{

+					FieldInfo fieldInfo = targetType.GetField(inputString,

+                                 BindingFlags.Public

+                               | BindingFlags.Static

+                               | BindingFlags.IgnoreCase);

+					if(fieldInfo == null)

+					{

+						throw new NMSException(string.Format(

+							"Invalid {0} value \"{1}\"", targetType.Name,

+							inputString));

+					}

+					value = fieldInfo.GetValue(null);

+				}

+			}

+			else

+			{

+				// Not an enumeration

+				value = Convert.ChangeType(inputString,

+					targetType, CultureInfo.InvariantCulture);

+			}

+			return value;

+		}

+

+		#endregion

+

+		#region Get member information and objects

+

+		/// <summary>

+		/// Gets member information for a property or field of the target

+		/// object.

+		///	</summary>

+		/// <param name="target">Target object.</param>

+		/// <param name="name">Property or field name.</param>

+		/// <returns>Retrieved member information.</returns>

+        private static MemberInfo FindMemberInfo(object target, string name)

+        {

+            BindingFlags flags = BindingFlags.FlattenHierarchy

+                               | BindingFlags.Public

+                               | BindingFlags.Instance

+                               | BindingFlags.IgnoreCase;

+

+            Type type = target.GetType();

+

+            MemberInfo member = type.GetProperty(name, flags);

+

+            if(member == null)

+            {

+                member = type.GetField(name, flags);

+            }

+

+            return member;

+        }

+

+		/// <summary>

+		/// Gets object assigned to the specified property or field member of

+		/// the target object.

+		///	</summary>

+		/// <param name="member">Member information.</param>

+		/// <param name="target">Target object.</param>

+		/// <returns>Retrieved object.</returns>

+		private static object GetUnderlyingObject(

+			MemberInfo member, object target)

+		{

+			object result = null;

+

+			if(member.MemberType == MemberTypes.Field)

+			{

+				FieldInfo field = member as FieldInfo;

+

+				if(field.FieldType.IsPrimitive)

+				{

+					throw new NMSException(string.Format(

+						"The field given is a primitive type: {0}",

+						member.Name));

+				}

+

+				result = field.GetValue(target);

+			}

+			else

+			{

+				PropertyInfo property = member as PropertyInfo;

+				MethodInfo getter = property.GetGetMethod();

+

+				if(getter == null)

+				{

+					throw new NMSException(string.Format(

+						"Cannot access member: {0}",

+						member.Name));

+				}

+

+				result = getter.Invoke(target, null);

+			}

+

+			if(result == null)

+			{

+				throw new NMSException(string.Format(

+					"Could not retrieve the value of member {0}.",

+					member.Name));

+			}

+

+			return result;

+		}

+

+		#endregion

+    }

+}

diff --git a/src/main/csharp/Util/UriAttributeAttribute.cs b/src/main/csharp/Util/UriAttributeAttribute.cs
new file mode 100644
index 0000000..f7278d8
--- /dev/null
+++ b/src/main/csharp/Util/UriAttributeAttribute.cs
@@ -0,0 +1,51 @@
+/*

+ * 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;

+

+namespace Apache.NMS.XMS.Util

+{

+    /// <summary>

+    /// Attribute for mapping a URI attribute key to an object's property.

+    /// </summary>

+    public class UriAttributeAttribute : System.Attribute

+    {

+        private readonly string[] attributeKeys;

+

+        /// <summary>

+        /// Constructs an <c>UriAttributeAttribute</c> specifying a list

+        /// of attribute keys.

+        /// </summary>

+        /// <param name="keys">URI attribute keys.</param>

+        public UriAttributeAttribute(params string[] keys)

+        {

+            this.attributeKeys = new string[keys.Length];

+            for(int k = 0; k < keys.Length; k++)

+            {

+                this.attributeKeys[k] = keys[k];

+            }

+        }

+

+        /// <summary>

+        /// URI attribute keys.

+        /// </summary>

+        public string[] AttributeKeys

+        {

+            get { return this.attributeKeys; }

+        }

+    }

+}

diff --git a/src/main/csharp/Util/XMSConvert.cs b/src/main/csharp/Util/XMSConvert.cs
new file mode 100644
index 0000000..06d8e2c
--- /dev/null
+++ b/src/main/csharp/Util/XMSConvert.cs
@@ -0,0 +1,1475 @@
+/*

+ * 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 IBM.XMS;

+

+namespace Apache.NMS.XMS.Util

+{

+	/// <summary>

+	/// This class implements conversion methods between the IBM XMS and

+	/// the Apache NMS models.

+	/// </summary>

+	public class XMSConvert

+	{

+		#region IBM XMS to Apache NMS objects conversion

+

+		/// <summary>

+		/// Converts an IBM XMS connection interface

+		/// into an NMS connection interface.

+		/// </summary>

+		/// <param name="xmsConnection">IBM XMS connection interface.</param>

+		/// <returns>Apache NMS connection interface.</returns>

+		public static Apache.NMS.IConnection ToNMSConnection(

+			IBM.XMS.IConnection xmsConnection)

+		{

+			return (xmsConnection != null

+				? new Apache.NMS.XMS.Connection(xmsConnection)

+				: null);

+		}

+

+		/// <summary>

+		/// Converts an IBM XMS session interface

+		/// into an NMS session interface.

+		/// </summary>

+		/// <param name="xmsSession">IBM XMS session interface.</param>

+		/// <returns>Apache NMS session interface.</returns>

+		public static Apache.NMS.ISession ToNMSSession(

+			IBM.XMS.ISession xmsSession)

+		{

+			return (xmsSession != null

+				? new Apache.NMS.XMS.Session(xmsSession)

+				: null);

+		}

+

+		/// <summary>

+		/// Converts an IBM XMS destination interface

+		/// into an NMS destination interface.

+		/// </summary>

+		/// <param name="xmsDestination">XMS destination.</param>

+		/// <returns>Apache NMS destination interface.</returns>

+		public static Apache.NMS.IDestination ToNMSDestination(

+				IBM.XMS.IDestination xmsDestination)

+		{

+			return ToNMSDestination(xmsDestination, false);

+		}

+

+		/// <summary>

+		/// Converts an IBM XMS destination interface

+		/// into an NMS destination interface.

+		/// </summary>

+		/// <param name="xmsDestination">XMS destination.</param>

+		/// <param name="isTemporary">Destination is temporary.</param>

+		/// <returns>Apache NMS destination interface.</returns>

+		public static Apache.NMS.IDestination ToNMSDestination(

+				IBM.XMS.IDestination xmsDestination,

+				bool isTemporary)

+		{

+			if(xmsDestination.TypeId == IBM.XMS.DestinationType.Queue)

+			{

+				return (isTemporary ? ToNMSTemporaryQueue(xmsDestination)

+									: ToNMSQueue(xmsDestination));

+			}

+

+			if(xmsDestination.TypeId == IBM.XMS.DestinationType.Topic)

+			{

+				return (isTemporary ? ToNMSTemporaryTopic(xmsDestination)

+									: ToNMSTopic(xmsDestination));

+			}

+

+			return null;

+		}

+

+		/// <summary>

+		/// Converts an IBM XMS queue interface

+		/// into an NMS queue interface.

+		/// </summary>

+		/// <param name="xmsQueue">XMS destination of type

+		/// <c>DestinationType.Queue</c>.</param>

+		/// <returns>Apache NMS queue interface.</returns>

+		public static Apache.NMS.IQueue ToNMSQueue(

+			IBM.XMS.IDestination xmsQueue)

+		{

+			if((xmsQueue != null) &&

+			(xmsQueue.TypeId != IBM.XMS.DestinationType.Queue))

+			{ throw new ArgumentException(

+				"Cannot convert IBM XMS destination to NMS destination: invalid destination type id.",

+				"xmsQueue");

+			}

+			return (xmsQueue != null

+				? new Apache.NMS.XMS.Queue(xmsQueue)

+				: null);

+		}

+

+		/// <summary>

+		/// Converts an IBM XMS topic interface

+		/// into an NMS topic interface.

+		/// </summary>

+		/// <param name="xmsTopic">XMS destination of type

+		/// <c>DestinationType.Topic</c>.</param>

+		/// <returns>Apache NMS topic interface.</returns>

+		public static Apache.NMS.ITopic ToNMSTopic(

+			IBM.XMS.IDestination xmsTopic)

+		{

+			if((xmsTopic != null) &&

+			(xmsTopic.TypeId != IBM.XMS.DestinationType.Topic))

+			{ throw new ArgumentException(

+				"Cannot convert IBM XMS destination to NMS destination: invalid destination type id.",

+				"xmsTopic");

+			}

+			return (xmsTopic != null

+				? new Apache.NMS.XMS.Topic(xmsTopic)

+				: null);

+		}

+

+		/// <summary>

+		/// Converts an IBM XMS temporary queue interface

+		/// into an NMS temporary queue interface.

+		/// </summary>

+		/// <param name="xmsTemporaryQueue">XMS destination of type

+		/// <c>DestinationType.Queue</c>.</param>

+		/// <returns>Apache NMS temporary queue interface.</returns>

+		// Couldn't find a means to test whether a XMS destination is temporary.

+		public static Apache.NMS.ITemporaryQueue ToNMSTemporaryQueue(

+			IBM.XMS.IDestination xmsTemporaryQueue)

+		{

+			if((xmsTemporaryQueue != null) &&

+			(xmsTemporaryQueue.TypeId != IBM.XMS.DestinationType.Queue))

+			{ throw new ArgumentException(

+				"Cannot convert IBM XMS destination to NMS destination: invalid destination type id.",

+				"xmsTemporaryQueue");

+			}

+			return (xmsTemporaryQueue != null

+				? new Apache.NMS.XMS.TemporaryQueue(xmsTemporaryQueue)

+				: null);

+		}

+

+		/// <summary>

+		/// Converts an IBM XMS temporary topic interface

+		/// into an NMS temporary topic interface.

+		/// </summary>

+		/// <param name="xmsTemporaryTopic">XMS destination of type

+		/// <c>DestinationType.Topic</c>.</param>

+		/// <returns>Apache NMS temporary topic interface.</returns>

+		// Couldn't find a means to test whether a XMS destination is temporary.

+		public static Apache.NMS.ITemporaryTopic ToNMSTemporaryTopic(

+			IBM.XMS.IDestination xmsTemporaryTopic)

+		{

+			if((xmsTemporaryTopic != null) &&

+			(xmsTemporaryTopic.TypeId != IBM.XMS.DestinationType.Queue))

+			{ throw new ArgumentException(

+				"Cannot convert IBM XMS destination to NMS destination: invalid destination type id.",

+				"xmsTemporaryTopic");

+			}

+			return (xmsTemporaryTopic != null

+				? new Apache.NMS.XMS.TemporaryTopic(xmsTemporaryTopic)

+				: null);

+		}

+

+		/// <summary>

+		/// Converts an IBM XMS message producer interface

+		/// into an NMS message producer interface.

+		/// </summary>

+		/// <param name="session">NMS session.</param>

+		/// <param name="xmsMessageProducer">XMS message producer.</param>

+		/// <returns>Apache NMS message producer interface.</returns>

+		public static Apache.NMS.IMessageProducer ToNMSMessageProducer(

+			Apache.NMS.XMS.Session session,

+			IBM.XMS.IMessageProducer xmsMessageProducer)

+		{

+			return (xmsMessageProducer != null

+				? new Apache.NMS.XMS.MessageProducer(session, xmsMessageProducer)

+				: null);

+		}

+

+		/// <summary>

+		/// Converts an IBM XMS message consumer interface

+		/// into an NMS message consumer interface.

+		/// </summary>

+		/// <param name="session">NMS session.</param>

+		/// <param name="xmsMessageConsumer">XMS message consumer.</param>

+		/// <returns>Apache NMS message consumer interface.</returns>

+		public static Apache.NMS.IMessageConsumer ToNMSMessageConsumer(

+			Apache.NMS.XMS.Session session,

+			IBM.XMS.IMessageConsumer xmsMessageConsumer)

+		{

+			return (xmsMessageConsumer != null

+				? new Apache.NMS.XMS.MessageConsumer(session, xmsMessageConsumer)

+				: null);

+		}

+

+		/// <summary>

+		/// Converts an IBM XMS queue browser interface

+		/// into an NMS queue browser interface.

+		/// </summary>

+		/// <param name="xmsQueueBrowser">XMS queue browser.</param>

+		/// <returns>Apache NMS queue browser interface.</returns>

+		public static Apache.NMS.IQueueBrowser ToNMSQueueBrowser(

+			IBM.XMS.IQueueBrowser xmsQueueBrowser)

+		{

+			return (xmsQueueBrowser != null

+				? new Apache.NMS.XMS.QueueBrowser(xmsQueueBrowser)

+				: null);

+		}

+

+		/// <summary>

+		/// Converts an IBM XMS message

+		/// into an NMS message.

+		/// </summary>

+		/// <param name="xmsMessage">IBM XMS message.</param>

+		/// <returns>NMS message.</returns>

+		public static Apache.NMS.IMessage ToNMSMessage(IBM.XMS.IMessage xmsMessage)

+		{

+			if(xmsMessage is IBM.XMS.ITextMessage)

+			{

+				return ToNMSTextMessage((IBM.XMS.ITextMessage)xmsMessage);

+			}

+

+			if(xmsMessage is IBM.XMS.IBytesMessage)

+			{

+				return ToNMSBytesMessage((IBM.XMS.IBytesMessage)xmsMessage);

+			}

+

+			if(xmsMessage is IBM.XMS.IStreamMessage)

+			{

+				return ToNMSStreamMessage((IBM.XMS.IStreamMessage)xmsMessage);

+			}

+

+			if(xmsMessage is IBM.XMS.IMapMessage)

+			{

+				return ToNMSMapMessage((IBM.XMS.IMapMessage)xmsMessage);

+			}

+

+			if(xmsMessage is IBM.XMS.IObjectMessage)

+			{

+				return ToNMSObjectMessage((IBM.XMS.IObjectMessage)xmsMessage);

+			}

+

+			return (xmsMessage != null

+				? new Apache.NMS.XMS.Message(xmsMessage)

+				: null);

+		}

+

+		/// <summary>

+		/// Converts an IBM XMS text message

+		/// into an NMS text message.

+		/// </summary>

+		/// <param name="xmsTextMessage">IBM XMS text message.</param>

+		/// <returns>NMS text message.</returns>

+		public static Apache.NMS.ITextMessage ToNMSTextMessage(

+			IBM.XMS.ITextMessage xmsTextMessage)

+		{

+			return (xmsTextMessage != null

+				? new Apache.NMS.XMS.TextMessage(xmsTextMessage)

+				: null);

+		}

+

+		/// <summary>

+		/// Converts an IBM XMS bytes message

+		/// into an NMS bytes message.

+		/// </summary>

+		/// <param name="xmsBytesMessage">IBM XMS bytes message.</param>

+		/// <returns>NMS bytes message.</returns>

+		public static Apache.NMS.IBytesMessage ToNMSBytesMessage(

+			IBM.XMS.IBytesMessage xmsBytesMessage)

+		{

+			return (xmsBytesMessage != null

+				? new Apache.NMS.XMS.BytesMessage(xmsBytesMessage)

+				: null);

+		}

+

+		/// <summary>

+		/// Converts an IBM XMS stream message

+		/// into an NMS stream message.

+		/// </summary>

+		/// <param name="xmsStreamMessage">IBM XMS stream message.</param>

+		/// <returns>NMS stream message.</returns>

+		public static Apache.NMS.IStreamMessage ToNMSStreamMessage(

+			IBM.XMS.IStreamMessage xmsStreamMessage)

+		{

+			return (xmsStreamMessage != null

+				? new Apache.NMS.XMS.StreamMessage(xmsStreamMessage)

+				: null);

+		}

+

+		/// <summary>

+		/// Converts an IBM XMS map message

+		/// into an NMS map message.

+		/// </summary>

+		/// <param name="xmsMapMessage">IBM XMS map message.</param>

+		/// <returns>NMS map message.</returns>

+		public static Apache.NMS.IMapMessage ToNMSMapMessage(

+			IBM.XMS.IMapMessage xmsMapMessage)

+		{

+			return (xmsMapMessage != null

+				? new Apache.NMS.XMS.MapMessage(xmsMapMessage)

+				: null);

+		}

+

+		/// <summary>

+		/// Converts an IBM XMS object message

+		/// into an NMS object message.

+		/// </summary>

+		/// <param name="xmsObjectMessage">IBM XMS object message.</param>

+		/// <returns>NMS object message.</returns>

+		public static Apache.NMS.IObjectMessage ToNMSObjectMessage(

+			IBM.XMS.IObjectMessage xmsObjectMessage)

+		{

+			return (xmsObjectMessage != null

+				? new Apache.NMS.XMS.ObjectMessage(xmsObjectMessage)

+				: null);

+		}

+

+		/// <summary>

+		/// Converts an IBM XMS message

+		/// into an NMS primitive map.

+		/// </summary>

+		/// <param name="xmsMessage">IBM XMS message.</param>

+		/// <returns>NMS primitive map.</returns>

+		public static Apache.NMS.IPrimitiveMap ToMessageProperties(

+			IBM.XMS.IMessage xmsMessage)

+		{

+			return (xmsMessage != null

+				? new Apache.NMS.XMS.MessageProperties(xmsMessage)

+				: null);

+		}

+

+		#endregion

+

+		#region Apache NMS to IBM XMS objects conversion

+

+		/// <summary>

+		/// Converts an NMS destination

+		/// into an IBM XMS destination.

+		/// </summary>

+		/// <param name="nmsDestination">NMS destination.</param>

+		/// <returns>IBM XMS destination.</returns>

+		public static IBM.XMS.IDestination ToXMSDestination(

+			Apache.NMS.IDestination nmsDestination)

+		{

+			if(nmsDestination is Apache.NMS.XMS.Destination)

+			{

+				return ((Apache.NMS.XMS.Destination)nmsDestination).xmsDestination;

+			}

+			return null;

+		}

+

+		#endregion

+

+		#region Property values conversion

+

+		#region Exception handling

+

+		/// <summary>

+		/// Throws a conversion exception.

+		/// </summary>

+		private static void ThrowCantConvertValueException(object value,

+					string conversionMethod)

+		{

+			throw new ArgumentException(string.Format(

+				"Cannot convert {0} using {1}.", value, conversionMethod),

+				conversionMethod);

+		}

+

+		#endregion

+

+		#region Encoding

+

+		/// <summary>

+		/// Converts an XMS encoding key.

+		/// </summary>

+		/// <param name="inputValue">Input value.</param>

+		/// <returns>Converted value.</returns>

+		public static Encoding ToEncoding(Int32 inputValue)

+		{

+			return (Encoding)inputValue;

+		}

+

+		/// <summary>

+		/// Converts an encoding to the equivalent XMS value.

+		/// </summary>

+		/// <param name="inputValue">Input value.</param>

+		/// <returns>Converted value.</returns>

+		public static Int32 ToXMSEncoding(Encoding inputValue)

+		{

+			return (Int32)inputValue;

+		}

+

+		#endregion

+

+		#region Message Type

+

+		/// <summary>

+		/// Converts an XMS message type key.

+		/// </summary>

+		/// <param name="inputValue">Input value.</param>

+		/// <returns>Converted value.</returns>

+		public static MessageType ToMessageType(Int32 inputValue)

+		{

+			return (MessageType)inputValue;

+		}

+

+		/// <summary>

+		/// Converts a message type to the equivalent XMS value.

+		/// </summary>

+		/// <param name="inputValue">Input value.</param>

+		/// <returns>Converted value.</returns>

+		public static Int32 ToXMSMessageType(MessageType inputValue)

+		{

+			return (Int32)inputValue;

+		}

+

+		#endregion

+

+		#region Report Confirm On Arrival

+

+		/// <summary>

+		/// Converts an XMS "confirm on arrival" key.

+		/// </summary>

+		/// <param name="inputValue">Input value.</param>

+		/// <returns>Converted value.</returns>

+		public static ReportConfirmOnArrival ToReportConfirmOnArrival(

+			Int32 inputValue)

+		{

+			return (ReportConfirmOnArrival)inputValue;

+		}

+

+		/// <summary>

+		/// Converts a "confirm on arrival" to the equivalent XMS value.

+		/// </summary>

+		/// <param name="inputValue">Input value.</param>

+		/// <returns>Converted value.</returns>

+		public static Int32 ToXMSReportConfirmOnArrival(

+			ReportConfirmOnArrival inputValue)

+		{

+			return (Int32)inputValue;

+		}

+

+		#endregion

+

+		#region Report Confirm On Delivery

+

+		/// <summary>

+		/// Converts an XMS "confirm on delivery" key.

+		/// </summary>

+		/// <param name="inputValue">Input value.</param>

+		/// <returns>Converted value.</returns>

+		public static ReportConfirmOnDelivery ToReportConfirmOnDelivery(

+			Int32 inputValue)

+		{

+			return (ReportConfirmOnDelivery)inputValue;

+		}

+

+		/// <summary>

+		/// Converts a "confirm on delivery" to the equivalent XMS value.

+		/// </summary>

+		/// <param name="inputValue">Input value.</param>

+		/// <returns>Converted value.</returns>

+		public static Int32 ToXMSReportConfirmOnDelivery(

+			ReportConfirmOnDelivery inputValue)

+		{

+			return (Int32)inputValue;

+		}

+

+		#endregion

+

+		#region Report Exception

+

+		/// <summary>

+		/// Converts an XMS "report exceptions" key.

+		/// </summary>

+		/// <param name="inputValue">Input value.</param>

+		/// <returns>Converted value.</returns>

+		public static ReportExceptions ToReportExceptions(

+			Int32 inputValue)

+		{

+			return (ReportExceptions)inputValue;

+		}

+

+		/// <summary>

+		/// Converts a "report exceptions" to the equivalent XMS value.

+		/// </summary>

+		/// <param name="inputValue">Input value.</param>

+		/// <returns>Converted value.</returns>

+		public static Int32 ToXMSReportExceptions(

+			ReportExceptions inputValue)

+		{

+			return (Int32)inputValue;

+		}

+

+		#endregion

+

+		#region Report Expiration

+

+		/// <summary>

+		/// Converts an XMS "report expiration" key.

+		/// </summary>

+		/// <param name="inputValue">Input value.</param>

+		/// <returns>Converted value.</returns>

+		public static ReportExpiration ToReportExpiration(

+			Int32 inputValue)

+		{

+			return (ReportExpiration)inputValue;

+		}

+

+		/// <summary>

+		/// Converts a "report expiration" to the equivalent XMS value.

+		/// </summary>

+		/// <param name="inputValue">Input value.</param>

+		/// <returns>Converted value.</returns>

+		public static Int32 ToXMSReportExpiration(

+			ReportExpiration inputValue)

+		{

+			return (Int32)inputValue;

+		}

+

+		#endregion

+

+		#region Report Correlation Id

+

+		/// <summary>

+		/// Converts an XMS "report correlation id." key.

+		/// </summary>

+		/// <param name="inputValue">Input value.</param>

+		/// <returns>Converted value.</returns>

+		public static ReportCorrelationId ToReportCorrelationId(

+			Int32 inputValue)

+		{

+			return (ReportCorrelationId)inputValue;

+		}

+

+		/// <summary>

+		/// Converts a "report correlation id." to the equivalent XMS value.

+		/// </summary>

+		/// <param name="inputValue">Input value.</param>

+		/// <returns>Converted value.</returns>

+		public static Int32 ToXMSReportCorrelationId(

+			ReportCorrelationId inputValue)

+		{

+			return (Int32)inputValue;

+		}

+

+		#endregion

+

+		#region Report Message Id

+

+		/// <summary>

+		/// Converts an XMS "report message id." key.

+		/// </summary>

+		/// <param name="inputValue">Input value.</param>

+		/// <returns>Converted value.</returns>

+		public static ReportMessageId ToReportMessageId(

+			Int32 inputValue)

+		{

+			return (ReportMessageId)inputValue;

+		}

+

+		/// <summary>

+		/// Converts a "report message id." to the equivalent XMS value.

+		/// </summary>

+		/// <param name="inputValue">Input value.</param>

+		/// <returns>Converted value.</returns>

+		public static Int32 ToXMSReportMessageId(

+			ReportMessageId inputValue)

+		{

+			return (Int32)inputValue;

+		}

+

+		#endregion

+

+		#region Asynchronous Exceptions

+

+		/// <summary>

+		/// Converts an XMS asynchronous exceptions handling directive key.

+		/// </summary>

+		/// <param name="inputValue">Input value.</param>

+		/// <returns>Converted value.</returns>

+		public static AsynchronousExceptions ToAsynchronousExceptions(

+			Int32 inputValue)

+		{

+			return (AsynchronousExceptions)inputValue;

+		}

+

+		/// <summary>

+		/// Converts an asynchronous exceptions handling directive to the

+		/// equivalent XMS value.

+		/// </summary>

+		/// <param name="inputValue">Input value.</param>

+		/// <returns>Converted value.</returns>

+		public static Int32 ToXMSAsynchronousExceptions(

+			AsynchronousExceptions inputValue)

+		{

+			return (Int32)inputValue;

+		}

+

+		#endregion

+

+		#region Connection Type

+

+		/// <summary>

+		/// Converts an XMS connection type key.

+		/// </summary>

+		/// <param name="inputValue">Input value.</param>

+		/// <returns>Converted value.</returns>

+		public static ConnectionType ToConnectionType(Int32 inputValue)

+		{

+			return (ConnectionType)inputValue;

+		}

+

+		/// <summary>

+		/// Converts a connection type to the equivalent XMS value.

+		/// </summary>

+		/// <param name="inputValue">Input value.</param>

+		/// <returns>Converted value.</returns>

+		public static Int32 ToXMSConnectionType(ConnectionType inputValue)

+		{

+			return (Int32)inputValue;

+		}

+

+		#endregion

+

+		#region Delivery Mode

+

+		/// <summary>

+		/// Converts an XMS delivery mode key.

+		/// </summary>

+		/// <param name="inputValue">Input value.</param>

+		/// <returns>Converted value.</returns>

+		public static DeliveryMode ToDeliveryMode(Int32 inputValue)

+		{

+			return (DeliveryMode)inputValue;

+		}

+

+		/// <summary>

+		/// Converts a delivery mode to the equivalent XMS value.

+		/// </summary>

+		/// <param name="inputValue">Input value.</param>

+		/// <returns>Converted value.</returns>

+		public static Int32 ToXMSDeliveryMode(DeliveryMode inputValue)

+		{

+			return (Int32)inputValue;

+		}

+

+		#endregion

+

+		#region Priority

+

+		/// <summary>

+		/// Converts an XMS priority key.

+		/// </summary>

+		/// <param name="inputValue">Input value.</param>

+		/// <returns>Converted value.</returns>

+		public static Priority ToPriority(Int32 inputValue)

+		{

+			return (Priority)inputValue;

+		}

+

+		/// <summary>

+		/// Converts a priority to the equivalent XMS value.

+		/// </summary>

+		/// <param name="inputValue">Input value.</param>

+		/// <returns>Converted value.</returns>

+		public static Int32 ToXMSPriority(Priority inputValue)

+		{

+			return (Int32)inputValue;

+		}

+

+		#endregion

+

+		#region Connection Protocol (RTT)

+

+		/// <summary>

+		/// Converts an RTT connection protocol key.

+		/// </summary>

+		/// <param name="inputValue">Input value.</param>

+		/// <returns>Converted value.</returns>

+		public static RTTConnectionProtocol ToRTTConnectionProtocol(

+			Int32 inputValue)

+		{

+			return (RTTConnectionProtocol)inputValue;

+		}

+

+		/// <summary>

+		/// Converts an RTT connection protocol to the equivalent XMS value.

+		/// </summary>

+		/// <param name="inputValue">Input value.</param>

+		/// <returns>Converted value.</returns>

+		public static Int32 ToXMSRTTConnectionProtocol(

+			RTTConnectionProtocol inputValue)

+		{

+			return (Int32)inputValue;

+		}

+

+		#endregion

+

+		#region Multicast (RTT)

+

+		/// <summary>

+		/// Converts an RTT multicast state key.

+		/// </summary>

+		/// <param name="inputValue">Input value.</param>

+		/// <returns>Converted value.</returns>

+		public static Multicast ToMulticast(Int32 inputValue)

+		{

+			return (Multicast)inputValue;

+		}

+

+		/// <summary>

+		/// Converts a multicast state to the equivalent XMS value.

+		/// </summary>

+		/// <param name="inputValue">Input value.</param>

+		/// <returns>Converted value.</returns>

+		public static Int32 ToXMSMulticast(Multicast inputValue)

+		{

+			return (Int32)inputValue;

+		}

+

+		#endregion

+

+		#region Broker Version (WMQ)

+

+		/// <summary>

+		/// Converts a WMQ broker version key.

+		/// </summary>

+		/// <param name="inputValue">Input value.</param>

+		/// <returns>Converted value.</returns>

+		public static BrokerVersion ToBrokerVersion(Int32 inputValue)

+		{

+			return (BrokerVersion)inputValue;

+		}

+

+		/// <summary>

+		/// Converts a broker version to the equivalent XMS value.

+		/// </summary>

+		/// <param name="inputValue">Input value.</param>

+		/// <returns>Converted value.</returns>

+		public static Int32 ToXMSBrokerVersion(BrokerVersion inputValue)

+		{

+			return (Int32)inputValue;

+		}

+

+		#endregion

+

+		#region Reconnect Options (WMQ)

+

+		/// <summary>

+		/// Converts a WMQ reconnect option key.

+		/// </summary>

+		/// <param name="inputValue">Input value.</param>

+		/// <returns>Converted value.</returns>

+		public static ReconnectOptions ToReconnectOptions(Int32 inputValue)

+		{

+			return (ReconnectOptions)inputValue;

+		}

+

+		/// <summary>

+		/// Converts a reconnect option to the equivalent XMS value.

+		/// </summary>

+		/// <param name="inputValue">Input value.</param>

+		/// <returns>Converted value.</returns>

+		public static Int32 ToXMSReconnectOptions(ReconnectOptions inputValue)

+		{

+			return (Int32)inputValue;

+		}

+

+		#endregion

+

+		#region Connection Mode (WMQ)

+

+		/// <summary>

+		/// Converts a WMQ connection mode key.

+		/// </summary>

+		/// <param name="inputValue">Input value.</param>

+		/// <returns>Converted value.</returns>

+		public static ConnectionMode ToConnectionMode(Int32 inputValue)

+		{

+			return (ConnectionMode)inputValue;

+		}

+

+		/// <summary>

+		/// Converts a connection mode to the equivalent XMS value.

+		/// </summary>

+		/// <param name="inputValue">Input value.</param>

+		/// <returns>Converted value.</returns>

+		public static Int32 ToXMSConnectionMode(ConnectionMode inputValue)

+		{

+			return (Int32)inputValue;

+		}

+

+		#endregion

+

+		#region Fail If Quiesce (WMQ)

+

+		/// <summary>

+		/// Converts a WMQ yes/no key to the equivalent boolean.

+		/// </summary>

+		/// <param name="inputValue">Input value.</param>

+		/// <returns>Converted value.</returns>

+		public static bool ToFailIfQuiesce(Int32 inputValue)

+		{

+			switch(inputValue)

+			{

+				case XMSC.WMQ_FIQ_YES: return true;

+				case XMSC.WMQ_FIQ_NO : return false;

+				default:

+					ThrowCantConvertValueException(inputValue, "ToFailIfQuiesce");

+					return false;

+

+			}

+		}

+

+		/// <summary>

+		/// Converts a WMQ boolean to the equivalent XMS yes/no value.

+		/// </summary>

+		/// <param name="inputValue">Input value.</param>

+		/// <returns>Converted value.</returns>

+		public static Int32 ToXMSFailIfQuiesce(bool inputValue)

+		{

+			return inputValue ? XMSC.WMQ_FIQ_YES : XMSC.WMQ_FIQ_NO;

+		}

+

+		#endregion

+

+		#region Message Body (WMQ)

+

+		/// <summary>

+		/// Converts a WMQ message body key.

+		/// </summary>

+		/// <param name="inputValue">Input value.</param>

+		/// <returns>Converted value.</returns>

+		public static MessageBody ToMessageBody(Int32 inputValue)

+		{

+			return (MessageBody)inputValue;

+		}

+

+		/// <summary>

+		/// Converts a message body to the equivalent XMS value.

+		/// </summary>

+		/// <param name="inputValue">Input value.</param>

+		/// <returns>Converted value.</returns>

+		public static Int32 ToXMSMessageBody(MessageBody inputValue)

+		{

+			return (Int32)inputValue;

+		}

+

+		#endregion

+

+		#region Message Context (WMQ)

+

+		/// <summary>

+		/// Converts a WMQ message context key.

+		/// </summary>

+		/// <param name="inputValue">Input value.</param>

+		/// <returns>Converted value.</returns>

+		public static MessageContext ToMessageContext(Int32 inputValue)

+		{

+			return (MessageContext)inputValue;

+		}

+

+		/// <summary>

+		/// Converts a message context to the equivalent XMS value.

+		/// </summary>

+		/// <param name="inputValue">Input value.</param>

+		/// <returns>Converted value.</returns>

+		public static Int32 ToXMSMessageContext(MessageContext inputValue)

+		{

+			return (Int32)inputValue;

+		}

+

+		#endregion

+

+		#region MQMD Read Enabled (WMQ)

+

+		/// <summary>

+		/// Converts a WMQ yes/no key to the equivalent boolean.

+		/// </summary>

+		/// <param name="inputValue">Input value.</param>

+		/// <returns>Converted value.</returns>

+		public static bool ToMQMDReadEnabled(Int32 inputValue)

+		{

+			return (inputValue != 0);

+			//switch(inputValue)

+			//{

+			//case XMSC.WMQ_READ_ENABLED_YES: return true;

+			//case XMSC.WMQ_READ_ENABLED_NO : return false;

+			//default:

+			//	ThrowCantConvertValueException(inputValue, "ToMQMDReadEnabled");

+			//	return false;

+			//}

+		}

+

+		/// <summary>

+		/// Converts a WMQ boolean to the equivalent XMS yes/no value.

+		/// </summary>

+		/// <param name="inputValue">Input value.</param>

+		/// <returns>Converted value.</returns>

+		public static Int32 ToXMSMQMDReadEnabled(bool inputValue)

+		{

+			return inputValue ? 1 : 0;

+			//	XMSC.WMQ_READ_ENABLED_YES : XMSC.WMQ_READ_ENABLED_NO;

+		}

+

+		#endregion

+

+		#region MQMD Write Enabled (WMQ)

+

+		/// <summary>

+		/// Converts a WMQ yes/no key to the equivalent boolean.

+		/// </summary>

+		/// <param name="inputValue">Input value.</param>

+		/// <returns>Converted value.</returns>

+		public static bool ToMQMDWriteEnabled(Int32 inputValue)

+		{

+			return (inputValue != 0);

+			//switch(inputValue)

+			//{

+			//case XMSC.WMQ_WRITE_ENABLED_YES: return true;

+			//case XMSC.WMQ_WRITE_ENABLED_NO : return false;

+			//default:

+			//	ThrowCantConvertValueException(inputValue, "ToMQMDWriteEnabled");

+			//	return false;

+			//}

+		}

+

+		/// <summary>

+		/// Converts a WMQ boolean to the equivalent XMS yes/no value.

+		/// </summary>

+		/// <param name="inputValue">Input value.</param>

+		/// <returns>Converted value.</returns>

+		public static Int32 ToXMSMQMDWriteEnabled(bool inputValue)

+		{

+			return inputValue ? 1 : 0;

+			//	XMSC.WMQ_WRITE_ENABLED_YES : XMSC.WMQ_WRITE_ENABLED_NO;

+		}

+

+		#endregion

+

+		#region Asynchronous Puts Allowed (WMQ)

+

+		/// <summary>

+		/// Converts a WMQ asynchronous puts allowed key.

+		/// </summary>

+		/// <param name="inputValue">Input value.</param>

+		/// <returns>Converted value.</returns>

+		public static AsynchronousPutsAllowed ToAsynchronousPutsAllowed(

+			Int32 inputValue)

+		{

+			return (AsynchronousPutsAllowed)inputValue;

+		}

+

+		/// <summary>

+		/// Converts a WMQ asynchronous puts allowed to the equivalent

+		/// XMS value.

+		/// </summary>

+		/// <param name="inputValue">Input value.</param>

+		/// <returns>Converted value.</returns>

+		public static Int32 ToXMSAsynchronousPutsAllowed(

+			AsynchronousPutsAllowed inputValue)

+		{

+			return (Int32)inputValue;

+		}

+

+		#endregion

+

+		#region Read Ahead Allowed (WMQ)

+

+		/// <summary>

+		/// Converts a WMQ read ahead allowed key.

+		/// </summary>

+		/// <param name="inputValue">Input value.</param>

+		/// <returns>Converted value.</returns>

+		public static ReadAheadAllowed ToReadAheadAllowed(

+			Int32 inputValue)

+		{

+			return (ReadAheadAllowed)inputValue;

+		}

+

+		/// <summary>

+		/// Converts a WMQ read ahead allowed to the equivalent

+		/// XMS value.

+		/// </summary>

+		/// <param name="inputValue">Input value.</param>

+		/// <returns>Converted value.</returns>

+		public static Int32 ToXMSReadAheadAllowed(

+			ReadAheadAllowed inputValue)

+		{

+			return (Int32)inputValue;

+		}

+

+		#endregion

+

+		#region Read Ahead Close Policy (WMQ)

+

+		/// <summary>

+		/// Converts a WMQ read ahead close policy key.

+		/// </summary>

+		/// <param name="inputValue">Input value.</param>

+		/// <returns>Converted value.</returns>

+		public static ReadAheadClosePolicy ToReadAheadClosePolicy(

+			Int32 inputValue)

+		{

+			return (ReadAheadClosePolicy)inputValue;

+		}

+

+		/// <summary>

+		/// Converts a WMQ read ahead close policy to the equivalent

+		/// XMS value.

+		/// </summary>

+		/// <param name="inputValue">Input value.</param>

+		/// <returns>Converted value.</returns>

+		public static Int32 ToXMSReadAheadClosePolicy(

+			ReadAheadClosePolicy inputValue)

+		{

+			return (Int32)inputValue;

+		}

+

+		#endregion

+

+		#region Message Selection (WMQ)

+

+		/// <summary>

+		/// Converts a WMQ message selection key.

+		/// </summary>

+		/// <param name="inputValue">Input value.</param>

+		/// <returns>Converted value.</returns>

+		public static MessageSelection ToMessageSelection(Int32 inputValue)

+		{

+			return (MessageSelection)inputValue;

+		}

+

+		/// <summary>

+		/// Converts a WMQ message selection to the equivalent XMS value.

+		/// </summary>

+		/// <param name="inputValue">Input value.</param>

+		/// <returns>Converted value.</returns>

+		public static Int32 ToXMSMessageSelection(MessageSelection inputValue)

+		{

+			return (Int32)inputValue;

+		}

+

+		#endregion

+

+		#region Receive Conversion (WMQ)

+

+		/// <summary>

+		/// Converts a WMQ receive conversion key.

+		/// </summary>

+		/// <param name="inputValue">Input value.</param>

+		/// <returns>Converted value.</returns>

+		public static ReceiveConversion ToReceiveConversion(Int32 inputValue)

+		{

+			return (ReceiveConversion)inputValue;

+		}

+

+		/// <summary>

+		/// Converts a WMQ receive conversion to the equivalent XMS value.

+		/// </summary>

+		/// <param name="inputValue">Input value.</param>

+		/// <returns>Converted value.</returns>

+		public static Int32 ToXMSReceiveConversion(ReceiveConversion inputValue)

+		{

+			return (Int32)inputValue;

+		}

+

+		#endregion

+

+		#region Share Socket Allowed (WMQ)

+

+		/// <summary>

+		/// Converts a WMQ yes/no key to the equivalent boolean.

+		/// </summary>

+		/// <param name="inputValue">Input value.</param>

+		/// <returns>Converted value.</returns>

+		public static bool ToShareSocketAllowed(Int32 inputValue)

+		{

+			switch(inputValue)

+			{

+			case XMSC.WMQ_SHARE_CONV_ALLOWED_YES: return true;

+			case XMSC.WMQ_SHARE_CONV_ALLOWED_NO : return false;

+			default:

+				ThrowCantConvertValueException(inputValue, "ShareSocketAllowed");

+				return false;

+			}

+		}

+

+		/// <summary>

+		/// Converts a WMQ boolean to the equivalent XMS yes/no value.

+		/// </summary>

+		/// <param name="inputValue">Input value.</param>

+		/// <returns>Converted value.</returns>

+		public static Int32 ToXMSShareSocketAllowed(bool inputValue)

+		{

+			return inputValue

+				? XMSC.WMQ_SHARE_CONV_ALLOWED_YES

+				: XMSC.WMQ_SHARE_CONV_ALLOWED_NO;

+		}

+

+		#endregion

+

+		#region Target Client (WMQ)

+

+		/// <summary>

+		/// Converts a WMQ target client key.

+		/// </summary>

+		/// <param name="inputValue">Input value.</param>

+		/// <returns>Converted value.</returns>

+		public static TargetClient ToTargetClient(Int32 inputValue)

+		{

+			return (TargetClient)inputValue;

+		}

+

+		/// <summary>

+		/// Converts a WMQ target client to the equivalent XMS value.

+		/// </summary>

+		/// <param name="inputValue">Input value.</param>

+		/// <returns>Converted value.</returns>

+		public static Int32 ToXMSTargetClient(TargetClient inputValue)

+		{

+			return (Int32)inputValue;

+		}

+

+		#endregion

+

+		#region Wildcard Format (WMQ)

+

+		/// <summary>

+		/// Converts a WMQ wildcard format key.

+		/// </summary>

+		/// <param name="inputValue">Input value.</param>

+		/// <returns>Converted value.</returns>

+		public static WildcardFormat ToWildcardFormat(Int32 inputValue)

+		{

+			return (WildcardFormat)inputValue;

+		}

+

+		/// <summary>

+		/// Converts a WMQ wildcard format to the equivalent XMS value.

+		/// </summary>

+		/// <param name="inputValue">Input value.</param>

+		/// <returns>Converted value.</returns>

+		public static Int32 ToXMSWildcardFormat(WildcardFormat inputValue)

+		{

+			return (Int32)inputValue;

+		}

+

+		#endregion

+

+		#region Connection Protocol (WPM)

+

+		/// <summary>

+		/// Converts a WPM connection protocol key.

+		/// </summary>

+		/// <param name="inputValue">Input value.</param>

+		/// <returns>Converted value.</returns>

+		public static WPMConnectionProtocol ToWPMConnectionProtocol(

+			Int32 inputValue)

+		{

+			return (WPMConnectionProtocol)inputValue;

+		}

+

+		/// <summary>

+		/// Converts a WPM connection protocol to the equivalent XMS value.

+		/// </summary>

+		/// <param name="inputValue">Input value.</param>

+		/// <returns>Converted value.</returns>

+		public static Int32 ToXMSWPMConnectionProtocol(

+			WPMConnectionProtocol inputValue)

+		{

+			return (Int32)inputValue;

+		}

+

+		#endregion

+

+		#region Connection Proximity (WPM)

+

+		/// <summary>

+		/// Converts a WPM connection proximity key.

+		/// </summary>

+		/// <param name="inputValue">Input value.</param>

+		/// <returns>Converted value.</returns>

+		public static ConnectionProximity ToConnectionProximity(

+			Int32 inputValue)

+		{

+			return (ConnectionProximity)inputValue;

+		}

+

+		/// <summary>

+		/// Converts a WPM connection proximity to the equivalent XMS value.

+		/// </summary>

+		/// <param name="inputValue">Input value.</param>

+		/// <returns>Converted value.</returns>

+		public static Int32 ToXMSConnectionProximity(

+			ConnectionProximity inputValue)

+		{

+			return (Int32)inputValue;

+		}

+

+		#endregion

+

+		#region Mapping (WPM)

+

+		/// <summary>

+		/// Converts a WPM mapping key.

+		/// </summary>

+		/// <param name="inputValue">Input value.</param>

+		/// <returns>Converted value.</returns>

+		public static Mapping ToMapping(Int32 inputValue)

+		{

+			return (Mapping)inputValue;

+		}

+

+		/// <summary>

+		/// Converts a WPM mapping to the equivalent XMS value.

+		/// </summary>

+		/// <param name="inputValue">Input value.</param>

+		/// <returns>Converted value.</returns>

+		public static Int32 ToXMSMapping(Mapping inputValue)

+		{

+			return (Int32)inputValue;

+		}

+

+		#endregion

+

+		#region Target Significance (WPM)

+

+		/// <summary>

+		/// Converts a WPM target significance key.

+		/// </summary>

+		/// <param name="inputValue">Input value.</param>

+		/// <returns>Converted value.</returns>

+		public static TargetSignificance ToTargetSignificance(

+			Int32 inputValue)

+		{

+			return (TargetSignificance)inputValue;

+		}

+

+		/// <summary>

+		/// Converts a WPM target significance to the equivalent XMS value.

+		/// </summary>

+		/// <param name="inputValue">Input value.</param>

+		/// <returns>Converted value.</returns>

+		public static Int32 ToXMSTargetSignificance(

+			TargetSignificance inputValue)

+		{

+			return (Int32)inputValue;

+		}

+

+		#endregion

+

+		#region Target Type (WPM)

+

+		/// <summary>

+		/// Converts a WPM target type key.

+		/// </summary>

+		/// <param name="inputValue">Input value.</param>

+		/// <returns>Converted value.</returns>

+		public static TargetType ToTargetType(Int32 inputValue)

+		{

+			return (TargetType)inputValue;

+		}

+

+		/// <summary>

+		/// Converts a WPM target type to the equivalent XMS value.

+		/// </summary>

+		/// <param name="inputValue">Input value.</param>

+		/// <returns>Converted value.</returns>

+		public static Int32 ToXMSTargetType(TargetType inputValue)

+		{

+			return (Int32)inputValue;

+		}

+

+		#endregion

+

+		#endregion

+

+		#region IBM XMS to Apache NMS enumerations conversion

+

+		/// <summary>

+		/// Converts an IBM XMS destination type

+		/// to the equivalent NMS value.

+		/// </summary>

+		/// <param name="xmsDestinationType">XMS destination type.</param>

+		/// <param name="isTemporary">Whether the destination is temporary.

+		/// </param>

+		/// <returns>NMS destination type.</returns>

+		public static DestinationType ToDestinationType(

+			IBM.XMS.DestinationType xmsDestinationType, bool isTemporary)

+		{

+			switch(xmsDestinationType)

+			{

+			case IBM.XMS.DestinationType.Queue:

+				return(isTemporary

+					? DestinationType.TemporaryQueue

+					: DestinationType.Queue);

+

+			case IBM.XMS.DestinationType.Topic:

+				return(isTemporary

+					? DestinationType.TemporaryTopic

+					: DestinationType.Queue);

+

+			default:

+				ThrowCantConvertValueException(

+					xmsDestinationType.ToString(),

+					"ToDestinationType");

+				return DestinationType.Queue;

+			}

+		}

+

+		/// <summary>

+		/// Converts an IBM XMS acknowledgement mode

+		/// to the equivalent NMS value.

+		/// </summary>

+		/// <param name="acknowledgeMode">XMS acknowledgement mode.</param>

+		/// <returns>NMS acknowledgement mode.</returns>

+		public static Apache.NMS.AcknowledgementMode ToAcknowledgementMode(

+			IBM.XMS.AcknowledgeMode acknowledgeMode)

+		{

+			Apache.NMS.AcknowledgementMode acknowledge =

+				Apache.NMS.AcknowledgementMode.AutoAcknowledge;

+

+			switch(acknowledgeMode)

+			{

+			case IBM.XMS.AcknowledgeMode.AutoAcknowledge:

+				acknowledge = Apache.NMS.AcknowledgementMode.AutoAcknowledge;

+				break;

+

+			case IBM.XMS.AcknowledgeMode.ClientAcknowledge:

+				acknowledge = Apache.NMS.AcknowledgementMode.ClientAcknowledge;

+				break;

+

+			case IBM.XMS.AcknowledgeMode.DupsOkAcknowledge:

+				acknowledge = Apache.NMS.AcknowledgementMode.DupsOkAcknowledge;

+				break;

+

+			case IBM.XMS.AcknowledgeMode.SessionTransacted:

+				acknowledge = Apache.NMS.AcknowledgementMode.Transactional;

+				break;

+			}

+

+			return acknowledge;

+		}

+

+		/// <summary>

+		/// Converts an IBM XMS delivery mode

+		/// to the equivalent NMS value.

+		/// </summary>

+		/// <param name="deliveryMode">XMS delivery mode.</param>

+		/// <returns>NMS delivery mode.</returns>

+		public static MsgDeliveryMode ToNMSMsgDeliveryMode(

+			IBM.XMS.DeliveryMode deliveryMode)

+		{

+			if(deliveryMode == IBM.XMS.DeliveryMode.Persistent)

+			{

+				return MsgDeliveryMode.Persistent;

+			}

+

+			if(deliveryMode == IBM.XMS.DeliveryMode.NonPersistent)

+			{

+				return MsgDeliveryMode.NonPersistent;

+			}

+

+			// Hard cast it to the enumeration.

+			return (MsgDeliveryMode) deliveryMode;

+		}

+

+		#endregion

+

+		#region Apache NMS to IBM XMS enumerations conversion

+

+		/// <summary>

+		/// Converts an NMS acknowledgement mode

+		/// to the equivalent IBM XMS value.

+		/// </summary>

+		/// <param name="acknowledge">NMS acknowledgement mode.</param>

+		/// <returns>IBM XMS acknowledgement mode.</returns>

+		public static IBM.XMS.AcknowledgeMode ToAcknowledgeMode(

+			Apache.NMS.AcknowledgementMode acknowledge)

+		{

+			IBM.XMS.AcknowledgeMode acknowledgeMode =

+				(IBM.XMS.AcknowledgeMode)0;

+

+			switch(acknowledge)

+			{

+			case Apache.NMS.AcknowledgementMode.AutoAcknowledge:

+				acknowledgeMode = IBM.XMS.AcknowledgeMode.AutoAcknowledge;

+				break;

+

+			case Apache.NMS.AcknowledgementMode.ClientAcknowledge:

+				acknowledgeMode = IBM.XMS.AcknowledgeMode.ClientAcknowledge;

+				break;

+

+			case Apache.NMS.AcknowledgementMode.DupsOkAcknowledge:

+				acknowledgeMode = IBM.XMS.AcknowledgeMode.DupsOkAcknowledge;

+				break;

+

+			case Apache.NMS.AcknowledgementMode.Transactional:

+				acknowledgeMode = IBM.XMS.AcknowledgeMode.SessionTransacted;

+				break;

+			}

+

+			return acknowledgeMode;

+		}

+

+		/// <summary>

+		/// Converts an NMS delivery mode

+		/// to the equivalent IBM XMS value.

+		/// </summary>

+		/// <param name="deliveryMode">NMS delivery mode.</param>

+		/// <returns>IBM XMS delivery mode.</returns>

+		public static IBM.XMS.DeliveryMode ToJMSDeliveryMode(

+			MsgDeliveryMode deliveryMode)

+		{

+			if(deliveryMode == MsgDeliveryMode.Persistent)

+			{

+				return IBM.XMS.DeliveryMode.Persistent;

+			}

+

+			if(deliveryMode == MsgDeliveryMode.NonPersistent)

+			{

+				return IBM.XMS.DeliveryMode.NonPersistent;

+			}

+

+			// Hard cast it to the enumeration.

+			return (IBM.XMS.DeliveryMode) deliveryMode;

+		}

+

+		#endregion

+

+		#region Enumerable adapter

+

+		private class EnumerableAdapter : IEnumerable

+		{

+			private readonly IEnumerator enumerator;

+			public EnumerableAdapter(IEnumerator _enumerator)

+			{

+				this.enumerator = _enumerator;

+			}

+

+			public IEnumerator GetEnumerator()

+			{

+				return this.enumerator;

+			}

+		}

+

+		public static IEnumerable ToEnumerable(IEnumerator enumerator)

+		{

+			return new EnumerableAdapter(enumerator);

+		}

+

+		#endregion

+	}

+}

diff --git a/src/main/csharp/Util/XMSEnum.cs b/src/main/csharp/Util/XMSEnum.cs
new file mode 100644
index 0000000..6a95cef
--- /dev/null
+++ b/src/main/csharp/Util/XMSEnum.cs
@@ -0,0 +1,1167 @@
+/*
+ * 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 IBM.XMS;
+
+namespace Apache.NMS.XMS.Util
+{
+
+#region Encoding (IBM JMS)*
+
+// http://www-01.ibm.com/support/knowledgecenter/SSFKSJ_8.0.0/com.ibm.mq.msc.doc/prp_jms_ibm_encoding.htm?lang=en
+/// <summary>
+/// How numerical data in the body of the message is represented when the XMS
+/// client forwards the message to its intended destination.
+/// </summary>
+public enum Encoding
+{
+	/// <summary>
+	/// Normal integer encoding.
+	/// </summary>
+	IntegerNormal = MQC.MQENC_INTEGER_NORMAL,
+
+	/// <summary>
+	/// Reversed integer encoding.
+	/// </summary>
+	IntegerReversed = MQC.MQENC_INTEGER_REVERSED,
+
+	/// <summary>
+	/// Normal packed decimal encoding.
+	/// </summary>
+	DecimalNormal = MQC.MQENC_DECIMAL_NORMAL,
+
+	/// <summary>
+	/// Reversed packed decimal encoding.
+	/// </summary>
+	DecimalReversed = MQC.MQENC_DECIMAL_REVERSED,
+
+	/// <summary>
+	/// Normal IEEE floating point encoding.
+	/// </summary>
+	FloatIEEENormal = MQC.MQENC_FLOAT_IEEE_NORMAL,
+
+	/// <summary>
+	/// Reversed IEEE floating point encoding.
+	/// </summary>
+	FloatIEEEReversed = MQC.MQENC_FLOAT_IEEE_REVERSED,
+
+	/// <summary>
+	/// z/OS® architecture floating point encoding.
+	/// </summary>
+	FloatS390 = MQC.MQENC_FLOAT_S390,
+
+	/// <summary>
+	/// Native machine encoding.
+	/// </summary>
+	Native = MQC.MQENC_NATIVE
+}
+
+#endregion
+
+#region Message Type (IBM JMS)
+
+// http://www-01.ibm.com/support/knowledgecenter/SSFKSJ_8.0.0/com.ibm.mq.msc.doc/prp_jms_ibm_msgtype.htm?lang=en
+/// <summary>
+/// Message type.
+/// </summary>
+public enum MessageType
+{
+	/// <summary>
+	/// The message is one that does not require a reply.
+	/// </summary>
+	Datagram = MQC.MQMT_DATAGRAM,
+
+	/// <summary>
+	/// The message is one that requires a reply.
+	/// </summary>
+	Request = MQC.MQMT_REQUEST,
+
+	/// <summary>
+	/// The message is a reply message.
+	/// </summary>
+	Reply = MQC.MQMT_REPLY,
+
+	/// <summary>
+	/// The message is a report message.
+	/// </summary>
+	Report = MQC.MQMT_REPORT
+}
+
+#endregion
+
+#region Report Confirm On Arrival (IBM JMS)
+
+// http://www-01.ibm.com/support/knowledgecenter/SSFKSJ_8.0.0/com.ibm.mq.msc.doc/prp_jms_ibm_rep_coa.htm?lang=en
+/// <summary>
+/// Request 'confirm on arrival' report messages, specifying how much
+/// application data from the original message must be included in a
+/// report message.
+/// </summary>
+public enum ReportConfirmOnArrival
+{
+	/// <summary>
+	/// Request 'confirm on arrival' report messages, with no application
+	/// data from the original message included in a report message.
+	/// </summary>
+	NoData = MQC.MQRO_COA,
+
+	/// <summary>
+	/// Request 'confirm on arrival' report messages, with the first 100 bytes
+	/// of application data from the original message included in a report
+	/// message.
+	/// </summary>
+	PartialData = MQC.MQRO_COA_WITH_DATA,
+
+	/// <summary>
+	/// Request 'confirm on arrival' report messages, with all the application
+	/// data from the original message included in a report message.
+	/// </summary>
+	FullData = MQC.MQRO_COA_WITH_FULL_DATA
+}
+
+#endregion
+
+#region Report Confirm On Delivery (IBM JMS)
+
+// http://www-01.ibm.com/support/knowledgecenter/SSFKSJ_8.0.0/com.ibm.mq.msc.doc/prp_jms_ibm_rep_cod.htm?lang=en
+/// <summary>
+/// Request 'confirm on delivery' report messages, specifying how much
+/// application data from the original message must be included in a
+/// report message.
+/// </summary>
+public enum ReportConfirmOnDelivery
+{
+	/// <summary>
+	/// Request 'confirm on delivery' report messages, with no application
+	/// data from the original message included in a report message.
+	/// </summary>
+	NoData = MQC.MQRO_COD,
+
+	/// <summary>
+	/// Request 'confirm on delivery' report messages, with the first 100 bytes
+	/// of application data from the original message included in a report
+	/// message.
+	/// </summary>
+	PartialData = MQC.MQRO_COD_WITH_DATA,
+
+	/// <summary>
+	/// Request 'confirm on delivery' report messages, with all the application
+	/// data from the original message included in a report message.
+	/// </summary>
+	FullData = MQC.MQRO_COD_WITH_FULL_DATA
+}
+
+#endregion
+
+#region Report Exception (IBM JMS)
+
+// http://www-01.ibm.com/support/knowledgecenter/SSFKSJ_8.0.0/com.ibm.mq.msc.doc/prp_jms_ibm_rep_excpt.htm?lang=en
+/// <summary>
+/// Request exception report messages, specifying how much application data
+/// from the original message must be included in a report message.
+/// </summary>
+public enum ReportExceptions
+{
+	/// <summary>
+	/// Request exception report messages, with no application data from the
+	/// original message included in a report message.
+	/// </summary>
+	NoData = MQC.MQRO_COD,
+
+	/// <summary>
+	/// Request exception report messages, with the first 100 bytes of
+	/// application data from the original message included in a report
+	/// message.
+	/// </summary>
+	PartialData = MQC.MQRO_COD_WITH_DATA,
+
+	/// <summary>
+	/// Request exception report messages, with all the application data from
+	/// the original message included in a report message.
+	/// </summary>
+	FullData = MQC.MQRO_COD_WITH_FULL_DATA
+}
+
+#endregion
+
+#region Report Expiration (IBM JMS)
+
+// http://www-01.ibm.com/support/knowledgecenter/SSFKSJ_8.0.0/com.ibm.mq.msc.doc/prp_jms_ibm_rep_exprn.htm?lang=en
+/// <summary>
+/// Request expiration report messages, specifying how much application data
+/// from the original message must be included in a report message.
+/// </summary>
+public enum ReportExpiration
+{
+	/// <summary>
+	/// Request expiration report messages, with no application data from the
+	/// original message included in a report message.
+	/// </summary>
+	NoData = MQC.MQRO_EXPIRATION,
+
+	/// <summary>
+	/// Request expiration report messages, with the first 100 bytes of
+	/// application data from the original message included in a report
+	/// message.
+	/// </summary>
+	PartialData = MQC.MQRO_EXPIRATION_WITH_DATA,
+
+	/// <summary>
+	/// Request expiration report messages, with all the application data from
+	/// the original message included in a report message.
+	/// </summary>
+	FullData = MQC.MQRO_EXPIRATION_WITH_FULL_DATA
+}
+
+#endregion
+
+#region Report Correlation Id (IBM JMS)
+
+// http://www-01.ibm.com/support/knowledgecenter/SSFKSJ_8.0.0/com.ibm.mq.msc.doc/prp_jms_ibm_rep_pcid.htm?lang=en
+/// <summary>
+/// Request that the correlation identifier of any report or reply message
+/// is the same as the correlation identifier of the original message.
+/// </summary>
+public enum ReportCorrelationId
+{
+	/// <summary>
+	/// Request that the correlation identifier of any report or reply message
+	/// is the same as the correlation identifier of the original message.
+	/// </summary>
+	OriginalCorrelationId = MQC.MQRO_PASS_CORREL_ID,
+
+	/// <summary>
+	/// Request that the correlation identifier of any report or reply message
+	/// is the same as the message identifier of the original message.
+	/// </summary>
+	OriginalMessageId = MQC.MQRO_COPY_MSG_ID_TO_CORREL_ID
+}
+
+#endregion
+
+#region Report Message Id (IBM JMS)
+
+// http://www-01.ibm.com/support/knowledgecenter/SSFKSJ_8.0.0/com.ibm.mq.msc.doc/prp_jms_ibm_rep_pmid.htm?lang=en
+/// <summary>
+/// Request that the message identifier of any report or reply message is the
+/// same as the message identifier of the original message.
+/// </summary>
+public enum ReportMessageId
+{
+	/// <summary>
+	/// Request that the message identifier of any report or reply message is the same as the message identifier of the original message.
+	/// </summary>
+	OriginalMessageId = MQC.MQRO_PASS_MSG_ID,
+
+	/// <summary>
+	/// Request that a new message identifier is generated for each report or
+	/// reply message.
+	/// </summary>
+	NewMessageId = MQC.MQRO_NEW_MSG_ID
+}
+
+#endregion
+
+#region Asynchronous Exceptions
+
+// http://www-01.ibm.com/support/knowledgecenter/SSFKSJ_8.0.0/com.ibm.mq.msc.doc/xmsc_async_exceptions.htm?lang=en
+/// <summary>
+/// whether XMS informs an ExceptionListener only when a connection is broken,
+/// or when any exception occurs asynchronously to an XMS API call.
+/// </summary>
+public enum AsynchronousExceptions
+{
+	/// <summary>
+	/// Any exception detected asynchronously, outside the scope of a
+	/// synchronous API call, and all connection broken exceptions are sent
+	/// to the <c>ExceptionListener</c>.
+	/// </summary>
+	All = XMSC.ASYNC_EXCEPTIONS_ALL,
+
+	/// <summary>
+	/// Only exceptions indicating a broken connection are sent to the
+	/// <c>ExceptionListener</c>. Any other exceptions occurring during
+	/// asynchronous processing are not reported to the
+	/// <c>ExceptionListener</c>, and hence the application is not informed
+	/// of these exceptions.
+	/// </summary>
+	ConnectionBroken = XMSC.ASYNC_EXCEPTIONS_CONNECTIONBROKEN
+}
+
+#endregion
+
+#region Connection Type
+
+// http://www-01.ibm.com/support/knowledgecenter/SSFKSJ_8.0.0/com.ibm.mq.msc.doc/prx_connection_type.htm?lang=en
+/// <summary>
+/// The type of messaging server to which an application connects.
+/// </summary>
+public enum ConnectionType
+{
+	/// <summary>
+	/// A real-time connection to a broker.
+	/// </summary>
+	RTT = XMSC.CT_RTT,
+
+	/// <summary>
+	/// A connection to a WebSphere® MQ queue manager.
+	/// </summary>
+	WMQ = XMSC.CT_WMQ,
+
+	/// <summary>
+	/// A connection to a WebSphere service integration bus.
+	/// </summary>
+	WPM = XMSC.CT_WPM
+}
+
+#endregion
+
+#region Delivery Mode
+
+/// <summary>
+/// The delivery mode of messages sent to the destination.
+/// </summary>
+public enum DeliveryMode
+{
+	/// <summary>
+	/// A message sent to the destination is nonpersistent. The default
+	/// delivery mode of the message producer, or any delivery mode specified
+	/// on the Send call, is ignored. If the destination is a WebSphere MQ
+	/// queue, the value of the queue attribute <c>DefPersistence</c> is also
+	/// ignored.
+	/// </summary>
+	NotPersistent = XMSC.DELIVERY_NOT_PERSISTENT,
+
+	/// <summary>
+	/// A message sent to the destination is persistent. The default
+	/// delivery mode of the message producer, or any delivery mode specified
+	/// on the Send call, is ignored. If the destination is a WebSphere MQ
+	/// queue, the value of the queue attribute <c>DefPersistence</c> is also
+	/// ignored.
+	/// </summary>
+	Persistent = XMSC.DELIVERY_PERSISTENT,
+
+	/// <summary>
+	/// A message sent to the destination has the delivery mode specified on
+	/// the Send call. If the Send call specifies no delivery mode, the default
+	/// delivery mode of the message producer is used instead. If the
+	/// destination is a WebSphere MQ queue, the value of the queue attribute
+	/// <c>DefPersistence</c> is ignored.
+	/// </summary>
+	AsApplication = XMSC.DELIVERY_AS_APP,
+
+	/// <summary>
+	/// If the destination is a WebSphere MQ queue, a message put on the queue
+	/// has the delivery mode specified by the value of the queue attribute
+	/// <c>DefPersistence</c>. The default delivery mode of the message
+	/// producer, or any delivery mode specified on the Send call, is ignored.
+	/// </summary>
+	AsDestination = XMSC.DELIVERY_AS_DEST
+}
+
+#endregion
+
+#region Priority
+
+// http://www-01.ibm.com/support/knowledgecenter/SSFKSJ_8.0.0/com.ibm.mq.msc.doc/prx_priority.htm?lang=en
+/// <summary>
+/// The priority of messages sent to the destination.
+/// </summary>
+public enum Priority
+{
+	/// <summary>
+	/// Lowest message priority.
+	/// </summary>
+	Lowest = 0,
+
+	/// <summary>
+	/// Between Low and Lowest message priority.
+	/// </summary>
+	VeryLow = 1,
+
+	/// <summary>
+	/// Low message priority.
+	/// </summary>
+	Low = 2,
+
+	/// <summary>
+	/// Normal message priority.
+	/// </summary>
+	Normal = 5,
+
+	/// <summary>
+	/// Between High and Normal message priority.
+	/// </summary>
+	AboveNormal = 6,
+
+	/// <summary>
+	/// High message priority.
+	/// </summary>
+	High = 7,
+
+	/// <summary>
+	/// Between Highest and High message priority.
+	/// </summary>
+	VeryHigh = 8,
+
+	/// <summary>
+	/// Highest message priority.
+	/// </summary>
+	Highest = 9,
+
+	/// <summary>
+	/// A message sent to the destination has the priority specified on the
+	/// Send call. If the Send call specifies no priority, the default
+	/// priority of the message producer is used instead. If the destination
+	/// is a WebSphere MQ queue, the value of the queue attribute
+	/// <c>DefPriority</c> is ignored.
+	/// </summary>
+	AsApplication = XMSC.PRIORITY_AS_APP,
+
+	/// <summary>
+	/// If the destination is a WebSphere MQ queue, a message put on the
+	/// queue has the priority specified by the value of the queue attribute
+	/// <c>DefPriority</c>. The default priority of the message producer,
+	/// or any priority specified on the Send call, is ignored.
+	/// </summary>
+	AsDestination = XMSC.PRIORITY_AS_DEST
+}
+
+#endregion
+
+#region Connection Protocol (RTT)
+
+// http://www-01.ibm.com/support/knowledgecenter/SSFKSJ_8.0.0/com.ibm.mq.msc.doc/prx_rtt_conn_prot.htm?lang=en
+/// <summary>
+/// The communications protocol used for a real-time connection to a broker.
+/// </summary>
+public enum RTTConnectionProtocol
+{
+	/// <summary>
+	/// Real-time connection to a broker over TCP/IP.
+	/// <c>ConnectionFactory</c> object.
+	/// </summary>
+	TCP = XMSC.RTT_CP_TCP
+}
+
+#endregion
+
+#region Multicast (RTT)
+
+// http://www-01.ibm.com/support/knowledgecenter/SSFKSJ_8.0.0/com.ibm.mq.msc.doc/prx_rtt_multicast.htm?lang=en
+/// <summary>
+/// The multicast setting for a connection factory or destination. Only a
+/// destination that is a topic can have this property.
+/// An application uses this property to enable multicast in association with
+/// a real-time connection to a broker and, if multicast is enabled, to
+/// specify the precise way in which multicast is used to deliver messages
+/// from the broker to a message consumer. The property has no effect on how
+/// a message producer sends messages to the broker.
+/// </summary>
+public enum Multicast
+{
+	/// <summary>
+	/// Messages are not delivered to a message consumer using WebSphere® MQ
+	/// Multicast Transport. This value is the default value for a
+	/// <c>ConnectionFactory</c> object.
+	/// </summary>
+	Disabled = XMSC.RTT_MULTICAST_DISABLED,
+
+	/// <summary>
+	/// Messages are delivered to a message consumer according to the multicast
+	/// setting for the connection factory associated with the message consumer.
+	/// The multicast setting for the connection factory is noted at the time
+	/// that the connection is created. This value is valid only for a
+	/// <c>Destination</c> object, and is the default value for a
+	/// <c>Destination</c> object.
+	/// </summary>
+	AsConnectionFactory = XMSC.RTT_MULTICAST_ASCF,
+
+	/// <summary>
+	/// If the topic is configured for multicast in the broker, messages are
+	/// delivered to a message consumer using WebSphere MQ Multicast Transport.
+	/// A reliable quality of service is used if the topic is configured for
+	/// reliable multicast.
+	/// </summary>
+	Enabled = XMSC.RTT_MULTICAST_ENABLED,
+
+	/// <summary>
+	/// If the topic is configured for reliable multicast in the broker,
+	/// messages are delivered to a message consumer using WebSphere MQ
+	/// Multicast Transport with a reliable quality of service. If the topic
+	/// is not configured for reliable multicast, you cannot create a message
+	/// consumer for the topic.
+	/// </summary>
+	Reliable = XMSC.RTT_MULTICAST_RELIABLE,
+
+	/// <summary>
+	/// If the topic is configured for multicast in the broker, messages are
+	/// delivered to a message consumer using WebSphere MQ Multicast Transport.
+	/// A reliable quality of service is not used even if the topic is
+	/// configured for reliable multicast.
+	/// </summary>
+	NotReliable = XMSC.RTT_MULTICAST_NOT_RELIABLE
+}
+
+#endregion
+
+#region Broker Version (WMQ)
+
+// http://www-01.ibm.com/support/knowledgecenter/SSFKSJ_8.0.0/com.ibm.mq.msc.doc/prx_wmq_brkr_version.htm?lang=en
+/// <summary>
+/// The type of broker used by the application for a connection or for the
+/// destination. Only a destination that is a topic can have this property.
+/// </summary>
+public enum BrokerVersion
+{
+	/// <summary>
+	/// The application is using a WebSphere® MQ Publish/Subscribe broker.
+	/// </summary>
+	Version1 = XMSC.WMQ_BROKER_V1,
+
+	/// <summary>
+	/// The application is using a broker of IBM® Integration Bus.
+	/// </summary>
+	Version2 = XMSC.WMQ_BROKER_V2,
+
+	/// <summary>
+	/// After the broker is migrated, set this property so that RFH2 headers
+	/// are no longer used. After migration, this property is no longer
+	/// relevant.
+	/// </summary>
+	Unspecified = XMSC.WMQ_BROKER_UNSPECIFIED
+}
+
+#endregion
+
+#region Reconnect Options (WMQ)
+
+// http://www-01.ibm.com/support/knowledgecenter/SSFKSJ_8.0.0/com.ibm.mq.msc.doc/prx_rtt_client_reconnect_options.htm?lang=en
+/// <summary>
+/// Client reconnect options for new connections created by a factory.
+/// </summary>
+public enum ReconnectOptions
+{
+	/// <summary>
+	/// Use the value specified in the <c>mqclient.ini</c> file. Set the value
+	/// by using the DefRecon property within the Channels stanza.
+	/// </summary>
+	AsDefault = XMSC.WMQ_CLIENT_RECONNECT_AS_DEF,
+
+	/// <summary>
+	/// Reconnect to any of the queue managers specified in the connection name
+	/// list.
+	/// </summary>
+	AnyQueueManager = XMSC.WMQ_CLIENT_RECONNECT,
+
+	/// <summary>
+	/// Reconnects to the same queue manager that it is originally connected to.
+	/// It returns <c>MQRC.RECONNECT_QMID_MISMATCH</c> if the queue manager it
+	/// tries to connect to (specified in the connection name list) has a
+	/// different QMID to the queue manager originally connected to.
+	/// </summary>
+	SameQueueManager = XMSC.WMQ_CLIENT_RECONNECT_Q_MGR,
+
+	/// <summary>
+	/// Reconnection is disabled.
+	/// </summary>
+	Disabled = XMSC.WMQ_CLIENT_RECONNECT_DISABLED
+}
+
+#endregion
+
+#region Connection Mode (WMQ)
+
+// http://www-01.ibm.com/support/knowledgecenter/SSFKSJ_8.0.0/com.ibm.mq.msc.doc/prx_wmq_conn_mode.htm?lang=en
+/// <summary>
+/// The mode by which an application connects to a queue manager.
+/// </summary>
+public enum ConnectionMode
+{
+	/// <summary>
+	/// A connection to a queue manager in bindings mode, for optimal performance. This value is the default value for C/C++.
+	/// </summary>
+	Bindings = XMSC.WMQ_CM_BINDINGS,
+
+	/// <summary>
+	/// A connection to a queue manager in client mode, to ensure a fully managed stack. This value is the default value for .NET.
+	/// </summary>
+	Client = XMSC.WMQ_CM_CLIENT,
+
+	/// <summary>
+	/// A connection to a queue manager which forces an unmanaged client stack.
+	/// </summary>
+	ClientUnmanaged = XMSC.WMQ_CM_CLIENT_UNMANAGED
+}
+
+#endregion
+
+#region Encoding (WMQ)
+
+// http://www-01.ibm.com/support/knowledgecenter/SSFKSJ_8.0.0/com.ibm.mq.msc.doc/prx_wmq_encoding.htm?lang=en
+// cf. "Encoding (IBM JMS)"
+
+#endregion
+
+#region Fail If Quiesce (WMQ)
+
+// http://www-01.ibm.com/support/knowledgecenter/SSFKSJ_8.0.0/com.ibm.mq.msc.doc/prx_wmq_fail_if_quiesce.htm?lang=en
+/// <summary>
+/// Whether calls to certain methods fail if the queue manager to which the
+/// application is connected is in a quiescing state.
+/// </summary>
+public enum FailIfQuiesce
+{
+	/// <summary>
+	/// Calls to certain methods fail if the queue manager is in a quiescing
+	/// state. When the application detects that the queue manager is
+	/// quiescing, the application can complete its immediate task and close
+	/// the connection, allowing the queue manager to stop.
+	/// </summary>
+	Yes = XMSC.WMQ_FIQ_YES,
+
+	/// <summary>
+	/// No method calls fail because the queue manager is in a quiescing
+	/// state. If you specify this value, the application cannot detect that
+	/// the queue manager is quiescing. The application might continue to
+	/// perform operations against the queue manager and therefore prevent
+	/// the queue manager from stopping.
+	/// </summary>
+	No = XMSC.WMQ_FIQ_NO
+}
+
+#endregion
+
+#region Message Body (WMQ)
+
+// http://www-01.ibm.com/support/knowledgecenter/SSFKSJ_8.0.0/com.ibm.mq.msc.doc/xmsc_wmq_message_body.htm?lang=en
+/// <summary>
+/// Whether an XMS application processes the <c>MQRFH2</c> of a WebSphere®
+/// MQ message as part of the message payload (that is, as part of the
+/// message body).
+/// </summary>
+public enum MessageBody
+{
+	/// <summary>
+	/// Receive: The inbound XMS message type and body are determined by the
+	/// contents of the <c>MQRFH2</c> (if present) or the <c>MQMD</c> (if there
+	/// is no <c>MQRFH2</c>) in the received WebSphere MQ message.
+	/// Send: The outbound XMS message body contains a prepended and
+	/// auto-generated <c>MQRFH2</c> header based on XMS Message properties and
+	/// header fields.
+	/// </summary>
+	JMS = XMSC.WMQ_MESSAGE_BODY_JMS,
+
+	/// <summary>
+	/// Receive: The inbound XMS message type is always <c>ByteMessage</c>,
+	/// irrespective of the contents of received WebSphere MQ message or the
+	/// format field of the received <c>MQMD</c>. The XMS message body is the
+	/// unaltered message data returned by the underlying messaging provider
+	/// API call. The character set and encoding of the data in the message
+	/// body is determined by the <c>CodedCharSetId</c> and <c>Encoding</c>
+	/// fields of the <c>MQMD</c>. The format of the data in the message body
+	/// is determined by the <c>Format</c> field of the <c>MQMD</c>.
+	/// Send: The outbound XMS message body contains the application payload
+	/// as-is; and no auto-generated WebSphere MQ header is added to the body.
+	/// </summary>
+	MQ = XMSC.WMQ_MESSAGE_BODY_MQ,
+
+	/// <summary>
+	/// Receive: The XMS client determines a suitable value for this property.
+	/// On receive path, this value is the <c>WMQ_MESSAGE_BODY_JMS</c> property
+	/// value.
+	/// Send: The XMS client determines a suitable value for this property. On
+	/// send path, this value is the <c>XMSC_WMQ_TARGET_CLIENT</c> property
+	/// value.
+	/// </summary>
+	Unspecified = XMSC.WMQ_MESSAGE_BODY_UNSPECIFIED
+}
+
+#endregion
+
+#region Message Context (WMQ)
+
+// http://www-01.ibm.com/support/knowledgecenter/SSFKSJ_8.0.0/com.ibm.mq.msc.doc/xmsc_wmq_mqmd_message_context.htm?lang=en
+/// <summary>
+/// Determines what level of message context is to be set by the XMS
+/// application. The application must be running with appropriate context
+/// authority for this property to take effect.
+/// </summary>
+public enum MessageContext
+{
+	/// <summary>
+	/// For outbound messages, the <c>MQOPEN</c> API call and the <c>MQPMO</c>
+	/// structure specifies no explicit message context options.
+	/// </summary>
+	Default = XMSC.WMQ_MDCTX_DEFAULT,
+
+	/// <summary>
+	/// The <c>MQOPEN</c> API call specifies the message context option 
+	/// <c>MQOO_SET_IDENTITY_CONTEXT</c> and the <c>MQPMO</c> structure
+	/// specifies <c>MQPMO_SET_IDENTITY_CONTEXT</c>.
+	/// </summary>
+	SetIdentity = XMSC.WMQ_MDCTX_SET_IDENTITY_CONTEXT,
+
+	/// <summary>
+	/// The <c>MQOPEN</c> API call specifies the message context option
+	/// <c>MQOO_SET_ALL_CONTEXT</c> and the <c>MQPMO</c> structure
+	/// specifies <c>MQPMO_SET_ALL_CONTEXT</c>. 
+	/// </summary>
+	SetAll = XMSC.WMQ_MDCTX_SET_ALL_CONTEXT,
+}
+
+#endregion
+
+#region MQMD Read Enabled (WMQ)
+
+// http://www-01.ibm.com/support/knowledgecenter/SSFKSJ_8.0.0/com.ibm.mq.msc.doc/xmsc_wmq_mqmd_read_enabled.htm?lang=en
+/// <summary>
+/// Whether an XMS application can extract the values of MQMD fields or not.
+/// </summary>
+public enum MQMDReadEnabled
+{
+	/// <summary>
+	/// When sending messages, the <c>JMS_IBM_MQMD*</c> properties on a sent
+	/// message are not updated to reflect the updated field values in the
+	/// <c>MQMD</c>.
+	/// When receiving messages, none of the <c>JMS_IBM_MQMD*</c> properties
+	/// are available on a received message, even if some or all of them are
+	/// set by the sender.
+	/// </summary>
+	No = 0, //XMSC.WMQ_READ_ENABLED_NO,
+
+	/// <summary>
+	/// When sending messages, all of the <c>JMS_IBM_MQMD*</c> properties on
+	/// a sent message are updated to reflect the updated field values in the
+	/// <c>MQMD</c>, including those properties that the sender did not set
+	/// explicitly.
+	/// When receiving messages, all of the <c>JMS_IBM_MQMD*</c> properties
+	/// are available on a received message, including those properties that
+	/// the sender did not set explicitly. 
+	/// </summary>
+	Yes = 1 //XMSC.WMQ_READ_ENABLED_YES
+}
+
+#endregion
+
+#region MQMD Write Enabled (WMQ)
+
+// http://www-01.ibm.com/support/knowledgecenter/SSFKSJ_8.0.0/com.ibm.mq.msc.doc/xmsc_wmq_mqmd_write_enabled.htm?lang=en
+/// <summary>
+/// Whether an XMS application can write the values of MQMD fields or not.
+/// </summary>
+public enum MQMDWriteEnabled
+{
+	/// <summary>
+	/// All <c>JMS_IBM_MQMD*</c> properties are ignored and their values are
+	/// not copied into the underlying <c>MQMD</c> structure.
+	/// </summary>
+	No = 0, //XMSC.WMQ_WRITE_ENABLED_NO,
+
+	/// <summary>
+	/// <c>JMS_IBM_MQMD*</c> properties are processed. Their values are copied
+	/// into the underlying <c>MQMD</c> structure.
+	/// </summary>
+	Yes = 1 //XMSC.WMQ_WRITE_ENABLED_YES
+}
+
+#endregion
+
+#region Asynchronous Puts Allowed (WMQ)
+
+// http://www-01.ibm.com/support/knowledgecenter/SSFKSJ_8.0.0/com.ibm.mq.msc.doc/xmsc_wmq_put_async_allowed.htm?lang=en
+/// <summary>
+/// Whether message producers are allowed to use asynchronous puts to send
+/// messages to this destination.
+/// </summary>
+public enum AsynchronousPutsAllowed
+{
+	/// <summary>
+	/// Determine whether asynchronous puts are allowed by referring to the
+	/// queue or topic definition.
+	/// </summary>
+	AsDestination = XMSC.WMQ_PUT_ASYNC_ALLOWED_AS_DEST,
+
+	/// <summary>
+	/// Determine whether asynchronous puts are allowed by referring to the
+	/// queue definition.
+	/// </summary>
+	AsQueueDefinition = XMSC.WMQ_PUT_ASYNC_ALLOWED_AS_Q_DEF,
+
+	/// <summary>
+	/// Determine whether asynchronous puts are allowed by referring to the
+	/// topic definition.
+	/// </summary>
+	AsTopicDefinition = XMSC.WMQ_PUT_ASYNC_ALLOWED_AS_TOPIC_DEF,
+
+	/// <summary>
+	/// Asynchronous puts are not allowed.
+	/// </summary>
+	Disabled = XMSC.WMQ_PUT_ASYNC_ALLOWED_DISABLED,
+
+	/// <summary>
+	/// Asynchronous puts are allowed.
+	/// </summary>
+	Enabled = XMSC.WMQ_PUT_ASYNC_ALLOWED_ENABLED
+}
+
+#endregion
+
+#region Read Ahead Allowed (WMQ)
+
+// http://www-01.ibm.com/support/knowledgecenter/SSFKSJ_8.0.0/com.ibm.mq.msc.doc/xmsc_wmq_read_ahead_allowed.htm?lang=en
+/// <summary>
+/// Whether message consumers and queue browsers are allowed to use read ahead
+/// to get non-persistent, non-transactional messages from this destination
+/// into an internal buffer before receiving them.
+/// </summary>
+public enum ReadAheadAllowed
+{
+	/// <summary>
+	/// Determine whether read ahead is allowed by referring to the queue
+	/// definition.
+	/// </summary>
+	AsQueueDefinition = XMSC.WMQ_READ_AHEAD_ALLOWED_AS_Q_DEF,
+
+	/// <summary>
+	/// Determine whether read ahead is allowed by referring to the topic
+	/// definition.
+	/// </summary>
+	AsTopicDefinition = XMSC.WMQ_READ_AHEAD_ALLOWED_AS_TOPIC_DEF,
+
+	/// <summary>
+	/// Determine whether read ahead is allowed by referring to the queue
+	/// or topic definition.
+	/// </summary>
+	AsDestinationDefinition = XMSC.WMQ_READ_AHEAD_ALLOWED_AS_DEST,
+
+	/// <summary>
+	/// Read ahead is not allowed while consuming or browsing messages.
+	/// </summary>
+	Disabled = XMSC.WMQ_READ_AHEAD_ALLOWED_DISABLED,
+
+	/// <summary>
+	/// Read ahead is allowed.
+	/// </summary>
+	Enabled = XMSC.WMQ_READ_AHEAD_ALLOWED_ENABLED
+}
+
+#endregion
+
+#region Read Ahead Close Policy (WMQ)
+
+// http://www-01.ibm.com/support/knowledgecenter/SSFKSJ_8.0.0/com.ibm.mq.msc.doc/xmsc_wmq_read_ahead_close_policy.htm?lang=en
+/// <summary>
+/// This property determines, for messages being delivered to an asynchronous
+/// message listener, what happens to messages in the internal read ahead buffer
+/// when the message consumer is closed.
+/// </summary>
+public enum ReadAheadClosePolicy
+{
+	/// <summary>
+	/// Only the current message listener invocation completes before returning,
+	/// potentially leaving messages in the internal read ahead buffer, which
+	/// are then discarded.
+	/// </summary>
+	DeliverCurrent = XMSC.WMQ_READ_AHEAD_DELIVERCURRENT,
+
+	/// <summary>
+	/// All messages in the internal read ahead buffer are delivered to the
+	/// application message listener before returning. 
+	/// </summary>
+	DeliverAll = XMSC.WMQ_READ_AHEAD_DELIVERALL
+}
+
+#endregion
+
+#region Message Selection (WMQ)
+
+// http://www-01.ibm.com/support/knowledgecenter/SSFKSJ_8.0.0/com.ibm.mq.msc.doc/prx_wmq_mes_selection.htm?lang=en
+/// <summary>
+/// Determines whether message selection is done by the XMS client or by
+/// the broker.
+/// </summary>
+public enum MessageSelection
+{
+	/// <summary>
+	/// Message selection is done by the XMS client.
+	/// </summary>
+	Client = XMSC.WMQ_MSEL_CLIENT,
+
+	/// <summary>
+	/// Message selection is done by the broker.
+	/// </summary>
+	Broker = XMSC.WMQ_MSEL_BROKER
+}
+
+#endregion
+
+#region Receive Conversion (WMQ)
+
+// http://www-01.ibm.com/support/knowledgecenter/SSFKSJ_8.0.0/com.ibm.mq.msc.doc/xmsc_wmq_receive_conversion.htm?lang=en
+/// <summary>
+/// Whether data conversion is going to be performed by the queue manager.
+/// </summary>
+public enum ReceiveConversion
+{
+	/// <summary>
+	/// Perform data conversion on the XMS client only. Conversion is always
+	/// done using codepage 1208.
+	/// </summary>
+	Client = XMSC.WMQ_RECEIVE_CONVERSION_CLIENT_MSG,
+
+	/// <summary>
+	/// Perform data conversion on the queue manager before sending a message
+	/// to the XMS client. 
+	/// </summary>
+	QueueManager = XMSC.WMQ_RECEIVE_CONVERSION_QMGR
+}
+
+#endregion
+
+#region Share Socket Allowed (WMQ)
+
+// http://www-01.ibm.com/support/knowledgecenter/SSFKSJ_8.0.0/com.ibm.mq.msc.doc/xmsc_wmq_share_conv_allowed.htm?lang=en
+/// <summary>
+/// Whether a client connection can share its socket with other top-level XMS
+/// connections from the same process to the same queue manager, if the channel
+/// definitions match.
+/// </summary>
+public enum ShareSocketAllowed
+{
+	/// <summary>
+	/// Connections do not share a socket.
+	/// </summary>
+	False = XMSC.WMQ_SHARE_CONV_ALLOWED_NO,
+
+	/// <summary>
+	/// Connections share a socket.
+	/// </summary>
+	True = XMSC.WMQ_SHARE_CONV_ALLOWED_YES
+}
+
+#endregion
+
+#region Target Client (WMQ)
+
+// http://www-01.ibm.com/support/knowledgecenter/SSFKSJ_8.0.0/com.ibm.mq.msc.doc/prx_wmq_target_client.htm?lang=en
+/// <summary>
+/// Whether messages sent to the destination contain an <c>MQRFH2</c> header.
+/// </summary>
+public enum TargetClient
+{
+	/// <summary>
+	/// Messages sent to the destination contain an <c>MQRFH2</c> header.
+	/// Specify this value if the application is sending the messages to
+	/// another XMS application, a WebSphere® JMS application, or a native
+	/// WebSphere MQ application that is designed to handle an <c>MQRFH2</c>
+	/// header.
+	/// </summary>
+	JMS = XMSC.WMQ_TARGET_DEST_JMS,
+
+	/// <summary>
+	/// Messages sent to the destination do not contain an <c>MQRFH2</c>
+	/// header. Specify this value if the application is sending the messages
+	/// to a native WebSphere MQ application that is not designed to handle
+	/// an <c>MQRFH2</c> header.
+	/// </summary>
+	MQ = XMSC.WMQ_TARGET_DEST_MQ
+}
+
+#endregion
+
+#region Wildcard Format (WMQ)
+
+// http://www-01.ibm.com/support/knowledgecenter/SSFKSJ_8.0.0/com.ibm.mq.msc.doc/xmsc_wmq_wildcard_format.htm?lang=en
+/// <summary>
+/// This property determines which version of wildcard syntax is to be used.
+/// </summary>
+public enum WildcardFormat
+{
+	/// <summary>
+	/// Recognizes the topic level wildcards only i.e. '#' and '+' are treated
+	/// as wildcards.
+	/// </summary>
+	TopicOnly = XMSC.WMQ_WILDCARD_TOPIC_ONLY,
+
+	/// <summary>
+	/// Recognizes the character wildcards only i.e. '*' and '?' are treated
+	/// as wildcards.
+	/// </summary>
+	CharacterOnly = XMSC.WMQ_WILDCARD_CHAR_ONLY
+}
+
+#endregion
+
+#region Connection Protocol (WPM)
+
+// http://www-01.ibm.com/support/knowledgecenter/SSFKSJ_8.0.0/com.ibm.mq.msc.doc/prx_wpm_conn_prot.htm?lang=en
+/// <summary>
+/// The communications protocol used for the connection to the messaging
+/// engine.
+/// </summary>
+public enum WPMConnectionProtocol
+{
+	/// <summary>
+	/// The connection uses HTTP over TCP/IP.
+	/// </summary>
+	HTTP = XMSC.WPM_CP_HTTP,
+
+	/// <summary>
+	/// The connection uses TCP/IP.
+	/// </summary>
+	TCP = XMSC.WPM_CP_TCP
+}
+
+#endregion
+
+#region Connection Proximity (WPM)
+
+// http://www-01.ibm.com/support/knowledgecenter/SSFKSJ_8.0.0/com.ibm.mq.msc.doc/prx_wpm_conn_prox.htm?lang=en
+/// <summary>
+/// The connection proximity setting for the connection. This property
+/// determines how close the messaging engine that the application connects
+/// to must be to the bootstrap server.
+/// </summary>
+public enum ConnectionProximity
+{
+	/// <summary>
+	/// Bus.
+	/// </summary>
+	Bus,           // XMSC.WPM_CONNECTION_PROXIMITY_BUS     = "Bus"
+
+	/// <summary>
+	/// Cluster.
+	/// </summary>
+	Cluster,       // XMSC.WPM_CONNECTION_PROXIMITY_CLUSTER = "Cluster"
+
+	/// <summary>
+	/// Host.
+	/// </summary>
+	Host,          // XMSC.WPM_CONNECTION_PROXIMITY_HOST    = "Host"
+
+	/// <summary>
+	/// Server.
+	/// </summary>
+	Server         // XMSC.WPM_CONNECTION_PROXIMITY_SERVER  = "Server"
+}
+
+#endregion
+
+#region Mapping (WPM)
+
+// http://www-01.ibm.com/support/knowledgecenter/SSFKSJ_8.0.0/com.ibm.mq.msc.doc/prx_wpm_non_pers_m.htm?lang=en
+// http://www-01.ibm.com/support/knowledgecenter/SSFKSJ_8.0.0/com.ibm.mq.msc.doc/prx_wpm_pers_m.htm?lang=en
+/// <summary>
+/// The reliability level of messages that are sent using the connection.
+/// </summary>
+public enum Mapping
+{
+	/// <summary>
+	/// Determined by the default reliability level specified for the queue
+	/// or topic space in the service integration bus.
+	/// </summary>
+	AsDestination = XMSC.WPM_MAPPING_AS_DESTINATION,
+
+	/// <summary>
+	/// Best effort nonpersistent.
+	/// </summary>
+	BestEffortNonPersistent = XMSC.WPM_MAPPING_BEST_EFFORT_NON_PERSISTENT,
+
+	/// <summary>
+	/// Express nonpersistent.
+	/// </summary>
+	ExpressNonPersistent = XMSC.WPM_MAPPING_EXPRESS_NON_PERSISTENT,
+
+	/// <summary>
+	/// Reliable nonpersistent.
+	/// </summary>
+	ReliableNonPersistent = XMSC.WPM_MAPPING_RELIABLE_NON_PERSISTENT,
+
+	/// <summary>
+	/// Reliable persistent.
+	/// </summary>
+	ReliablePersistent = XMSC.WPM_MAPPING_RELIABLE_PERSISTENT,
+
+	/// <summary>
+	/// Assured persistent.
+	/// </summary>
+	AssuredPersistent = XMSC.WPM_MAPPING_ASSURED_PERSISTENT
+}
+
+#endregion
+
+#region Target Significance (WPM)
+
+// http://www-01.ibm.com/support/knowledgecenter/SSFKSJ_8.0.0/com.ibm.mq.msc.doc/prx_wpm_target_signf.htm?lang=en
+/// <summary>
+/// The significance of the target group of messaging engines.
+/// </summary>
+public enum TargetSignificance
+{
+	/// <summary>
+	/// A messaging engine in the target group is selected if one is available.
+	/// Otherwise, a messaging engine outside the target group is selected,
+	/// provided it is in the same service integration bus.
+	/// </summary>
+	Preferred, // XMSC.WPM_TARGET_SIGNIFICANCE_PREFERRED = "Preferred"
+
+	/// <summary>
+	/// The selected messaging engine must be in the target group. If a
+	/// messaging engine in the target group is not available, the connection
+	/// process fails.
+	/// </summary>
+	Required   // XMSC.WPM_TARGET_SIGNIFICANCE_REQUIRED  = "Required"
+}
+
+#endregion
+
+#region Target Type (WPM)
+
+// http://www-01.ibm.com/support/knowledgecenter/SSFKSJ_8.0.0/com.ibm.mq.msc.doc/prx_wpm_target_type.htm?lang=en
+/// <summary>
+/// The type of the target group of messaging engines. This property
+/// determines the nature of the target group identified by the
+/// <c>XMSC_WPM_TARGET_GROUP</c> property.
+/// </summary>
+public enum TargetType
+{
+	/// <summary>
+	/// The name of the target group is the name of a bus member. The target
+	/// group is all the messaging engines in the bus member.
+	/// </summary>
+	BusMember,      // XMSC.WPM_TARGET_TYPE_BUSMEMBER = "BusMember"
+
+	/// <summary>
+	/// The name of the target group is the name of a user-defined group of
+	/// messaging engines. The target group is all the messaging engines that
+	/// are registered with the user-defined group.
+	/// </summary>
+	Custom,         // XMSC.WPM_TARGET_TYPE_CUSTOM = "Custom"
+
+	/// <summary>
+	/// The name of the target group is the name of a messaging engine. The
+	/// target group is the specified messaging engine.
+	/// </summary>
+	MessagingEngine // XMSC.WPM_TARGET_TYPE_ME = "ME"
+}
+
+#endregion
+
+}
\ No newline at end of file
diff --git a/src/main/csharp/_TODO_.txt b/src/main/csharp/_TODO_.txt
new file mode 100644
index 0000000..d14384c
--- /dev/null
+++ b/src/main/csharp/_TODO_.txt
@@ -0,0 +1,29 @@
+ ~ BytesMessage.cs				// Ajouter commentaires

+ X Connection.cs

+ X ConnectionFactory.cs

+ X ConnectionMetaData.cs

+ X Destination.cs

+ X InitialContext.cs

+ X MapMessage.cs

+ X Message.cs

+ ~ MessageConsumer.cs			// Ajouter commentaires

+ ~ MessageProducer.cs			// Ajouter commentaires

+ ~ MessageProperties.cs			// Ajouter commentaires

+ X ObjectMessage.cs

+ X Queue.cs

+ ~ QueueBrowser.cs				// Ajouter commentaires

+ ~ Session.cs					// Ajouter commentaires

+ X StreamMessage.cs

+ X TemporaryQueue.cs

+ X TemporaryTopic.cs

+ X TextMessage.cs

+ X Topic.cs

+ ? Util\Dispatcher.cs

+ X Util\ExceptionUtil.cs

+ X Util\IntrospectionSupport.cs

+ X Util\UriAttributeAttribute.cs

+ X Util\XMSConvert.cs

+ X Util\XMSEnum.cs

+

+

+Temporary Queue / Topic
\ No newline at end of file
diff --git a/src/main/ndoc/NamespaceSummary.xml b/src/main/ndoc/NamespaceSummary.xml
new file mode 100644
index 0000000..e4aa15e
--- /dev/null
+++ b/src/main/ndoc/NamespaceSummary.xml
@@ -0,0 +1,21 @@
+<!--

+    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.

+-->

+<namespaces>

+    <namespace name="XMS">

+        The <b>XMS</b> namespace defines the IBM XMS provider API for the .Net Message System (NMS) API, which is an interface to messaging systems rather like JMS is for Java.

+    </namespace>

+</namespaces>

diff --git a/src/main/sandcastle/feedback_content.xml b/src/main/sandcastle/feedback_content.xml
new file mode 100644
index 0000000..ee30a12
--- /dev/null
+++ b/src/main/sandcastle/feedback_content.xml
@@ -0,0 +1,32 @@
+<content xml:space="preserve">

+

+  <item id="fb_alias">activemq.docs@apache.org</item>

+  <item id="fb_product"></item>

+  <item id="fb_deliverable"></item>

+

+  <item id="fb_subject">Customer%20Feedback</item>

+  <item id="fb_body">%0\dThank%20you%20for%20your%20feedback.%20The%20developer%20writing%20teams%20use%20your%20feedback%20to%20improve%20documentation.%20While%20we%20are%20reviewing%20your%20feedback,%20we%20may%20send%20you%20e-mail%20to%20ask%20for%20clarification%20or%20feedback%20on%20a%20solution.%20We%20do%20not%20use%20your%20e-mail%20address%20for%20any%20other%20purpose.%0\d</item>

+ 

+   <item id="fb_headerFeedBack">Send Feedback</item>

+  

+

+   <!-- feedback values for sandcastle scenario -->

+

+   <item id="feedback_alias"></item>

+   <item id="feedback_product"></item>

+   <item id="feedback_deliverable"></item>

+   <item id="feedback_fileVersion"></item>

+   <item id="feedback_topicVersion"></item>

+   <item id="feedback_body"></item>

+   <item id="feedback_subject"></item>

+

+   <item id="fb_Introduction">We value your feedback. To rate this topic and send feedback about this topic to the documentation team, click a rating, and then click <b>Send Feedback</b>. For assistance with support issues, refer to the technical support information included with the product.</item>

+

+   <item id="fb_Send">Send Feedback</item>

+   <item id="fb_Poor">Poor</item>

+   <item id="fb_Excellent">Outstanding</item>

+   <item id="fb_EnterFeedbackText">To e-mail your feedback, click here:</item>

+   <item id="fb_Title">Documentation Feedback</item>

+   <item id="fb_altIcon">Display feedback instructions at the bottom of the page.</item>

+

+</content>
\ No newline at end of file
diff --git a/src/test/csharp/AsyncConsumeTest.cs b/src/test/csharp/AsyncConsumeTest.cs
new file mode 100644
index 0000000..c414927
--- /dev/null
+++ b/src/test/csharp/AsyncConsumeTest.cs
@@ -0,0 +1,228 @@
+/*

+ * 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.Threading;

+using NUnit.Framework;

+

+namespace Apache.NMS.Test

+{

+	//[TestFixture]

+	public class AsyncConsumeTest : NMSTest

+	{

+		protected string RESPONSE_CLIENT_ID;

+		protected AutoResetEvent semaphore;

+		protected bool received;

+		protected IMessage receivedMsg;

+

+		public AsyncConsumeTest(NMSTestSupport testSupport)

+			: base(testSupport)

+		{

+		}

+

+		//[SetUp]

+		public override void SetUp()

+		{

+			base.SetUp();

+			semaphore = new AutoResetEvent(false);

+			received = false;

+			receivedMsg = null;

+

+			RESPONSE_CLIENT_ID = GetTestClientId() + ":RESPONSE";

+		}

+

+		//[TearDown]

+		public override void TearDown()

+		{

+			receivedMsg = null;

+			base.TearDown();

+		}

+

+		//[Test]

+		public virtual void TestAsynchronousConsume(

+			//[Values(MsgDeliveryMode.Persistent, MsgDeliveryMode.NonPersistent)]

+			MsgDeliveryMode deliveryMode, string testQueueRef)

+		{

+			// IBM XMS doesn't support both synchronous and asynchronous operations

+			// in the same session. Needs 2 separate sessions.

+			using(IConnection connection = CreateConnectionAndStart(GetTestClientId()))

+			using(ISession producerSession = connection.CreateSession(AcknowledgementMode.AutoAcknowledge))

+			using(ISession consumerSession = connection.CreateSession(AcknowledgementMode.AutoAcknowledge))

+			using(IDestination producerDestination = GetClearDestination(producerSession, DestinationType.Queue, testQueueRef))

+			using(IDestination consumerDestination = GetDestination(consumerSession, DestinationType.Queue, testQueueRef))

+			using(IMessageConsumer consumer = consumerSession.CreateConsumer(consumerDestination))

+			using(IMessageProducer producer = producerSession.CreateProducer(producerDestination))

+			{

+				producer.DeliveryMode = deliveryMode;

+				consumer.Listener += new MessageListener(OnMessage);

+

+				IMessage request = producerSession.CreateMessage();

+				request.NMSCorrelationID = "AsyncConsume";

+				request.NMSType = "Test";

+				producer.Send(request);

+

+				WaitForMessageToArrive();

+				Assert.AreEqual(request.NMSCorrelationID, receivedMsg.NMSCorrelationID, "Invalid correlation ID.");

+			}

+		}

+

+		//[Test]

+		public virtual void TestCreateConsumerAfterSend(

+			//[Values(MsgDeliveryMode.Persistent, MsgDeliveryMode.NonPersistent)]

+			MsgDeliveryMode deliveryMode, string testQueueRef)

+		{

+			using(IConnection connection = CreateConnectionAndStart(GetTestClientId()))

+			using(ISession producerSession = connection.CreateSession(AcknowledgementMode.AutoAcknowledge))

+			using(ISession consumerSession = connection.CreateSession(AcknowledgementMode.AutoAcknowledge))

+			using(IDestination producerDestination = GetClearDestination(producerSession, DestinationType.Queue, testQueueRef))

+			using(IDestination consumerDestination = GetDestination(consumerSession, DestinationType.Queue, testQueueRef))

+			{

+				string correlationId = "AsyncConsumeAfterSend";

+

+				using(IMessageProducer producer = producerSession.CreateProducer(producerDestination))

+				{

+					producer.DeliveryMode = deliveryMode;

+					IMessage request = producerSession.CreateMessage();

+					request.NMSCorrelationID = correlationId;

+					request.NMSType = "Test";

+					producer.Send(request);

+				}

+

+				using(IMessageConsumer consumer = consumerSession.CreateConsumer(consumerDestination))

+				{

+					consumer.Listener += new MessageListener(OnMessage);

+					WaitForMessageToArrive();

+					Assert.AreEqual(correlationId, receivedMsg.NMSCorrelationID, "Invalid correlation ID.");

+				}

+			}

+		}

+

+		//[Test]

+		public virtual void TestCreateConsumerBeforeSendAddListenerAfterSend(

+			//[Values(MsgDeliveryMode.Persistent, MsgDeliveryMode.NonPersistent)]

+			MsgDeliveryMode deliveryMode, string testQueueRef)

+		{

+			using(IConnection connection = CreateConnectionAndStart(GetTestClientId()))

+			using(ISession producerSession = connection.CreateSession(AcknowledgementMode.AutoAcknowledge))

+			using(ISession consumerSession = connection.CreateSession(AcknowledgementMode.AutoAcknowledge))

+			using(IDestination producerDestination = GetClearDestination(producerSession, DestinationType.Queue, testQueueRef))

+			using(IDestination consumerDestination = GetDestination(consumerSession, DestinationType.Queue, testQueueRef))

+			using(IMessageConsumer consumer = consumerSession.CreateConsumer(consumerDestination))

+			using(IMessageProducer producer = producerSession.CreateProducer(producerDestination))

+			{

+				producer.DeliveryMode = deliveryMode;

+

+				IMessage request = producerSession.CreateMessage();

+				request.NMSCorrelationID = "AsyncConsumeAfterSendLateListener";

+				request.NMSType = "Test";

+				producer.Send(request);

+

+				// now lets add the listener

+				consumer.Listener += new MessageListener(OnMessage);

+				WaitForMessageToArrive();

+				Assert.AreEqual(request.NMSCorrelationID, receivedMsg.NMSCorrelationID, "Invalid correlation ID.");

+			}

+		}

+

+		//[Test]

+		public virtual void TestAsynchronousTextMessageConsume(

+			//[Values(MsgDeliveryMode.Persistent, MsgDeliveryMode.NonPersistent)]

+			MsgDeliveryMode deliveryMode, string testQueueRef)

+		{

+			using(IConnection connection = CreateConnectionAndStart(GetTestClientId()))

+			using(ISession producerSession = connection.CreateSession(AcknowledgementMode.AutoAcknowledge))

+			using(ISession consumerSession = connection.CreateSession(AcknowledgementMode.AutoAcknowledge))

+			using(IDestination producerDestination = GetClearDestination(producerSession, DestinationType.Queue, testQueueRef))

+			using(IDestination consumerDestination = GetDestination(consumerSession, DestinationType.Queue, testQueueRef))

+			using(IMessageConsumer consumer = consumerSession.CreateConsumer(consumerDestination))

+			using(IMessageProducer producer = producerSession.CreateProducer(producerDestination))

+			{

+				consumer.Listener += new MessageListener(OnMessage);

+				producer.DeliveryMode = deliveryMode;

+

+				ITextMessage request = producerSession.CreateTextMessage("Hello, World!");

+				request.NMSCorrelationID = "AsyncConsumeTextMessage";

+				request.Properties["NMSXGroupID"] = "cheese";

+				request.Properties["myHeader"] = "James";

+

+				producer.Send(request);

+

+				WaitForMessageToArrive();

+				Assert.AreEqual(request.NMSCorrelationID, receivedMsg.NMSCorrelationID, "Invalid correlation ID.");

+				Assert.AreEqual(request.Properties["NMSXGroupID"], receivedMsg.Properties["NMSXGroupID"], "Invalid NMSXGroupID.");

+				Assert.AreEqual(request.Properties["myHeader"], receivedMsg.Properties["myHeader"], "Invalid myHeader.");

+				Assert.AreEqual(request.Text, ((ITextMessage) receivedMsg).Text, "Invalid text body.");

+			}

+		}

+

+		//[Test]

+		public virtual void TestTemporaryQueueAsynchronousConsume(

+			//[Values(MsgDeliveryMode.Persistent, MsgDeliveryMode.NonPersistent)]

+			MsgDeliveryMode deliveryMode, string testQueueRef)

+		{

+			using(IConnection connection = CreateConnectionAndStart(GetTestClientId()))

+			using(ISession session = connection.CreateSession(AcknowledgementMode.AutoAcknowledge))

+			using(ITemporaryQueue tempReplyDestination = session.CreateTemporaryQueue())

+			using(IDestination destination = GetClearDestination(session, DestinationType.Queue, testQueueRef))

+			using(IMessageConsumer consumer = session.CreateConsumer(destination))

+			using(IMessageConsumer tempConsumer = session.CreateConsumer(tempReplyDestination))

+			using(IMessageProducer producer = session.CreateProducer(destination))

+			{

+				producer.DeliveryMode = deliveryMode;

+				tempConsumer.Listener += new MessageListener(OnMessage);

+				consumer.Listener += new MessageListener(OnQueueMessage);

+

+				IMessage request = session.CreateMessage();

+				request.NMSCorrelationID = "TemqQueueAsyncConsume";

+				request.NMSType = "Test";

+				request.NMSReplyTo = tempReplyDestination;

+				producer.Send(request);

+

+				WaitForMessageToArrive();

+				Assert.AreEqual("TempQueueAsyncResponse", receivedMsg.NMSCorrelationID, "Invalid correlation ID.");

+			}

+		}

+

+		protected void OnQueueMessage(IMessage message)

+		{

+			Assert.AreEqual("TemqQueueAsyncConsume", message.NMSCorrelationID, "Invalid correlation ID.");

+			using(IConnection connection = CreateConnectionAndStart(RESPONSE_CLIENT_ID))

+			using(ISession session = connection.CreateSession(AcknowledgementMode.AutoAcknowledge))

+			using(IMessageProducer producer = session.CreateProducer(message.NMSReplyTo))

+			{

+				producer.DeliveryMode = message.NMSDeliveryMode;

+

+				ITextMessage response = session.CreateTextMessage("Asynchronous Response Message Text");

+				response.NMSCorrelationID = "TempQueueAsyncResponse";

+				response.NMSType = message.NMSType;

+				producer.Send(response);

+			}

+		}

+

+		protected void OnMessage(IMessage message)

+		{

+			receivedMsg = message;

+			received = true;

+			semaphore.Set();

+		}

+

+		protected void WaitForMessageToArrive()

+		{

+			semaphore.WaitOne((int) receiveTimeout.TotalMilliseconds, true);

+			Assert.IsTrue(received, "Should have received a message by now!");

+		}

+	}

+}

diff --git a/src/test/csharp/BadConsumeTest.cs b/src/test/csharp/BadConsumeTest.cs
new file mode 100644
index 0000000..564f9d8
--- /dev/null
+++ b/src/test/csharp/BadConsumeTest.cs
@@ -0,0 +1,69 @@
+/*

+ * 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 NUnit.Framework;

+

+namespace Apache.NMS.Test

+{

+	//[TestFixture]

+	public class BadConsumeTest : NMSTest

+	{

+		protected IConnection connection;

+		protected ISession session;

+

+		protected BadConsumeTest(NMSTestSupport testSupport)

+			: base(testSupport)

+		{

+		}

+

+		//[SetUp]

+		public override void SetUp()

+		{

+			connection = CreateConnection(GetTestClientId());

+			connection.Start();

+			session = connection.CreateSession(AcknowledgementMode.AutoAcknowledge);

+		}

+

+		//[TearDown]

+		public override void TearDown()

+		{

+			if(null != session)

+			{

+				session.Dispose();

+				session = null;

+			}

+

+			if(null != connection)

+			{

+				connection.Dispose();

+				connection = null;

+			}

+		}

+

+		//[Test]

+		//[ExpectedException(Handler="ExceptionValidationCheck")]

+		public virtual void TestBadConsumerException()

+		{

+			session.CreateConsumer(null);

+		}

+

+		public void ExceptionValidationCheck(Exception ex)

+		{

+			Assert.IsNotNull(ex as NMSException, "Invalid exception was thrown.");

+		}

+	}

+}

diff --git a/src/test/csharp/BytesMessageTest.cs b/src/test/csharp/BytesMessageTest.cs
new file mode 100644
index 0000000..d8c3af7
--- /dev/null
+++ b/src/test/csharp/BytesMessageTest.cs
@@ -0,0 +1,138 @@
+/*

+ * 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 NUnit.Framework;

+

+namespace Apache.NMS.Test

+{

+	//[TestFixture]

+	public class BytesMessageTest : NMSTest

+	{

+		protected byte[] msgContent = {1, 2, 3, 4, 5, 6, 7, 8};

+

+		protected BytesMessageTest(NMSTestSupport testSupport)

+			: base(testSupport)

+		{

+		}

+

+		//[Test]

+		public virtual void SendReceiveBytesMessage(

+			//[Values(MsgDeliveryMode.Persistent, MsgDeliveryMode.NonPersistent)]

+			MsgDeliveryMode deliveryMode, string testQueueRef)

+		{

+			using(IConnection connection = CreateConnection(GetTestClientId()))

+			{

+				connection.Start();

+				using(ISession session = connection.CreateSession(AcknowledgementMode.AutoAcknowledge))

+				{

+					IDestination destination = GetClearDestination(session, DestinationType.Queue, testQueueRef);

+					using(IMessageConsumer consumer = session.CreateConsumer(destination))

+					using(IMessageProducer producer = session.CreateProducer(destination))

+					{

+						producer.DeliveryMode = deliveryMode;

+						IMessage request = session.CreateBytesMessage(msgContent);

+						producer.Send(request);

+

+						IMessage message = consumer.Receive(receiveTimeout);

+                        AssertMessageIsReadOnly(message);

+						AssertBytesMessageEqual(request, message);

+						Assert.AreEqual(deliveryMode, message.NMSDeliveryMode, "NMSDeliveryMode does not match");

+

+					}

+				}

+			}

+		}

+

+        //[Test]

+        public virtual void SendReceiveBytesMessageContent(

+			//[Values(MsgDeliveryMode.Persistent, MsgDeliveryMode.NonPersistent)]

+			MsgDeliveryMode deliveryMode, string testQueueRef)

+        {

+            using(IConnection connection = CreateConnection(GetTestClientId()))

+            {

+                connection.Start();

+                using(ISession session = connection.CreateSession(AcknowledgementMode.AutoAcknowledge))

+                {

+					IDestination destination = GetClearDestination(session, DestinationType.Queue, testQueueRef);

+                    using(IMessageConsumer consumer = session.CreateConsumer(destination))

+                    using(IMessageProducer producer = session.CreateProducer(destination))

+                    {

+                        producer.DeliveryMode = deliveryMode;

+                        IBytesMessage request = session.CreateBytesMessage();

+                        

+                        request.WriteBoolean(true);

+                        request.WriteByte((byte) 1);

+                        request.WriteBytes(new byte[1]);

+                        request.WriteBytes(new byte[3], 0, 2);

+                        request.WriteChar('a');

+                        request.WriteDouble(1.5);

+                        request.WriteSingle((float) 1.5);

+                        request.WriteInt32(1);

+                        request.WriteInt64(1);

+                        request.WriteObject("stringobj");

+                        request.WriteInt16((short) 1);

+                        request.WriteString("utfstring");

+                        

+                        producer.Send(request);

+

+                        IMessage message = consumer.Receive(receiveTimeout);

+                        AssertMessageIsReadOnly(message);

+                        AssertBytesMessageEqual(request, message);

+                        Assert.AreEqual(deliveryMode, message.NMSDeliveryMode, "NMSDeliveryMode does not match");

+

+                    }

+                }

+            }

+        }

+        

+        protected void AssertMessageIsReadOnly(IMessage message)

+        {

+			Type writeableExceptionType = typeof(MessageNotWriteableException);

+			IBytesMessage theMessage = message as IBytesMessage;

+            Assert.IsNotNull(theMessage);

+			Assert.Throws(writeableExceptionType, delegate () { theMessage.WriteBoolean(true); });

+			Assert.Throws(writeableExceptionType, delegate () { theMessage.WriteByte((byte) 1); });

+			Assert.Throws(writeableExceptionType, delegate () { theMessage.WriteBytes(new byte[1]); });

+			Assert.Throws(writeableExceptionType, delegate () { theMessage.WriteBytes(new byte[3], 0, 2); });

+			Assert.Throws(writeableExceptionType, delegate () { theMessage.WriteChar('a'); });

+			Assert.Throws(writeableExceptionType, delegate () { theMessage.WriteDouble(1.5); });

+			Assert.Throws(writeableExceptionType, delegate () { theMessage.WriteSingle((float) 1.5); });

+			Assert.Throws(writeableExceptionType, delegate () { theMessage.WriteInt32(1); });

+			Assert.Throws(writeableExceptionType, delegate () { theMessage.WriteInt64(1); });

+			Assert.Throws(writeableExceptionType, delegate () { theMessage.WriteObject("stringobj"); });

+			Assert.Throws(writeableExceptionType, delegate () { theMessage.WriteInt16((short) 1); });

+			Assert.Throws(writeableExceptionType, delegate () { theMessage.WriteString("utfstring"); });

+		}

+        

+		/// <summary>

+		/// Assert that two messages are IBytesMessages and their contents are equal.

+		/// </summary>

+		/// <param name="expected"></param>

+		/// <param name="actual"></param>

+		protected void AssertBytesMessageEqual(IMessage expected, IMessage actual)

+		{

+			IBytesMessage expectedBytesMsg = expected as IBytesMessage;

+			expectedBytesMsg.Reset();

+			Assert.IsNotNull(expectedBytesMsg, "'expected' message not a bytes message");

+			IBytesMessage actualBytesMsg = actual as IBytesMessage;

+			Assert.IsNotNull(actualBytesMsg, "'actual' message not a bytes message");

+			Assert.AreEqual(expectedBytesMsg.Content, actualBytesMsg.Content, "Bytes message contents do not match.");

+		}

+	}

+}

diff --git a/src/test/csharp/Commands/BytesMessage.cs b/src/test/csharp/Commands/BytesMessage.cs
new file mode 100644
index 0000000..e581942
--- /dev/null
+++ b/src/test/csharp/Commands/BytesMessage.cs
@@ -0,0 +1,511 @@
+/*

+ * 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 Apache.NMS.Util;

+using System;

+using System.Collections;

+using System.IO;

+

+namespace Apache.NMS.Commands

+{

+    public class BytesMessage : Message, IBytesMessage

+    {

+        private EndianBinaryReader dataIn = null;

+        private EndianBinaryWriter dataOut = null;

+        private MemoryStream outputBuffer = null;

+        private int length = 0;

+

+        public override Object Clone()

+        {

+            StoreContent();

+            return base.Clone();

+        }

+

+        public override void ClearBody()

+        {

+            base.ClearBody();

+            this.outputBuffer = null;

+            this.dataIn = null;

+            this.dataOut = null;

+            this.length = 0;

+        }

+

+        public long BodyLength

+        {

+            get

+            {

+                InitializeReading();

+                return this.length;

+            }

+        }

+

+        public byte ReadByte()

+        {

+            InitializeReading();

+            try

+            {

+                return dataIn.ReadByte();

+            }

+            catch(EndOfStreamException e)

+            {

+                throw NMSExceptionSupport.CreateMessageEOFException(e);

+            }

+            catch(IOException e)

+            {

+                throw NMSExceptionSupport.CreateMessageFormatException(e);

+            }

+        }

+

+        public void WriteByte( byte value )

+        {

+            InitializeWriting();

+            try

+            {

+                dataOut.Write( value );

+            }

+            catch(Exception e)

+            {

+                throw NMSExceptionSupport.Create(e);

+            }

+        }

+

+        public bool ReadBoolean()

+        {

+            InitializeReading();

+            try

+            {

+                return dataIn.ReadBoolean();

+            }

+            catch(EndOfStreamException e)

+            {

+                throw NMSExceptionSupport.CreateMessageEOFException(e);

+            }

+            catch(IOException e)

+            {

+                throw NMSExceptionSupport.CreateMessageFormatException(e);

+            }

+        }

+

+        public void WriteBoolean( bool value )

+        {

+            InitializeWriting();

+            try

+            {

+                dataOut.Write( value );

+            }

+            catch(Exception e)

+            {

+                throw NMSExceptionSupport.Create(e);

+            }

+        }

+

+        public char ReadChar()

+        {

+            InitializeReading();

+            try

+            {

+                return dataIn.ReadChar();

+            }

+            catch(EndOfStreamException e)

+            {

+                throw NMSExceptionSupport.CreateMessageEOFException(e);

+            }

+            catch(IOException e)

+            {

+                throw NMSExceptionSupport.CreateMessageFormatException(e);

+            }

+        }

+

+        public void WriteChar( char value )

+        {

+            InitializeWriting();

+            try

+            {

+                dataOut.Write( value );

+            }

+            catch(Exception e)

+            {

+                throw NMSExceptionSupport.Create(e);

+            }

+        }

+

+        public short ReadInt16()

+        {

+            InitializeReading();

+            try

+            {

+                return dataIn.ReadInt16();

+            }

+            catch(EndOfStreamException e)

+            {

+                throw NMSExceptionSupport.CreateMessageEOFException(e);

+            }

+            catch(IOException e)

+            {

+                throw NMSExceptionSupport.CreateMessageFormatException(e);

+            }

+        }

+

+        public void WriteInt16( short value )

+        {

+            InitializeWriting();

+            try

+            {

+                dataOut.Write( value );

+            }

+            catch(Exception e)

+            {

+                throw NMSExceptionSupport.Create(e);

+            }

+        }

+

+        public int ReadInt32()

+        {

+            InitializeReading();

+            try

+            {

+                return dataIn.ReadInt32();

+            }

+            catch(EndOfStreamException e)

+            {

+                throw NMSExceptionSupport.CreateMessageEOFException(e);

+            }

+            catch(IOException e)

+            {

+                throw NMSExceptionSupport.CreateMessageFormatException(e);

+            }

+        }

+

+        public void WriteInt32( int value )

+        {

+            InitializeWriting();

+            try

+            {

+                dataOut.Write( value );

+            }

+            catch(Exception e)

+            {

+                throw NMSExceptionSupport.Create(e);

+            }

+        }

+

+        public long ReadInt64()

+        {

+            InitializeReading();

+            try

+            {

+                return dataIn.ReadInt64();

+            }

+            catch(EndOfStreamException e)

+            {

+                throw NMSExceptionSupport.CreateMessageEOFException(e);

+            }

+            catch(IOException e)

+            {

+                throw NMSExceptionSupport.CreateMessageFormatException(e);

+            }

+        }

+

+        public void WriteInt64( long value )

+        {

+            InitializeWriting();

+            try

+            {

+                dataOut.Write( value );

+            }

+            catch(Exception e)

+            {

+                throw NMSExceptionSupport.Create(e);

+            }

+        }

+

+        public float ReadSingle()

+        {

+            InitializeReading();

+            try

+            {

+                return dataIn.ReadSingle();

+            }

+            catch(EndOfStreamException e)

+            {

+                throw NMSExceptionSupport.CreateMessageEOFException(e);

+            }

+            catch(IOException e)

+            {

+                throw NMSExceptionSupport.CreateMessageFormatException(e);

+            }

+        }

+

+        public void WriteSingle( float value )

+        {

+            InitializeWriting();

+            try

+            {

+                dataOut.Write( value );

+            }

+            catch(Exception e)

+            {

+                throw NMSExceptionSupport.Create(e);

+            }

+        }

+

+        public double ReadDouble()

+        {

+            InitializeReading();

+            try

+            {

+                return dataIn.ReadDouble();

+            }

+            catch(EndOfStreamException e)

+            {

+                throw NMSExceptionSupport.CreateMessageEOFException(e);

+            }

+            catch(IOException e)

+            {

+                throw NMSExceptionSupport.CreateMessageFormatException(e);

+            }

+        }

+

+        public void WriteDouble( double value )

+        {

+            InitializeWriting();

+            try

+            {

+                dataOut.Write( value );

+            }

+            catch(Exception e)

+            {

+                throw NMSExceptionSupport.Create(e);

+            }

+        }

+

+        public int ReadBytes( byte[] value )

+        {

+            InitializeReading();

+            try

+            {

+                return dataIn.Read( value, 0, value.Length );

+            }

+            catch(EndOfStreamException e)

+            {

+                throw NMSExceptionSupport.CreateMessageEOFException(e);

+            }

+            catch(IOException e)

+            {

+                throw NMSExceptionSupport.CreateMessageFormatException(e);

+            }

+        }

+

+        public int ReadBytes( byte[] value, int length )

+        {

+            InitializeReading();

+            try

+            {

+                return dataIn.Read( value, 0, length );

+            }

+            catch(EndOfStreamException e)

+            {

+                throw NMSExceptionSupport.CreateMessageEOFException(e);

+            }

+            catch(IOException e)

+            {

+                throw NMSExceptionSupport.CreateMessageFormatException(e);

+            }

+        }

+

+        public void WriteBytes( byte[] value )

+        {

+            InitializeWriting();

+            try

+            {

+                dataOut.Write( value, 0, value.Length );

+            }

+            catch(Exception e)

+            {

+                throw NMSExceptionSupport.Create(e);

+            }

+        }

+

+        public void WriteBytes( byte[] value, int offset, int length )

+        {

+            InitializeWriting();

+            try

+            {

+                dataOut.Write( value, offset, length );

+            }

+            catch(Exception e)

+            {

+                throw NMSExceptionSupport.Create(e);

+            }

+        }

+

+        public string ReadString()

+        {

+            InitializeReading();

+            try

+            {

+                // JMS, CMS and NMS all encode the String using a 16 bit size header.

+                return dataIn.ReadString16();

+            }

+            catch(EndOfStreamException e)

+            {

+                throw NMSExceptionSupport.CreateMessageEOFException(e);

+            }

+            catch(IOException e)

+            {

+                throw NMSExceptionSupport.CreateMessageFormatException(e);

+            }

+        }

+

+        public void WriteString( string value )

+        {

+            InitializeWriting();

+            try

+            {

+                // JMS, CMS and NMS all encode the String using a 16 bit size header.

+                dataOut.WriteString16(value);

+            }

+            catch(Exception e)

+            {

+                throw NMSExceptionSupport.Create(e);

+            }

+        }

+

+        public void WriteObject( System.Object value )

+        {

+            InitializeWriting();

+            if( value is System.Byte )

+            {

+                this.dataOut.Write( (byte) value );

+            }

+            else if( value is Char )

+            {

+                this.dataOut.Write( (char) value );

+            }

+            else if( value is Boolean )

+            {

+                this.dataOut.Write( (bool) value );

+            }

+            else if( value is Int16 )

+            {

+                this.dataOut.Write( (short) value );

+            }

+            else if( value is Int32 )

+            {

+                this.dataOut.Write( (int) value );

+            }

+            else if( value is Int64 )

+            {

+                this.dataOut.Write( (long) value );

+            }

+            else if( value is Single )

+            {

+                this.dataOut.Write( (float) value );

+            }

+            else if( value is Double )

+            {

+                this.dataOut.Write( (double) value );

+            }

+            else if( value is byte[] )

+            {

+                this.dataOut.Write( (byte[]) value );

+            }

+            else if( value is String )

+            {

+                this.dataOut.WriteString16( (string) value );

+            }

+            else

+            {

+                throw new MessageFormatException("Cannot write non-primitive type:" + value.GetType());

+            }

+        }

+

+        public new byte[] Content

+        {

+            get

+            {

+                byte[] buffer = null;

+                InitializeReading();

+                if(this.length != 0)

+                {

+                    buffer = new byte[this.length];

+                    this.dataIn.Read(buffer, 0, buffer.Length);

+                }

+                return buffer;

+            }

+

+            set

+            {

+                InitializeWriting();

+                this.dataOut.Write(value, 0, value.Length);

+            }

+        }

+

+        public void Reset()

+        {

+            StoreContent();

+            this.dataIn = null;

+            this.dataOut = null;

+            this.outputBuffer = null;

+            this.ReadOnlyBody = true;

+        }

+

+        private void InitializeReading()

+        {

+            FailIfWriteOnlyBody();

+            if(this.dataIn == null)

+            {

+                byte[] data = base.Content;

+

+                if(base.Content == null)

+                {

+                    data = new byte[0];

+                }

+

+                Stream target = new MemoryStream(data, false);

+

+                this.length = data.Length;

+                this.dataIn = new EndianBinaryReader(target);

+            }

+        }

+

+        private void InitializeWriting()

+        {

+            FailIfReadOnlyBody();

+            if(this.dataOut == null)

+            {

+                this.outputBuffer = new MemoryStream();

+                this.dataOut = new EndianBinaryWriter(this.outputBuffer);

+            }

+        }

+

+        private void StoreContent()

+        {

+            if(this.dataOut != null)

+            {

+                this.dataOut.Close();

+                base.Content = outputBuffer.ToArray();

+

+                this.dataOut = null;

+                this.outputBuffer = null;

+            }

+        }

+

+    }

+}

+

diff --git a/src/test/csharp/Commands/Destination.cs b/src/test/csharp/Commands/Destination.cs
new file mode 100644
index 0000000..23c477d
--- /dev/null
+++ b/src/test/csharp/Commands/Destination.cs
@@ -0,0 +1,380 @@
+/*

+ * 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.Specialized;

+using Apache.NMS.Util;

+

+namespace Apache.NMS.Commands

+{

+    /// <summary>

+    /// Summary description for Destination.

+    /// </summary>

+    public abstract class Destination : IDestination, ICloneable

+    {

+        /// <summary>

+        /// Topic Destination object

+        /// </summary>

+        public const int TOPIC = 1;

+        /// <summary>

+        /// Temporary Topic Destination object

+        /// </summary>

+        public const int TEMPORARY_TOPIC = 2;

+        /// <summary>

+        /// Queue Destination object

+        /// </summary>

+        public const int QUEUE = 3;

+        /// <summary>

+        /// Temporary Queue Destination object

+        /// </summary>

+        public const int TEMPORARY_QUEUE = 4;

+

+        private const String TEMP_PREFIX = "{TD{";

+        private const String TEMP_POSTFIX = "}TD}";

+

+        private String physicalName = "";

+        private StringDictionary options = null;

+

+		private bool disposed = false;

+

+        /// <summary>

+        /// The Default Constructor

+        /// </summary>

+        protected Destination()

+        {

+        }

+

+        /// <summary>

+        /// Construct the Destination with a defined physical name;

+        /// </summary>

+        /// <param name="name"></param>

+        protected Destination(String name)

+        {

+            setPhysicalName(name);

+        }

+

+		~Destination()

+		{

+			Dispose(false);

+		}

+

+		public void Dispose()

+		{

+			Dispose(true);

+			GC.SuppressFinalize(this);

+		}

+

+		private void Dispose(bool disposing)

+		{

+			if(disposed)

+			{

+				return;

+			}

+

+			if(disposing)

+			{

+				try

+				{

+					OnDispose();

+				}

+				catch(Exception ex)

+				{

+					Tracer.ErrorFormat("Exception disposing Destination {0}: {1}", this.physicalName, ex.Message);

+				}

+			}

+

+			disposed = true;

+		}

+

+		/// <summary>

+		/// Child classes can override this method to perform clean-up logic.

+		/// </summary>

+		protected virtual void OnDispose()

+		{

+		}

+

+		public bool IsTopic

+        {

+            get

+            {

+                int destinationType = GetDestinationType();

+                return TOPIC == destinationType

+                    || TEMPORARY_TOPIC == destinationType;

+            }

+        }

+

+        public bool IsQueue

+        {

+            get

+            {

+                int destinationType = GetDestinationType();

+                return QUEUE == destinationType

+                    || TEMPORARY_QUEUE == destinationType;

+            }

+        }

+

+        public bool IsTemporary

+        {

+            get

+            {

+                int destinationType = GetDestinationType();

+                return TEMPORARY_QUEUE == destinationType

+                    || TEMPORARY_TOPIC == destinationType;

+            }

+        }

+

+        /// <summary>

+        /// Dictionary of name/value pairs representing option values specified

+        /// in the URI used to create this Destination.  A null value is returned

+        /// if no options were specified.

+        /// </summary>

+        internal StringDictionary Options

+        {

+            get { return this.options; }

+        }

+

+        private void setPhysicalName(string name)

+        {

+            this.physicalName = name;

+

+            int p = name.IndexOf('?');

+            if(p >= 0)

+            {

+                String optstring = physicalName.Substring(p + 1);

+                this.physicalName = name.Substring(0, p);

+                options = URISupport.ParseQuery(optstring);

+            }

+        }

+

+        /// <summary>

+        /// </summary>

+        /// <param name="destination"></param>

+        /// <returns></returns>

+        public static Destination Transform(IDestination destination)

+        {

+            Destination result = null;

+            if(destination != null)

+            {

+                if(destination is Destination)

+                {

+                    result = (Destination) destination;

+                }

+                else

+                {

+                    if(destination is ITemporaryQueue)

+                    {

+                        result = new TempQueue(((IQueue) destination).QueueName);

+                    }

+                    else if(destination is ITemporaryTopic)

+                    {

+                        result = new TempTopic(((ITopic) destination).TopicName);

+                    }

+                    else if(destination is IQueue)

+                    {

+                        result = new Queue(((IQueue) destination).QueueName);

+                    }

+                    else if(destination is ITopic)

+                    {

+                        result = new Topic(((ITopic) destination).TopicName);

+                    }

+                }

+            }

+            return result;

+        }

+

+        /// <summary>

+        /// Create a temporary name from the clientId

+        /// </summary>

+        /// <param name="clientId"></param>

+        /// <returns></returns>

+        public static String CreateTemporaryName(String clientId)

+        {

+            return TEMP_PREFIX + clientId + TEMP_POSTFIX;

+        }

+

+        /// <summary>

+        /// From a temporary destination find the clientId of the Connection that created it

+        /// </summary>

+        /// <param name="destination"></param>

+        /// <returns>the clientId or null if not a temporary destination</returns>

+        public static String GetClientId(Destination destination)

+        {

+            String answer = null;

+            if(destination != null && destination.IsTemporary)

+            {

+                String name = destination.PhysicalName;

+                int start = name.IndexOf(TEMP_PREFIX);

+                if(start >= 0)

+                {

+                    start += TEMP_PREFIX.Length;

+                    int stop = name.LastIndexOf(TEMP_POSTFIX);

+                    if(stop > start && stop < name.Length)

+                    {

+                        answer = name.Substring(start, stop);

+                    }

+                }

+            }

+            return answer;

+        }

+

+        /// <summary>

+        /// </summary>

+        /// <param name="o">object to compare</param>

+        /// <returns>1 if this is less than o else 0 if they are equal or -1 if this is less than o</returns>

+        public int CompareTo(Object o)

+        {

+            if(o is Destination)

+            {

+                return CompareTo((Destination) o);

+            }

+            return -1;

+        }

+

+        /// <summary>

+        /// Lets sort by name first then lets sort topics greater than queues

+        /// </summary>

+        /// <param name="that">another destination to compare against</param>

+        /// <returns>1 if this is less than o else 0 if they are equal or -1 if this is less than o</returns>

+        public int CompareTo(Destination that)

+        {

+            int answer = 0;

+            if(physicalName != that.physicalName)

+            {

+                if(physicalName == null)

+                {

+                    return -1;

+                }

+                else if(that.physicalName == null)

+                {

+                    return 1;

+                }

+                answer = physicalName.CompareTo(that.physicalName);

+            }

+

+            if(answer == 0)

+            {

+                if(IsTopic)

+                {

+                    if(that.IsQueue)

+                    {

+                        return 1;

+                    }

+                }

+                else

+                {

+                    if(that.IsTopic)

+                    {

+                        return -1;

+                    }

+                }

+            }

+            return answer;

+        }

+

+        /// <summary>

+        /// </summary>

+        /// <returns>Returns the Destination type</returns>

+        public abstract int GetDestinationType();

+

+        public String PhysicalName

+        {

+            get { return this.physicalName; }

+            set

+            {

+                this.physicalName = value;

+            }

+        }

+

+        /// <summary>

+        /// </summary>

+        /// <returns>string representation of this instance</returns>

+        public override String ToString()

+        {

+            switch(DestinationType)

+            {

+            case DestinationType.Topic:

+            return "topic://" + PhysicalName;

+

+            case DestinationType.TemporaryTopic:

+            return "temp-topic://" + PhysicalName;

+

+            case DestinationType.TemporaryQueue:

+            return "temp-queue://" + PhysicalName;

+

+            default:

+            return "queue://" + PhysicalName;

+            }

+        }

+

+        /// <summary>

+        /// </summary>

+        /// <returns>hashCode for this instance</returns>

+        public override int GetHashCode()

+        {

+            int answer = 37;

+

+            if(this.physicalName != null)

+            {

+                answer = physicalName.GetHashCode();

+            }

+            if(IsTopic)

+            {

+                answer ^= 0xfabfab;

+            }

+            return answer;

+        }

+

+        /// <summary>

+        /// if the object passed in is equivalent, return true

+        /// </summary>

+        /// <param name="obj">the object to compare</param>

+        /// <returns>true if this instance and obj are equivalent</returns>

+        public override bool Equals(Object obj)

+        {

+            bool result = this == obj;

+            if(!result && obj != null && obj is Destination)

+            {

+                Destination other = (Destination) obj;

+                result = this.GetDestinationType() == other.GetDestinationType()

+                    && this.physicalName.Equals(other.physicalName);

+            }

+            return result;

+        }

+

+        /// <summary>

+        /// Factory method to create a child destination if this destination is a composite

+        /// </summary>

+        /// <param name="name"></param>

+        /// <returns>the created Destination</returns>

+        public abstract Destination CreateDestination(String name);

+

+        public abstract DestinationType DestinationType

+        {

+            get;

+        }

+

+        public virtual Object Clone()

+        {

+            // Since we are the lowest level base class, do a

+            // shallow copy which will include the derived classes.

+            // From here we would do deep cloning of other objects

+            // if we had any.

+            return this.MemberwiseClone();

+        }

+    }

+}

+

diff --git a/src/test/csharp/Commands/MapMessage.cs b/src/test/csharp/Commands/MapMessage.cs
new file mode 100644
index 0000000..4ba9751
--- /dev/null
+++ b/src/test/csharp/Commands/MapMessage.cs
@@ -0,0 +1,90 @@
+/*

+ * 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.IO;

+using Apache.NMS;

+using Apache.NMS.Util;

+

+namespace Apache.NMS.Commands

+{

+    public class MapMessage : Message, IMapMessage

+    {

+        private PrimitiveMap body;

+        private PrimitiveMapInterceptor typeConverter;

+

+        public MapMessage() : base()

+        {

+        }

+

+        public MapMessage(PrimitiveMap body) : base()

+        {

+            this.body = body;

+            this.typeConverter = new PrimitiveMapInterceptor(this, this.body);

+        }

+

+        public override void ClearBody()

+        {

+            this.body = null;

+            this.typeConverter = null;

+            base.ClearBody();

+        }

+

+        public override bool ReadOnlyBody

+        {

+            get { return base.ReadOnlyBody; }

+

+            set

+            {

+                if(this.typeConverter != null)

+                {

+                    this.typeConverter.ReadOnly = true;

+                }

+

+                base.ReadOnlyBody = value;

+            }

+        }

+

+

+        public IPrimitiveMap Body

+        {

+            get

+            {

+                if(this.body == null)

+                {

+                    this.body = new PrimitiveMap();

+                    this.typeConverter = new PrimitiveMapInterceptor(this, this.body);

+                }

+

+                return this.typeConverter;

+            }

+

+            set

+            {

+                this.body = value as PrimitiveMap;

+                if(value != null)

+                {

+                    this.typeConverter = new PrimitiveMapInterceptor(this, value);

+                }

+                else

+                {

+                    this.typeConverter = null;

+                }

+            }

+        }

+    }

+}

diff --git a/src/test/csharp/Commands/Message.cs b/src/test/csharp/Commands/Message.cs
new file mode 100644
index 0000000..5cadd5f
--- /dev/null
+++ b/src/test/csharp/Commands/Message.cs
@@ -0,0 +1,329 @@
+/*

+ * 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.Util;

+

+namespace Apache.NMS.Commands

+{

+    public class Message : IMessage, ICloneable

+    {

+        private IDestination destination;

+        private string transactionId;

+        private string messageId;

+        private string groupID;

+		private int groupSequence;

+        private string correlationId;

+        private bool persistent;

+        private long expiration;

+        private byte priority;

+        private IDestination replyTo;

+        private long timestamp;

+        private string type;

+        private bool redelivered;

+        private byte[] content;

+        private bool readOnlyMsgProperties;

+        private bool readOnlyMsgBody;

+

+        private MessagePropertyIntercepter propertyHelper;

+        private PrimitiveMap properties;

+

+        ///

+        /// <summery>

+        ///  Clone this object and return a new instance that the caller now owns.

+        /// </summery>

+        ///

+        public virtual Object Clone()

+        {

+            // Since we are the lowest level base class, do a

+            // shallow copy which will include the derived classes.

+            // From here we would do deep cloning of other objects

+            // if we had any.

+            Message o = (Message) this.MemberwiseClone();

+

+            if(this.messageId != null)

+            {

+                o.NMSMessageId = (string) this.messageId.Clone();

+            }

+			

+			return o;

+		}		

+

+        ///

+        /// <summery>

+        ///  Returns a string containing the information for this DataStructure

+        ///  such as its type and value of its elements.

+        /// </summery>

+        ///

+        public override string ToString()

+        {

+            return GetType().Name + "[" +

+                "Destination=" + destination + ", " +

+                "TransactionId=" + transactionId + ", " +

+                "MessageId=" + messageId + ", " +

+                "GroupID=" + groupID + ", " +

+                "GroupSequence=" + groupSequence + ", " +

+                "CorrelationId=" + correlationId + ", " +

+                "Expiration=" + expiration + ", " +

+                "Priority=" + priority + ", " +

+                "ReplyTo=" + replyTo + ", " +

+                "Timestamp=" + timestamp + ", " +

+                "Type=" + type + ", " +

+                "Redelivered=" + redelivered +

+                "]";

+        }

+

+        public void Acknowledge()

+        {

+        }

+		

+        public virtual void ClearBody()

+        {

+			this.content = null;

+        }

+

+        public virtual void ClearProperties()

+        {

+            this.properties.Clear();

+        }

+		

+        protected void FailIfReadOnlyBody()

+        {

+            if(ReadOnlyBody == true)

+            {

+                throw new MessageNotWriteableException("Message is in Read-Only mode.");

+            }

+        }

+

+        protected void FailIfWriteOnlyBody()

+        {

+            if(ReadOnlyBody == false)

+            {

+                throw new MessageNotReadableException("Message is in Write-Only mode.");

+            }

+        }

+		

+        #region Properties

+		

+		public string TransactionId

+		{

+			get { return this.transactionId; }

+			set { this.transactionId = value; }

+		}

+

+        public byte[] Content

+        {

+            get { return content; }

+            set { this.content = value; }

+        }

+		

+        public virtual bool ReadOnlyProperties

+        {

+            get { return this.readOnlyMsgProperties; }

+            set { this.readOnlyMsgProperties = value; }

+        }

+

+        public virtual bool ReadOnlyBody

+        {

+            get { return this.readOnlyMsgBody; }

+            set { this.readOnlyMsgBody = value; }

+        }

+		

+        public IPrimitiveMap Properties

+        {

+            get

+            {

+                if(null == properties)

+                {

+                    properties = new PrimitiveMap();

+                    propertyHelper = new MessagePropertyIntercepter(this, properties, this.ReadOnlyProperties);

+                    propertyHelper.AllowByteArrays = false;

+                }

+

+                return propertyHelper;

+            }

+        }

+

+        /// <summary>

+        /// The correlation ID used to correlate messages with conversations or long running business processes

+        /// </summary>

+        public string NMSCorrelationID

+        {

+            get { return correlationId; }

+            set { correlationId = value; }

+        }

+

+        /// <summary>

+        /// The destination of the message

+        /// </summary>

+        public IDestination NMSDestination

+        {

+            get { return destination; }

+            set { this.destination = Destination.Transform(value); }

+        }

+

+        private TimeSpan timeToLive = TimeSpan.FromMilliseconds(0);

+        /// <summary>

+        /// The time in milliseconds that this message should expire in

+        /// </summary>

+        public TimeSpan NMSTimeToLive

+        {

+            get { return timeToLive; }

+

+            set

+            {

+                timeToLive = value;

+                if(timeToLive.TotalMilliseconds > 0)

+                {

+                    long timeStamp = timestamp;

+

+                    if(timeStamp == 0)

+                    {

+                        timeStamp = DateUtils.ToJavaTimeUtc(DateTime.UtcNow);

+                    }

+

+                    expiration = timeStamp + (long) timeToLive.TotalMilliseconds;

+                }

+                else

+                {

+                    expiration = 0;

+                }

+            }

+        }

+

+        /// <summary>

+        /// The timestamp the broker added to the message

+        /// </summary>

+        public DateTime NMSTimestamp

+        {

+            get { return DateUtils.ToDateTime(timestamp); }

+            set

+            {

+                timestamp = DateUtils.ToJavaTimeUtc(value);

+                if(timeToLive.TotalMilliseconds > 0)

+                {

+                    expiration = timestamp + (long) timeToLive.TotalMilliseconds;

+                }

+            }

+        }

+

+        /// <summary>

+        /// The message ID which is set by the provider

+        /// </summary>

+        public string NMSMessageId

+        {

+            get { return this.messageId; }

+            set { this.messageId = value; }

+        }

+

+        /// <summary>

+        /// Whether or not this message is persistent

+        /// </summary>

+        public MsgDeliveryMode NMSDeliveryMode

+        {

+            get { return (persistent ? MsgDeliveryMode.Persistent : MsgDeliveryMode.NonPersistent); }

+            set { persistent = (MsgDeliveryMode.Persistent == value); }

+        }

+

+        /// <summary>

+        /// The Priority on this message

+        /// </summary>

+        public MsgPriority NMSPriority

+        {

+            get { return (MsgPriority) priority; }

+            set { priority = (byte) value; }

+        }

+

+        /// <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.redelivered; }

+            set { this.redelivered = value; }

+        }

+

+        /// <summary>

+        /// The destination that the consumer of this message should send replies to

+        /// </summary>

+        public IDestination NMSReplyTo

+        {

+            get { return replyTo; }

+            set { replyTo = Destination.Transform(value); }

+        }

+

+        /// <summary>

+        /// The type name of this message

+        /// </summary>

+        public string NMSType

+        {

+            get { return type; }

+            set { type = value; }

+        }

+

+        #endregion

+

+        #region NMS Extension headers

+

+        /// <summary>

+        /// Returns the number of times this message has been redelivered to other consumers without being acknowledged successfully.

+        /// </summary>

+        public int NMSXDeliveryCount

+        {

+            get { return 0; }

+        }

+

+        /// <summary>

+        /// The Message Group ID used to group messages together to the same consumer for the same group ID value

+        /// </summary>

+        public string NMSXGroupID

+        {

+            get { return groupID; }

+            set { groupID = value; }

+        }

+        /// <summary>

+        /// The Message Group Sequence counter to indicate the position in a group

+        /// </summary>

+        public int NMSXGroupSeq

+        {

+            get { return groupSequence; }

+            set { groupSequence = value; }

+        }

+

+        /// <summary>

+        /// Returns the ID of the producers transaction

+        /// </summary>

+        public string NMSXProducerTXID

+        {

+            get

+            {

+                if(null != transactionId)

+                {

+                    return transactionId;

+                }

+

+                return String.Empty;

+            }

+        }

+

+        #endregion

+

+    };

+}

+

diff --git a/src/test/csharp/Commands/ObjectMessage.cs b/src/test/csharp/Commands/ObjectMessage.cs
new file mode 100644
index 0000000..ba68ee0
--- /dev/null
+++ b/src/test/csharp/Commands/ObjectMessage.cs
@@ -0,0 +1,44 @@
+/*

+* 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.IO;

+

+using Apache.NMS;

+

+namespace Apache.NMS.Commands

+{

+    public class ObjectMessage : Message, IObjectMessage

+    {

+        private object body;

+

+        public override string ToString() {

+            return GetType().Name + "["

+                + " ]";

+        }

+

+        // Properties

+

+        public object Body

+        {

+            get { return body; }

+            set { body = value; }

+        }

+

+    }

+}

diff --git a/src/test/csharp/Commands/Queue.cs b/src/test/csharp/Commands/Queue.cs
new file mode 100644
index 0000000..c0dd5f9
--- /dev/null
+++ b/src/test/csharp/Commands/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;

+

+namespace Apache.NMS.Commands

+{

+    /// <summary>

+    /// Summary description for Queue.

+    /// </summary>

+    public class Queue : Destination, IQueue

+    {

+        public Queue()

+            : base()

+        {

+        }

+

+        public Queue(String name)

+            : base(name)

+        {

+        }

+

+        override public DestinationType DestinationType

+        {

+            get

+            {

+                return DestinationType.Queue;

+            }

+        }

+

+        public String QueueName

+        {

+            get { return PhysicalName; }

+        }

+

+        public override int GetDestinationType()

+        {

+            return QUEUE;

+        }

+

+        public override Destination CreateDestination(String name)

+        {

+            return new Queue(name);

+        }

+

+        public override Object Clone()

+        {

+            // Since we are a derived class use the base's Clone()

+            // to perform the shallow copy. Since it is shallow it

+            // will include our derived class. Since we are derived,

+            // this method is an override.

+            Queue o = (Queue) base.Clone();

+

+            // Now do the deep work required

+            // If any new variables are added then this routine will

+            // likely need updating

+

+            return o;

+        }

+    }

+}

+

diff --git a/src/test/csharp/Commands/StreamMessage.cs b/src/test/csharp/Commands/StreamMessage.cs
new file mode 100644
index 0000000..1195a12
--- /dev/null
+++ b/src/test/csharp/Commands/StreamMessage.cs
@@ -0,0 +1,901 @@
+/*

+ * 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.IO;

+using System.Collections;

+

+using Apache.NMS;

+using Apache.NMS.Util;

+

+namespace Apache.NMS.Commands

+{

+    public class StreamMessage : Message, IStreamMessage

+    {

+        private EndianBinaryReader dataIn = null;

+        private EndianBinaryWriter dataOut = null;

+        private MemoryStream byteBuffer = null;

+        private int bytesRemaining = -1;

+

+        public bool ReadBoolean()

+        {

+            InitializeReading();

+

+            try

+            {

+                long startingPos = this.byteBuffer.Position;

+                try

+                {

+                    int type = this.dataIn.ReadByte();

+

+                    if(type == PrimitiveMap.BOOLEAN_TYPE)

+                    {

+                        return this.dataIn.ReadBoolean();

+                    }

+                    else if(type == PrimitiveMap.STRING_TYPE)

+                    {

+                        return Boolean.Parse(this.dataIn.ReadString16());

+                    }

+                    else if(type == PrimitiveMap.NULL)

+                    {

+                        this.byteBuffer.Seek(startingPos, SeekOrigin.Begin);

+                        throw new NMSException("Cannot convert Null type to a bool");

+                    }

+                    else

+                    {

+                        this.byteBuffer.Seek(startingPos, SeekOrigin.Begin);

+                        throw new MessageFormatException("Value is not a Boolean type.");

+                    }

+                }

+                catch(FormatException e)

+                {

+                    this.byteBuffer.Seek(startingPos, SeekOrigin.Begin);

+                    throw NMSExceptionSupport.CreateMessageFormatException(e);

+                }

+            }

+            catch(EndOfStreamException e)

+            {

+                throw NMSExceptionSupport.CreateMessageEOFException(e);

+            }

+            catch(IOException e)

+            {

+                throw NMSExceptionSupport.CreateMessageFormatException(e);

+            }

+        }

+

+        public byte ReadByte()

+        {

+            InitializeReading();

+

+            try

+            {

+                long startingPos = this.byteBuffer.Position;

+                try

+                {

+                    int type = this.dataIn.ReadByte();

+

+                    if(type == PrimitiveMap.BYTE_TYPE)

+                    {

+                        return this.dataIn.ReadByte();

+                    }

+                    else if(type == PrimitiveMap.STRING_TYPE)

+                    {

+                        return Byte.Parse(this.dataIn.ReadString16());

+                    }

+                    else if(type == PrimitiveMap.NULL)

+                    {

+                        this.byteBuffer.Seek(startingPos, SeekOrigin.Begin);

+                        throw new NMSException("Cannot convert Null type to a byte");

+                    }

+                    else

+                    {

+                        this.byteBuffer.Seek(startingPos, SeekOrigin.Begin);

+                        throw new MessageFormatException("Value is not a Byte type.");

+                    }

+                }

+                catch(FormatException e)

+                {

+                    this.byteBuffer.Seek(startingPos, SeekOrigin.Begin);

+                    throw NMSExceptionSupport.CreateMessageFormatException(e);

+                }

+            }

+            catch(EndOfStreamException e)

+            {

+                throw NMSExceptionSupport.CreateMessageEOFException(e);

+            }

+            catch(IOException e)

+            {

+                throw NMSExceptionSupport.CreateMessageFormatException(e);

+            }

+        }

+

+        public char ReadChar()

+        {

+            InitializeReading();

+

+            try

+            {

+                long startingPos = this.byteBuffer.Position;

+                try

+                {

+                    int type = this.dataIn.ReadByte();

+

+                    if(type == PrimitiveMap.CHAR_TYPE)

+                    {

+                        return this.dataIn.ReadChar();

+                    }

+                    else if(type == PrimitiveMap.NULL)

+                    {

+                        this.byteBuffer.Seek(startingPos, SeekOrigin.Begin);

+                        throw new NMSException("Cannot convert Null type to a char");

+                    }

+                    else

+                    {

+                        this.byteBuffer.Seek(startingPos, SeekOrigin.Begin);

+                        throw new MessageFormatException("Value is not a Char type.");

+                    }

+                }

+                catch(FormatException e)

+                {

+                    this.byteBuffer.Seek(startingPos, SeekOrigin.Begin);

+                    throw NMSExceptionSupport.CreateMessageFormatException(e);

+                }

+            }

+            catch(EndOfStreamException e)

+            {

+                throw NMSExceptionSupport.CreateMessageEOFException(e);

+            }

+            catch(IOException e)

+            {

+                throw NMSExceptionSupport.CreateMessageFormatException(e);

+            }

+        }

+

+        public short ReadInt16()

+        {

+            InitializeReading();

+

+            try

+            {

+                long startingPos = this.byteBuffer.Position;

+                try

+                {

+                    int type = this.dataIn.ReadByte();

+

+                    if(type == PrimitiveMap.SHORT_TYPE)

+                    {

+                        return this.dataIn.ReadInt16();

+                    }

+                    else if(type == PrimitiveMap.BYTE_TYPE)

+                    {

+                        return this.dataIn.ReadByte();

+                    }

+                    else if(type == PrimitiveMap.STRING_TYPE)

+                    {

+                        return Int16.Parse(this.dataIn.ReadString16());

+                    }

+                    else if(type == PrimitiveMap.NULL)

+                    {

+                        this.byteBuffer.Seek(startingPos, SeekOrigin.Begin);

+                        throw new NMSException("Cannot convert Null type to a short");

+                    }

+                    else

+                    {

+                        this.byteBuffer.Seek(startingPos, SeekOrigin.Begin);

+                        throw new MessageFormatException("Value is not a Int16 type.");

+                    }

+                }

+                catch(FormatException e)

+                {

+                    this.byteBuffer.Seek(startingPos, SeekOrigin.Begin);

+                    throw NMSExceptionSupport.CreateMessageFormatException(e);

+                }

+            }

+            catch(EndOfStreamException e)

+            {

+                throw NMSExceptionSupport.CreateMessageEOFException(e);

+            }

+            catch(IOException e)

+            {

+                throw NMSExceptionSupport.CreateMessageFormatException(e);

+            }

+        }

+

+        public int ReadInt32()

+        {

+            InitializeReading();

+

+            try

+            {

+                long startingPos = this.byteBuffer.Position;

+                try

+                {

+                    int type = this.dataIn.ReadByte();

+

+                    if(type == PrimitiveMap.INTEGER_TYPE)

+                    {

+                        return this.dataIn.ReadInt32();

+                    }

+                    else if(type == PrimitiveMap.SHORT_TYPE)

+                    {

+                        return this.dataIn.ReadInt16();

+                    }

+                    else if(type == PrimitiveMap.BYTE_TYPE)

+                    {

+                        return this.dataIn.ReadByte();

+                    }

+                    else if(type == PrimitiveMap.STRING_TYPE)

+                    {

+                        return Int32.Parse(this.dataIn.ReadString16());

+                    }

+                    else if(type == PrimitiveMap.NULL)

+                    {

+                        this.byteBuffer.Seek(startingPos, SeekOrigin.Begin);

+                        throw new NMSException("Cannot convert Null type to a int");

+                    }

+                    else

+                    {

+                        this.byteBuffer.Seek(startingPos, SeekOrigin.Begin);

+                        throw new MessageFormatException("Value is not a Int32 type.");

+                    }

+                }

+                catch(FormatException e)

+                {

+                    this.byteBuffer.Seek(startingPos, SeekOrigin.Begin);

+                    throw NMSExceptionSupport.CreateMessageFormatException(e);

+                }

+            }

+            catch(EndOfStreamException e)

+            {

+                throw NMSExceptionSupport.CreateMessageEOFException(e);

+            }

+            catch(IOException e)

+            {

+                throw NMSExceptionSupport.CreateMessageFormatException(e);

+            }

+        }

+

+        public long ReadInt64()

+        {

+            InitializeReading();

+

+            try

+            {

+                long startingPos = this.byteBuffer.Position;

+                try

+                {

+                    int type = this.dataIn.ReadByte();

+

+                    if(type == PrimitiveMap.LONG_TYPE)

+                    {

+                        return this.dataIn.ReadInt64();

+                    }

+                    else if(type == PrimitiveMap.INTEGER_TYPE)

+                    {

+                        return this.dataIn.ReadInt32();

+                    }

+                    else if(type == PrimitiveMap.SHORT_TYPE)

+                    {

+                        return this.dataIn.ReadInt16();

+                    }

+                    else if(type == PrimitiveMap.BYTE_TYPE)

+                    {

+                        return this.dataIn.ReadByte();

+                    }

+                    else if(type == PrimitiveMap.STRING_TYPE)

+                    {

+                        return Int64.Parse(this.dataIn.ReadString16());

+                    }

+                    else if(type == PrimitiveMap.NULL)

+                    {

+                        this.byteBuffer.Seek(startingPos, SeekOrigin.Begin);

+                        throw new NMSException("Cannot convert Null type to a long");

+                    }

+                    else

+                    {

+                        this.byteBuffer.Seek(startingPos, SeekOrigin.Begin);

+                        throw new MessageFormatException("Value is not a Int64 type.");

+                    }

+                }

+                catch(FormatException e)

+                {

+                    this.byteBuffer.Seek(startingPos, SeekOrigin.Begin);

+                    throw NMSExceptionSupport.CreateMessageFormatException(e);

+                }

+            }

+            catch(EndOfStreamException e)

+            {

+                throw NMSExceptionSupport.CreateMessageEOFException(e);

+            }

+            catch(IOException e)

+            {

+                throw NMSExceptionSupport.CreateMessageFormatException(e);

+            }

+        }

+

+        public float ReadSingle()

+        {

+            InitializeReading();

+

+            try

+            {

+                long startingPos = this.byteBuffer.Position;

+                try

+                {

+                    int type = this.dataIn.ReadByte();

+

+                    if(type == PrimitiveMap.FLOAT_TYPE)

+                    {

+                        return this.dataIn.ReadSingle();

+                    }

+                    else if(type == PrimitiveMap.STRING_TYPE)

+                    {

+                        return Single.Parse(this.dataIn.ReadString16());

+                    }

+                    else if(type == PrimitiveMap.NULL)

+                    {

+                        this.byteBuffer.Seek(startingPos, SeekOrigin.Begin);

+                        throw new NMSException("Cannot convert Null type to a float");

+                    }

+                    else

+                    {

+                        this.byteBuffer.Seek(startingPos, SeekOrigin.Begin);

+                        throw new MessageFormatException("Value is not a Single type.");

+                    }

+                }

+                catch(FormatException e)

+                {

+                    this.byteBuffer.Seek(startingPos, SeekOrigin.Begin);

+                    throw NMSExceptionSupport.CreateMessageFormatException(e);

+                }

+            }

+            catch(EndOfStreamException e)

+            {

+                throw NMSExceptionSupport.CreateMessageEOFException(e);

+            }

+            catch(IOException e)

+            {

+                throw NMSExceptionSupport.CreateMessageFormatException(e);

+            }

+        }

+

+        public double ReadDouble()

+        {

+            InitializeReading();

+

+            try

+            {

+                long startingPos = this.byteBuffer.Position;

+                try

+                {

+                    int type = this.dataIn.ReadByte();

+

+                    if(type == PrimitiveMap.DOUBLE_TYPE)

+                    {

+                        return this.dataIn.ReadDouble();

+                    }

+                    else if(type == PrimitiveMap.FLOAT_TYPE)

+                    {

+                        return this.dataIn.ReadSingle();

+                    }

+                    else if(type == PrimitiveMap.STRING_TYPE)

+                    {

+                        return Single.Parse(this.dataIn.ReadString16());

+                    }

+                    else if(type == PrimitiveMap.NULL)

+                    {

+                        this.byteBuffer.Seek(startingPos, SeekOrigin.Begin);

+                        throw new NMSException("Cannot convert Null type to a double");

+                    }

+                    else

+                    {

+                        this.byteBuffer.Seek(startingPos, SeekOrigin.Begin);

+                        throw new MessageFormatException("Value is not a Double type.");

+                    }

+                }

+                catch(FormatException e)

+                {

+                    this.byteBuffer.Seek(startingPos, SeekOrigin.Begin);

+                    throw NMSExceptionSupport.CreateMessageFormatException(e);

+                }

+            }

+            catch(EndOfStreamException e)

+            {

+                throw NMSExceptionSupport.CreateMessageEOFException(e);

+            }

+            catch(IOException e)

+            {

+                throw NMSExceptionSupport.CreateMessageFormatException(e);

+            }

+        }

+

+        public string ReadString()

+        {

+            InitializeReading();

+

+            long startingPos = this.byteBuffer.Position;

+

+            try

+            {

+                int type = this.dataIn.ReadByte();

+

+                if(type == PrimitiveMap.BIG_STRING_TYPE)

+                {

+                    return this.dataIn.ReadString32();

+                }

+                else if(type == PrimitiveMap.STRING_TYPE)

+                {

+                    return this.dataIn.ReadString16();

+                }

+                else if(type == PrimitiveMap.LONG_TYPE)

+                {

+                    return this.dataIn.ReadInt64().ToString();

+                }

+                else if(type == PrimitiveMap.INTEGER_TYPE)

+                {

+                    return this.dataIn.ReadInt32().ToString();

+                }

+                else if(type == PrimitiveMap.SHORT_TYPE)

+                {

+                    return this.dataIn.ReadInt16().ToString();

+                }

+                else if(type == PrimitiveMap.FLOAT_TYPE)

+                {

+                    return this.dataIn.ReadSingle().ToString();

+                }

+                else if(type == PrimitiveMap.DOUBLE_TYPE)

+                {

+                    return this.dataIn.ReadDouble().ToString();

+                }

+                else if(type == PrimitiveMap.CHAR_TYPE)

+                {

+                    return this.dataIn.ReadChar().ToString();

+                }

+                else if(type == PrimitiveMap.BYTE_TYPE)

+                {

+                    return this.dataIn.ReadByte().ToString();

+                }

+                else if(type == PrimitiveMap.BOOLEAN_TYPE)

+                {

+                    return this.dataIn.ReadBoolean().ToString();

+                }

+                else if(type == PrimitiveMap.NULL)

+                {

+                    return null;

+                }

+                else

+                {

+                    this.byteBuffer.Seek(startingPos, SeekOrigin.Begin);

+                    throw new MessageFormatException("Value is not a known type.");

+                }

+            }

+            catch(FormatException e)

+            {

+                this.byteBuffer.Seek(startingPos, SeekOrigin.Begin);

+                throw NMSExceptionSupport.CreateMessageFormatException(e);

+            }

+            catch(EndOfStreamException e)

+            {

+                throw NMSExceptionSupport.CreateMessageEOFException(e);

+            }

+            catch(IOException e)

+            {

+                throw NMSExceptionSupport.CreateMessageFormatException(e);

+            }

+        }

+

+        public int ReadBytes(byte[] value)

+        {

+            InitializeReading();

+

+            if(value == null)

+            {

+                throw new NullReferenceException("Passed Byte Array is null");

+            }

+

+            try

+            {

+                if(this.bytesRemaining == -1)

+                {

+                    long startingPos = this.byteBuffer.Position;

+                    byte type = this.dataIn.ReadByte();

+

+                    if(type != PrimitiveMap.BYTE_ARRAY_TYPE)

+                    {

+                        this.byteBuffer.Seek(startingPos, SeekOrigin.Begin);

+                        throw new MessageFormatException("Not a byte array");

+                    }

+

+                    this.bytesRemaining = this.dataIn.ReadInt32();

+                }

+                else if(this.bytesRemaining == 0)

+                {

+                    this.bytesRemaining = -1;

+                    return -1;

+                }

+

+                if(value.Length <= this.bytesRemaining)

+                {

+                    // small buffer

+                    this.bytesRemaining -= value.Length;

+                    this.dataIn.Read(value, 0, value.Length);

+                    return value.Length;

+                }

+                else

+                {

+                    // big buffer

+                    int rc = this.dataIn.Read(value, 0, this.bytesRemaining);

+                    this.bytesRemaining = 0;

+                    return rc;

+                }

+            }

+            catch(EndOfStreamException ex)

+            {

+                throw NMSExceptionSupport.CreateMessageEOFException(ex);

+            }

+            catch(IOException ex)

+            {

+                throw NMSExceptionSupport.CreateMessageFormatException(ex);

+            }

+        }

+

+        public Object ReadObject()

+        {

+            InitializeReading();

+

+            long startingPos = this.byteBuffer.Position;

+

+            try

+            {

+                int type = this.dataIn.ReadByte();

+

+                if(type == PrimitiveMap.BIG_STRING_TYPE)

+                {

+                    return this.dataIn.ReadString32();

+                }

+                else if(type == PrimitiveMap.STRING_TYPE)

+                {

+                    return this.dataIn.ReadString16();

+                }

+                else if(type == PrimitiveMap.LONG_TYPE)

+                {

+                    return this.dataIn.ReadInt64();

+                }

+                else if(type == PrimitiveMap.INTEGER_TYPE)

+                {

+                    return this.dataIn.ReadInt32();

+                }

+                else if(type == PrimitiveMap.SHORT_TYPE)

+                {

+                    return this.dataIn.ReadInt16();

+                }

+                else if(type == PrimitiveMap.FLOAT_TYPE)

+                {

+                    return this.dataIn.ReadSingle();

+                }

+                else if(type == PrimitiveMap.DOUBLE_TYPE)

+                {

+                    return this.dataIn.ReadDouble();

+                }

+                else if(type == PrimitiveMap.CHAR_TYPE)

+                {

+                    return this.dataIn.ReadChar();

+                }

+                else if(type == PrimitiveMap.BYTE_TYPE)

+                {

+                    return this.dataIn.ReadByte();

+                }

+                else if(type == PrimitiveMap.BOOLEAN_TYPE)

+                {

+                    return this.dataIn.ReadBoolean();

+                }

+                else if(type == PrimitiveMap.BYTE_ARRAY_TYPE)

+                {

+                    int length = this.dataIn.ReadInt32();

+                    byte[] data = new byte[length];

+                    this.dataIn.Read(data, 0, length);

+                    return data;

+                }

+                else if(type == PrimitiveMap.NULL)

+                {

+                    return null;

+                }

+                else

+                {

+                    this.byteBuffer.Seek(startingPos, SeekOrigin.Begin);

+                    throw new MessageFormatException("Value is not a known type.");

+                }

+            }

+            catch(FormatException e)

+            {

+                this.byteBuffer.Seek(startingPos, SeekOrigin.Begin);

+                throw NMSExceptionSupport.CreateMessageFormatException(e);

+            }

+            catch(EndOfStreamException e)

+            {

+                throw NMSExceptionSupport.CreateMessageEOFException(e);

+            }

+            catch(IOException e)

+            {

+                throw NMSExceptionSupport.CreateMessageFormatException(e);

+            }

+        }

+

+        public void WriteBoolean(bool value)

+        {

+            InitializeWriting();

+            try

+            {

+                this.dataOut.Write(PrimitiveMap.BOOLEAN_TYPE);

+                this.dataOut.Write(value);

+            }

+            catch(IOException e)

+            {

+                NMSExceptionSupport.Create(e);

+            }

+        }

+

+        public void WriteByte(byte value)

+        {

+            InitializeWriting();

+            try

+            {

+                this.dataOut.Write(PrimitiveMap.BYTE_TYPE);

+                this.dataOut.Write(value);

+            }

+            catch(IOException e)

+            {

+                NMSExceptionSupport.Create(e);

+            }

+        }

+

+        public void WriteBytes(byte[] value)

+        {

+            InitializeWriting();

+            this.WriteBytes(value, 0, value.Length);

+        }

+

+        public void WriteBytes(byte[] value, int offset, int length)

+        {

+            InitializeWriting();

+            try

+            {

+                this.dataOut.Write(PrimitiveMap.BYTE_ARRAY_TYPE);

+                this.dataOut.Write((int) length);

+                this.dataOut.Write(value, offset, length);

+            }

+            catch(IOException e)

+            {

+                NMSExceptionSupport.Create(e);

+            }

+        }

+

+        public void WriteChar(char value)

+        {

+            InitializeWriting();

+            try

+            {

+                this.dataOut.Write(PrimitiveMap.CHAR_TYPE);

+                this.dataOut.Write(value);

+            }

+            catch(IOException e)

+            {

+                NMSExceptionSupport.Create(e);

+            }

+        }

+

+        public void WriteInt16(short value)

+        {

+            InitializeWriting();

+            try

+            {

+                this.dataOut.Write(PrimitiveMap.SHORT_TYPE);

+                this.dataOut.Write(value);

+            }

+            catch(IOException e)

+            {

+                NMSExceptionSupport.Create(e);

+            }

+        }

+

+        public void WriteInt32(int value)

+        {

+            InitializeWriting();

+            try

+            {

+                this.dataOut.Write(PrimitiveMap.INTEGER_TYPE);

+                this.dataOut.Write(value);

+            }

+            catch(IOException e)

+            {

+                NMSExceptionSupport.Create(e);

+            }

+        }

+

+        public void WriteInt64(long value)

+        {

+            InitializeWriting();

+            try

+            {

+                this.dataOut.Write(PrimitiveMap.LONG_TYPE);

+                this.dataOut.Write(value);

+            }

+            catch(IOException e)

+            {

+                NMSExceptionSupport.Create(e);

+            }

+        }

+

+        public void WriteSingle(float value)

+        {

+            InitializeWriting();

+            try

+            {

+                this.dataOut.Write(PrimitiveMap.FLOAT_TYPE);

+                this.dataOut.Write(value);

+            }

+            catch(IOException e)

+            {

+                NMSExceptionSupport.Create(e);

+            }

+        }

+

+        public void WriteDouble(double value)

+        {

+            InitializeWriting();

+            try

+            {

+                this.dataOut.Write(PrimitiveMap.DOUBLE_TYPE);

+                this.dataOut.Write(value);

+            }

+            catch(IOException e)

+            {

+                NMSExceptionSupport.Create(e);

+            }

+        }

+

+        public void WriteString(string value)

+        {

+            InitializeWriting();

+            try

+            {

+                if( value.Length > 8192 )

+                {

+                    this.dataOut.Write(PrimitiveMap.BIG_STRING_TYPE);

+                    this.dataOut.WriteString32(value);

+                }

+                else

+                {

+                    this.dataOut.Write(PrimitiveMap.STRING_TYPE);

+                    this.dataOut.WriteString16(value);

+                }

+            }

+            catch(IOException e)

+            {