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)

+            {

+                NMSExceptionSupport.Create(e);

+            }

+        }

+

+        public void WriteObject(Object value)

+        {

+            InitializeWriting();

+            if( value is System.Byte )

+            {

+                this.WriteByte( (byte) value );

+            }

+            else if( value is Char )

+            {

+                this.WriteChar( (char) value );

+            }

+            else if( value is Boolean )

+            {

+                this.WriteBoolean( (bool) value );

+            }

+            else if( value is Int16 )

+            {

+                this.WriteInt16( (short) value );

+            }

+            else if( value is Int32 )

+            {

+                this.WriteInt32( (int) value );

+            }

+            else if( value is Int64 )

+            {

+                this.WriteInt64( (long) value );

+            }

+            else if( value is Single )

+            {

+                this.WriteSingle( (float) value );

+            }

+            else if( value is Double )

+            {

+                this.WriteDouble( (double) value );

+            }

+            else if( value is byte[] )

+            {

+                this.WriteBytes( (byte[]) value );

+            }

+            else if( value is String )

+            {

+                this.WriteString( (string) value );

+            }

+            else

+            {

+                throw new MessageFormatException("Cannot write non-primitive type:" + value.GetType());

+            }

+        }

+

+        public override Object Clone()

+        {

+            StoreContent();

+            return base.Clone();

+        }

+

+        public override void ClearBody()

+        {

+            base.ClearBody();

+            this.byteBuffer = null;

+            this.dataIn = null;

+            this.dataOut = null;

+            this.bytesRemaining = -1;

+        }

+

+        public void Reset()

+        {

+            StoreContent();

+            this.dataIn = null;

+            this.dataOut = null;

+            this.byteBuffer = null;

+            this.bytesRemaining = -1;

+            this.ReadOnlyBody = true;

+        }

+

+        private void InitializeReading()

+        {

+            FailIfWriteOnlyBody();

+            if(this.dataIn == null)

+            {

+                this.byteBuffer = new MemoryStream(this.Content, false);

+                this.dataIn = new EndianBinaryReader(this.byteBuffer);

+            }

+        }

+

+        private void InitializeWriting()

+        {

+            FailIfReadOnlyBody();

+            if(this.dataOut == null)

+            {

+                this.byteBuffer = new MemoryStream();

+                this.dataOut = new EndianBinaryWriter(this.byteBuffer);

+            }

+        }

+

+        private void StoreContent()

+        {

+            if( dataOut != null)

+            {

+                dataOut.Close();

+

+                this.Content = byteBuffer.ToArray();

+                this.dataOut = null;

+                this.byteBuffer = null;

+            }

+        }

+

+    }

+}

+

diff --git a/src/test/csharp/Commands/TempDestination.cs b/src/test/csharp/Commands/TempDestination.cs
new file mode 100644
index 0000000..6e2e63f
--- /dev/null
+++ b/src/test/csharp/Commands/TempDestination.cs
@@ -0,0 +1,70 @@
+/*

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

+{

+    public abstract class TempDestination : Destination

+    {

+        /// <summary>

+        /// Method CreateDestination

+        /// </summary>

+        /// <returns>An Destination</returns>

+        /// <param name="name">A  String</param>

+        public override Destination CreateDestination(String name)

+        {

+            return null;

+        }

+

+        abstract override public DestinationType DestinationType

+        {

+            get;

+        }

+

+        public TempDestination()

+            : base()

+        {

+        }

+

+        public TempDestination(String name)

+            : base(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.

+            TempDestination o = (TempDestination) base.Clone();

+

+            // Now do the deep work required

+            // If any new variables are added then this routine will

+            // likely need updating

+

+            return o;

+        }

+

+        public void Delete()

+        {

+            throw new NotSupportedException("Stomp Cannot Delete Temporary Destinations");

+        }

+    }

+}

+

diff --git a/src/test/csharp/Commands/TempQueue.cs b/src/test/csharp/Commands/TempQueue.cs
new file mode 100644
index 0000000..0f39e5e
--- /dev/null
+++ b/src/test/csharp/Commands/TempQueue.cs
@@ -0,0 +1,81 @@
+/*

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

+    /// A Temporary Queue

+    /// </summary>

+    public class TempQueue : TempDestination, ITemporaryQueue

+    {

+        public TempQueue()

+            : base()

+        {

+        }

+

+        public TempQueue(String name)

+            : base(name)

+        {

+        }

+

+        override public DestinationType DestinationType

+        {

+            get

+            {

+                return DestinationType.TemporaryQueue;

+            }

+        }

+

+        public String QueueName

+        {

+            get { return PhysicalName; }

+        }

+

+        public String GetQueueName()

+        {

+            return PhysicalName;

+        }

+

+        public override int GetDestinationType()

+        {

+            return TEMPORARY_QUEUE;

+        }

+

+        public override Destination CreateDestination(String name)

+        {

+            return new TempQueue(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.

+            TempQueue o = (TempQueue) 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/TempTopic.cs b/src/test/csharp/Commands/TempTopic.cs
new file mode 100644
index 0000000..3a42a55
--- /dev/null
+++ b/src/test/csharp/Commands/TempTopic.cs
@@ -0,0 +1,77 @@
+/*

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

+    /// A Temporary Topic

+    /// </summary>

+    public class TempTopic : TempDestination, ITemporaryTopic

+    {

+        public TempTopic() : base()

+        {

+        }

+

+        public TempTopic(String name) : base(name)

+        {

+        }

+

+        override public DestinationType DestinationType

+        {

+            get { return DestinationType.TemporaryTopic; }

+        }

+

+        public String TopicName

+        {

+            get { return PhysicalName; }

+        }

+

+        public String GetTopicName()

+        {

+            return PhysicalName;

+        }

+

+        public override int GetDestinationType()

+        {

+            return TEMPORARY_TOPIC;

+        }

+

+        public override Destination CreateDestination(String name)

+        {

+            return new TempTopic(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.

+            TempTopic o = (TempTopic) 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/TextMessage.cs b/src/test/csharp/Commands/TextMessage.cs
new file mode 100644
index 0000000..40eac3b
--- /dev/null
+++ b/src/test/csharp/Commands/TextMessage.cs
@@ -0,0 +1,70 @@
+/*

+ * 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 TextMessage : Message, ITextMessage

+    {

+        private String text = null;

+

+        public TextMessage()

+        {

+        }

+

+        public TextMessage(String text)

+        {

+            this.Text = text;

+        }

+

+        public override string ToString()

+        {

+            string text = this.Text;

+

+            if(text != null && text.Length > 63)

+            {

+                text = text.Substring(0, 45) + "..." + text.Substring(text.Length - 12);

+            }

+            return base.ToString() + " Text = " + (text ?? "null");

+        }

+

+        public override void ClearBody()

+        {

+            base.ClearBody();

+            this.text = null;

+        }

+

+        // Properties

+

+        public string Text

+        {

+            get { return this.text; }

+            set

+            {

+                FailIfReadOnlyBody();

+                this.text = value;

+                this.Content = null;

+            }

+        }

+    }

+}

+

diff --git a/src/test/csharp/Commands/Topic.cs b/src/test/csharp/Commands/Topic.cs
new file mode 100644
index 0000000..adb7c11
--- /dev/null
+++ b/src/test/csharp/Commands/Topic.cs
@@ -0,0 +1,74 @@
+/*

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

+    /// </summary>

+    public class Topic : Destination, ITopic

+    {

+        public Topic() : base()

+        {

+        }

+

+        public Topic(String name) : base(name)

+        {

+        }

+

+        override public DestinationType DestinationType

+        {

+            get

+            {

+                return DestinationType.Topic;

+            }

+        }

+

+        public String TopicName

+        {

+            get { return PhysicalName; }

+        }

+

+        public override int GetDestinationType()

+        {

+            return TOPIC;

+        }

+

+        public override Destination CreateDestination(String name)

+        {

+            return new Topic(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.

+            Topic o = (Topic) 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/ConnectionTest.cs b/src/test/csharp/ConnectionTest.cs
new file mode 100644
index 0000000..22cdf08
--- /dev/null
+++ b/src/test/csharp/ConnectionTest.cs
@@ -0,0 +1,191 @@
+/*

+ * 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 ConnectionTest : NMSTest

+	{

+		IConnection startedConnection = null;

+		IConnection stoppedConnection = null;

+

+		protected ConnectionTest(NMSTestSupport testSupport)

+			: base(testSupport)

+		{

+		}

+

+		//[SetUp]

+		public override void SetUp()

+		{

+			base.SetUp();

+

+			startedConnection = CreateConnection(null);

+			startedConnection.Start();

+			stoppedConnection = CreateConnection(null);

+		}

+

+		//[TearDown]

+		public override void TearDown()

+		{

+			startedConnection.Close();

+			stoppedConnection.Close();

+

+			base.TearDown();

+		}

+

+		/// <summary>

+		/// Verify that it is possible to create multiple connections to the broker.

+		/// There was a bug in the connection factory which set the clientId member which made

+		/// it impossible to create an additional connection.

+		/// </summary>

+		//[Test]

+		public virtual void TestTwoConnections()

+		{

+			using(IConnection connection1 = CreateConnection(null))

+			{

+				connection1.Start();

+				using(IConnection connection2 = CreateConnection(null))

+				{

+					// with the bug present we'll get an exception in connection2.start()

+					connection2.Start();

+				}

+			}

+		}

+

+		//[Test]

+		public virtual void TestCreateAndDisposeWithConsumer(

+			//[Values(true, false)]

+			bool disposeConsumer, string testQueueRef)

+		{

+			using(IConnection connection = CreateConnection("DisposalTestConnection"))

+			{

+				connection.Start();

+

+				using(ISession session = connection.CreateSession())

+				{

+					IDestination destination = GetClearDestination(session, DestinationType.Queue, testQueueRef);

+					IMessageConsumer consumer = session.CreateConsumer(destination);

+

+					connection.Stop();

+					if(disposeConsumer)

+					{

+						consumer.Dispose();

+					}

+				}

+			}

+		}

+

+		//[Test]

+		public virtual void TestCreateAndDisposeWithProducer(

+			//[Values(true, false)]

+			bool disposeProducer, string testQueueRef)

+		{

+			using(IConnection connection = CreateConnection("DisposalTestConnection"))

+			{

+				connection.Start();

+

+				using(ISession session = connection.CreateSession())

+				{

+					IDestination destination = GetClearDestination(session, DestinationType.Queue, testQueueRef);

+					IMessageProducer producer = session.CreateProducer(destination);

+

+					connection.Stop();

+					if(disposeProducer)

+					{

+						producer.Dispose();

+					}

+				}

+			}

+		}

+

+		//[Test]

+		public virtual void TestStartAfterSend(

+			//[Values(MsgDeliveryMode.Persistent, MsgDeliveryMode.NonPersistent)]

+			MsgDeliveryMode deliveryMode,

+			//[Values(DestinationType.Queue, DestinationType.Topic)]

+			DestinationType destinationType, string testDestinationRef)

+		{

+			using(IConnection connection = CreateConnection(GetTestClientId()))

+			{

+				ISession session = connection.CreateSession(AcknowledgementMode.AutoAcknowledge);

+				IDestination destination = GetClearDestination(session, destinationType, testDestinationRef);

+				IMessageConsumer consumer = session.CreateConsumer(destination);

+

+				// Send the messages

+				SendMessages(session, destination, deliveryMode, 1);

+

+				// Start the conncection after the message was sent.

+				connection.Start();

+

+				// Make sure only 1 message was delivered.

+				Assert.IsNotNull(consumer.Receive(TimeSpan.FromMilliseconds(1000)));

+				Assert.IsNull(consumer.ReceiveNoWait());

+			}

+		}

+

+		/// <summary>

+		/// Tests if the consumer receives the messages that were sent before the

+		/// connection was started.

+		/// </summary>

+		//[Test]

+		public virtual void TestStoppedConsumerHoldsMessagesTillStarted(string testTopicRef)

+		{

+			ISession startedSession = startedConnection.CreateSession(AcknowledgementMode.AutoAcknowledge);

+			ISession stoppedSession = stoppedConnection.CreateSession(AcknowledgementMode.AutoAcknowledge);

+

+			// Setup the consumers.

+			IDestination topic = GetClearDestination(startedSession, DestinationType.Topic, testTopicRef);

+			IMessageConsumer startedConsumer = startedSession.CreateConsumer(topic);

+			IMessageConsumer stoppedConsumer = stoppedSession.CreateConsumer(topic);

+

+			// Send the message.

+			IMessageProducer producer = startedSession.CreateProducer(topic);

+			ITextMessage message = startedSession.CreateTextMessage("Hello");

+			producer.Send(message);

+

+			// Test the assertions.

+			IMessage m = startedConsumer.Receive(TimeSpan.FromMilliseconds(1000));

+			Assert.IsNotNull(m);

+

+			m = stoppedConsumer.Receive(TimeSpan.FromMilliseconds(1000));

+			Assert.IsNull(m);

+

+			stoppedConnection.Start();

+			m = stoppedConsumer.Receive(TimeSpan.FromMilliseconds(5000));

+			Assert.IsNotNull(m);

+

+			startedSession.Close();

+			stoppedSession.Close();

+		}

+

+		/// <summary>

+		/// Tests if the consumer is able to receive messages eveb when the

+		/// connecction restarts multiple times.

+		/// </summary>

+		//[Test]

+		public virtual void TestMultipleConnectionStops(string testTopicRef)

+		{

+			TestStoppedConsumerHoldsMessagesTillStarted(testTopicRef);

+			stoppedConnection.Stop();

+			TestStoppedConsumerHoldsMessagesTillStarted(testTopicRef);

+			stoppedConnection.Stop();

+			TestStoppedConsumerHoldsMessagesTillStarted(testTopicRef);

+		}

+	}

+}

diff --git a/src/test/csharp/ConsumerTest.cs b/src/test/csharp/ConsumerTest.cs
new file mode 100644
index 0000000..a3aec2e
--- /dev/null
+++ b/src/test/csharp/ConsumerTest.cs
@@ -0,0 +1,573 @@
+/*

+ * 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 NUnit.Framework;

+

+namespace Apache.NMS.Test

+{

+	//[TestFixture]

+	public class ConsumerTest : NMSTest

+	{

+		protected const int COUNT = 25;

+		protected const string VALUE_NAME = "value";

+

+		private bool dontAck;

+

+		protected ConsumerTest(NMSTestSupport testSupport)

+			: base(testSupport)

+		{

+		}

+

+// The .NET CF does not have the ability to interrupt threads, so this test is impossible.

+#if !NETCF

+		//[Test]

+		public virtual void TestNoTimeoutConsumer(

+			//[Values(AcknowledgementMode.AutoAcknowledge, AcknowledgementMode.ClientAcknowledge,

+			//	AcknowledgementMode.DupsOkAcknowledge, AcknowledgementMode.Transactional)]

+			AcknowledgementMode ackMode)

+		{

+			// Launch a thread to perform IMessageConsumer.Receive().

+			// If it doesn't fail in less than three seconds, no exception was thrown.

+			Thread receiveThread = new Thread(new ThreadStart(TimeoutConsumerThreadProc));

+			using(IConnection connection = CreateConnection())

+			{

+				connection.Start();

+				using(ISession session = connection.CreateSession(ackMode))

+				{

+					ITemporaryQueue queue = session.CreateTemporaryQueue();

+					using(this.timeoutConsumer = session.CreateConsumer(queue))

+					{

+						receiveThread.Start();

+						if(receiveThread.Join(3000))

+						{

+							Assert.Fail("IMessageConsumer.Receive() returned without blocking.  Test failed.");

+						}

+						else

+						{

+							// Kill the thread - otherwise it'll sit in Receive() until a message arrives.

+							receiveThread.Interrupt();

+						}

+					}

+				}

+			}

+		}

+

+		protected IMessageConsumer timeoutConsumer;

+

+		protected void TimeoutConsumerThreadProc()

+		{

+			try

+			{

+				timeoutConsumer.Receive();

+			}

+			catch(ArgumentOutOfRangeException e)

+			{

+				// The test failed.  We will know because the timeout will expire inside TestNoTimeoutConsumer().

+				Assert.Fail("Test failed with exception: " + e.Message);

+			}

+			catch(ThreadInterruptedException)

+			{

+				// The test succeeded!  We were still blocked when we were interrupted.

+			}

+			catch(Exception e)

+			{

+				// Some other exception occurred.

+				Assert.Fail("Test failed with exception: " + e.Message);

+			}

+		}

+

+		//[Test]

+		public virtual void TestSyncReceiveConsumerClose(

+			//[Values(AcknowledgementMode.AutoAcknowledge, AcknowledgementMode.ClientAcknowledge,

+			//	AcknowledgementMode.DupsOkAcknowledge, AcknowledgementMode.Transactional)]

+			AcknowledgementMode ackMode)

+		{

+			// Launch a thread to perform IMessageConsumer.Receive().

+			// If it doesn't fail in less than three seconds, no exception was thrown.

+			Thread receiveThread = new Thread(new ThreadStart(TimeoutConsumerThreadProc));

+			using (IConnection connection = CreateConnection())

+			{

+				connection.Start();

+				using (ISession session = connection.CreateSession(ackMode))

+				{

+					ITemporaryQueue queue = session.CreateTemporaryQueue();

+					using (this.timeoutConsumer = session.CreateConsumer(queue))

+					{

+						receiveThread.Start();

+						if (receiveThread.Join(3000))

+						{

+							Assert.Fail("IMessageConsumer.Receive() returned without blocking.  Test failed.");

+						}

+						else

+						{

+							// Kill the thread - otherwise it'll sit in Receive() until a message arrives.

+							this.timeoutConsumer.Close();

+							receiveThread.Join(10000);

+							if (receiveThread.IsAlive)

+							{

+								// Kill the thread - otherwise it'll sit in Receive() until a message arrives.

+								receiveThread.Interrupt();

+								Assert.Fail("IMessageConsumer.Receive() thread is still alive, Close should have killed it.");

+							}

+						}

+					}

+				}

+			}

+		}

+

+		internal class ThreadArg

+		{

+			internal IConnection connection = null;

+			internal ISession session = null;

+			internal IDestination destination = null;

+		}

+

+		protected void DelayedProducerThreadProc(Object arg)

+		{

+			try

+			{

+				ThreadArg args = arg as ThreadArg;

+

+				using(ISession session = args.connection.CreateSession())

+				{

+					using(IMessageProducer producer = session.CreateProducer(args.destination))

+					{

+						// Give the consumer time to enter the receive.

+						Thread.Sleep(5000);

+

+						producer.Send(args.session.CreateTextMessage("Hello World"));

+					}

+				}

+			}

+			catch(Exception e)

+			{

+				// Some other exception occurred.

+				Assert.Fail("Test failed with exception: " + e.Message);

+			}

+		}

+

+		//[Test]

+		public virtual void TestDoChangeSentMessage(

+			//[Values(AcknowledgementMode.AutoAcknowledge, AcknowledgementMode.ClientAcknowledge,

+			//	AcknowledgementMode.DupsOkAcknowledge, AcknowledgementMode.Transactional)]

+			AcknowledgementMode ackMode,

+			//[Values(true, false)]

+			bool doClear)

+		{

+			using(IConnection connection = CreateConnection())

+			{

+				connection.Start();

+				using(ISession session = connection.CreateSession(ackMode))

+				{

+					ITemporaryQueue queue = session.CreateTemporaryQueue();

+					using(IMessageConsumer consumer = session.CreateConsumer(queue))

+					{

+						IMessageProducer producer = session.CreateProducer(queue);

+						ITextMessage message = session.CreateTextMessage();

+

+						string prefix = "ConsumerTest - TestDoChangeSentMessage: ";

+

+						for(int i = 0; i < COUNT; i++)

+						{

+							message.Properties[VALUE_NAME] = i;

+							message.Text = prefix + Convert.ToString(i);

+

+							producer.Send(message);

+

+							if(doClear)

+							{

+								message.ClearBody();

+								message.ClearProperties();

+							}

+						}

+

+						if(ackMode == AcknowledgementMode.Transactional)

+						{

+							session.Commit();

+						}

+

+						for(int i = 0; i < COUNT; i++)

+						{

+							ITextMessage msg = consumer.Receive(TimeSpan.FromMilliseconds(2000)) as ITextMessage;

+							Assert.AreEqual(msg.Text, prefix + Convert.ToString(i));

+							Assert.AreEqual(msg.Properties.GetInt(VALUE_NAME), i);

+						}

+

+						if(ackMode == AcknowledgementMode.Transactional)

+						{

+							session.Commit();

+						}

+

+					}

+				}

+			}

+		}

+

+		//[Test]

+		public virtual void TestConsumerReceiveBeforeMessageDispatched(

+			//[Values(AcknowledgementMode.AutoAcknowledge, AcknowledgementMode.ClientAcknowledge,

+			//	AcknowledgementMode.DupsOkAcknowledge, AcknowledgementMode.Transactional)]

+			AcknowledgementMode ackMode)

+		{

+			// Launch a thread to perform a delayed send.

+			Thread sendThread = new Thread(DelayedProducerThreadProc);

+			using(IConnection connection = CreateConnection())

+			{

+				connection.Start();

+				using(ISession session = connection.CreateSession(ackMode))

+				{

+					ITemporaryQueue queue = session.CreateTemporaryQueue();

+					using(IMessageConsumer consumer = session.CreateConsumer(queue))

+					{

+						ThreadArg arg = new ThreadArg();

+

+						arg.connection = connection;

+						arg.session = session;

+						arg.destination = queue;

+

+						sendThread.Start(arg);

+						IMessage message = consumer.Receive(TimeSpan.FromMinutes(1));

+						Assert.IsNotNull(message);

+					}

+				}

+			}

+		}

+

+		//[Test]

+		public virtual void TestDontStart(

+			//[Values(MsgDeliveryMode.NonPersistent)]

+			MsgDeliveryMode deliveryMode,

+			//[Values(DestinationType.Queue, DestinationType.Topic)]

+			DestinationType destinationType, string testDestinationRef)

+		{

+			using(IConnection connection = CreateConnection())

+			{

+				ISession session = connection.CreateSession();

+				IDestination destination = GetClearDestination(session, destinationType, testDestinationRef);

+				IMessageConsumer consumer = session.CreateConsumer(destination);

+

+				// Send the messages

+				SendMessages(session, destination, deliveryMode, 1);

+

+				// Make sure no messages were delivered.

+				Assert.IsNull(consumer.Receive(TimeSpan.FromMilliseconds(1000)));

+			}

+		}

+

+		//[Test]

+		public void TestSendReceiveTransacted(

+			//[Values(MsgDeliveryMode.NonPersistent, MsgDeliveryMode.Persistent)]

+			MsgDeliveryMode deliveryMode,

+			//[Values(DestinationType.Queue, DestinationType.Topic, DestinationType.TemporaryQueue, DestinationType.TemporaryTopic)]

+			DestinationType destinationType, string testDestinationRef)

+		{

+			using(IConnection connection = CreateConnection())

+			{

+				// Send a message to the broker.

+				connection.Start();

+				ISession session = connection.CreateSession(AcknowledgementMode.Transactional);

+				IDestination destination = GetClearDestination(session, destinationType, testDestinationRef);

+				IMessageConsumer consumer = session.CreateConsumer(destination);

+				IMessageProducer producer = session.CreateProducer(destination);

+

+				producer.DeliveryMode = deliveryMode;

+				producer.Send(session.CreateTextMessage("Test"));

+

+				// Message should not be delivered until commit.

+				Thread.Sleep(1000);

+				Assert.IsNull(consumer.ReceiveNoWait());

+				session.Commit();

+

+				// Make sure only 1 message was delivered.

+				IMessage message = consumer.Receive(TimeSpan.FromMilliseconds(1000));

+				Assert.IsNotNull(message);

+				Assert.IsFalse(message.NMSRedelivered);

+				Assert.IsNull(consumer.ReceiveNoWait());

+

+				// Message should be redelivered is rollback is used.

+				session.Rollback();

+

+				// Make sure only 1 message was delivered.

+				message = consumer.Receive(TimeSpan.FromMilliseconds(2000));

+				Assert.IsNotNull(message);

+				Assert.IsTrue(message.NMSRedelivered);

+				Assert.IsNull(consumer.ReceiveNoWait());

+

+				// If we commit now, the message should not be redelivered.

+				session.Commit();

+				Thread.Sleep(1000);

+				Assert.IsNull(consumer.ReceiveNoWait());

+			}

+		}

+

+		//[Test]

+		public virtual void TestAckedMessageAreConsumed(string testQueueRef)

+		{

+			using(IConnection connection = CreateConnection())

+			{

+				connection.Start();

+				ISession session = connection.CreateSession(AcknowledgementMode.ClientAcknowledge);

+				IDestination destination = GetClearDestination(session, DestinationType.Queue, testQueueRef);

+				IMessageProducer producer = session.CreateProducer(destination);

+				producer.Send(session.CreateTextMessage("Hello"));

+

+				// Consume the message...

+				IMessageConsumer consumer = session.CreateConsumer(destination);

+				IMessage msg = consumer.Receive(TimeSpan.FromMilliseconds(1000));

+				Assert.IsNotNull(msg);

+				msg.Acknowledge();

+

+				// Reset the session.

+				session.Close();

+				session = connection.CreateSession(AcknowledgementMode.ClientAcknowledge);

+

+				// Attempt to Consume the message...

+				consumer = session.CreateConsumer(destination);

+				msg = consumer.Receive(TimeSpan.FromMilliseconds(1000));

+				Assert.IsNull(msg);

+

+				session.Close();

+			}

+		}

+

+		//[Test]

+		public virtual void TestLastMessageAcked(string testQueueRef)

+		{

+			using(IConnection connection = CreateConnection())

+			{

+				connection.Start();

+				ISession session = connection.CreateSession(AcknowledgementMode.ClientAcknowledge);

+				IDestination destination = GetClearDestination(session, DestinationType.Queue, testQueueRef);

+				IMessageProducer producer = session.CreateProducer(destination);

+				producer.Send(session.CreateTextMessage("Hello"));

+				producer.Send(session.CreateTextMessage("Hello2"));

+				producer.Send(session.CreateTextMessage("Hello3"));

+

+				// Consume the message...

+				IMessageConsumer consumer = session.CreateConsumer(destination);

+				IMessage msg = consumer.Receive(TimeSpan.FromMilliseconds(1000));

+				Assert.IsNotNull(msg);

+				msg = consumer.Receive(TimeSpan.FromMilliseconds(1000));

+				Assert.IsNotNull(msg);

+				msg = consumer.Receive(TimeSpan.FromMilliseconds(1000));

+				Assert.IsNotNull(msg);

+				msg.Acknowledge();

+

+				// Reset the session.

+				session.Close();

+				session = connection.CreateSession(AcknowledgementMode.ClientAcknowledge);

+

+				// Attempt to Consume the message...

+				consumer = session.CreateConsumer(destination);

+				msg = consumer.Receive(TimeSpan.FromMilliseconds(1000));

+				Assert.IsNull(msg);

+

+				session.Close();

+			}

+		}

+

+		//[Test]

+		public virtual void TestUnAckedMessageAreNotConsumedOnSessionClose(string testQueueRef)

+		{

+			using(IConnection connection = CreateConnection())

+			{

+				connection.Start();

+				ISession session = connection.CreateSession(AcknowledgementMode.ClientAcknowledge);

+				IDestination destination = GetClearDestination(session, DestinationType.Queue, testQueueRef);

+				IMessageProducer producer = session.CreateProducer(destination);

+				producer.Send(session.CreateTextMessage("Hello"));

+

+				// Consume the message...

+				IMessageConsumer consumer = session.CreateConsumer(destination);

+				IMessage msg = consumer.Receive(TimeSpan.FromMilliseconds(1000));

+				Assert.IsNotNull(msg);

+				// Don't ack the message.

+

+				// Reset the session.  This should cause the unacknowledged message to be re-delivered.

+				session.Close();

+				session = connection.CreateSession(AcknowledgementMode.ClientAcknowledge);

+

+				// Attempt to Consume the message...

+				consumer = session.CreateConsumer(destination);

+				msg = consumer.Receive(TimeSpan.FromMilliseconds(2000));

+				Assert.IsNotNull(msg);

+				msg.Acknowledge();

+

+				session.Close();

+			}

+		}

+

+		//[Test]

+		public virtual void TestAsyncAckedMessageAreConsumed(string testQueueRef)

+		{

+			using(IConnection connection = CreateConnection())

+			{

+				connection.Start();

+				ISession session = connection.CreateSession(AcknowledgementMode.ClientAcknowledge);

+				IDestination destination = GetClearDestination(session, DestinationType.Queue, testQueueRef);

+				IMessageProducer producer = session.CreateProducer(destination);

+				producer.Send(session.CreateTextMessage("Hello"));

+

+				// Consume the message...

+				IMessageConsumer consumer = session.CreateConsumer(destination);

+				consumer.Listener += new MessageListener(OnMessage);

+

+				Thread.Sleep(5000);

+

+				// Reset the session.

+				session.Close();

+

+				session = connection.CreateSession(AcknowledgementMode.ClientAcknowledge);

+

+				// Attempt to Consume the message...

+				consumer = session.CreateConsumer(destination);

+				IMessage msg = consumer.Receive(TimeSpan.FromMilliseconds(1000));

+				Assert.IsNull(msg);

+

+				session.Close();

+			}

+		}

+

+		//[Test]

+		public virtual void TestAsyncUnAckedMessageAreNotConsumedOnSessionClose(string testQueueRef)

+		{

+			using(IConnection connection = CreateConnection())

+			{

+				connection.Start();

+				// don't aknowledge message on onMessage() call

+				dontAck = true;

+				ISession session = connection.CreateSession(AcknowledgementMode.ClientAcknowledge);

+				IDestination destination = GetClearDestination(session, DestinationType.Queue, testQueueRef);

+				IMessageProducer producer = session.CreateProducer(destination);

+				producer.Send(session.CreateTextMessage("Hello"));

+

+				// Consume the message...

+				using(IMessageConsumer consumer = session.CreateConsumer(destination))

+				{

+					consumer.Listener += new MessageListener(OnMessage);

+					// Don't ack the message.

+				}

+

+				// Reset the session. This should cause the Unacked message to be

+				// redelivered.

+				session.Close();

+

+				Thread.Sleep(5000);

+				session = connection.CreateSession(AcknowledgementMode.ClientAcknowledge);

+				// Attempt to Consume the message...

+				using(IMessageConsumer consumer = session.CreateConsumer(destination))

+				{

+					IMessage msg = consumer.Receive(TimeSpan.FromMilliseconds(2000));

+					Assert.IsNotNull(msg);

+					msg.Acknowledge();

+				}

+

+				session.Close();

+			}

+		}

+

+		//[Test]

+		public virtual void TestAddRemoveAsnycMessageListener()

+		{

+			using(IConnection connection = CreateConnection())

+			{

+				connection.Start();

+

+				ISession session = connection.CreateSession(AcknowledgementMode.ClientAcknowledge);

+				ITemporaryTopic topic = session.CreateTemporaryTopic();

+				IMessageConsumer consumer = session.CreateConsumer(topic);

+

+				consumer.Listener += OnMessage;

+				consumer.Listener -= OnMessage;

+				consumer.Listener += OnMessage;

+

+				consumer.Close();

+			}

+		}

+

+		public void OnMessage(IMessage message)

+		{

+			Assert.IsNotNull(message);

+

+			if(!dontAck)

+			{

+				try

+				{

+					message.Acknowledge();

+				}

+				catch(Exception)

+				{

+				}

+			}

+		}

+

+		//[Test]

+		public virtual void TestReceiveNoWait(

+			//[Values(AcknowledgementMode.AutoAcknowledge, AcknowledgementMode.ClientAcknowledge,

+			//	AcknowledgementMode.DupsOkAcknowledge, AcknowledgementMode.Transactional)]

+			AcknowledgementMode ackMode,

+			//[Values(MsgDeliveryMode.NonPersistent, MsgDeliveryMode.Persistent)]

+			MsgDeliveryMode deliveryMode)

+		{

+			const int RETRIES = 20;

+

+			using(IConnection connection = CreateConnection())

+			{

+				connection.Start();

+				using(ISession session = connection.CreateSession(ackMode))

+				{

+					IDestination destination = session.CreateTemporaryQueue();

+

+					using(IMessageProducer producer = session.CreateProducer(destination))

+					{

+						producer.DeliveryMode = deliveryMode;

+						ITextMessage message = session.CreateTextMessage("TEST");

+						producer.Send(message);

+

+						if(AcknowledgementMode.Transactional == ackMode)

+						{

+							session.Commit();

+						}

+					}

+

+					using(IMessageConsumer consumer = session.CreateConsumer(destination))

+					{

+						IMessage message = null;

+

+						for(int i = 0; i < RETRIES && message == null; ++i)

+						{

+							message = consumer.ReceiveNoWait();

+							Thread.Sleep(100);

+						}

+

+						Assert.IsNotNull(message);

+						message.Acknowledge();

+

+						if(AcknowledgementMode.Transactional == ackMode)

+						{

+							session.Commit();

+						}

+					}

+				}

+			}

+		}

+

+#endif

+

+    }

+}

diff --git a/src/test/csharp/DurableTest.cs b/src/test/csharp/DurableTest.cs
new file mode 100644
index 0000000..819f10c
--- /dev/null
+++ b/src/test/csharp/DurableTest.cs
@@ -0,0 +1,267 @@
+/*

+ * 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.Util;

+using NUnit.Framework;

+

+namespace Apache.NMS.Test

+{

+	//[TestFixture]

+	public class DurableTest : NMSTest

+	{

+		protected static string DURABLE_SELECTOR = "2 > 1";

+

+		protected string TEST_CLIENT_AND_CONSUMER_ID;

+		protected string SEND_CLIENT_ID;

+

+		protected DurableTest(NMSTestSupport testSupport)

+			: base(testSupport)

+		{

+		}

+

+		//[SetUp]

+		public override void SetUp()

+		{

+			base.SetUp();

+			

+			TEST_CLIENT_AND_CONSUMER_ID = GetTestClientId();

+			SEND_CLIENT_ID = GetTestClientId();

+		}

+

+		//[Test]

+		public virtual void TestSendWhileClosed(

+			//[Values(AcknowledgementMode.AutoAcknowledge, AcknowledgementMode.ClientAcknowledge,

+			//	AcknowledgementMode.DupsOkAcknowledge, AcknowledgementMode.Transactional)]

+			AcknowledgementMode ackMode, string testTopicRef)

+		{

+			try

+			{				

+		        using(IConnection connection = CreateConnection(TEST_CLIENT_AND_CONSUMER_ID))

+				{

+			        connection.Start();

+

+					using(ISession session = connection.CreateSession(ackMode))

+					{

+						ITopic topic = (ITopic)GetClearDestination(session, DestinationType.Topic, testTopicRef);

+						IMessageProducer producer = session.CreateProducer(topic);

+

+						producer.DeliveryMode = MsgDeliveryMode.Persistent;

+										

+				        ISession consumeSession = connection.CreateSession(ackMode);

+				        IMessageConsumer consumer = consumeSession.CreateDurableConsumer(topic, TEST_CLIENT_AND_CONSUMER_ID, null, false);

+				        Thread.Sleep(1000);

+				        consumer.Dispose();

+						consumer = null;

+				        

+						ITextMessage message = session.CreateTextMessage("DurableTest-TestSendWhileClosed");

+				        message.Properties.SetString("test", "test");

+				        message.NMSType = "test";

+				        producer.Send(message);

+						if(AcknowledgementMode.Transactional == ackMode)

+						{

+							session.Commit();

+						}

+										        

+				        Thread.Sleep(1000);

+						consumer = consumeSession.CreateDurableConsumer(topic, TEST_CLIENT_AND_CONSUMER_ID, null, false);

+				        ITextMessage msg = consumer.Receive(TimeSpan.FromMilliseconds(1000)) as ITextMessage;

+						msg.Acknowledge();

+						if(AcknowledgementMode.Transactional == ackMode)

+						{

+							consumeSession.Commit();

+						}

+						

+						Assert.IsNotNull(msg);

+				        Assert.AreEqual(msg.Text, "DurableTest-TestSendWhileClosed");

+				        Assert.AreEqual(msg.NMSType, "test");

+				        Assert.AreEqual(msg.Properties.GetString("test"), "test");

+					}

+				}

+			}

+			catch(Exception ex)

+			{

+				Assert.Fail(ex.Message);

+			}

+			finally

+			{

+                // Pause to allow Stomp to unregister at the broker.

+                Thread.Sleep(500);

+

+				UnregisterDurableConsumer(TEST_CLIENT_AND_CONSUMER_ID, TEST_CLIENT_AND_CONSUMER_ID);

+			}			

+	    }		

+		

+		//[Test]

+		public void TestDurableConsumerSelectorChange(

+			//[Values(AcknowledgementMode.AutoAcknowledge, AcknowledgementMode.ClientAcknowledge,

+			//	AcknowledgementMode.DupsOkAcknowledge, AcknowledgementMode.Transactional)]

+			AcknowledgementMode ackMode, string testTopicRef)

+		{

+			try

+			{

+				using(IConnection connection = CreateConnection(TEST_CLIENT_AND_CONSUMER_ID))

+				{

+					connection.Start();

+					using(ISession session = connection.CreateSession(ackMode))

+					{

+						ITopic topic = (ITopic)GetClearDestination(session, DestinationType.Topic, testTopicRef);

+						IMessageProducer producer = session.CreateProducer(topic);

+						IMessageConsumer consumer = session.CreateDurableConsumer(topic, TEST_CLIENT_AND_CONSUMER_ID, "color='red'", false);

+

+						producer.DeliveryMode = MsgDeliveryMode.Persistent;

+

+						// Send the messages

+						ITextMessage sendMessage = session.CreateTextMessage("1st");

+						sendMessage.Properties["color"] = "red";

+						producer.Send(sendMessage);

+						if(AcknowledgementMode.Transactional == ackMode)

+						{

+							session.Commit();

+						}

+

+						ITextMessage receiveMsg = consumer.Receive(receiveTimeout) as ITextMessage;

+						Assert.IsNotNull(receiveMsg, "Failed to retrieve 1st durable message.");

+						Assert.AreEqual("1st", receiveMsg.Text);

+						Assert.AreEqual(MsgDeliveryMode.Persistent, receiveMsg.NMSDeliveryMode, "NMSDeliveryMode does not match");

+						receiveMsg.Acknowledge();

+						if(AcknowledgementMode.Transactional == ackMode)

+						{

+							session.Commit();

+						}

+

+						// Change the subscription, allowing some time for the Broker to purge the

+						// consumers resources.

+						consumer.Dispose();

+                        Thread.Sleep(1000);

+						

+						consumer = session.CreateDurableConsumer(topic, TEST_CLIENT_AND_CONSUMER_ID, "color='blue'", false);

+

+						sendMessage = session.CreateTextMessage("2nd");

+						sendMessage.Properties["color"] = "red";

+						producer.Send(sendMessage);

+						sendMessage = session.CreateTextMessage("3rd");

+						sendMessage.Properties["color"] = "blue";

+						producer.Send(sendMessage);

+						if(AcknowledgementMode.Transactional == ackMode)

+						{

+							session.Commit();

+						}

+

+						// Selector should skip the 2nd message.

+						receiveMsg = consumer.Receive(receiveTimeout) as ITextMessage;

+						Assert.IsNotNull(receiveMsg, "Failed to retrieve durable message.");

+						Assert.AreEqual("3rd", receiveMsg.Text, "Retrieved the wrong durable message.");

+						Assert.AreEqual(MsgDeliveryMode.Persistent, receiveMsg.NMSDeliveryMode, "NMSDeliveryMode does not match");

+						receiveMsg.Acknowledge();

+						if(AcknowledgementMode.Transactional == ackMode)

+						{

+							session.Commit();

+						}

+

+						// Make sure there are no pending messages.

+						Assert.IsNull(consumer.ReceiveNoWait(), "Wrong number of messages in durable subscription.");

+					}

+				}

+			}

+			catch(Exception ex)

+			{

+				Assert.Fail(ex.Message);

+			}

+			finally

+			{

+                // Pause to allow Stomp to unregister at the broker.

+                Thread.Sleep(500);

+

+				UnregisterDurableConsumer(TEST_CLIENT_AND_CONSUMER_ID, TEST_CLIENT_AND_CONSUMER_ID);

+			}

+		}

+

+		//[Test]

+		public void TestDurableConsumer(

+			//[Values(AcknowledgementMode.AutoAcknowledge, AcknowledgementMode.ClientAcknowledge,

+			//	AcknowledgementMode.DupsOkAcknowledge, AcknowledgementMode.Transactional)]

+			AcknowledgementMode ackMode, string testDurableTopicName)

+		{

+			try

+			{

+				RegisterDurableConsumer(TEST_CLIENT_AND_CONSUMER_ID, testDurableTopicName, TEST_CLIENT_AND_CONSUMER_ID, null, false);

+				RunTestDurableConsumer(testDurableTopicName, ackMode);

+				if(AcknowledgementMode.Transactional == ackMode)

+				{

+					RunTestDurableConsumer(testDurableTopicName, ackMode);

+				}

+			}

+			finally

+			{

+                // Pause to allow Stomp to unregister at the broker.

+                Thread.Sleep(500);

+				

+				UnregisterDurableConsumer(TEST_CLIENT_AND_CONSUMER_ID, TEST_CLIENT_AND_CONSUMER_ID);

+			}

+		}

+

+		protected void RunTestDurableConsumer(string topicName, AcknowledgementMode ackMode)

+		{

+			SendDurableMessage(topicName);

+			SendDurableMessage(topicName);

+

+			using(IConnection connection = CreateConnection(TEST_CLIENT_AND_CONSUMER_ID))

+			{

+				connection.Start();

+				using(ISession session = connection.CreateSession(ackMode))

+				{

+					ITopic topic = SessionUtil.GetTopic(session, topicName);

+					using(IMessageConsumer consumer = session.CreateDurableConsumer(topic, TEST_CLIENT_AND_CONSUMER_ID, null, false))

+					{

+						IMessage msg = consumer.Receive(receiveTimeout);

+						Assert.IsNotNull(msg, "Did not receive first durable message.");

+						msg.Acknowledge();

+

+						msg = consumer.Receive(receiveTimeout);

+						Assert.IsNotNull(msg, "Did not receive second durable message.");

+						msg.Acknowledge();

+

+						if(AcknowledgementMode.Transactional == ackMode)

+						{

+							session.Commit();

+						}

+					}

+				}

+			}

+		}

+

+		protected void SendDurableMessage(string topicName)

+		{

+			using(IConnection connection = CreateConnection(SEND_CLIENT_ID))

+			{

+				connection.Start();

+				using(ISession session = connection.CreateSession())

+				{

+					ITopic topic = SessionUtil.GetTopic(session, topicName);

+					using(IMessageProducer producer = session.CreateProducer(topic))

+					{

+						ITextMessage message = session.CreateTextMessage("Durable Hello");

+

+						producer.DeliveryMode = MsgDeliveryMode.Persistent;

+						producer.Send(message);

+					}

+				}

+			}

+		}

+	}

+}

diff --git a/src/test/csharp/EndianBinaryReaderTest.cs b/src/test/csharp/EndianBinaryReaderTest.cs
new file mode 100644
index 0000000..dca24d0
--- /dev/null
+++ b/src/test/csharp/EndianBinaryReaderTest.cs
@@ -0,0 +1,162 @@
+/*

+ * 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.IO;

+using Apache.NMS.Util;

+using NUnit.Framework;

+

+namespace Apache.NMS.Test

+{

+	[TestFixture]

+	public class EndianBinaryReaderTest

+	{

+		public void readString16Helper(byte[] input, char[] expect)

+		{

+			MemoryStream stream = new MemoryStream(input);

+			EndianBinaryReader reader = new EndianBinaryReader(stream);

+

+			char[] result = reader.ReadString16().ToCharArray();

+

+			for(int i = 0; i < expect.Length; ++i)

+			{

+				Assert.AreEqual(expect[i], result[i]);

+			}

+		}

+

+		[Test]

+		public void testReadString16_1byteUTF8encoding()

+		{

+			// Test data with 1-byte UTF8 encoding.

+			char[] expect = { '\u0000', '\u000B', '\u0048', '\u0065', '\u006C', '\u006C', '\u006F', '\u0020', '\u0057', '\u006F', '\u0072', '\u006C', '\u0064' };

+			byte[] input = { 0x00, 0x0E, 0xC0, 0x80, 0x0B, 0x48, 0x65, 0x6C, 0x6C, 0x6F, 0x20, 0x57, 0x6F, 0x72, 0x6C, 0x64 };

+

+			readString16Helper(input, expect);

+		}

+

+		[Test]

+		public void testReadString16_2byteUTF8encoding()

+		{

+			// Test data with 2-byte UT8 encoding.

+			char[] expect = { '\u0000', '\u00C2', '\u00A9', '\u00C3', '\u00A6' };

+			byte[] input = { 0x00, 0x0A, 0xC0, 0x80, 0xC3, 0x82, 0xC2, 0xA9, 0xC3, 0x83, 0xC2, 0xA6 };

+			readString16Helper(input, expect);

+		}

+

+		[Test]

+		public void testReadString16_1byteAnd2byteEmbeddedNULLs()

+		{

+			// Test data with 1-byte and 2-byte encoding with embedded NULL's.

+			char[] expect = { '\u0000', '\u0004', '\u00C2', '\u00A9', '\u00C3', '\u0000', '\u00A6' };

+			byte[] input = { 0x00, 0x0D, 0xC0, 0x80, 0x04, 0xC3, 0x82, 0xC2, 0xA9, 0xC3, 0x83, 0xC0, 0x80, 0xC2, 0xA6 };

+

+			readString16Helper(input, expect);

+		}

+

+		[Test]

+		[ExpectedException(typeof(IOException))]

+		public void testReadString16_UTF8Missing2ndByte()

+		{

+			// Test with bad UTF-8 encoding, missing 2nd byte of two byte value

+			byte[] input = { 0x00, 0x0D, 0xC0, 0x80, 0x04, 0xC3, 0x82, 0xC2, 0xC2, 0xC3, 0x83, 0xC0, 0x80, 0xC2, 0xA6 };

+

+			MemoryStream stream = new MemoryStream(input);

+			EndianBinaryReader reader = new EndianBinaryReader(stream);

+

+			reader.ReadString16();

+		}

+

+		[Test]

+		[ExpectedException(typeof(IOException))]

+		public void testReadString16_3byteEncodingMissingLastByte()

+		{

+			// Test with three byte encode that's missing a last byte.

+			byte[] input = { 0x00, 0x02, 0xE8, 0xA8 };

+

+			MemoryStream stream = new MemoryStream(input);

+			EndianBinaryReader reader = new EndianBinaryReader(stream);

+

+			reader.ReadString16();

+		}

+

+		public void readString32Helper(byte[] input, char[] expect)

+		{

+			MemoryStream stream = new MemoryStream(input);

+			EndianBinaryReader reader = new EndianBinaryReader(stream);

+

+			char[] result = reader.ReadString32().ToCharArray();

+

+			for(int i = 0; i < expect.Length; ++i)

+			{

+				Assert.AreEqual(expect[i], result[i]);

+			}

+		}

+

+		[Test]

+		public void testReadString32_1byteUTF8encoding()

+		{

+			// Test data with 1-byte UTF8 encoding.

+			char[] expect = { '\u0000', '\u000B', '\u0048', '\u0065', '\u006C', '\u006C', '\u006F', '\u0020', '\u0057', '\u006F', '\u0072', '\u006C', '\u0064' };

+			byte[] input = { 0x00, 0x00, 0x00, 0x0E, 0xC0, 0x80, 0x0B, 0x48, 0x65, 0x6C, 0x6C, 0x6F, 0x20, 0x57, 0x6F, 0x72, 0x6C, 0x64 };

+

+			readString32Helper(input, expect);

+		}

+

+		[Test]

+		public void testReadString32_2byteUTF8encoding()

+		{

+			// Test data with 2-byte UT8 encoding.

+			char[] expect = { '\u0000', '\u00C2', '\u00A9', '\u00C3', '\u00A6' };

+			byte[] input = { 0x00, 0x00, 0x00, 0x0A, 0xC0, 0x80, 0xC3, 0x82, 0xC2, 0xA9, 0xC3, 0x83, 0xC2, 0xA6 };

+			readString32Helper(input, expect);

+		}

+

+		[Test]

+		public void testReadString32_1byteAnd2byteEmbeddedNULLs()

+		{

+			// Test data with 1-byte and 2-byte encoding with embedded NULL's.

+			char[] expect = { '\u0000', '\u0004', '\u00C2', '\u00A9', '\u00C3', '\u0000', '\u00A6' };

+			byte[] input = { 0x00, 0x00, 0x00, 0x0D, 0xC0, 0x80, 0x04, 0xC3, 0x82, 0xC2, 0xA9, 0xC3, 0x83, 0xC0, 0x80, 0xC2, 0xA6 };

+

+			readString32Helper(input, expect);

+		}

+

+		[Test]

+		[ExpectedException(typeof(IOException))]

+		public void testReadString32_UTF8Missing2ndByte()

+		{

+			// Test with bad UTF-8 encoding, missing 2nd byte of two byte value

+			byte[] input = { 0x00, 0x00, 0x00, 0x0D, 0xC0, 0x80, 0x04, 0xC3, 0x82, 0xC2, 0xC2, 0xC3, 0x83, 0xC0, 0x80, 0xC2, 0xA6 };

+

+			MemoryStream stream = new MemoryStream(input);

+			EndianBinaryReader reader = new EndianBinaryReader(stream);

+

+			reader.ReadString32();

+		}

+

+		[Test]

+		[ExpectedException(typeof(IOException))]

+		public void testReadString32_3byteEncodingMissingLastByte()

+		{

+			// Test with three byte encode that's missing a last byte.

+			byte[] input = { 0x00, 0x00, 0x00, 0x02, 0xE8, 0xA8 };

+

+			MemoryStream stream = new MemoryStream(input);

+			EndianBinaryReader reader = new EndianBinaryReader(stream);

+

+			reader.ReadString32();

+		}

+	}

+}

diff --git a/src/test/csharp/EndianBinaryWriterTest.cs b/src/test/csharp/EndianBinaryWriterTest.cs
new file mode 100644
index 0000000..635b449
--- /dev/null
+++ b/src/test/csharp/EndianBinaryWriterTest.cs
@@ -0,0 +1,202 @@
+/*

+ * 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.Util;

+using NUnit.Framework;

+

+namespace Apache.NMS.Test

+{

+	[TestFixture]

+	public class EndianBinaryWriterTest

+	{

+		void writeString16TestHelper(char[] input, byte[] expect)

+		{

+			MemoryStream stream = new MemoryStream();

+			EndianBinaryWriter writer = new EndianBinaryWriter(stream);

+

+			String str = new String(input);

+

+			writer.WriteString16(str);

+

+			byte[] result = stream.GetBuffer();

+

+			Assert.AreEqual(result[0], 0x00);

+			Assert.AreEqual(result[1], expect.Length);

+

+			for(int i = 4; i < expect.Length; ++i)

+			{

+				Assert.AreEqual(result[i], expect[i - 2]);

+			}

+		}

+

+		[Test]

+		public void testWriteString16_1byteUTF8encoding()

+		{

+			// Test data with 1-byte UTF8 encoding.

+			char[] input = { '\u0000', '\u000B', '\u0048', '\u0065', '\u006C', '\u006C', '\u006F', '\u0020', '\u0057', '\u006F', '\u0072', '\u006C', '\u0064' };

+			byte[] expect = { 0xC0, 0x80, 0x0B, 0x48, 0x65, 0x6C, 0x6C, 0x6F, 0x20, 0x57, 0x6F, 0x72, 0x6C, 0x64 };

+

+			writeString16TestHelper(input, expect);

+		}

+

+		[Test]

+		public void testWriteString16_2byteUTF8encoding()

+		{

+			// Test data with 2-byte UT8 encoding.

+			char[] input = { '\u0000', '\u00C2', '\u00A9', '\u00C3', '\u00A6' };

+			byte[] expect = { 0xC0, 0x80, 0xC3, 0x82, 0xC2, 0xA9, 0xC3, 0x83, 0xC2, 0xA6 };

+

+			writeString16TestHelper(input, expect);

+		}

+

+		[Test]

+		public void testWriteString16_1byteAnd2byteEmbeddedNULLs()

+		{

+			// Test data with 1-byte and 2-byte encoding with embedded NULL's.

+			char[] input = { '\u0000', '\u0004', '\u00C2', '\u00A9', '\u00C3', '\u0000', '\u00A6' };

+			byte[] expect = { 0xC0, 0x80, 0x04, 0xC3, 0x82, 0xC2, 0xA9, 0xC3, 0x83, 0xC0, 0x80, 0xC2, 0xA6 };

+

+			writeString16TestHelper(input, expect);

+		}

+

+		[Test]

+		public void testWriteString16_nullstring()

+		{

+			// test that a null string writes no output.

+			MemoryStream stream = new MemoryStream();

+			EndianBinaryWriter writer = new EndianBinaryWriter(stream);

+			writer.WriteString16(null);

+			Assert.AreEqual(0, stream.Length);

+		}

+

+		[Test]

+		public void testWriteString16_emptystring()

+		{

+			// test that a null string writes no output.

+			MemoryStream stream = new MemoryStream();

+			EndianBinaryWriter writer = new EndianBinaryWriter(stream);

+			writer.WriteString16("");

+

+			stream.Seek(0, SeekOrigin.Begin);

+			EndianBinaryReader reader = new EndianBinaryReader(stream);

+			Assert.AreEqual(0, reader.ReadInt16());

+		}

+

+		[Test]

+		[ExpectedException(typeof(IOException))]

+		public void testWriteString16_stringTooLong()

+		{

+			// String of length 65536 of Null Characters.

+			MemoryStream stream = new MemoryStream();

+			EndianBinaryWriter writer = new EndianBinaryWriter(stream);

+			String testStr = new String('a', 65536);

+			writer.Write(testStr);

+		}

+

+		[Test]

+		public void testWriteString16_maxStringLength()

+		{

+			// String of length 65535 of non Null Characters since Null encodes as UTF-8.

+			MemoryStream stream = new MemoryStream();

+			EndianBinaryWriter writer = new EndianBinaryWriter(stream);

+			String testStr = new String('a', 65535);

+			writer.Write(testStr);

+		}

+

+		[Test]

+		[ExpectedException(typeof(IOException))]

+		public void testWriteString16_invalidEncodingHeader()

+		{

+			// Set one of the 65535 bytes to a value that will result in a 2 byte UTF8 encoded sequence.

+			// This will cause the string of length 65535 to have a utf length of 65536.

+			MemoryStream stream = new MemoryStream();

+			EndianBinaryWriter writer = new EndianBinaryWriter(stream);

+			String testStr = new String('a', 65535);

+			char[] array = testStr.ToCharArray();

+			array[0] = '\u0000';

+			testStr = new String(array);

+			writer.Write(testStr);

+		}

+

+		void writeString32TestHelper(char[] input, byte[] expect)

+		{

+			MemoryStream stream = new MemoryStream();

+			EndianBinaryWriter writer = new EndianBinaryWriter(stream);

+

+			String str = new String(input);

+

+			writer.WriteString32(str);

+

+			byte[] result = stream.GetBuffer();

+

+			Assert.AreEqual(result[0], 0x00);

+			Assert.AreEqual(result[1], 0x00);

+			Assert.AreEqual(result[2], 0x00);

+			Assert.AreEqual(result[3], expect.Length);

+

+			for(int i = 4; i < expect.Length; ++i)

+			{

+				Assert.AreEqual(result[i], expect[i - 4]);

+			}

+		}

+

+		[Test]

+		public void testWriteString32_1byteUTF8encoding()

+		{

+			// Test data with 1-byte UTF8 encoding.

+			char[] input = { '\u0000', '\u000B', '\u0048', '\u0065', '\u006C', '\u006C', '\u006F', '\u0020', '\u0057', '\u006F', '\u0072', '\u006C', '\u0064' };

+			byte[] expect = { 0xC0, 0x80, 0x0B, 0x48, 0x65, 0x6C, 0x6C, 0x6F, 0x20, 0x57, 0x6F, 0x72, 0x6C, 0x64 };

+

+			writeString32TestHelper(input, expect);

+		}

+

+		[Test]

+		public void testWriteString32_2byteUTF8encoding()

+		{

+			// Test data with 2-byte UT8 encoding.

+			char[] input = { '\u0000', '\u00C2', '\u00A9', '\u00C3', '\u00A6' };

+			byte[] expect = { 0xC0, 0x80, 0xC3, 0x82, 0xC2, 0xA9, 0xC3, 0x83, 0xC2, 0xA6 };

+

+			writeString32TestHelper(input, expect);

+		}

+

+		[Test]

+		public void testWriteString32_1byteAnd2byteEmbeddedNULLs()

+		{

+			// Test data with 1-byte and 2-byte encoding with embedded NULL's.

+			char[] input = { '\u0000', '\u0004', '\u00C2', '\u00A9', '\u00C3', '\u0000', '\u00A6' };

+			byte[] expect = { 0xC0, 0x80, 0x04, 0xC3, 0x82, 0xC2, 0xA9, 0xC3, 0x83, 0xC0, 0x80, 0xC2, 0xA6 };

+

+			writeString32TestHelper(input, expect);

+		}

+

+		[Test]

+		public void testWriteString32_nullstring()

+		{

+			// test that a null strings writes a -1

+			MemoryStream stream = new MemoryStream();

+			EndianBinaryWriter writer = new EndianBinaryWriter(stream);

+			writer.WriteString32(null);

+

+			stream.Seek(0, SeekOrigin.Begin);

+			EndianBinaryReader reader = new EndianBinaryReader(stream);

+			Assert.AreEqual(-1, reader.ReadInt32());

+		}

+	}

+}

diff --git a/src/test/csharp/EndianTest.cs b/src/test/csharp/EndianTest.cs
new file mode 100644
index 0000000..773eaf1
--- /dev/null
+++ b/src/test/csharp/EndianTest.cs
@@ -0,0 +1,131 @@
+/*

+ * 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.IO;

+using Apache.NMS.Util;

+using NUnit.Framework;

+

+namespace Apache.NMS.Test

+{

+	[TestFixture]

+	public class EndianTest

+	{

+		[Test]

+		public void TestLongEndian()

+		{

+			long value = 0x0102030405060708L;

+			long newValue = EndianSupport.SwitchEndian(value);

+			Assert.AreEqual(0x0807060504030201L, newValue);

+			long actual = EndianSupport.SwitchEndian(newValue);

+			Assert.AreEqual(value, actual);

+		}

+

+		[Test]

+		public void TestIntEndian()

+		{

+			int value = 0x12345678;

+			int newValue = EndianSupport.SwitchEndian(value);

+			Assert.AreEqual(0x78563412, newValue);

+			int actual = EndianSupport.SwitchEndian(newValue);

+			Assert.AreEqual(value, actual);

+		}

+

+		[Test]

+		public void TestCharEndian()

+		{

+			char value = 'J';

+			char newValue = EndianSupport.SwitchEndian(value);

+			char actual = EndianSupport.SwitchEndian(newValue);

+			Assert.AreEqual(value, actual);

+		}

+

+		[Test]

+		public void TestShortEndian()

+		{

+			short value = 0x1234;

+			short newValue = EndianSupport.SwitchEndian(value);

+			Assert.AreEqual(0x3412, newValue);

+			short actual = EndianSupport.SwitchEndian(newValue);

+			Assert.AreEqual(value, actual);

+		}

+

+		[Test]

+		public void TestNegativeLongEndian()

+		{

+			long value = -0x0102030405060708L;

+			long newValue = EndianSupport.SwitchEndian(value);

+			long actual = EndianSupport.SwitchEndian(newValue);

+			Assert.AreEqual(value, actual);

+		}

+

+		[Test]

+		public void TestNegativeIntEndian()

+		{

+			int value = -0x12345678;

+			int newValue = EndianSupport.SwitchEndian(value);

+			int actual = EndianSupport.SwitchEndian(newValue);

+			Assert.AreEqual(value, actual);

+		}

+

+		[Test]

+		public void TestNegativeShortEndian()

+		{

+			short value = -0x1234;

+			short newValue = EndianSupport.SwitchEndian(value);

+			short actual = EndianSupport.SwitchEndian(newValue);

+			Assert.AreEqual(value, actual);

+		}

+

+		[Test]

+		public void TestFloatDontNeedEndianSwitch()

+		{

+			float value = -1.223F;

+

+			// Convert to int so we can compare to Java version.

+			MemoryStream ms = new MemoryStream(4);

+			BinaryWriter bw = new BinaryWriter(ms);

+			bw.Write(value);

+			bw.Close();

+			ms = new MemoryStream(ms.ToArray());

+			BinaryReader br = new BinaryReader(ms);

+

+			// System.out.println(Integer.toString(Float.floatToIntBits(-1.223F), 16));

+			Assert.AreEqual(-0x406374bc, br.ReadInt32());

+		}

+

+		[Test]

+		public void TestDoublDontNeedEndianSwitch()

+		{

+			double value = -1.223D;

+

+			// Convert to int so we can compare to Java version.

+			MemoryStream ms = new MemoryStream(4);

+			BinaryWriter bw = new BinaryWriter(ms);

+			bw.Write(value);

+			bw.Close();

+			ms = new MemoryStream(ms.ToArray());

+			BinaryReader br = new BinaryReader(ms);

+			long longVersion = br.ReadInt64();

+

+			// System.out.println(Long.toString(Double.doubleToLongBits(-1.223D), 16));

+			Assert.AreEqual(-0x400c6e978d4fdf3b, longVersion);

+		}

+	}

+}

+

+

+

diff --git a/src/test/csharp/ForeignMessageTransformationTest.cs b/src/test/csharp/ForeignMessageTransformationTest.cs
new file mode 100644
index 0000000..e5870b8
--- /dev/null
+++ b/src/test/csharp/ForeignMessageTransformationTest.cs
@@ -0,0 +1,305 @@
+/*

+ * 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.Commands;

+using NUnit.Framework;

+

+namespace Apache.NMS.Test

+{

+    //[TestFixture]

+    public class ForeignMessageTransformationTest : NMSTest

+    {

+        private string propertyName = "Test-Property";

+        private string propertyValue = "Test-Property-Value";

+        private string mapElementName = "Test-Map-Property";

+        private string mapElementValue = "Test-Map-Property-Value";

+        private string textBody = "This is a TextMessage from a Foreign Provider";

+        private byte[] bytesContent = {1, 2, 3, 4, 5, 6, 7, 8};

+

+        private bool a = true;

+        private byte b = 123;

+        private char c = 'c';

+        private short d = 0x1234;

+        private int e = 0x12345678;

+        private long f = 0x1234567812345678;

+        private string g = "Hello World!";

+        private bool h = false;

+        private byte i = 0xFF;

+        private short j = -0x1234;

+        private int k = -0x12345678;

+        private long l = -0x1234567812345678;

+        private float m = 2.1F;

+        private double n = 2.3;

+

+		protected ForeignMessageTransformationTest(NMSTestSupport testSupport)

+			: base(testSupport)

+		{

+		}

+

+        //[Test]

+        public virtual void TestSendReceiveForeignMessage(

+            //[Values(MsgDeliveryMode.Persistent, MsgDeliveryMode.NonPersistent)]

+            MsgDeliveryMode deliveryMode, string testTopicRef)

+        {

+            using(IConnection connection = CreateConnection())

+            {

+                connection.Start();

+                using(ISession session = connection.CreateSession(AcknowledgementMode.AutoAcknowledge))

+                {

+					IDestination destination = GetClearDestination(session, DestinationType.Topic, testTopicRef);

+                    using(IMessageConsumer consumer = session.CreateConsumer(destination))

+                    using(IMessageProducer producer = session.CreateProducer(destination))

+                    {

+                        try

+                        {

+                            producer.DeliveryMode = deliveryMode;

+                            Message request = new Message();

+                            request.Properties[propertyName] = propertyValue;

+

+                            producer.Send(request);

+

+                            IMessage message = consumer.Receive(receiveTimeout);

+                            Assert.IsNotNull(message, "No message returned!");

+                            Assert.AreEqual(request.Properties.Count, message.Properties.Count, "Invalid number of properties.");

+                            Assert.AreEqual(deliveryMode, message.NMSDeliveryMode, "NMSDeliveryMode does not match");

+

+                            // use generic API to access entries

+                            Assert.AreEqual(propertyValue, message.Properties[propertyName], "generic map entry: " + propertyName);

+

+                            // use type safe APIs

+                            Assert.AreEqual(propertyValue, message.Properties.GetString(propertyName),   "map entry: " + propertyName);

+                        }

+                        catch(NotSupportedException)

+                        {

+                        }

+                    }

+                }

+            }

+        }

+

+        //[Test]

+        public virtual void TestSendReceiveForeignTextMessage(

+            //[Values(MsgDeliveryMode.Persistent, MsgDeliveryMode.NonPersistent)]

+            MsgDeliveryMode deliveryMode, string testTopicRef)

+        {

+            using(IConnection connection = CreateConnection())

+            {

+                connection.Start();

+                using(ISession session = connection.CreateSession(AcknowledgementMode.AutoAcknowledge))

+                {

+					IDestination destination = GetClearDestination(session, DestinationType.Topic, testTopicRef);

+                    using(IMessageConsumer consumer = session.CreateConsumer(destination))

+                    using(IMessageProducer producer = session.CreateProducer(destination))

+                    {

+                        try

+                        {

+                            producer.DeliveryMode = deliveryMode;

+                            TextMessage request = new TextMessage();

+                            request.Properties[propertyName] = propertyValue;

+                            request.Text = textBody;

+

+                            producer.Send(request);

+

+                            ITextMessage message = consumer.Receive(receiveTimeout) as ITextMessage;

+                            Assert.IsNotNull(message, "No message returned!");

+                            Assert.AreEqual(request.Properties.Count, message.Properties.Count, "Invalid number of properties.");

+                            Assert.AreEqual(deliveryMode, message.NMSDeliveryMode, "NMSDeliveryMode does not match");

+

+                            // Check the body

+                            Assert.AreEqual(textBody, message.Text, "TextMessage body was wrong.");

+

+                            // use generic API to access entries

+                            Assert.AreEqual(propertyValue, message.Properties[propertyName], "generic map entry: " + propertyName);

+

+                            // use type safe APIs

+                            Assert.AreEqual(propertyValue, message.Properties.GetString(propertyName),   "map entry: " + propertyName);

+                        }

+                        catch(NotSupportedException)

+                        {

+                        }

+                    }

+                }

+            }

+        }

+

+		//[Test]

+		public virtual void TestSendReceiveForeignBytesMessage(

+			//[Values(MsgDeliveryMode.Persistent, MsgDeliveryMode.NonPersistent)]

+			MsgDeliveryMode deliveryMode, string testTopicRef)

+		{

+			using(IConnection connection = CreateConnection())

+			{

+				connection.Start();

+				using(ISession session = connection.CreateSession(AcknowledgementMode.AutoAcknowledge))

+				{

+					IDestination destination = GetClearDestination(session, DestinationType.Topic, testTopicRef);

+					using(IMessageConsumer consumer = session.CreateConsumer(destination))

+					using(IMessageProducer producer = session.CreateProducer(destination))

+					{

+						try

+						{

+							producer.DeliveryMode = deliveryMode;

+							BytesMessage request = new BytesMessage();

+							request.Properties[propertyName] = propertyValue;

+							request.WriteBytes(bytesContent);

+

+							producer.Send(request);

+

+							IBytesMessage message = consumer.Receive(receiveTimeout) as IBytesMessage;

+							Assert.IsNotNull(message, "No message returned!");

+							Assert.AreEqual(request.Properties.Count, message.Properties.Count, "Invalid number of properties.");

+							Assert.AreEqual(deliveryMode, message.NMSDeliveryMode, "NMSDeliveryMode does not match");

+

+							// Check the body

+							byte[] content = new byte[bytesContent.Length];

+							Assert.AreEqual(bytesContent.Length, message.ReadBytes(content));

+							Assert.AreEqual(bytesContent, content, "BytesMessage body was wrong.");

+

+							// use generic API to access entries

+							Assert.AreEqual(propertyValue, message.Properties[propertyName], "generic map entry: " + propertyName);

+

+							// use type safe APIs

+							Assert.AreEqual(propertyValue, message.Properties.GetString(propertyName),   "map entry: " + propertyName);

+						}

+						catch(NotSupportedException)

+						{

+						}

+					}

+				}

+			}

+		}

+

+		//[Test]

+		public virtual void TestSendReceiveForeignMapMessage(

+			//[Values(MsgDeliveryMode.Persistent, MsgDeliveryMode.NonPersistent)]

+			MsgDeliveryMode deliveryMode, string testTopicRef)

+		{

+			using(IConnection connection = CreateConnection())

+			{

+				connection.Start();

+				using(ISession session = connection.CreateSession(AcknowledgementMode.AutoAcknowledge))

+				{

+					IDestination destination = GetClearDestination(session, DestinationType.Topic, testTopicRef);

+					using(IMessageConsumer consumer = session.CreateConsumer(destination))

+					using(IMessageProducer producer = session.CreateProducer(destination))

+					{

+						try

+						{

+							producer.DeliveryMode = deliveryMode;

+							MapMessage request = new MapMessage();

+							request.Properties[propertyName] = propertyValue;

+							request.Body[mapElementName] = mapElementValue;

+

+							producer.Send(request);

+

+							IMapMessage message = consumer.Receive(receiveTimeout) as IMapMessage;

+							Assert.IsNotNull(message, "No message returned!");

+							Assert.AreEqual(request.Properties.Count, message.Properties.Count, "Invalid number of properties.");

+							Assert.AreEqual(deliveryMode, message.NMSDeliveryMode, "NMSDeliveryMode does not match");

+

+							// Check the body

+							Assert.AreEqual(request.Body.Count, message.Body.Count);

+							Assert.AreEqual(mapElementValue, message.Body[mapElementName], "MapMessage body was wrong.");

+

+							// use generic API to access entries

+							Assert.AreEqual(propertyValue, message.Properties[propertyName], "generic map entry: " + propertyName);

+

+							// use type safe APIs

+							Assert.AreEqual(propertyValue, message.Properties.GetString(propertyName),   "map entry: " + propertyName);

+						}

+						catch(NotSupportedException)

+						{

+						}

+					}

+				}

+			}

+		}

+

+		//[Test]

+		public virtual void TestSendReceiveForeignStreamMessage(

+			//[Values(MsgDeliveryMode.Persistent, MsgDeliveryMode.NonPersistent)]

+			MsgDeliveryMode deliveryMode, string testTopicRef)

+		{

+			using(IConnection connection = CreateConnection())

+			{

+				connection.Start();

+				using(ISession session = connection.CreateSession(AcknowledgementMode.AutoAcknowledge))

+				{

+					IDestination destination = GetClearDestination(session, DestinationType.Topic, testTopicRef);

+					using(IMessageConsumer consumer = session.CreateConsumer(destination))

+					using(IMessageProducer producer = session.CreateProducer(destination))

+					{

+						try

+						{

+							producer.DeliveryMode = deliveryMode;

+							StreamMessage request = new StreamMessage();

+							request.Properties[propertyName] = propertyValue;

+

+							request.WriteBoolean(a);

+							request.WriteByte(b);

+							request.WriteChar(c);

+							request.WriteInt16(d);

+							request.WriteInt32(e);

+							request.WriteInt64(f);

+							request.WriteString(g);

+							request.WriteBoolean(h);

+							request.WriteByte(i);

+							request.WriteInt16(j);

+							request.WriteInt32(k);

+							request.WriteInt64(l);

+							request.WriteSingle(m);

+							request.WriteDouble(n);

+

+							producer.Send(request);

+

+							IStreamMessage message = consumer.Receive(receiveTimeout) as IStreamMessage;

+							Assert.IsNotNull(message, "No message returned!");

+							Assert.AreEqual(request.Properties.Count, message.Properties.Count, "Invalid number of properties.");

+							Assert.AreEqual(deliveryMode, message.NMSDeliveryMode, "NMSDeliveryMode does not match");

+

+							// Check the body

+							Assert.AreEqual(a, message.ReadBoolean(), "Stream Boolean Value: a");

+							Assert.AreEqual(b, message.ReadByte(), "Stream Byte Value: b");

+							Assert.AreEqual(c, message.ReadChar(), "Stream Char Value: c");

+							Assert.AreEqual(d, message.ReadInt16(), "Stream Int16 Value: d");

+							Assert.AreEqual(e, message.ReadInt32(), "Stream Int32 Value: e");

+							Assert.AreEqual(f, message.ReadInt64(), "Stream Int64 Value: f");

+							Assert.AreEqual(g, message.ReadString(), "Stream String Value: g");

+							Assert.AreEqual(h, message.ReadBoolean(), "Stream Boolean Value: h");

+							Assert.AreEqual(i, message.ReadByte(), "Stream Byte Value: i");

+							Assert.AreEqual(j, message.ReadInt16(), "Stream Int16 Value: j");

+							Assert.AreEqual(k, message.ReadInt32(), "Stream Int32 Value: k");

+							Assert.AreEqual(l, message.ReadInt64(), "Stream Int64 Value: l");

+							Assert.AreEqual(m, message.ReadSingle(), "Stream Single Value: m");

+							Assert.AreEqual(n, message.ReadDouble(), "Stream Double Value: n");

+

+							// use generic API to access entries

+							Assert.AreEqual(propertyValue, message.Properties[propertyName], "generic map entry: " + propertyName);

+

+							// use type safe APIs

+							Assert.AreEqual(propertyValue, message.Properties.GetString(propertyName),   "map entry: " + propertyName);

+						}

+						catch(NotSupportedException)

+						{

+						}

+					}

+				}

+			}

+		}

+	}

+}

diff --git a/src/test/csharp/MapMessageTest.cs b/src/test/csharp/MapMessageTest.cs
new file mode 100644
index 0000000..6b7385d
--- /dev/null
+++ b/src/test/csharp/MapMessageTest.cs
@@ -0,0 +1,208 @@
+/*

+ * 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;

+using NUnit.Framework;

+

+namespace Apache.NMS.Test

+{

+	//[TestFixture]

+	public class MapMessageTest : NMSTest

+	{

+		protected bool a = true;

+		protected byte b = 123;

+		protected char c = 'c';

+		protected short d = 0x1234;

+		protected int e = 0x12345678;

+		protected long f = 0x1234567812345678;

+		protected string g = "Hello World!";

+		protected bool h = false;

+		protected byte i = 0xFF;

+		protected short j = -0x1234;

+		protected int k = -0x12345678;

+		protected long l = -0x1234567812345678;

+		protected float m = 2.1F;

+		protected double n = 2.3;

+		protected byte[] o = {1, 2, 3, 4, 5};

+

+		protected MapMessageTest(NMSTestSupport testSupport)

+			: base(testSupport)

+		{

+		}

+

+		//[Test]

+		public virtual void TestSendReceiveMapMessage(

+			//[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;

+						IMapMessage request = session.CreateMapMessage();

+						request.Body["a"] = a;

+						request.Body["b"] = b;

+						request.Body["c"] = c;

+						request.Body["d"] = d;

+						request.Body["e"] = e;

+						request.Body["f"] = f;

+						request.Body["g"] = g;

+						request.Body["h"] = h;

+						request.Body["i"] = i;

+						request.Body["j"] = j;

+						request.Body["k"] = k;

+						request.Body["l"] = l;

+						request.Body["m"] = m;

+						request.Body["n"] = n;

+						request.Body["o"] = o;

+						producer.Send(request);

+

+						IMapMessage message = consumer.Receive(receiveTimeout) as IMapMessage;

+						Assert.IsNotNull(message, "No message returned!");

+						Assert.AreEqual(request.Body.Count, message.Body.Count, "Invalid number of message maps.");

+						Assert.AreEqual(deliveryMode, message.NMSDeliveryMode, "NMSDeliveryMode does not match");

+						Assert.AreEqual(ToHex(f), ToHex(message.Body.GetLong("f")), "map entry: f as hex");

+

+						// use generic API to access entries

+						Assert.AreEqual(a, message.Body["a"], "generic map entry: a");

+						Assert.AreEqual(b, message.Body["b"], "generic map entry: b");

+						Assert.AreEqual(c, message.Body["c"], "generic map entry: c");

+						Assert.AreEqual(d, message.Body["d"], "generic map entry: d");

+						Assert.AreEqual(e, message.Body["e"], "generic map entry: e");

+						Assert.AreEqual(f, message.Body["f"], "generic map entry: f");

+						Assert.AreEqual(g, message.Body["g"], "generic map entry: g");

+						Assert.AreEqual(h, message.Body["h"], "generic map entry: h");

+						Assert.AreEqual(i, message.Body["i"], "generic map entry: i");

+						Assert.AreEqual(j, message.Body["j"], "generic map entry: j");

+						Assert.AreEqual(k, message.Body["k"], "generic map entry: k");

+						Assert.AreEqual(l, message.Body["l"], "generic map entry: l");

+						Assert.AreEqual(m, message.Body["m"], "generic map entry: m");

+						Assert.AreEqual(n, message.Body["n"], "generic map entry: n");

+						Assert.AreEqual(o, message.Body["o"], "generic map entry: o");

+

+						// use type safe APIs

+						Assert.AreEqual(a, message.Body.GetBool("a"), "map entry: a");

+						Assert.AreEqual(b, message.Body.GetByte("b"), "map entry: b");

+						Assert.AreEqual(c, message.Body.GetChar("c"), "map entry: c");

+						Assert.AreEqual(d, message.Body.GetShort("d"), "map entry: d");

+						Assert.AreEqual(e, message.Body.GetInt("e"), "map entry: e");

+						Assert.AreEqual(f, message.Body.GetLong("f"), "map entry: f");

+						Assert.AreEqual(g, message.Body.GetString("g"), "map entry: g");

+						Assert.AreEqual(h, message.Body.GetBool("h"), "map entry: h");

+						Assert.AreEqual(i, message.Body.GetByte("i"), "map entry: i");

+						Assert.AreEqual(j, message.Body.GetShort("j"), "map entry: j");

+						Assert.AreEqual(k, message.Body.GetInt("k"), "map entry: k");

+						Assert.AreEqual(l, message.Body.GetLong("l"), "map entry: l");

+						Assert.AreEqual(m, message.Body.GetFloat("m"), "map entry: m");

+						Assert.AreEqual(n, message.Body.GetDouble("n"), "map entry: n");

+						Assert.AreEqual(o, message.Body.GetBytes("o"), "map entry: o");

+					}

+				}

+			}

+		}

+

+		//[Test]

+		public virtual void TestSendReceiveNestedMapMessage(

+			//[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))

+					{

+						try

+						{

+							producer.DeliveryMode = deliveryMode;

+							IMapMessage request = session.CreateMapMessage();

+							const string textFieldValue = "Nested Map Messages Rule!";

+

+							request.Body.SetString("textField", textFieldValue);

+

+							IDictionary grandChildMap = new Hashtable();

+							grandChildMap["x"] = "abc";

+							grandChildMap["y"] = new ArrayList(new object[] { "a", "b", "c" });

+

+							IDictionary nestedMap = new Hashtable();

+							nestedMap["a"] = "foo";

+							nestedMap["b"] = (int) 23;

+							nestedMap["c"] = (long) 45;

+							nestedMap["d"] = grandChildMap;

+

+							request.Body.SetDictionary("mapField", nestedMap);

+							request.Body.SetList("listField", new ArrayList(new Object[] { "a", "b", "c" }));

+

+							producer.Send(request);

+

+							IMapMessage message = consumer.Receive(receiveTimeout) as IMapMessage;

+							Assert.IsNotNull(message, "No message returned!");

+							Assert.AreEqual(request.Body.Count, message.Body.Count, "Invalid number of message maps.");

+							Assert.AreEqual(deliveryMode, message.NMSDeliveryMode, "NMSDeliveryMode does not match");

+

+							string textFieldResponse = message.Body.GetString("textField");

+							Assert.AreEqual(textFieldValue, textFieldResponse, "textField does not match.");

+

+							IDictionary nestedMapResponse = message.Body.GetDictionary("mapField");

+							Assert.IsNotNull(nestedMapResponse, "Nested map not returned.");

+							Assert.AreEqual(nestedMap.Count, nestedMapResponse.Count, "nestedMap: Wrong number of elements");

+							Assert.AreEqual("foo", nestedMapResponse["a"], "nestedMap: a");

+							Assert.AreEqual(23, nestedMapResponse["b"], "nestedMap: b");

+							Assert.AreEqual(45, nestedMapResponse["c"], "nestedMap: c");

+

+							IDictionary grandChildMapResponse = nestedMapResponse["d"] as IDictionary;

+							Assert.IsNotNull(grandChildMapResponse, "Grand child map not returned.");

+							Assert.AreEqual(grandChildMap.Count, grandChildMapResponse.Count, "grandChildMap: Wrong number of elements");

+							Assert.AreEqual(grandChildMapResponse["x"], "abc", "grandChildMap: x");

+

+							IList grandChildList = grandChildMapResponse["y"] as IList;

+							Assert.IsNotNull(grandChildList, "Grand child list not returned.");

+							Assert.AreEqual(3, grandChildList.Count, "grandChildList: Wrong number of list elements.");

+							Assert.AreEqual("a", grandChildList[0], "grandChildList: a");

+							Assert.AreEqual("b", grandChildList[1], "grandChildList: b");

+							Assert.AreEqual("c", grandChildList[2], "grandChildList: c");

+

+							IList listFieldResponse = message.Body.GetList("listField");

+							Assert.IsNotNull(listFieldResponse, "Nested list not returned.");

+							Assert.AreEqual(3, listFieldResponse.Count, "listFieldResponse: Wrong number of list elements.");

+							Assert.AreEqual("a", listFieldResponse[0], "listFieldResponse: a");

+							Assert.AreEqual("b", listFieldResponse[1], "listFieldResponse: b");

+							Assert.AreEqual("c", listFieldResponse[2], "listFieldResponse: c");

+						}

+						catch(NotSupportedException)

+						{

+						}

+						catch(NMSException e)

+						{

+							Assert.IsTrue(e.InnerException.GetType() == typeof(NotSupportedException));

+						}

+					}

+				}

+			}

+		}

+	}

+}

diff --git a/src/test/csharp/MessageSelectorTest.cs b/src/test/csharp/MessageSelectorTest.cs
new file mode 100644
index 0000000..03f0a4e
--- /dev/null
+++ b/src/test/csharp/MessageSelectorTest.cs
@@ -0,0 +1,184 @@
+/*

+ * 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.Util;

+using NUnit.Framework;

+

+namespace Apache.NMS.Test

+{

+	//[TestFixture]

+	//[Category("LongRunning")]

+	public class MessageSelectorTest : NMSTest

+	{

+		private int receivedNonIgnoredMsgCount = 0;

+		private int receivedIgnoredMsgCount = 0;

+		private bool simulateSlowConsumer = false;

+

+		protected MessageSelectorTest(NMSTestSupport testSupport)

+			: base(testSupport)

+		{

+		}

+

+		//[Test]

+		public virtual void TestFilterIgnoredMessages(

+			//[Values(SELECTOR_TEST_QUEUE_URI, SELECTOR_TEST_TOPIC_URI)]

+			string testDestinationURI)

+		{

+			simulateSlowConsumer = false;

+			RunFilterIgnoredMessagesTest(testDestinationURI);

+		}

+

+		/// <summary>

+		/// A slow consumer will trigger the producer flow control on the broker when the destination is

+		/// a queue.  It will also trigger the consumer flow control by slowing down the feed to all of the

+		/// consumers on the queue to only send messages as fast as the slowest consumer can run.

+		/// When sending to a topic, the producer will not be slowed down, and consumers will be allowed

+		/// to run as fast as they can go.

+		/// Since this test can take a long time to run, it is marked as explicit.

+		/// </summary>

+		/// <param name="testDestinationURI"></param>

+		//[Test]

+		public virtual void TestFilterIgnoredMessagesSlowConsumer(

+			//[Values(SELECTOR_TEST_QUEUE_URI, SELECTOR_TEST_TOPIC_URI)]

+			string testDestinationURI)

+		{

+			simulateSlowConsumer = true;

+			RunFilterIgnoredMessagesTest(testDestinationURI);

+		}

+

+		public void RunFilterIgnoredMessagesTest(string testDestinationURI)

+		{

+			TimeSpan ttl = TimeSpan.FromMinutes(30);

+			const int MaxNumRequests = 100000;

+

+			using(IConnection connection1 = CreateConnection(GetTestClientId()))

+			using(IConnection connection2 = CreateConnection(GetTestClientId()))

+			using(IConnection connection3 = CreateConnection(GetTestClientId()))

+			{

+				connection1.Start();

+				connection2.Start();

+				connection3.Start();

+				using(ISession session1 = connection1.CreateSession(AcknowledgementMode.AutoAcknowledge))

+				using(ISession session2 = connection2.CreateSession(AcknowledgementMode.AutoAcknowledge))

+				using(ISession session3 = connection3.CreateSession(AcknowledgementMode.AutoAcknowledge))

+				{

+					IDestination destination1 = GetClearDestination(session1, testDestinationURI);

+					IDestination destination2 = GetClearDestination(session2, testDestinationURI);

+					IDestination destination3 = GetClearDestination(session3, testDestinationURI);

+

+					using(IMessageProducer producer = session1.CreateProducer(destination1))

+					using(IMessageConsumer consumer1 = session2.CreateConsumer(destination2, "JMSType NOT LIKE '%IGNORE'"))

+					{

+						int numNonIgnoredMsgsSent = 0;

+						int numIgnoredMsgsSent = 0;

+

+						producer.DeliveryMode = MsgDeliveryMode.NonPersistent;

+

+						receivedNonIgnoredMsgCount = 0;

+						receivedIgnoredMsgCount = 0;

+						consumer1.Listener += new MessageListener(OnNonIgnoredMessage);

+						IMessageConsumer consumer2 = null;

+

+						for(int index = 1; index <= MaxNumRequests; index++)

+						{

+							IMessage request = session1.CreateTextMessage(String.Format("Hello World! [{0} of {1}]", index, MaxNumRequests));

+

+							request.NMSTimeToLive = ttl;

+							if(0 == (index % 2))

+							{

+								request.NMSType = "ACTIVE";

+								numNonIgnoredMsgsSent++;

+							}

+							else

+							{

+								request.NMSType = "ACTIVE.IGNORE";

+								numIgnoredMsgsSent++;

+							}

+

+							producer.Send(request);

+

+							if(2000 == index)

+							{

+								// Start the second consumer

+								if(destination3.IsTopic)

+								{

+									// Reset the ignored message sent count, since all previous messages

+									// will not have been consumed on a topic.

+									numIgnoredMsgsSent = 0;

+								}

+

+								consumer2 = session3.CreateConsumer(destination3, "JMSType LIKE '%IGNORE'");

+								consumer2.Listener += new MessageListener(OnIgnoredMessage);

+							}

+						}

+

+						// Create a waiting loop that will coordinate the end of the test.  It checks

+						// to see that all intended messages were received.  It will continue to wait as

+						// long as new messages are being received.  If it stops receiving messages before

+						// it receives everything it expects, it will eventually timeout and the test will fail.

+						int waitCount = 0;

+						int lastReceivedINongnoredMsgCount = receivedNonIgnoredMsgCount;

+						int lastReceivedIgnoredMsgCount = receivedIgnoredMsgCount;

+

+						while(receivedNonIgnoredMsgCount < numNonIgnoredMsgsSent

+								|| receivedIgnoredMsgCount < numIgnoredMsgsSent)

+						{

+							if(lastReceivedINongnoredMsgCount != receivedNonIgnoredMsgCount

+								|| lastReceivedIgnoredMsgCount != receivedIgnoredMsgCount)

+							{

+								// Reset the wait count.

+								waitCount = 0;

+							}

+							else

+							{

+								waitCount++;

+							}

+

+							lastReceivedINongnoredMsgCount = receivedNonIgnoredMsgCount;

+							lastReceivedIgnoredMsgCount = receivedIgnoredMsgCount;

+

+							Assert.IsTrue(waitCount <= 30, String.Format("Timeout waiting for all messages to be delivered. Only {0} of {1} non-ignored messages delivered.  Only {2} of {3} ignored messages delivered.",

+								receivedNonIgnoredMsgCount, numNonIgnoredMsgsSent, receivedIgnoredMsgCount, numIgnoredMsgsSent));

+							Thread.Sleep(1000);

+						}

+

+						consumer2.Dispose();

+					}

+				}

+			}

+		}

+

+		protected void OnNonIgnoredMessage(IMessage message)

+		{

+			receivedNonIgnoredMsgCount++;

+			Assert.AreEqual(message.NMSType, "ACTIVE");

+		}

+

+		protected void OnIgnoredMessage(IMessage message)

+		{

+			receivedIgnoredMsgCount++;

+			Assert.AreEqual(message.NMSType, "ACTIVE.IGNORE");

+			if(simulateSlowConsumer)

+			{

+				// Simulate a slow consumer  It doesn't have to be too slow in a high speed environment

+				// in order to trigger producer flow control.

+				Thread.Sleep(10);

+			}

+		}

+	}

+}

diff --git a/src/test/csharp/MessageTest.cs b/src/test/csharp/MessageTest.cs
new file mode 100644
index 0000000..228ed98
--- /dev/null
+++ b/src/test/csharp/MessageTest.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 Apache.NMS.Util;

+using NUnit.Framework;

+

+namespace Apache.NMS.Test

+{

+	//[TestFixture]

+	public class MessageTest : NMSTest

+	{

+		protected bool		a = true;

+		protected byte		b = 123;

+		protected char		c = 'c';

+		protected short		d = 0x1234;

+		protected int		e = 0x12345678;

+		protected long		f = 0x1234567812345678;

+		protected string	g = "Hello World!";

+		protected bool		h = false;

+		protected byte		i = 0xFF;

+		protected short		j = -0x1234;

+		protected int		k = -0x12345678;

+		protected long		l = -0x1234567812345678;

+		protected float		m = 2.1F;

+		protected double	n = 2.3;

+		protected byte[]    o = {1, 2, 3, 4, 5};

+

+		protected MessageTest(NMSTestSupport testSupport)

+			: base(testSupport)

+		{

+		}

+

+		//[Test]

+		public virtual void TestSendReceiveMessageProperties(

+			//[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.CreateMessage();

+						request.Properties["a"] = a;

+						request.Properties["b"] = b;

+						request.Properties["c"] = c;

+						request.Properties["d"] = d;

+						request.Properties["e"] = e;

+						request.Properties["f"] = f;

+						request.Properties["g"] = g;

+						request.Properties["h"] = h;

+						request.Properties["i"] = i;

+						request.Properties["j"] = j;

+						request.Properties["k"] = k;

+						request.Properties["l"] = l;

+						request.Properties["m"] = m;

+						request.Properties["n"] = n;

+						

+						try

+						{

+							request.Properties["o"] = o;

+							Assert.Fail("Should not be able to add a Byte[] to the Properties of a Message.");

+						}

+						catch

+						{

+							// Expected

+						}

+						

+						try

+						{

+							request.Properties.SetBytes("o", o);

+							Assert.Fail("Should not be able to add a Byte[] to the Properties of a Message.");

+						}

+						catch

+						{

+							// Expected

+						}						

+						

+						producer.Send(request);

+

+						IMessage message = consumer.Receive(receiveTimeout);

+						Assert.IsNotNull(message, "No message returned!");

+						Assert.AreEqual(request.Properties.Count, message.Properties.Count, "Invalid number of properties.");

+						Assert.AreEqual(deliveryMode, message.NMSDeliveryMode, "NMSDeliveryMode does not match");

+						Assert.AreEqual(ToHex(f), ToHex(message.Properties.GetLong("f")), "map entry: f as hex");

+

+						// use generic API to access entries

+						// Perform a string only comparison here since some NMS providers are type limited and

+						// may return only a string instance from the generic [] accessor.  Each provider should

+						// further test this functionality to determine that the correct type is returned if

+						// it is capable of doing so.

+						Assert.AreEqual(a.ToString(), message.Properties["a"].ToString(), "generic map entry: a");

+						Assert.AreEqual(b.ToString(), message.Properties["b"].ToString(), "generic map entry: b");

+						Assert.AreEqual(c.ToString(), message.Properties["c"].ToString(), "generic map entry: c");

+						Assert.AreEqual(d.ToString(), message.Properties["d"].ToString(), "generic map entry: d");

+						Assert.AreEqual(e.ToString(), message.Properties["e"].ToString(), "generic map entry: e");

+						Assert.AreEqual(f.ToString(), message.Properties["f"].ToString(), "generic map entry: f");

+						Assert.AreEqual(g.ToString(), message.Properties["g"].ToString(), "generic map entry: g");

+						Assert.AreEqual(h.ToString(), message.Properties["h"].ToString(), "generic map entry: h");

+						Assert.AreEqual(i.ToString(), message.Properties["i"].ToString(), "generic map entry: i");

+						Assert.AreEqual(j.ToString(), message.Properties["j"].ToString(), "generic map entry: j");

+						Assert.AreEqual(k.ToString(), message.Properties["k"].ToString(), "generic map entry: k");

+						Assert.AreEqual(l.ToString(), message.Properties["l"].ToString(), "generic map entry: l");

+						Assert.AreEqual(m.ToString(), message.Properties["m"].ToString(), "generic map entry: m");

+						Assert.AreEqual(n.ToString(), message.Properties["n"].ToString(), "generic map entry: n");

+

+						// use type safe APIs

+						Assert.AreEqual(a, message.Properties.GetBool("a"),   "map entry: a");

+						Assert.AreEqual(b, message.Properties.GetByte("b"),   "map entry: b");

+						Assert.AreEqual(c, message.Properties.GetChar("c"),   "map entry: c");

+						Assert.AreEqual(d, message.Properties.GetShort("d"),  "map entry: d");

+						Assert.AreEqual(e, message.Properties.GetInt("e"),    "map entry: e");

+						Assert.AreEqual(f, message.Properties.GetLong("f"),   "map entry: f");

+						Assert.AreEqual(g, message.Properties.GetString("g"), "map entry: g");

+						Assert.AreEqual(h, message.Properties.GetBool("h"),   "map entry: h");

+						Assert.AreEqual(i, message.Properties.GetByte("i"),   "map entry: i");

+						Assert.AreEqual(j, message.Properties.GetShort("j"),  "map entry: j");

+						Assert.AreEqual(k, message.Properties.GetInt("k"),    "map entry: k");

+						Assert.AreEqual(l, message.Properties.GetLong("l"),   "map entry: l");

+						Assert.AreEqual(m, message.Properties.GetFloat("m"),  "map entry: m");

+						Assert.AreEqual(n, message.Properties.GetDouble("n"), "map entry: n");

+					}

+				}

+			}

+		}

+	}

+}

+

diff --git a/src/test/csharp/MessageTransformerTest.cs b/src/test/csharp/MessageTransformerTest.cs
new file mode 100644
index 0000000..f2d5b12
--- /dev/null
+++ b/src/test/csharp/MessageTransformerTest.cs
@@ -0,0 +1,124 @@
+/*

+ * 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 MessageTransformerTest : NMSTest

+	{

+		private string propertyName = "ADDITIONAL-PROPERTY";

+		private string propertyValue = "ADDITIONAL-PROPERTY-VALUE";

+

+		protected MessageTransformerTest(NMSTestSupport testSupport)

+			: base(testSupport)

+		{

+		}

+

+		//[Test]

+		public virtual void TestProducerTransformer(

+			//[Values(MsgDeliveryMode.Persistent, MsgDeliveryMode.NonPersistent)]

+			MsgDeliveryMode deliveryMode)

+		{

+			using(IConnection connection = CreateConnection())

+			{

+				connection.Start();

+				using(ISession session = connection.CreateSession(AcknowledgementMode.AutoAcknowledge))

+				{

+					IDestination destination = session.CreateTemporaryTopic();

+					using(IMessageConsumer consumer = session.CreateConsumer(destination))

+					using(IMessageProducer producer = session.CreateProducer(destination))

+					{

+						producer.DeliveryMode = deliveryMode;

+						producer.ProducerTransformer = DoProducerTransform;

+

+                        IMessage message = session.CreateMessage();

+

+                        message.Properties["Test"] = "Value";

+

+                        producer.Send(message);

+

+                        message = consumer.Receive(TimeSpan.FromMilliseconds(5000));

+

+                        Assert.IsNotNull(message);

+                        Assert.IsTrue(message.Properties.Count == 2);

+

+                        Assert.AreEqual("Value", message.Properties["Test"]);

+                        Assert.AreEqual(propertyValue, message.Properties[propertyName]);

+					}

+				}

+			}

+		}

+		

+		//[Test]

+		public virtual void TestConsumerTransformer(

+			//[Values(MsgDeliveryMode.Persistent, MsgDeliveryMode.NonPersistent)]

+			MsgDeliveryMode deliveryMode)

+		{

+			using(IConnection connection = CreateConnection())

+			{

+				connection.Start();

+				using(ISession session = connection.CreateSession(AcknowledgementMode.AutoAcknowledge))

+				{

+					IDestination destination = session.CreateTemporaryTopic();

+					using(IMessageConsumer consumer = session.CreateConsumer(destination))

+					using(IMessageProducer producer = session.CreateProducer(destination))

+					{

+						producer.DeliveryMode = deliveryMode;

+

+						consumer.ConsumerTransformer = DoConsumerTransform;

+

+                        IMessage message = session.CreateMessage();

+

+                        message.Properties["Test"] = "Value";

+

+                        producer.Send(message);

+

+                        message = consumer.Receive(TimeSpan.FromMilliseconds(5000));

+

+                        Assert.IsNotNull(message);

+                        Assert.IsTrue(message.Properties.Count == 2, "Property Count should be 2");

+

+                        Assert.AreEqual("Value", message.Properties["Test"], "Property 'Value' was incorrect");

+                        Assert.AreEqual(propertyValue, message.Properties[propertyName], "Property not inserted");

+                    }

+				}

+			}

+		}

+		

+		private IMessage DoProducerTransform(ISession session, IMessageProducer producer, IMessage message)

+		{

+			message.Properties[propertyName] = propertyValue;

+			

+			return message;

+		}

+

+		private IMessage DoConsumerTransform(ISession session, IMessageConsumer consumer, IMessage message)

+		{

+            IMessage newMessage = session.CreateMessage();

+

+            MessageTransformation.CopyNMSMessageProperties(message, newMessage);

+

+			newMessage.Properties[propertyName] = propertyValue;

+

+			return newMessage;

+		}

+	}

+}

+

diff --git a/src/test/csharp/NMSPropertyTest.cs b/src/test/csharp/NMSPropertyTest.cs
new file mode 100644
index 0000000..82b1021
--- /dev/null
+++ b/src/test/csharp/NMSPropertyTest.cs
@@ -0,0 +1,82 @@
+/*

+ * 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 NMSPropertyTest : NMSTest

+	{

+		// standard NMS properties

+		protected string expectedText = "Hey this works!";

+		protected string correlationID = "FooBar";

+		protected MsgPriority priority = MsgPriority.Normal;

+		protected String type = "FooType";

+		protected String groupID = "BarGroup";

+		protected int groupSeq = 1;

+

+		protected NMSPropertyTest(NMSTestSupport testSupport)

+			: base (testSupport)

+		{

+		}

+

+		//[Test]

+		public void TestSendReceiveNMSProperties(

+			//[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.Priority = priority;

+						producer.DeliveryMode = deliveryMode;

+						ITextMessage request = session.CreateTextMessage(expectedText);

+

+						// Set the headers

+						request.NMSCorrelationID = correlationID;

+						request.NMSType = type;

+						request.Properties["NMSXGroupID"] = groupID;

+						request.Properties["NMSXGroupSeq"] = groupSeq;

+

+						producer.Send(request);

+

+						ITextMessage message = consumer.Receive(receiveTimeout) as ITextMessage;

+

+						Assert.IsNotNull(message, "Did not receive an ITextMessage!");

+						Assert.AreEqual(expectedText, message.Text, "Message text does not match.");

+

+						// compare standard NMS headers

+						Assert.AreEqual(correlationID, message.NMSCorrelationID, "NMSCorrelationID does not match");

+						Assert.AreEqual(deliveryMode, message.NMSDeliveryMode, "NMSDeliveryMode does not match");

+						Assert.AreEqual(priority, message.NMSPriority, "NMSPriority does not match");

+						Assert.AreEqual(type, message.NMSType, "NMSType does not match");

+						Assert.AreEqual(groupID, message.Properties["NMSXGroupID"], "NMSXGroupID does not match");

+						Assert.AreEqual(groupSeq, message.Properties["NMSXGroupSeq"], "NMSXGroupSeq does not match");

+					}

+				}

+			}

+		}

+	}

+}

diff --git a/src/test/csharp/NMSTest.cs b/src/test/csharp/NMSTest.cs
new file mode 100644
index 0000000..1069586
--- /dev/null
+++ b/src/test/csharp/NMSTest.cs
@@ -0,0 +1,508 @@
+/*

+ * 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.Xml;

+using Apache.NMS.Util;

+using NUnit.Framework;

+

+namespace Apache.NMS.Test

+{

+	/// <summary>

+	/// Base class for test cases

+	/// </summary>

+	public abstract class NMSTest

+	{

+		protected TimeSpan receiveTimeout = TimeSpan.FromMilliseconds(15000);

+

+		public static string ToHex(long value)

+		{

+			return String.Format("{0:x}", value);

+		}

+

+		#region Constructors and test support

+

+		private NMSTestSupport testSupport;

+

+		static NMSTest()

+		{

+			Apache.NMS.Tracer.Trace = new NMSTracer();

+		}

+

+		protected NMSTest(NMSTestSupport testSupport)

+		{

+			this.testSupport = testSupport;

+			this.testSupport.TestClassType = this.GetType();

+		}

+

+		#endregion

+

+		#region Set up and tear down

+

+		[SetUp]

+		public virtual void SetUp()

+		{

+			this.testSupport.SetUp();

+		}

+

+		[TearDown]

+		public virtual void TearDown()

+		{

+			this.testSupport.TearDown();

+		}

+

+		#endregion

+

+		#region Configuration file

+

+		/// <summary>

+		/// The configuration document.

+		/// </summary>

+		public XmlDocument ConfigurationDocument

+		{

+			get { return this.testSupport.ConfigurationDocument; }

+		}

+

+		/// <summary>

+		/// Loads the configuration file.

+		/// </summary>

+		/// <returns>XmlDocument of the configuration file</returns>

+		protected virtual XmlDocument LoadConfigFile()

+		{

+			return this.testSupport.LoadConfigFile();

+		}

+

+		/// <summary>

+		/// Loads the configuration file.

+		/// </summary>

+		/// <param name="configFilePath">Configuration file path</param>

+		/// <returns>XmlDocument of the configuration file</returns>

+		protected virtual XmlDocument LoadConfigFile(string configFilePath)

+		{

+			return this.testSupport.LoadConfigFile(configFilePath);

+		}

+

+		/// <summary>

+		/// Gets the path of the configuration filename.

+		/// </summary>

+		/// <returns>Path of the configuration filename</returns>

+		protected virtual string GetConfigFilePath()

+		{

+			return this.testSupport.GetConfigFilePath();

+		}

+

+		/// <summary>

+		/// Gets the environment variable name for the configuration file path.

+		/// </summary>

+		/// <returns>Environment variable name</returns>

+		protected virtual string GetConfigEnvVarName()

+		{

+			return this.testSupport.GetConfigEnvVarName();

+		}

+

+		/// <summary>

+		/// Gets the default name for the configuration filename.

+		/// </summary>

+		/// <returns>Default name of the configuration filename</returns>

+		protected virtual string GetDefaultConfigFileName()

+		{

+			return this.testSupport.GetDefaultConfigFileName();

+		}

+

+		/// <summary>

+		/// Gets the value of the "value" attribute of the specified node.

+		/// </summary>

+		/// <param name="parentNode">Parent node</param>

+		/// <param name="nodeName">Node name</param>

+		/// <param name="defaultVaue">Default value</param>

+		/// <returns></returns>

+		protected virtual string GetNodeValueAttribute(XmlElement parentNode,

+			string nodeName, string defaultVaue)

+		{

+			return this.testSupport.GetNodeValueAttribute(parentNode,

+				nodeName, defaultVaue);

+		}

+

+		#endregion

+

+		#region URI node

+

+		/// <summary>

+		/// Gets the URI node for the default configuration.

+		/// </summary>

+		/// <returns>URI node for the default configuration name</returns>

+		public virtual XmlElement GetURINode()

+		{

+			return this.testSupport.GetURINode();

+		}

+

+		/// <summary>

+		/// Gets the URI node for the default configuration.

+		/// </summary>

+		/// <param name="nameTestURI">Name of the default configuration node

+		/// </param>

+		/// <returns>URI node for the default configuration name</returns>

+		public virtual XmlElement GetURINode(string nameTestURI)

+		{

+			return this.testSupport.GetURINode(nameTestURI);

+		}

+

+		/// <summary>

+		/// Gets the name of the default connection configuration to be loaded.

+		/// </summary>

+		/// <returns>Default configuration name</returns>

+		protected virtual string GetNameTestURI()

+		{

+			return this.testSupport.GetNameTestURI();

+		}

+

+		#endregion

+

+		#region Factory

+

+		private NMSConnectionFactory nmsFactory;

+		/// <summary>

+		/// The connection factory interface property.

+		/// </summary>

+		public IConnectionFactory Factory

+		{

+			get { return this.testSupport.Factory; }

+		}

+

+		/// <summary>

+		/// Create the NMS Factory that can create NMS Connections.

+		/// </summary>

+		/// <returns>Connection factory</returns>

+		protected NMSConnectionFactory CreateNMSFactory()

+		{

+			return this.testSupport.CreateNMSFactory();

+		}

+

+		/// <summary>

+		/// Create the NMS Factory that can create NMS Connections. This

+		/// function loads the connection settings from the configuration file.

+		/// </summary>

+		/// <param name="nameTestURI">The named connection configuration.

+		/// </param>

+		/// <returns>Connection factory</returns>

+		protected NMSConnectionFactory CreateNMSFactory(string nameTestURI)

+		{

+			return this.testSupport.CreateNMSFactory(nameTestURI);

+		}

+

+		/// <summary>

+		/// Get the parameters for the ConnectionFactory from the configuration

+		/// file.

+		/// </summary>

+		/// <param name="uriNode">Parent node of the factoryParams node.</param>

+		/// <returns>Object array of parameter objects to be passsed to provider

+		/// factory object.  Null if no parameters are specified in

+		/// configuration file.</returns>

+		protected object[] GetFactoryParams(XmlElement uriNode)

+		{

+			return this.testSupport.GetFactoryParams(uriNode);

+		}

+

+		#endregion

+

+		#region Client id and connection

+

+		/// <summary>

+		/// Client id.

+		/// </summary>

+		public string ClientId

+		{

+			get { return this.testSupport.ClientId; }

+		}

+

+		/// <summary>

+		/// Gets a new client id.

+		/// </summary>

+		/// <returns>Client id</returns>

+		public virtual string GetTestClientId()

+		{

+			return this.testSupport.GetTestClientId();

+		}

+

+		/// <summary>

+		/// Create a new connection to the broker.

+		/// </summary>

+		/// <returns>New connection</returns>

+		public virtual IConnection CreateConnection()

+		{

+			return this.testSupport.CreateConnection();

+		}

+

+		/// <summary>

+		/// Create a new connection to the broker.

+		/// </summary>

+		/// <param name="newClientId">Client ID of the new connection.</param>

+		/// <returns>New connection</returns>

+		public virtual IConnection CreateConnection(string newClientId)

+		{

+			return this.testSupport.CreateConnection(newClientId);

+		}

+

+		/// <summary>

+		/// Create a new connection to the broker, and start it.

+		/// </summary>

+		/// <returns>Started connection</returns>

+		public virtual IConnection CreateConnectionAndStart()

+		{

+			return this.testSupport.CreateConnectionAndStart();

+		}

+

+		/// <summary>

+		/// Create a new connection to the broker, and start it.

+		/// </summary>

+		/// <param name="newClientId">Client ID of the new connection.</param>

+		/// <returns>Started connection</returns>

+		public virtual IConnection CreateConnectionAndStart(string newClientId)

+		{

+			return this.testSupport.CreateConnectionAndStart(newClientId);

+		}

+

+		#endregion

+

+		#region Destination

+

+		/// <summary>

+		/// Gets a clear destination.

+		/// </summary>

+		/// <param name="session">Session</param>

+		/// <param name="type">Destination type</param>

+		/// <param name="destinationRef">Configuration node name for the

+		/// destination URI</param>

+		/// <returns>Destination</returns>

+		public virtual IDestination GetClearDestination(ISession session,

+			DestinationType type, string destinationRef)

+		{

+			return this.testSupport.GetClearDestination(session, type, destinationRef);

+		}

+

+		/// <summary>

+		/// Gets a clear destination. This will try to delete an existing

+		/// destination and re-create it.

+		/// </summary>

+		/// <param name="session">Session</param>

+		/// <param name="destinationURI">Destination URI</param>

+		/// <returns>Clear destination</returns>

+		public virtual IDestination GetClearDestination(ISession session,

+			string destinationURI)

+		{

+			return this.testSupport.GetClearDestination(session, destinationURI);

+		}

+

+		/// <summary>

+		/// Gets an existing destination. Don't clear its contents.

+		/// </summary>

+		/// <param name="session">Session</param>

+		/// <param name="type">Destination type</param>

+		/// <param name="destinationRef">Configuration node name for the

+		/// destination URI</param>

+		/// <returns>Destination</returns>

+		public virtual IDestination GetDestination(ISession session,

+			DestinationType type, string destinationRef)

+		{

+			return this.testSupport.GetDestination(session, type, destinationRef);

+		}

+

+		/// <summary>

+		/// Gets a destination URI.

+		/// </summary>

+		/// <param name="type">Destination type</param>

+		/// <param name="destinationRef">Configuration node name for the

+		/// destination URI</param>

+		/// <returns>Destination URI</returns>

+		public virtual string GetDestinationURI(DestinationType type, string destinationRef)

+		{

+			return this.testSupport.GetDestinationURI(type, destinationRef);

+		}

+

+		#endregion

+

+		#region Durable consumer

+

+		/// <summary>

+		/// Register a durable consumer

+		/// </summary>

+		/// <param name="connectionID">Connection ID of the consumer.</param>

+		/// <param name="destination">Destination name to register.  Supports

+		/// embedded prefix names.</param>

+		/// <param name="consumerID">Name of the durable consumer.</param>

+		/// <param name="selector">Selector parameters for consumer.</param>

+		/// <param name="noLocal"></param>

+		protected void RegisterDurableConsumer(string connectionID,

+			string destination, string consumerID, string selector, bool noLocal)

+		{

+			using(IConnection connection = CreateConnection(connectionID))

+			{

+				connection.Start();

+				using(ISession session = connection.CreateSession(

+					AcknowledgementMode.DupsOkAcknowledge))

+				{

+					ITopic destinationTopic = (ITopic)SessionUtil.GetDestination(session, destination);

+					Assert.IsNotNull(destinationTopic, "Could not get destination topic.");

+

+					using(IMessageConsumer consumer = session.CreateDurableConsumer(destinationTopic, consumerID, selector, noLocal))

+					{

+						Assert.IsNotNull(consumer, "Could not create durable consumer.");

+					}

+				}

+			}

+		}

+

+		/// <summary>

+		/// Unregister a durable consumer for the given connection ID.

+		/// </summary>

+		/// <param name="connectionID">Connection ID of the consumer.</param>

+		/// <param name="consumerID">Name of the durable consumer.</param>

+		protected void UnregisterDurableConsumer(string connectionID, string consumerID)

+		{

+			using(IConnection connection = CreateConnection(connectionID))

+			{

+				connection.Start();

+				using(ISession session = connection.CreateSession(AcknowledgementMode.DupsOkAcknowledge))

+				{

+					session.DeleteDurableConsumer(consumerID);

+				}

+			}

+		}

+

+		#endregion

+

+		#region Send messages

+

+		/// <summary>

+		/// Sends a specified number of text messages to the designated

+		/// destination.

+		/// </summary>

+		/// <param name="destination">Destination.</param>

+		/// <param name="deliveryMode">Delivery mode.</param>

+		/// <param name="count">Number of messages to be sent.</param>

+		public void SendMessages(IDestination destination,

+			MsgDeliveryMode deliveryMode, int count)

+		{

+			IConnection connection = CreateConnection();

+			connection.Start();

+			SendMessages(connection, destination, deliveryMode, count);

+			connection.Close();

+		}

+

+		/// <summary>

+		/// Sends a specified number of text messages to the designated

+		/// destination.

+		/// </summary>

+		/// <param name="connection">Connection.</param>

+		/// <param name="destination">Destination.</param>

+		/// <param name="deliveryMode">Delivery mode.</param>

+		/// <param name="count">Number of messages to be sent.</param>

+		public void SendMessages(IConnection connection,

+			IDestination destination, MsgDeliveryMode deliveryMode, int count)

+		{

+			ISession session = connection.CreateSession(AcknowledgementMode.AutoAcknowledge);

+			SendMessages(session, destination, deliveryMode, count);

+			session.Close();

+		}

+

+		/// <summary>

+		/// Sends a specified number of text messages to the designated

+		/// destination.

+		/// </summary>

+		/// <param name="session">Session.</param>

+		/// <param name="destination">Destination.</param>

+		/// <param name="deliveryMode">Delivery mode.</param>

+		/// <param name="count">Number of messages to be sent.</param>

+		public void SendMessages(ISession session, IDestination destination,

+			MsgDeliveryMode deliveryMode, int count)

+		{

+			IMessageProducer producer = session.CreateProducer(destination);

+			producer.DeliveryMode = deliveryMode;

+			for(int i = 0; i < count; i++)

+			{

+				producer.Send(session.CreateTextMessage("" + i));

+			}

+			producer.Close();

+		}

+

+		#endregion

+

+		#region Check messages

+

+		protected void AssertTextMessagesEqual(IMessage[] firstSet, IMessage[] secondSet)

+		{

+			AssertTextMessagesEqual(firstSet, secondSet, "");

+		}

+

+		protected void AssertTextMessagesEqual(IMessage[] firstSet, IMessage[] secondSet, string messsage)

+		{

+			Assert.AreEqual(firstSet.Length, secondSet.Length, "Message count does not match: " + messsage);

+

+			for(int i = 0; i < secondSet.Length; i++)

+			{

+				ITextMessage m1 = firstSet[i] as ITextMessage;

+				ITextMessage m2 = secondSet[i] as ITextMessage;

+

+				AssertTextMessageEqual(m1, m2, "Message " + (i + 1) + " did not match : ");

+			}

+		}

+

+		protected void AssertEquals(ITextMessage m1, ITextMessage m2)

+		{

+			AssertEquals(m1, m2, "");

+		}

+

+		protected void AssertTextMessageEqual(ITextMessage m1, ITextMessage m2, string message)

+		{

+			Assert.IsFalse(m1 == null ^ m2 == null, message + ": expected {" + m1 + "}, but was {" + m2 + "}");

+

+			if(m1 == null)

+			{

+				return;

+			}

+

+			Assert.AreEqual(m1.Text, m2.Text, message);

+		}

+

+		protected void AssertEquals(IMessage m1, IMessage m2)

+		{

+			AssertEquals(m1, m2, "");

+		}

+

+		protected void AssertEquals(IMessage m1, IMessage m2, string message)

+		{

+			Assert.IsFalse(m1 == null ^ m2 == null, message + ": expected {" + m1 + "}, but was {" + m2 + "}");

+

+			if(m1 == null)

+			{

+				return;

+			}

+

+			Assert.IsTrue(m1.GetType() == m2.GetType(), message + ": expected {" + m1 + "}, but was {" + m2 + "}");

+

+			if(m1 is ITextMessage)

+			{

+				AssertTextMessageEqual((ITextMessage) m1, (ITextMessage) m2, message);

+			}

+			else

+			{

+				Assert.AreEqual(m1, m2, message);

+			}

+		}

+

+		#endregion

+	}

+}

diff --git a/src/test/csharp/NMSTestSupport.cs b/src/test/csharp/NMSTestSupport.cs
new file mode 100644
index 0000000..39da8bb
--- /dev/null
+++ b/src/test/csharp/NMSTestSupport.cs
@@ -0,0 +1,651 @@
+/*

+ * 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 System.Reflection;

+using System.Text.RegularExpressions;

+using System.Xml;

+using Apache.NMS.Util;

+using NUnit.Framework;

+

+namespace Apache.NMS.Test

+{

+	/// <summary>

+	/// Useful class for test cases support.

+	/// </summary>

+	public class NMSTestSupport

+	{

+		protected TimeSpan receiveTimeout = TimeSpan.FromMilliseconds(15000);

+		protected int testRun;

+		protected int idCounter;

+

+        protected Type testClassType;

+		public Type TestClassType

+		{

+			get { return this.testClassType; }

+			set { this.testClassType = value; }

+		}

+

+		#region Constructors

+

+		public NMSTestSupport()

+		{

+		}

+

+		#endregion

+

+		#region Set up and tear down

+

+		public virtual void SetUp()

+		{

+			this.testRun++;

+		}

+

+		public virtual void TearDown()

+		{

+		}

+

+		#endregion

+

+		#region Configuration file

+

+		private XmlDocument configurationDocument = null;

+		/// <summary>

+		/// The configuration document.

+		/// </summary>

+		public XmlDocument ConfigurationDocument

+		{

+			get

+			{

+				if(this.configurationDocument == null)

+				{

+					this.configurationDocument = LoadConfigFile();

+					Assert.IsTrue(this.configurationDocument != null,

+						"Error loading configuration.");

+				}

+

+				return this.configurationDocument;

+			}

+		}

+

+		/// <summary>

+		/// Loads the configuration file.

+		/// </summary>

+		/// <returns>XmlDocument of the configuration file</returns>

+		public virtual XmlDocument LoadConfigFile()

+		{

+			return LoadConfigFile(GetConfigFilePath());

+		}

+

+		/// <summary>

+		/// Loads the configuration file.

+		/// </summary>

+		/// <param name="configFilePath">Configuration file path</param>

+		/// <returns>XmlDocument of the configuration file</returns>

+		public virtual XmlDocument LoadConfigFile(string configFilePath)

+		{

+			XmlDocument configDoc = new XmlDocument();

+

+			configDoc.Load(configFilePath);

+

+			return configDoc;

+		}

+

+		/// <summary>

+		/// Gets the path of the configuration filename.

+		/// </summary>

+		/// <returns>Path of the configuration filename</returns>

+		public virtual string GetConfigFilePath()

+		{

+			// The full path may be specified by an environment variable

+			string configFilePath = GetEnvVar(GetConfigEnvVarName(), "");

+			bool configFound = (!string.IsNullOrEmpty(configFilePath)

+				&& File.Exists(configFilePath));

+

+			// Else it may be found in well known locations

+			if(!configFound)

+			{

+				string[] paths = GetConfigSearchPaths();

+				string configFileName = GetDefaultConfigFileName();

+

+				foreach(string path in paths)

+				{

+					string fullpath = Path.Combine(path, configFileName);

+					Tracer.Debug("\tScanning folder: " + path);

+

+					if(File.Exists(fullpath))

+					{

+						Tracer.Debug("\tAssembly found!");

+						configFilePath = fullpath;

+						configFound = true;

+						break;

+					}

+				}

+			}

+

+			Tracer.Debug("\tConfig file: " + configFilePath);

+			Assert.IsTrue(configFound, "Connection configuration file does not exist.");

+			return configFilePath;

+		}

+

+		/// <summary>

+		/// Gets the environment variable name for the configuration file path.

+		/// </summary>

+		/// <returns>Environment variable name</returns>

+		public virtual string GetConfigEnvVarName()

+		{

+			return "NMSTESTCONFIGPATH";

+		}

+

+		/// <summary>

+		/// Gets the default name for the configuration filename.

+		/// </summary>

+		/// <returns>Default name of the configuration filename</returns>

+		public virtual string GetDefaultConfigFileName()

+		{

+			return "nmsprovider-test.config";

+		}

+

+		/// <summary>

+		/// Gets an array of paths where the configuration file sould be found.

+		/// </summary>

+		/// <returns>Array of paths</returns>

+		private static string[] GetConfigSearchPaths()

+		{

+			ArrayList pathList = new ArrayList();

+

+			// Check the current folder first.

+			pathList.Add("");

+#if !NETCF

+			AppDomain currentDomain = AppDomain.CurrentDomain;

+

+			// Check the folder the assembly is located in.

+			pathList.Add(Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location));

+			if(null != currentDomain.BaseDirectory)

+			{

+				pathList.Add(currentDomain.BaseDirectory);

+			}

+

+			if(null != currentDomain.RelativeSearchPath)

+			{

+				pathList.Add(currentDomain.RelativeSearchPath);

+			}

+#endif

+

+			return (string[]) pathList.ToArray(typeof(string));

+		}

+

+		/// <summary>

+		/// Gets the value of the "value" attribute of the specified node.

+		/// </summary>

+		/// <param name="parentNode">Parent node</param>

+		/// <param name="nodeName">Node name</param>

+		/// <param name="defaultVaue">Default value</param>

+		/// <returns></returns>

+		public string GetNodeValueAttribute(XmlElement parentNode,

+			string nodeName, string defaultVaue)

+		{

+			XmlElement node = (XmlElement)parentNode.SelectSingleNode(nodeName);

+

+			return (node == null ? defaultVaue : node.GetAttribute("value"));

+		}

+

+		#endregion

+

+		#region URI node

+

+		/// <summary>

+		/// Gets the URI node for the default configuration.

+		/// </summary>

+		/// <returns>URI node for the default configuration name</returns>

+		public virtual XmlElement GetURINode()

+		{

+			return GetURINode(GetNameTestURI());

+		}

+

+		/// <summary>

+		/// Gets the URI node for the default configuration.

+		/// </summary>

+		/// <param name="nameTestURI">Name of the default configuration node

+		/// </param>

+		/// <returns>URI node for the default configuration name</returns>

+		public virtual XmlElement GetURINode(string nameTestURI)

+		{

+			return (XmlElement)ConfigurationDocument.SelectSingleNode(

+				String.Format("/configuration/{0}", nameTestURI));

+		}

+

+		/// <summary>

+		/// Gets the name of the default connection configuration to be loaded.

+		/// </summary>

+		/// <returns>Default configuration name</returns>

+		public virtual string GetNameTestURI()

+		{

+			return "testURI";

+		}

+

+		#endregion

+

+		#region Factory

+

+		private NMSConnectionFactory nmsFactory;

+		/// <summary>

+		/// The connection factory interface property.

+		/// </summary>

+		public IConnectionFactory Factory

+		{

+			get

+			{

+				if(this.nmsFactory == null)

+				{

+					this.nmsFactory = CreateNMSFactory();

+

+					Assert.IsNotNull(this.nmsFactory, "Error creating factory.");

+				}

+

+				return this.nmsFactory.ConnectionFactory;

+			}

+		}

+

+		/// <summary>

+		/// Create the NMS Factory that can create NMS Connections.

+		/// </summary>

+		/// <returns>Connection factory</returns>

+		public NMSConnectionFactory CreateNMSFactory()

+		{

+			return CreateNMSFactory(GetNameTestURI());

+		}

+

+		/// <summary>

+		/// Create the NMS Factory that can create NMS Connections. This

+		/// function loads the connection settings from the configuration file.

+		/// </summary>

+		/// <param name="nameTestURI">The named connection configuration.

+		/// </param>

+		/// <returns>Connection factory</returns>

+		public NMSConnectionFactory CreateNMSFactory(string nameTestURI)

+		{

+			XmlElement uriNode = GetURINode(nameTestURI);

+

+			Uri brokerUri = null;

+			object[] factoryParams = null;

+			if(uriNode != null)

+			{

+				// Replace any environment variables embedded inside the string.

+				brokerUri = new Uri(uriNode.GetAttribute("value"));

+				factoryParams = GetFactoryParams(uriNode);

+				clientId = GetNodeValueAttribute(uriNode, "clientId", "NMSTestClientId");

+				userName = GetNodeValueAttribute(uriNode, "userName", null);

+				passWord = GetNodeValueAttribute(uriNode, "passWord", null);

+			}

+

+			if(factoryParams == null)

+			{

+				this.nmsFactory = new Apache.NMS.NMSConnectionFactory(brokerUri);

+			}

+			else

+			{

+				this.nmsFactory = new Apache.NMS.NMSConnectionFactory(brokerUri, factoryParams);

+			}

+

+			return this.nmsFactory;

+		}

+

+		/// <summary>

+		/// Get the parameters for the ConnectionFactory from the configuration

+		/// file.

+		/// </summary>

+		/// <param name="uriNode">Parent node of the factoryParams node.</param>

+		/// <returns>Object array of parameter objects to be passsed to provider

+		/// factory object.  Null if no parameters are specified in

+		/// configuration file.</returns>

+		public object[] GetFactoryParams(XmlElement uriNode)

+		{

+			ArrayList factoryParams = new ArrayList();

+			XmlElement factoryParamsNode = (XmlElement)uriNode.SelectSingleNode("factoryParams");

+

+			if(factoryParamsNode != null)

+			{

+				XmlNodeList nodeList = factoryParamsNode.SelectNodes("param");

+

+				if(nodeList != null)

+				{

+					foreach(XmlElement paramNode in nodeList)

+					{

+						string paramType = paramNode.GetAttribute("type");

+						string paramValue = paramNode.GetAttribute("value");

+

+						switch(paramType)

+						{

+							case "string":

+								factoryParams.Add(paramValue);

+								break;

+

+							case "int":

+								factoryParams.Add(int.Parse(paramValue));

+								break;

+

+							// TODO: Add more parameter types

+						}

+					}

+				}

+			}

+

+			if(factoryParams.Count > 0)

+			{

+				return factoryParams.ToArray();

+			}

+

+			return null;

+		}

+

+		#endregion

+

+		#region Environment variables

+

+		/// <summary>

+		/// Get environment variable value.

+		/// </summary>

+		/// <param name="varName"></param>

+		/// <param name="defaultValue"></param>

+		/// <returns></returns>

+		public static string GetEnvVar(string varName, string defaultValue)

+		{

+#if (PocketPC||NETCF||NETCF_2_0)

+            string varValue = null;

+#else

+			string varValue = Environment.GetEnvironmentVariable(varName);

+#endif

+			if(null == varValue)

+			{

+				varValue = defaultValue;

+			}

+

+			return varValue;

+		}

+

+		#endregion

+

+		#region Client id and connection

+

+		protected string clientId;

+		/// <summary>

+		/// Client id.

+		/// </summary>

+		public string ClientId

+		{

+			get { return this.clientId; }

+		}

+

+		/// <summary>

+		/// Gets a new client id.

+		/// </summary>

+		/// <returns>Client id</returns>

+		public virtual string GetTestClientId()

+		{

+			System.Text.StringBuilder id = new System.Text.StringBuilder();

+

+			id.Append("ID:");

+			id.Append(this.GetType().Name);

+			id.Append(":");

+			id.Append(this.testRun);

+			id.Append(":");

+			id.Append(++idCounter);

+

+			return id.ToString();

+		}

+

+		protected string userName;

+		/// <summary>

+		/// User name.

+		/// </summary>

+		public string UserName

+		{

+			get { return this.userName; }

+		}

+

+		protected string passWord;

+		/// <summary>

+		/// User pass word.

+		/// </summary>

+		public string PassWord

+		{

+			get { return this.passWord; }

+		}

+

+		/// <summary>

+		/// Create a new connection to the broker.

+		/// </summary>

+		/// <returns>New connection</returns>

+		public virtual IConnection CreateConnection()

+		{

+			return CreateConnection(null);

+		}

+

+		/// <summary>

+		/// Create a new connection to the broker.

+		/// </summary>

+		/// <param name="newClientId">Client ID of the new connection.</param>

+		/// <returns>New connection</returns>

+		public virtual IConnection CreateConnection(string newClientId)

+		{

+			IConnection newConnection;

+

+			if(this.userName == null)

+			{

+				newConnection = Factory.CreateConnection();

+			}

+			else

+			{

+				newConnection = Factory.CreateConnection(userName, passWord);

+			}

+

+			Assert.IsNotNull(newConnection, "Connection not created");

+

+			if(newClientId != null)

+			{

+				newConnection.ClientId = newClientId;

+			}

+

+			return newConnection;

+		}

+

+		/// <summary>

+		/// Create a new connection to the broker, and start it.

+		/// </summary>

+		/// <returns>Started connection</returns>

+		public virtual IConnection CreateConnectionAndStart()

+		{

+			return CreateConnectionAndStart(null);

+		}

+

+		/// <summary>

+		/// Create a new connection to the broker, and start it.

+		/// </summary>

+		/// <param name="newClientId">Client ID of the new connection.</param>

+		/// <returns>Started connection</returns>

+		public virtual IConnection CreateConnectionAndStart(string newClientId)

+		{

+			IConnection newConnection = CreateConnection(newClientId);

+			newConnection.Start();

+			return newConnection;

+		}

+

+		#endregion

+

+		#region Destination

+

+		/// <summary>

+		/// Gets a clear destination.

+		/// </summary>

+		/// <param name="session">Session</param>

+		/// <param name="type">Destination type</param>

+		/// <param name="destinationRef">Configuration node name for the

+		/// destination URI</param>

+		/// <returns>Destination</returns>

+		public virtual IDestination GetClearDestination(ISession session,

+			DestinationType type, string destinationRef)

+		{

+			string uri = GetDestinationURI(type, destinationRef);

+

+			return GetClearDestination(session, uri);

+		}

+

+		/// <summary>

+		/// Gets a clear destination. This will try to delete an existing

+		/// destination and re-create it.

+		/// </summary>

+		/// <param name="session">Session</param>

+		/// <param name="destinationURI">Destination URI</param>

+		/// <returns>Clear destination</returns>

+		public virtual IDestination GetClearDestination(ISession session,

+			string destinationURI)

+		{

+			IDestination destination;

+

+			try

+			{

+				DeleteDestination(session, destinationURI);

+				destination = CreateDestination(session, destinationURI);

+			}

+			catch(Exception)

+			{

+				// Can't delete it, so lets try and purge it.

+				destination = SessionUtil.GetDestination(session, destinationURI);

+

+				using(IMessageConsumer consumer = session.CreateConsumer(destination))

+				{

+					while(consumer.Receive(TimeSpan.FromMilliseconds(750)) != null)

+					{

+					}

+				}

+			}

+

+			return destination;

+		}

+

+		/// <summary>

+		/// Deletes a destination.

+		/// </summary>

+		/// <param name="session">Session</param>

+		/// <param name="destinationURI">Destination URI</param>

+		protected virtual void DeleteDestination(ISession session,

+			string destinationURI)

+		{

+			// Only delete the destination if it can be recreated

+			// SessionUtil.DeleteDestination(session, destinationURI, DestinationType.Queue)

+			throw new NotSupportedException();

+		}

+

+		/// <summary>

+		/// Creates a destination.

+		/// </summary>

+		/// <param name="session">Session</param>

+		/// <param name="destinationURI">Destination URI</param>

+		protected virtual IDestination CreateDestination(ISession session,

+			string destinationURI)

+		{

+			throw new NotSupportedException();

+		}

+

+		/// <summary>

+		/// Gets an existing destination. Don't clear its contents.

+		/// </summary>

+		/// <param name="session">Session</param>

+		/// <param name="type">Destination type</param>

+		/// <param name="destinationRef">Configuration node name for the

+		/// destination URI</param>

+		/// <returns>Destination</returns>

+		public virtual IDestination GetDestination(ISession session,

+			DestinationType type, string destinationRef)

+		{

+			string uri = GetDestinationURI(type, destinationRef);

+

+			IDestination destination = SessionUtil.GetDestination(session, uri);

+

+			return destination;

+		}

+

+		/// <summary>

+		/// Gets a destination URI.

+		/// </summary>

+		/// <param name="type">Destination type</param>

+		/// <param name="destinationRef">Configuration node name for the

+		/// destination URI</param>

+		/// <returns>Destination URI</returns>

+		public virtual string GetDestinationURI(

+			DestinationType type, string destinationRef)

+		{

+			string uri = null;

+

+			if(!string.IsNullOrEmpty(destinationRef))

+			{

+				XmlElement uriNode = GetURINode();

+

+				if(uriNode != null)

+				{

+					uri = GetNodeValueAttribute(uriNode, destinationRef, null);

+				}

+			}

+

+			if(string.IsNullOrEmpty(uri))

+			{

+				uri = NewDestinationURI(type);

+			}

+

+			return uri;

+		}

+

+		/// <summary>

+		/// Gets a new destination URI.

+		/// </summary>

+		/// <param name="type">Destination type</param>

+		/// <returns>Destination URI</returns>

+		public virtual string NewDestinationURI(DestinationType type)

+		{

+			string name = "TEST." + this.TestClassType.Name

+						+ "." + Guid.NewGuid().ToString();

+			string scheme;

+			switch(type)

+			{

+				case DestinationType.Queue:

+					scheme = "queue://";

+					break;

+

+				case DestinationType.Topic:

+					scheme = "topic://";

+					break;

+

+				case DestinationType.TemporaryQueue:

+					scheme = "temp-queue://";

+					break;

+

+				case DestinationType.TemporaryTopic:

+					scheme = "temp-topic://";

+					break;

+

+				default:

+					throw new ArgumentException("type: " + type);

+			}

+

+			return scheme + name;

+		}

+

+		#endregion

+	}

+}

diff --git a/src/test/csharp/NMSTracer.cs b/src/test/csharp/NMSTracer.cs
new file mode 100644
index 0000000..1e254bd
--- /dev/null
+++ b/src/test/csharp/NMSTracer.cs
@@ -0,0 +1,87 @@
+/*

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

+ */

+

+#define TRACE	// Force tracing to be enabled for this class

+

+namespace Apache.NMS.Test

+{

+	public class NMSTracer : Apache.NMS.ITrace

+	{

+		#region ITrace Members

+		public void Debug(string message)

+		{

+#if !NETCF

+			System.Diagnostics.Trace.WriteLine(string.Format("DEBUG: {0}", message));

+#endif

+		}

+

+		public void Error(string message)

+		{

+#if !NETCF

+			System.Diagnostics.Trace.WriteLine(string.Format("ERROR: {0}", message));

+#endif

+		}

+

+		public void Fatal(string message)

+		{

+#if !NETCF

+			System.Diagnostics.Trace.WriteLine(string.Format("FATAL: {0}", message));

+#endif

+		}

+

+		public void Info(string message)

+		{

+#if !NETCF

+			System.Diagnostics.Trace.WriteLine(string.Format("INFO: {0}", message));

+#endif

+		}

+

+		public void Warn(string message)

+		{

+#if !NETCF

+			System.Diagnostics.Trace.WriteLine(string.Format("WARN: {0}", message));

+#endif

+		}

+

+		public bool IsDebugEnabled

+		{

+			get { return true; }

+		}

+

+		public bool IsErrorEnabled

+		{

+			get { return true; }

+		}

+

+		public bool IsFatalEnabled

+		{

+			get { return true; }

+		}

+

+		public bool IsInfoEnabled

+		{

+			get { return true; }

+		}

+

+		public bool IsWarnEnabled

+		{

+			get { return true; }

+		}

+

+		#endregion

+	}

+}

diff --git a/src/test/csharp/PrimitiveMapTest.cs b/src/test/csharp/PrimitiveMapTest.cs
new file mode 100644
index 0000000..f98322a
--- /dev/null
+++ b/src/test/csharp/PrimitiveMapTest.cs
@@ -0,0 +1,170 @@
+/*

+ * 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;

+using NUnit.Framework;

+

+namespace Apache.NMS.Test

+{

+	[TestFixture]

+	public class PrimitiveMapTest

+	{

+

+		bool a = true;

+		byte b = 123;

+		char c = 'c';

+		short d = 0x1234;

+		int e = 0x12345678;

+		long f = 0x1234567812345678;

+		string g = "Hello World!";

+		bool h = false;

+		byte i = 0xFF;

+		short j = -0x1234;

+		int k = -0x12345678;

+		long l = -0x1234567812345678;

+		IList m = CreateList();

+		IDictionary n = CreateDictionary();

+

+		[Test]

+		public void TestNotMarshalled()

+		{

+			PrimitiveMap map = CreatePrimitiveMap();

+			AssertPrimitiveMap(map);

+		}

+

+		[Test]

+		public void TestMarshalled()

+		{

+			PrimitiveMap map = CreatePrimitiveMap();

+			byte[] data = map.Marshal();

+			map = PrimitiveMap.Unmarshal(data);

+			AssertPrimitiveMap(map);

+		}

+

+		[Test]

+		public void TestMarshalledWithBigString()

+		{

+			PrimitiveMap map = CreatePrimitiveMap();

+			String test = new String('a', 65538);

+			map.SetString("BIG_STRING", test);

+			byte[] data = map.Marshal();

+			map = PrimitiveMap.Unmarshal(data);

+			AssertPrimitiveMap(map);

+			Assert.AreEqual(test, map.GetString("BIG_STRING"));

+		}

+

+		protected PrimitiveMap CreatePrimitiveMap()

+		{

+			PrimitiveMap map = new PrimitiveMap();

+

+			map["a"] = a;

+			map["b"] = b;

+			map["c"] = c;

+			map["d"] = d;

+			map["e"] = e;

+			map["f"] = f;

+			map["g"] = g;

+			map["h"] = h;

+			map["i"] = i;

+			map["j"] = j;

+			map["k"] = k;

+			map["l"] = l;

+			map["m"] = m;

+			map["n"] = n;

+

+			return map;

+		}

+

+		protected void AssertPrimitiveMap(PrimitiveMap map)

+		{

+			// use generic API to access entries

+			Assert.AreEqual(a, map["a"], "generic map entry: a");

+			Assert.AreEqual(b, map["b"], "generic map entry: b");

+			Assert.AreEqual(c, map["c"], "generic map entry: c");

+			Assert.AreEqual(d, map["d"], "generic map entry: d");

+			Assert.AreEqual(e, map["e"], "generic map entry: e");

+			Assert.AreEqual(f, map["f"], "generic map entry: f");

+			Assert.AreEqual(g, map["g"], "generic map entry: g");

+			Assert.AreEqual(h, map["h"], "generic map entry: h");

+			Assert.AreEqual(i, map["i"], "generic map entry: i");

+			Assert.AreEqual(j, map["j"], "generic map entry: j");

+			Assert.AreEqual(k, map["k"], "generic map entry: k");

+			Assert.AreEqual(l, map["l"], "generic map entry: l");

+			//Assert.AreEqual(m, map["m"], "generic map entry: m");

+			//Assert.AreEqual(n, map["n"], "generic map entry: n");

+

+			// use type safe APIs

+			Assert.AreEqual(a, map.GetBool("a"), "map entry: a");

+			Assert.AreEqual(b, map.GetByte("b"), "map entry: b");

+			Assert.AreEqual(c, map.GetChar("c"), "map entry: c");

+			Assert.AreEqual(d, map.GetShort("d"), "map entry: d");

+			Assert.AreEqual(e, map.GetInt("e"), "map entry: e");

+			Assert.AreEqual(f, map.GetLong("f"), "map entry: f");

+			Assert.AreEqual(g, map.GetString("g"), "map entry: g");

+			Assert.AreEqual(h, map.GetBool("h"), "map entry: h");

+			Assert.AreEqual(i, map.GetByte("i"), "map entry: i");

+			Assert.AreEqual(j, map.GetShort("j"), "map entry: j");

+			Assert.AreEqual(k, map.GetInt("k"), "map entry: k");

+			Assert.AreEqual(l, map.GetLong("l"), "map entry: l");

+			//Assert.AreEqual(m, map.GetList("m"), "map entry: m");

+			//Assert.AreEqual(n, map.GetDictionary("n"), "map entry: n");

+

+			IList list = map.GetList("m");

+			Assert.AreEqual(2, list.Count, "list size");

+			Assert.IsTrue(list.Contains("Item1"));

+			Assert.IsTrue(list.Contains("Item2"));

+

+			IDictionary dictionary = map.GetDictionary("n");

+			Assert.AreEqual(5, dictionary.Count, "dictionary size");

+

+			IDictionary childMap = (IDictionary) dictionary["childMap"];

+			Assert.IsNotNull(childMap);

+			Assert.AreEqual("childMap", childMap["name"], "childMap[name]");

+

+			IList childList = (IList) dictionary["childList"];

+			Assert.IsNotNull(childList);

+			Assert.IsTrue(childList.Contains("childListElement1"));

+		}

+

+		protected static IList CreateList()

+		{

+			ArrayList answer = new ArrayList();

+			answer.Add("Item1");

+			answer.Add("Item2");

+			return answer;

+		}

+

+		protected static IDictionary CreateDictionary()

+		{

+			Hashtable answer = new Hashtable();

+			answer.Add("Name", "James");

+			answer.Add("Location", "London");

+			answer.Add("Company", "LogicBlaze");

+

+			Hashtable childMap = new Hashtable();

+			childMap.Add("name", "childMap");

+			answer.Add("childMap", childMap);

+

+			ArrayList childList = new ArrayList();

+			childList.Add("childListElement1");

+			answer.Add("childList", childList);

+			return answer;

+		}

+	}

+}

diff --git a/src/test/csharp/ProducerTest.cs b/src/test/csharp/ProducerTest.cs
new file mode 100644
index 0000000..4cb30ac
--- /dev/null
+++ b/src/test/csharp/ProducerTest.cs
@@ -0,0 +1,113 @@
+/*

+ * 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 ProducerTest : NMSTest

+	{

+		protected ProducerTest(NMSTestSupport testSupport)

+			: base(testSupport)

+		{

+		}

+

+        //[Test]

+        public virtual void TestProducerSendToNullDestinationWithoutDefault()

+        {

+            using(IConnection connection = CreateConnection(GetTestClientId()))

+            {

+                connection.Start();

+                using(ISession session = connection.CreateSession())

+                {

+                    IMessageProducer producer = session.CreateProducer(null);

+

+                    try

+                    {

+                        producer.Send(null, session.CreateTextMessage("Message"));

+                        Assert.Fail("Producer should have thrown an NotSupportedException");

+                    }

+                    catch(NotSupportedException)

+                    {

+                    }

+                    catch(Exception ex)

+                    {

+                        Assert.Fail("Wrong Exception Type Thrown: " + ex.GetType().Name);

+                    }

+                }

+            }

+        }

+

+        //[Test]

+        public virtual void TestProducerSendToNullDestinationWithDefault()

+        {

+            using(IConnection connection = CreateConnection(GetTestClientId()))

+            {

+                connection.Start();

+                using(ISession session = connection.CreateSession())

+                {

+                    IDestination unusedDest = session.CreateTemporaryQueue();

+

+                    IMessageProducer producer = session.CreateProducer(unusedDest);

+

+                    try

+                    {

+                        producer.Send(null, session.CreateTextMessage("Message"));

+                        Assert.Fail("Producer should have thrown an InvalidDestinationException");

+                    }

+                    catch(InvalidDestinationException)

+                    {

+                    }

+                    catch(Exception ex)

+                    {

+                        Assert.Fail("Wrong Exception Type Thrown: " + ex.GetType().Name);

+                    }

+                }

+            }

+        }

+

+		//[Test]

+		public virtual void TestProducerSendToNonDefaultDestination()

+		{

+            using(IConnection connection = CreateConnection(GetTestClientId()))

+            {

+                connection.Start();

+                using(ISession session = connection.CreateSession())

+                {

+					IDestination unusedDest = session.CreateTemporaryQueue();

+					IDestination usedDest = session.CreateTemporaryQueue();

+

+					IMessageProducer producer = session.CreateProducer(unusedDest);

+

+                    try

+                    {

+					    producer.Send(usedDest, session.CreateTextMessage("Message"));

+                        Assert.Fail("Producer should have thrown an NotSupportedException");

+                    }

+                    catch(NotSupportedException)

+                    {

+                    }

+                    catch(Exception ex)

+                    {

+                        Assert.Fail("Wrong Exception Type Thrown: " + ex.GetType().Name);

+                    }

+				}

+			}

+        }

+	}

+}

diff --git a/src/test/csharp/RedeliveryPolicyTest.cs b/src/test/csharp/RedeliveryPolicyTest.cs
new file mode 100644
index 0000000..d11a6fb
--- /dev/null
+++ b/src/test/csharp/RedeliveryPolicyTest.cs
@@ -0,0 +1,135 @@
+/*

+ * 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.Policies;

+using NUnit.Framework;

+

+namespace Apache.NMS.Test

+{

+    [TestFixture]

+    public class RedeliveryPolicyTest

+    {

+        [Test]

+        public void Executes_redelivery_policy_with_backoff_enabled_correctly()

+        {

+            RedeliveryPolicy policy = new RedeliveryPolicy();

+

+            policy.BackOffMultiplier = 2;

+            policy.InitialRedeliveryDelay = 5;

+            policy.UseExponentialBackOff = true;

+

+            // simulate a retry of 10 times

+            Assert.IsTrue(policy.RedeliveryDelay(0) == 0, "redelivery delay not 5 is " + policy.RedeliveryDelay(0));

+            Assert.IsTrue(policy.RedeliveryDelay(1) == 5, "redelivery delay not 10 is " + policy.RedeliveryDelay(1));

+            Assert.IsTrue(policy.RedeliveryDelay(2) == 10, "redelivery delay not 20 is " + policy.RedeliveryDelay(2));

+            Assert.IsTrue(policy.RedeliveryDelay(3) == 20, "redelivery delay not 40 is " + policy.RedeliveryDelay(3));

+            Assert.IsTrue(policy.RedeliveryDelay(4) == 40, "redelivery delay not 80 is " + policy.RedeliveryDelay(4));

+            Assert.IsTrue(policy.RedeliveryDelay(5) == 80, "redelivery delay not 160 is " + policy.RedeliveryDelay(5));

+            Assert.IsTrue(policy.RedeliveryDelay(6) == 160, "redelivery delay not 320 is " + policy.RedeliveryDelay(6));

+            Assert.IsTrue(policy.RedeliveryDelay(7) == 320, "redelivery delay not 640 is " + policy.RedeliveryDelay(7));

+            Assert.IsTrue(policy.RedeliveryDelay(8) == 640, "redelivery delay not 1280 is " + policy.RedeliveryDelay(8));

+            Assert.IsTrue(policy.RedeliveryDelay(9) == 1280, "redelivery delay not 2560 is " + policy.RedeliveryDelay(9));

+        }

+

+        [Test]

+        public void Executes_redelivery_policy_with_backoff_of_3_enabled_correctly()

+        {

+            RedeliveryPolicy policy = new RedeliveryPolicy();

+

+            policy.BackOffMultiplier = 3;

+            policy.InitialRedeliveryDelay = 3;

+            policy.UseExponentialBackOff = true;

+

+            // simulate a retry of 10 times

+            Assert.IsTrue(policy.RedeliveryDelay(0) == 0, "redelivery delay not 5 is " + policy.RedeliveryDelay(0));

+            Assert.IsTrue(policy.RedeliveryDelay(1) == 3, "redelivery delay not 10 is " + policy.RedeliveryDelay(1));

+            Assert.IsTrue(policy.RedeliveryDelay(2) == 9, "redelivery delay not 20 is " + policy.RedeliveryDelay(2));

+            Assert.IsTrue(policy.RedeliveryDelay(3) == 27, "redelivery delay not 40 is " + policy.RedeliveryDelay(3));

+            Assert.IsTrue(policy.RedeliveryDelay(4) == 81, "redelivery delay not 80 is " + policy.RedeliveryDelay(4));

+            Assert.IsTrue(policy.RedeliveryDelay(5) == 243, "redelivery delay not 160 is " + policy.RedeliveryDelay(5));

+            Assert.IsTrue(policy.RedeliveryDelay(6) == 729, "redelivery delay not 320 is " + policy.RedeliveryDelay(6));

+            Assert.IsTrue(policy.RedeliveryDelay(7) == 2187, "redelivery delay not 640 is " + policy.RedeliveryDelay(7));

+            Assert.IsTrue(policy.RedeliveryDelay(8) == 6561, "redelivery delay not 1280 is " + policy.RedeliveryDelay(8));

+            Assert.IsTrue(policy.RedeliveryDelay(9) == 19683, "redelivery delay not 2560 is " + policy.RedeliveryDelay(9));

+        }

+

+        [Test]

+        public void Executes_redelivery_policy_without_backoff_enabled_correctly()

+        {

+            RedeliveryPolicy policy = new RedeliveryPolicy();

+

+            policy.InitialRedeliveryDelay = 5;

+

+            // simulate a retry of 10 times

+            Assert.IsTrue(policy.RedeliveryDelay(0) == 0, "redelivery delay not 0 is " + policy.RedeliveryDelay(0));

+            Assert.IsTrue(policy.RedeliveryDelay(1) == 5, "redelivery delay not 5 is " + policy.RedeliveryDelay(1));

+            Assert.IsTrue(policy.RedeliveryDelay(2) == 5, "redelivery delay not 5 is " + policy.RedeliveryDelay(2));

+            Assert.IsTrue(policy.RedeliveryDelay(3) == 5, "redelivery delay not 5 is " + policy.RedeliveryDelay(3));

+            Assert.IsTrue(policy.RedeliveryDelay(4) == 5, "redelivery delay not 5 is " + policy.RedeliveryDelay(4));

+            Assert.IsTrue(policy.RedeliveryDelay(5) == 5, "redelivery delay not 5 is " + policy.RedeliveryDelay(5));

+            Assert.IsTrue(policy.RedeliveryDelay(6) == 5, "redelivery delay not 5 is " + policy.RedeliveryDelay(6));

+            Assert.IsTrue(policy.RedeliveryDelay(7) == 5, "redelivery delay not 5 is " + policy.RedeliveryDelay(7));

+            Assert.IsTrue(policy.RedeliveryDelay(8) == 5, "redelivery delay not 5 is " + policy.RedeliveryDelay(8));

+            Assert.IsTrue(policy.RedeliveryDelay(9) == 5, "redelivery delay not 5 is " + policy.RedeliveryDelay(9));

+        }

+

+        [Test]

+        public void Should_get_collision_percent_correctly()

+        {

+            RedeliveryPolicy policy = new RedeliveryPolicy();

+

+            policy.CollisionAvoidancePercent = 45;

+

+            Assert.IsTrue(policy.CollisionAvoidancePercent == 45);

+        }

+

+        [Test]

+        public void Executes_redelivery_policy_with_collision_enabled_correctly()

+        {

+            RedeliveryPolicy policy = new RedeliveryPolicy();

+

+            policy.BackOffMultiplier = 2;

+            policy.InitialRedeliveryDelay = 5;

+            policy.UseExponentialBackOff = true;

+            policy.UseCollisionAvoidance = true;

+            policy.CollisionAvoidancePercent = 10;

+

+            // simulate a retry of 10 times

+            int delay = policy.RedeliveryDelay(0);

+            Assert.IsTrue(delay == 0, "not zero is " + policy.RedeliveryDelay(0));

+            delay = policy.RedeliveryDelay(1);

+            Assert.IsTrue(delay >= 4.5 && delay <= 5.5, "not delay >= 4.5 && delay <= 5.5 is " + policy.RedeliveryDelay(1));

+            delay = policy.RedeliveryDelay(2);

+            Assert.IsTrue(delay >= 9 && delay <= 11, "not delay >= 9 && delay <= 11 is " + policy.RedeliveryDelay(2));

+            delay = policy.RedeliveryDelay(3);

+            Assert.IsTrue(delay >= 18 && delay <= 22, "not delay >= 18 && delay <= 22 is " + policy.RedeliveryDelay(3));

+            delay = policy.RedeliveryDelay(4);

+            Assert.IsTrue(delay >= 36 && delay <= 44, "not delay >= 36 && delay <= 44 is " + policy.RedeliveryDelay(4));

+            delay = policy.RedeliveryDelay(5);

+            Assert.IsTrue(delay >= 72 && delay <= 88, "not delay >= 72 && delay <= 88 is " + policy.RedeliveryDelay(5));

+            delay = policy.RedeliveryDelay(6);

+            Assert.IsTrue(delay >= 144 && delay <= 176, "not delay >= 144 && delay <= 176 is " + policy.RedeliveryDelay(6));

+            delay = policy.RedeliveryDelay(7);

+            Assert.IsTrue(delay >= 288 && delay <= 352, "not delay >= 288 && delay <= 352 is " + policy.RedeliveryDelay(7));

+            delay = policy.RedeliveryDelay(8);

+            Assert.IsTrue(delay >= 576 && delay <= 704, "not delay >= 576 && delay <= 704 is " + policy.RedeliveryDelay(8));

+            delay = policy.RedeliveryDelay(9);

+            Assert.IsTrue(delay >= 1152 && delay <= 1408, "not delay >= 1152 && delay <= 1408 is " + policy.RedeliveryDelay(9));

+            delay = policy.RedeliveryDelay(10);

+            Assert.IsTrue(delay >= 2304 && delay <= 2816, "not delay >= 2304 && delay <= 2816 is " + policy.RedeliveryDelay(10));

+        }

+    }

+}

diff --git a/src/test/csharp/RequestResponseTest.cs b/src/test/csharp/RequestResponseTest.cs
new file mode 100644
index 0000000..1c1ca41
--- /dev/null
+++ b/src/test/csharp/RequestResponseTest.cs
@@ -0,0 +1,74 @@
+/*

+ * 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 RequestResponseTest : NMSTest

+	{

+		protected RequestResponseTest(NMSTestSupport testSupport)

+			: base(testSupport)

+		{

+		}

+

+		//[Test]

+		//[Category("RequestResponse")]		

+		public virtual void TestRequestResponseMessaging(string testQueueRef)

+		{

+			using(IConnection connection = CreateConnection())

+			{

+				connection.Start();

+				using(ISession session = connection.CreateSession(AcknowledgementMode.AutoAcknowledge))

+				{

+					IDestination destination = GetClearDestination(session, DestinationType.Queue, testQueueRef);

+					ITemporaryQueue replyTo = session.CreateTemporaryQueue();

+

+					using(IMessageConsumer consumer = session.CreateConsumer(destination))

+					using(IMessageProducer producer = session.CreateProducer(destination))

+					{

+						IMessage request = session.CreateMessage();

+						

+						request.NMSReplyTo = replyTo;

+						

+						producer.Send(request);

+						

+						request = consumer.Receive(TimeSpan.FromMilliseconds(3000));

+						Assert.IsNotNull(request);

+						Assert.IsNotNull(request.NMSReplyTo);

+						

+						using(IMessageProducer responder = session.CreateProducer(request.NMSReplyTo))

+						{

+							IMessage response = session.CreateTextMessage("RESPONSE");							

+							responder.Send(response);

+						}						

+					}

+					

+					using(IMessageConsumer consumer = session.CreateConsumer(replyTo))

+					{

+						ITextMessage response = consumer.Receive(TimeSpan.FromMilliseconds(3000)) as ITextMessage;

+						Assert.IsNotNull(response);

+						Assert.AreEqual("RESPONSE", response.Text);

+					}

+				}

+			}

+		}

+	}

+}

+

diff --git a/src/test/csharp/StreamMessageTest.cs b/src/test/csharp/StreamMessageTest.cs
new file mode 100644
index 0000000..d2c6d87
--- /dev/null
+++ b/src/test/csharp/StreamMessageTest.cs
@@ -0,0 +1,111 @@
+/*

+ * 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.Util;

+using NUnit.Framework;

+

+namespace Apache.NMS.Test

+{

+	//[TestFixture]

+	public class StreamMessageTest : NMSTest

+	{

+		protected bool a = true;

+		protected byte b = 123;

+		protected char c = 'c';

+		protected short d = 0x1234;

+		protected int e = 0x12345678;

+		protected long f = 0x1234567812345678;

+		protected string g = "Hello World!";

+		protected bool h = false;

+		protected byte i = 0xFF;

+		protected short j = -0x1234;

+		protected int k = -0x12345678;

+		protected long l = -0x1234567812345678;

+		protected float m = 2.1F;

+		protected double n = 2.3;

+

+		protected StreamMessageTest(NMSTestSupport testSupport)

+			: base(testSupport)

+		{

+		}

+

+		//[Test]

+		public virtual void TestSendReceiveStreamMessage(

+			//[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;

+						IStreamMessage request;

+

+						try

+						{

+							request = session.CreateStreamMessage();

+						}

+						catch(System.NotSupportedException)

+						{

+							return;

+						}

+

+						request.WriteBoolean(a);

+						request.WriteByte(b);

+						request.WriteChar(c);

+						request.WriteInt16(d);

+						request.WriteInt32(e);

+						request.WriteInt64(f);

+						request.WriteString(g);

+						request.WriteBoolean(h);

+						request.WriteByte(i);

+						request.WriteInt16(j);

+						request.WriteInt32(k);

+						request.WriteInt64(l);

+						request.WriteSingle(m);

+						request.WriteDouble(n);

+						producer.Send(request);

+

+						IStreamMessage message = consumer.Receive(receiveTimeout) as IStreamMessage;

+						Assert.IsNotNull(message, "No message returned!");

+						Assert.AreEqual(deliveryMode, message.NMSDeliveryMode, "NMSDeliveryMode does not match");

+

+						// use generic API to access entries

+						Assert.AreEqual(a, message.ReadBoolean(), "Stream Boolean Value: a");

+						Assert.AreEqual(b, message.ReadByte(), "Stream Byte Value: b");

+						Assert.AreEqual(c, message.ReadChar(), "Stream Char Value: c");

+						Assert.AreEqual(d, message.ReadInt16(), "Stream Int16 Value: d");

+						Assert.AreEqual(e, message.ReadInt32(), "Stream Int32 Value: e");

+						Assert.AreEqual(f, message.ReadInt64(), "Stream Int64 Value: f");

+						Assert.AreEqual(g, message.ReadString(), "Stream String Value: g");

+						Assert.AreEqual(h, message.ReadBoolean(), "Stream Boolean Value: h");

+						Assert.AreEqual(i, message.ReadByte(), "Stream Byte Value: i");

+						Assert.AreEqual(j, message.ReadInt16(), "Stream Int16 Value: j");

+						Assert.AreEqual(k, message.ReadInt32(), "Stream Int32 Value: k");

+						Assert.AreEqual(l, message.ReadInt64(), "Stream Int64 Value: l");

+						Assert.AreEqual(m, message.ReadSingle(), "Stream Single Value: m");

+						Assert.AreEqual(n, message.ReadDouble(), "Stream Double Value: n");

+					}

+				}

+			}

+		}

+	}

+}

diff --git a/src/test/csharp/TempDestinationDeletionTest.cs b/src/test/csharp/TempDestinationDeletionTest.cs
new file mode 100644
index 0000000..6c96d74
--- /dev/null
+++ b/src/test/csharp/TempDestinationDeletionTest.cs
@@ -0,0 +1,80 @@
+/*

+ * 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 TempDestinationDeletionTest : NMSTest

+	{

+		protected TempDestinationDeletionTest(NMSTestSupport testSupport)

+			: base(testSupport)

+		{

+		}

+

+		//[Test]

+		public virtual void TestTempDestinationDeletion(

+			//[Values(MsgDeliveryMode.Persistent, MsgDeliveryMode.NonPersistent)]

+			MsgDeliveryMode deliveryMode,

+			//[Values(QUEUE_DESTINATION_NAME, TOPIC_DESTINATION_NAME, TEMP_QUEUE_DESTINATION_NAME, TEMP_TOPIC_DESTINATION_NAME)]

+			string testDestinationURI)

+		{

+			using(IConnection connection1 = CreateConnection(GetTestClientId()))

+			{

+				connection1.Start();

+				using(ISession session = connection1.CreateSession(AcknowledgementMode.AutoAcknowledge))

+				{

+					const int MaxNumDestinations = 100;

+

+					for(int index = 1; index <= MaxNumDestinations; index++)

+					{

+						IDestination destination = GetClearDestination(session, testDestinationURI);

+

+						using(IMessageProducer producer = session.CreateProducer(destination))

+						using(IMessageConsumer consumer = session.CreateConsumer(destination))

+						{

+							producer.DeliveryMode = deliveryMode;

+

+							IMessage request = session.CreateTextMessage("Hello World, Just Passing Through!");

+

+							request.NMSType = "TEMP_MSG";

+							producer.Send(request);

+							IMessage receivedMsg = consumer.Receive(TimeSpan.FromMilliseconds(5000));

+							Assert.IsNotNull(receivedMsg);

+							Assert.AreEqual(receivedMsg.NMSType, "TEMP_MSG");

+							

+							// Ensures that Consumer closes out its subscription

+							consumer.Close();

+						}

+

+						try

+						{

+							session.DeleteDestination(destination);

+						}

+						catch(NotSupportedException)

+						{

+							// Might as well not try this again.

+							break;

+						}

+					}

+				}

+			}

+		}

+	}

+}

diff --git a/src/test/csharp/TempDestinationTest.cs b/src/test/csharp/TempDestinationTest.cs
new file mode 100644
index 0000000..f773698
--- /dev/null
+++ b/src/test/csharp/TempDestinationTest.cs
@@ -0,0 +1,175 @@
+/*

+ * 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 NUnit.Framework;

+

+namespace Apache.NMS.Test

+{

+    //[TestFixture]

+    public class TempDestinationTest : NMSTest

+    {

+        private IConnection connection;

+        private IList connections = ArrayList.Synchronized(new ArrayList());

+

+		protected TempDestinationTest(NMSTestSupport testSupport)

+			: base(testSupport)

+		{

+		}

+

+        //[SetUp]

+        public override void SetUp()

+        {

+            base.SetUp();

+

+            this.connection = CreateConnection();

+            this.connections.Add(connection);

+        }

+

+        //[TearDown]

+        public override void TearDown()

+        {

+            foreach(IConnection conn in this.connections)

+            {

+                try

+                {

+                    conn.Close();

+                }

+                catch

+                {

+                }

+            }

+

+            connections.Clear();

+

+            base.TearDown();

+        }

+

+        //[Test]

+        public virtual void TestTempDestOnlyConsumedByLocalConn()

+        {

+            connection.Start();

+

+            ISession tempSession = connection.CreateSession(AcknowledgementMode.AutoAcknowledge);

+            ITemporaryQueue queue = tempSession.CreateTemporaryQueue();

+            IMessageProducer producer = tempSession.CreateProducer(queue);

+            producer.DeliveryMode = (MsgDeliveryMode.NonPersistent);

+            ITextMessage message = tempSession.CreateTextMessage("First");

+            producer.Send(message);

+

+            // temp destination should not be consume when using another connection

+            IConnection otherConnection = CreateConnection();

+            connections.Add(otherConnection);

+            ISession otherSession = otherConnection.CreateSession(AcknowledgementMode.AutoAcknowledge);

+            ITemporaryQueue otherQueue = otherSession.CreateTemporaryQueue();

+            IMessageConsumer consumer = otherSession.CreateConsumer(otherQueue);

+            IMessage msg = consumer.Receive(TimeSpan.FromMilliseconds(3000));

+            Assert.IsNull(msg);

+

+            // should be able to consume temp destination from the same connection

+            consumer = tempSession.CreateConsumer(queue);

+            msg = consumer.Receive(TimeSpan.FromMilliseconds(3000));

+            Assert.IsNotNull(msg);

+        }

+

+        //[Test]

+        public virtual void TestTempQueueHoldsMessagesWithConsumers()

+        {

+            ISession session = connection.CreateSession(AcknowledgementMode.AutoAcknowledge);

+            ITemporaryQueue queue = session.CreateTemporaryQueue();

+            IMessageConsumer consumer = session.CreateConsumer(queue);

+            connection.Start();

+

+            IMessageProducer producer = session.CreateProducer(queue);

+            producer.DeliveryMode = (MsgDeliveryMode.NonPersistent);

+            ITextMessage message = session.CreateTextMessage("Hello");

+            producer.Send(message);

+

+            IMessage message2 = consumer.Receive(TimeSpan.FromMilliseconds(1000));

+            Assert.IsNotNull(message2);

+            Assert.IsTrue(message2 is ITextMessage, "Expected message to be a ITextMessage");

+            Assert.IsTrue(((ITextMessage)message2).Text == message.Text, "Expected message to be a '" + message.Text + "'");

+        }

+

+        //[Test]

+        public virtual void TestTempQueueHoldsMessagesWithoutConsumers()

+        {

+            ISession session = connection.CreateSession(AcknowledgementMode.AutoAcknowledge);

+            ITemporaryQueue queue = session.CreateTemporaryQueue();

+            IMessageProducer producer = session.CreateProducer(queue);

+            producer.DeliveryMode = MsgDeliveryMode.NonPersistent;

+            ITextMessage message = session.CreateTextMessage("Hello");

+            producer.Send(message);

+

+            connection.Start();

+            IMessageConsumer consumer = session.CreateConsumer(queue);

+            IMessage message2 = consumer.Receive(TimeSpan.FromMilliseconds(3000));

+            Assert.IsNotNull(message2);

+            Assert.IsTrue(message2 is ITextMessage, "Expected message to be a ITextMessage");

+            Assert.IsTrue(((ITextMessage)message2).Text == message.Text, "Expected message to be a '" + message.Text + "'");

+        }

+

+        //[Test]

+        public virtual void TestTmpQueueWorksUnderLoad()

+        {

+            int count = 500;

+            int dataSize = 1024;

+

+            ArrayList list = new ArrayList(count);

+            ISession session = connection.CreateSession(AcknowledgementMode.AutoAcknowledge);

+            ITemporaryQueue queue = session.CreateTemporaryQueue();

+            IBytesMessage message;

+            IBytesMessage message2;

+            IMessageProducer producer = session.CreateProducer(queue);

+            producer.DeliveryMode = MsgDeliveryMode.NonPersistent;

+

+            byte[] srcdata = new byte[dataSize];

+            srcdata[0] = (byte) 'B';

+            srcdata[1] = (byte) 'A';

+            srcdata[2] = (byte) 'D';

+            srcdata[3] = (byte) 'W';

+            srcdata[4] = (byte) 'O';

+            srcdata[5] = (byte) 'L';

+            srcdata[6] = (byte) 'F';

+            for(int i = 0; i < count; i++)

+            {

+                message = session.CreateBytesMessage();

+                message.WriteBytes(srcdata);

+                message.Properties.SetInt("c", i);

+                producer.Send(message);

+                list.Add(message);

+            }

+

+            connection.Start();

+            byte[] data = new byte[dataSize];

+            byte[] data2 = new byte[dataSize];

+            IMessageConsumer consumer = session.CreateConsumer(queue);

+            for(int i = 0; i < count; i++)

+            {

+                message2 = consumer.Receive(TimeSpan.FromMilliseconds(2000)) as IBytesMessage;

+                Assert.IsNotNull(message2);

+                Assert.AreEqual(i, message2.Properties.GetInt("c"));

+                message = list[i] as IBytesMessage;

+                Assert.IsNotNull(message);

+				message.Reset();

+                message.ReadBytes(data);

+                message2.ReadBytes(data2);

+                Assert.AreEqual(data, data2);

+            }

+        }

+    }

+}

diff --git a/src/test/csharp/TextMessageTest.cs b/src/test/csharp/TextMessageTest.cs
new file mode 100644
index 0000000..8db26aa
--- /dev/null
+++ b/src/test/csharp/TextMessageTest.cs
@@ -0,0 +1,71 @@
+/*

+ * 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 TextMessageTest : NMSTest

+	{

+		protected TextMessageTest(NMSTestSupport testSupport)

+			: base(testSupport)

+		{

+		}

+

+		//[Test]

+		public virtual void TestSendReceiveTextMessage(

+			//[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.CreateTextMessage("Hello World!");

+						producer.Send(request);

+

+						IMessage message = consumer.Receive(receiveTimeout);

+						AssertTextMessageEqual(request, message);

+						Assert.AreEqual(deliveryMode, message.NMSDeliveryMode, "NMSDeliveryMode does not match");

+					}

+				}

+			}

+		}

+

+		/// <summary>

+		/// Assert that two messages are ITextMessages and their text bodies are equal.

+		/// </summary>

+		/// <param name="expected"></param>

+		/// <param name="actual"></param>

+		protected void AssertTextMessageEqual(IMessage expected, IMessage actual)

+		{

+			ITextMessage expectedTextMsg = expected as ITextMessage;

+			Assert.IsNotNull(expectedTextMsg, "'expected' message not a text message");

+			ITextMessage actualTextMsg = actual as ITextMessage;

+			Assert.IsNotNull(actualTextMsg, "'actual' message not a text message");

+			Assert.AreEqual(expectedTextMsg.Text, actualTextMsg.Text, "Text message does not match.");

+		}

+	}

+}

diff --git a/src/test/csharp/TransactionTest.cs b/src/test/csharp/TransactionTest.cs
new file mode 100644
index 0000000..7c13827
--- /dev/null
+++ b/src/test/csharp/TransactionTest.cs
@@ -0,0 +1,439 @@
+/*

+ * 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 TransactionTest : NMSTest

+	{

+		protected TransactionTest(NMSTestSupport testSupport)

+			: base(testSupport)

+		{

+		}

+

+		//[Test]

+		public virtual void TestSendRollback(

+			//[Values(MsgDeliveryMode.Persistent, MsgDeliveryMode.NonPersistent)]

+			MsgDeliveryMode deliveryMode, string testQueueRef)

+		{

+			using(IConnection connection = CreateConnection(GetTestClientId()))

+			{

+				connection.Start();

+				using(ISession session = connection.CreateSession(AcknowledgementMode.Transactional))

+				{

+					IDestination destination = GetClearDestination(session, DestinationType.Queue, testQueueRef);

+					using(IMessageConsumer consumer = session.CreateConsumer(destination))

+					using(IMessageProducer producer = session.CreateProducer(destination))

+					{

+						producer.DeliveryMode = deliveryMode;

+						ITextMessage firstMsgSend = session.CreateTextMessage("First Message");

+						producer.Send(firstMsgSend);

+						session.Commit();

+

+						ITextMessage rollbackMsg = session.CreateTextMessage("I'm going to get rolled back.");

+						producer.Send(rollbackMsg);

+						session.Rollback();

+

+						ITextMessage secondMsgSend = session.CreateTextMessage("Second Message");

+						producer.Send(secondMsgSend);

+						session.Commit();

+

+						// Receive the messages

+

+						IMessage message = consumer.Receive(receiveTimeout);

+						AssertTextMessageEqual(firstMsgSend, message, "First message does not match.");

+

+						message = consumer.Receive(receiveTimeout);

+						AssertTextMessageEqual(secondMsgSend, message, "Second message does not match.");

+

+						// validates that the rollback was not consumed

+						session.Commit();

+					}

+				}

+			}

+		}

+

+		//[Test]

+		public virtual void TestSendSessionClose(

+			//[Values(MsgDeliveryMode.Persistent, MsgDeliveryMode.NonPersistent)]

+			MsgDeliveryMode deliveryMode, string testQueueRef)

+		{

+			ITextMessage firstMsgSend;

+			ITextMessage secondMsgSend;

+

+			using(IConnection connection1 = CreateConnection(GetTestClientId()))

+			{

+				connection1.Start();

+				using(ISession session1 = connection1.CreateSession(AcknowledgementMode.Transactional))

+				{

+					IDestination destination1 = GetClearDestination(session1, DestinationType.Queue, testQueueRef);

+					using(IMessageConsumer consumer = session1.CreateConsumer(destination1))

+					{

+						// First connection session that sends one message, and the

+						// second message is implicitly rolled back as the session is

+						// disposed before Commit() can be called.

+						using(IConnection connection2 = CreateConnection(GetTestClientId()))

+						{

+							connection2.Start();

+							using(ISession session2 = connection2.CreateSession(AcknowledgementMode.Transactional))

+							{

+								IDestination destination2 = GetClearDestination(session2, DestinationType.Queue, testQueueRef);

+								using(IMessageProducer producer = session2.CreateProducer(destination2))

+								{

+									producer.DeliveryMode = deliveryMode;

+									firstMsgSend = session2.CreateTextMessage("First Message");

+									producer.Send(firstMsgSend);

+									session2.Commit();

+

+									ITextMessage rollbackMsg = session2.CreateTextMessage("I'm going to get rolled back.");

+									producer.Send(rollbackMsg);

+								}

+							}

+						}

+

+						// Second connection session that will send one message.

+						using(IConnection connection2 = CreateConnection(GetTestClientId()))

+						{

+							connection2.Start();

+							using(ISession session2 = connection2.CreateSession(AcknowledgementMode.Transactional))

+							{

+								IDestination destination2 = GetClearDestination(session2, DestinationType.Queue, testQueueRef);

+								using(IMessageProducer producer = session2.CreateProducer(destination2))

+								{

+									producer.DeliveryMode = deliveryMode;

+									secondMsgSend = session2.CreateTextMessage("Second Message");

+									producer.Send(secondMsgSend);

+									session2.Commit();

+								}

+							}

+						}

+

+						// Check the consumer to verify which messages were actually received.

+						IMessage message = consumer.Receive(receiveTimeout);

+						AssertTextMessageEqual(firstMsgSend, message, "First message does not match.");

+

+						message = consumer.Receive(receiveTimeout);

+						AssertTextMessageEqual(secondMsgSend, message, "Second message does not match.");

+

+						// validates that the rollback was not consumed

+						session1.Commit();

+					}

+				}

+			}

+		}

+

+		//[Test]

+		public virtual void TestReceiveRollback(

+			//[Values(MsgDeliveryMode.Persistent, MsgDeliveryMode.NonPersistent)]

+			MsgDeliveryMode deliveryMode, string testQueueRef)

+		{

+			using(IConnection connection = CreateConnection(GetTestClientId()))

+			{

+				connection.Start();

+				using(ISession session = connection.CreateSession(AcknowledgementMode.Transactional))

+				{

+					IDestination destination = GetClearDestination(session, DestinationType.Queue, testQueueRef);

+					using(IMessageConsumer consumer = session.CreateConsumer(destination))

+					using(IMessageProducer producer = session.CreateProducer(destination))

+					{

+						producer.DeliveryMode = deliveryMode;

+						// Send both messages

+						ITextMessage firstMsgSend = session.CreateTextMessage("First Message");

+						producer.Send(firstMsgSend);

+						ITextMessage secondMsgSend = session.CreateTextMessage("Second Message");

+						producer.Send(secondMsgSend);

+						session.Commit();

+

+						// Receive the messages

+

+						IMessage message = consumer.Receive(receiveTimeout);

+						AssertTextMessageEqual(firstMsgSend, message, "First message does not match.");

+						session.Commit();

+

+						message = consumer.Receive(receiveTimeout);

+						AssertTextMessageEqual(secondMsgSend, message, "Second message does not match.");

+

+						// Rollback so we can get that last message again.

+						session.Rollback();

+						IMessage rollbackMsg = consumer.Receive(receiveTimeout);

+						AssertTextMessageEqual(secondMsgSend, rollbackMsg, "Rollback message does not match.");

+						session.Commit();

+					}

+				}

+			}

+		}

+

+

+		//[Test]

+		public virtual void TestReceiveTwoThenRollback(

+			//[Values(MsgDeliveryMode.Persistent, MsgDeliveryMode.NonPersistent)]

+			MsgDeliveryMode deliveryMode, string testQueueRef)

+		{

+			using(IConnection connection = CreateConnection(GetTestClientId()))

+			{

+				connection.Start();

+				using(ISession session = connection.CreateSession(AcknowledgementMode.Transactional))

+				{

+					IDestination destination = GetClearDestination(session, DestinationType.Queue, testQueueRef);

+					using(IMessageConsumer consumer = session.CreateConsumer(destination))

+					using(IMessageProducer producer = session.CreateProducer(destination))

+					{

+						producer.DeliveryMode = deliveryMode;

+						// Send both messages

+						ITextMessage firstMsgSend = session.CreateTextMessage("First Message");

+						producer.Send(firstMsgSend);

+						ITextMessage secondMsgSend = session.CreateTextMessage("Second Message");

+						producer.Send(secondMsgSend);

+						session.Commit();

+

+						// Receive the messages

+

+						IMessage message = consumer.Receive(receiveTimeout);

+						AssertTextMessageEqual(firstMsgSend, message, "First message does not match.");

+						message = consumer.Receive(receiveTimeout);

+						AssertTextMessageEqual(secondMsgSend, message, "Second message does not match.");

+

+						// Rollback so we can get that last two messages again.

+						session.Rollback();

+						IMessage rollbackMsg = consumer.Receive(receiveTimeout);

+						AssertTextMessageEqual(firstMsgSend, rollbackMsg, "First rollback message does not match.");

+						rollbackMsg = consumer.Receive(receiveTimeout);

+						AssertTextMessageEqual(secondMsgSend, rollbackMsg, "Second rollback message does not match.");

+

+						Assert.IsNull(consumer.ReceiveNoWait());

+						session.Commit();

+					}

+				}

+			}

+		}

+

+		//[Test]

+		public virtual void TestSendCommitNonTransaction(

+			//[Values(AcknowledgementMode.AutoAcknowledge, AcknowledgementMode.ClientAcknowledge)]

+			AcknowledgementMode ackMode,

+			//[Values(MsgDeliveryMode.Persistent, MsgDeliveryMode.NonPersistent)]

+			MsgDeliveryMode deliveryMode, string testQueueRef)

+		{

+			using(IConnection connection = CreateConnection(GetTestClientId()))

+			{

+				connection.Start();

+				using(ISession session = connection.CreateSession(ackMode))

+				{

+					IDestination destination = GetClearDestination(session, DestinationType.Queue, testQueueRef);

+					using(IMessageConsumer consumer = session.CreateConsumer(destination))

+					using(IMessageProducer producer = session.CreateProducer(destination))

+					{

+						producer.DeliveryMode = deliveryMode;

+						ITextMessage firstMsgSend = session.CreateTextMessage("SendCommitNonTransaction Message");

+						producer.Send(firstMsgSend);

+						try

+						{

+							session.Commit();

+							Assert.Fail("Should have thrown an InvalidOperationException.");

+						}

+						catch(InvalidOperationException)

+						{

+						}

+					}

+				}

+			}

+		}

+

+		//[Test]

+		public virtual void TestReceiveCommitNonTransaction(

+			//[Values(AcknowledgementMode.AutoAcknowledge, AcknowledgementMode.ClientAcknowledge)]

+			AcknowledgementMode ackMode,

+			//[Values(MsgDeliveryMode.Persistent, MsgDeliveryMode.NonPersistent)]

+			MsgDeliveryMode deliveryMode, string testQueueRef)

+		{

+			using(IConnection connection = CreateConnection(GetTestClientId()))

+			{

+				connection.Start();

+				using(ISession session = connection.CreateSession(ackMode))

+				{

+					IDestination destination = GetClearDestination(session, DestinationType.Queue, testQueueRef);

+					using(IMessageConsumer consumer = session.CreateConsumer(destination))

+					using(IMessageProducer producer = session.CreateProducer(destination))

+					{

+						producer.DeliveryMode = deliveryMode;

+						ITextMessage firstMsgSend = session.CreateTextMessage("ReceiveCommitNonTransaction Message");

+						producer.Send(firstMsgSend);

+

+						// Receive the messages

+

+						IMessage message = consumer.Receive(receiveTimeout);

+						AssertTextMessageEqual(firstMsgSend, message, "First message does not match.");

+						if(AcknowledgementMode.ClientAcknowledge == ackMode)

+						{

+							message.Acknowledge();

+						}

+

+						try

+						{

+							session.Commit();

+							Assert.Fail("Should have thrown an InvalidOperationException.");

+						}

+						catch(InvalidOperationException)

+						{

+						}

+					}

+				}

+			}

+		}

+

+		//[Test]

+		public virtual void TestReceiveRollbackNonTransaction(

+			//[Values(AcknowledgementMode.AutoAcknowledge, AcknowledgementMode.ClientAcknowledge)]

+			AcknowledgementMode ackMode,

+			//[Values(MsgDeliveryMode.Persistent, MsgDeliveryMode.NonPersistent)]

+			MsgDeliveryMode deliveryMode, string testQueueRef)

+		{

+			using(IConnection connection = CreateConnection(GetTestClientId()))

+			{

+				connection.Start();

+				using(ISession session = connection.CreateSession(ackMode))

+				{

+					IDestination destination = GetClearDestination(session, DestinationType.Queue, testQueueRef);

+					using(IMessageConsumer consumer = session.CreateConsumer(destination))

+					using(IMessageProducer producer = session.CreateProducer(destination))

+					{

+						producer.DeliveryMode = deliveryMode;

+						ITextMessage firstMsgSend = session.CreateTextMessage("ReceiveCommitNonTransaction Message");

+						producer.Send(firstMsgSend);

+

+						// Receive the messages

+

+						IMessage message = consumer.Receive(receiveTimeout);

+						AssertTextMessageEqual(firstMsgSend, message, "First message does not match.");

+						if(AcknowledgementMode.ClientAcknowledge == ackMode)

+						{

+							message.Acknowledge();

+						}

+

+						try

+						{

+							session.Rollback();

+							Assert.Fail("Should have thrown an InvalidOperationException.");

+						}

+						catch(InvalidOperationException)

+						{

+						}

+					}

+				}

+			}

+		}

+

+		/// <summary>

+		/// Assert that two messages are ITextMessages and their text bodies are equal.

+		/// </summary>

+		/// <param name="expected"></param>

+		/// <param name="actual"></param>

+		/// <param name="message"></param>

+		protected void AssertTextMessageEqual(IMessage expected, IMessage actual, String message)

+		{

+			ITextMessage expectedTextMsg = expected as ITextMessage;

+			Assert.IsNotNull(expectedTextMsg, "'expected' message not a text message");

+			ITextMessage actualTextMsg = actual as ITextMessage;

+			Assert.IsNotNull(actualTextMsg, "'actual' message not a text message");

+			Assert.AreEqual(expectedTextMsg.Text, actualTextMsg.Text, message);

+		}

+

+		//[Test]

+		public virtual void TestRedispatchOfRolledbackTx(

+			//[Values(MsgDeliveryMode.Persistent, MsgDeliveryMode.NonPersistent)]

+			MsgDeliveryMode deliveryMode, string testQueueRef)

+		{

+			using(IConnection connection = CreateConnection(GetTestClientId()))

+			{

+				connection.Start();

+				ISession session = connection.CreateSession(AcknowledgementMode.Transactional);

+				IDestination destination = GetClearDestination(session, DestinationType.Queue, testQueueRef);

+

+				SendMessages(connection, destination, deliveryMode, 2);

+

+				IMessageConsumer consumer = session.CreateConsumer(destination);

+				Assert.IsNotNull(consumer.Receive(TimeSpan.FromMilliseconds(1500)));

+				Assert.IsNotNull(consumer.Receive(TimeSpan.FromMilliseconds(1500)));

+

+				// install another consumer while message dispatch is unacked/uncommitted

+				ISession redispatchSession = connection.CreateSession(AcknowledgementMode.Transactional);

+				IMessageConsumer redispatchConsumer = redispatchSession.CreateConsumer(destination);

+

+				session.Rollback();

+				session.Close();

+

+				IMessage msg = redispatchConsumer.Receive(TimeSpan.FromMilliseconds(1500));

+				Assert.IsNotNull(msg);

+				Assert.IsTrue(msg.NMSRedelivered);

+				Assert.AreEqual(2, msg.Properties.GetLong("NMSXDeliveryCount"));

+				msg = redispatchConsumer.Receive(TimeSpan.FromMilliseconds(1500));

+				Assert.IsNotNull(msg);

+				Assert.IsTrue(msg.NMSRedelivered);

+				Assert.AreEqual(2, msg.Properties.GetLong("NMSXDeliveryCount"));

+				redispatchSession.Commit();

+

+				Assert.IsNull(redispatchConsumer.Receive(TimeSpan.FromMilliseconds(500)));

+				redispatchSession.Close();

+			}

+		}

+

+		//[Test]

+		public virtual void TestRedispatchOfUncommittedTx(

+			//[Values(MsgDeliveryMode.Persistent, MsgDeliveryMode.NonPersistent)]

+			MsgDeliveryMode deliveryMode, string testQueueRef)

+		{

+			using(IConnection connection = CreateConnection(GetTestClientId()))

+			{

+				connection.Start();

+				ISession session = connection.CreateSession(AcknowledgementMode.Transactional);

+				IDestination destination = GetClearDestination(session, DestinationType.Queue, testQueueRef);

+

+				SendMessages(connection, destination, deliveryMode, 2);

+

+				IMessageConsumer consumer = session.CreateConsumer(destination);

+				Assert.IsNotNull(consumer.Receive(TimeSpan.FromMilliseconds(2000)));

+				Assert.IsNotNull(consumer.Receive(TimeSpan.FromMilliseconds(2000)));

+

+				// install another consumer while message dispatch is unacked/uncommitted

+				ISession redispatchSession = connection.CreateSession(AcknowledgementMode.Transactional);

+				IMessageConsumer redispatchConsumer = redispatchSession.CreateConsumer(destination);

+

+				// no commit so will auto rollback and get re-dispatched to redisptachConsumer

+				session.Close();

+

+				IMessage msg = redispatchConsumer.Receive(TimeSpan.FromMilliseconds(2000));

+				Assert.IsNotNull(msg);

+				Assert.IsTrue(msg.NMSRedelivered);

+				Assert.AreEqual(2, msg.Properties.GetLong("NMSXDeliveryCount"));

+

+				msg = redispatchConsumer.Receive(TimeSpan.FromMilliseconds(2000));

+				Assert.IsNotNull(msg);

+				Assert.IsTrue(msg.NMSRedelivered);

+				Assert.AreEqual(2, msg.Properties.GetLong("NMSXDeliveryCount"));

+				redispatchSession.Commit();

+

+				Assert.IsNull(redispatchConsumer.Receive(TimeSpan.FromMilliseconds(500)));

+				redispatchSession.Close();

+			}

+		}

+	}

+}

+

+

diff --git a/src/test/csharp/XMSAsyncConsumeTest.cs b/src/test/csharp/XMSAsyncConsumeTest.cs
new file mode 100644
index 0000000..7ef2954
--- /dev/null
+++ b/src/test/csharp/XMSAsyncConsumeTest.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.Threading;

+using Apache.NMS.Test;

+using NUnit.Framework;

+

+namespace Apache.NMS.XMS.Test

+{

+	[TestFixture]

+	public class XMSAsyncConsumeTest : AsyncConsumeTest

+	{

+		protected static string DEFAULT_TEST_QUEUE = "defaultTestQueue";

+

+		public XMSAsyncConsumeTest() :

+			base(new XMSTestSupport())

+		{

+		}

+

+		[SetUp]

+		public override void SetUp()

+		{

+			base.SetUp();

+		}

+

+		[TearDown]

+		public override void TearDown()

+		{

+			base.TearDown();

+		}

+

+		[Test]

+		public void TestAsynchronousConsume(

+			[Values(MsgDeliveryMode.Persistent, MsgDeliveryMode.NonPersistent)]

+			MsgDeliveryMode deliveryMode)

+		{

+			base.TestAsynchronousConsume(deliveryMode, DEFAULT_TEST_QUEUE);

+		}

+

+		[Test]

+		public void TestCreateConsumerAfterSend(

+			[Values(MsgDeliveryMode.Persistent, MsgDeliveryMode.NonPersistent)]

+			MsgDeliveryMode deliveryMode)

+		{

+			base.TestCreateConsumerAfterSend(deliveryMode, DEFAULT_TEST_QUEUE);

+		}

+

+		[Test]

+		public void TestCreateConsumerBeforeSendAddListenerAfterSend(

+			[Values(MsgDeliveryMode.Persistent, MsgDeliveryMode.NonPersistent)]

+			MsgDeliveryMode deliveryMode)

+		{

+			base.TestCreateConsumerBeforeSendAddListenerAfterSend(deliveryMode, DEFAULT_TEST_QUEUE);

+		}

+

+		[Test]

+		public void TestAsynchronousTextMessageConsume(

+			[Values(MsgDeliveryMode.Persistent, MsgDeliveryMode.NonPersistent)]

+			MsgDeliveryMode deliveryMode)

+		{

+			base.TestAsynchronousTextMessageConsume(deliveryMode, DEFAULT_TEST_QUEUE);

+		}

+

+		[Test]

+		public void TestTemporaryQueueAsynchronousConsume(

+			[Values(MsgDeliveryMode.Persistent, MsgDeliveryMode.NonPersistent)]

+			MsgDeliveryMode deliveryMode)

+		{

+			using(IConnection connection = CreateConnectionAndStart(GetTestClientId()))

+			using(ISession syncSession = connection.CreateSession(AcknowledgementMode.AutoAcknowledge))

+			using(ISession asyncSession = connection.CreateSession(AcknowledgementMode.AutoAcknowledge))

+			using(IDestination destination = GetClearDestination(syncSession, DestinationType.Queue, DEFAULT_TEST_QUEUE))

+			using(ITemporaryQueue tempReplyDestination = syncSession.CreateTemporaryQueue())

+			using(IMessageConsumer consumer = asyncSession.CreateConsumer(destination))

+			using(IMessageConsumer tempConsumer = asyncSession.CreateConsumer(tempReplyDestination))

+			using(IMessageProducer producer = syncSession.CreateProducer(destination))

+			{

+				producer.DeliveryMode = deliveryMode;

+				tempConsumer.Listener += new MessageListener(OnMessage);

+				consumer.Listener += new MessageListener(OnQueueMessage);

+

+				IMessage request = syncSession.CreateMessage();

+				request.NMSCorrelationID = "TemqQueueAsyncConsume";

+				request.NMSType = "Test";

+				request.NMSReplyTo = tempReplyDestination;

+				producer.Send(request);

+

+				WaitForMessageToArrive();

+				Assert.AreEqual("TempQueueAsyncResponse", receivedMsg.NMSCorrelationID, "Invalid correlation ID.");

+			}

+		}

+	}

+}

diff --git a/src/test/csharp/XMSBadConsumeTest.cs b/src/test/csharp/XMSBadConsumeTest.cs
new file mode 100644
index 0000000..4c6b0b8
--- /dev/null
+++ b/src/test/csharp/XMSBadConsumeTest.cs
@@ -0,0 +1,50 @@
+/*

+ * 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;

+using Apache.NMS.Test;

+

+namespace Apache.NMS.XMS.Test

+{

+	[TestFixture]

+	public class XMSBadConsumeTest : BadConsumeTest

+	{

+		public XMSBadConsumeTest()

+			: base(new NMSTestSupport())

+		{

+		}

+

+		[SetUp]

+		public override void SetUp()

+		{

+			base.SetUp();

+		}

+

+		[TearDown]

+		public override void TearDown()

+		{

+			base.TearDown();

+		}

+

+		[Test]

+		[ExpectedException(Handler="ExceptionValidationCheck")]

+		public override void TestBadConsumerException()

+		{

+			base.TestBadConsumerException();

+		}

+	}

+}

diff --git a/src/test/csharp/XMSBytesMessageTest.cs b/src/test/csharp/XMSBytesMessageTest.cs
new file mode 100644
index 0000000..25a3382
--- /dev/null
+++ b/src/test/csharp/XMSBytesMessageTest.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;

+using Apache.NMS.Util;

+using Apache.NMS.Test;

+using NUnit.Framework;

+

+namespace Apache.NMS.XMS.Test

+{

+	[TestFixture]

+	public class XMSBytesMessageTest : BytesMessageTest

+	{

+		protected static string DEFAULT_TEST_QUEUE = "defaultTestQueue";

+

+		public XMSBytesMessageTest()

+			: base(new XMSTestSupport())

+		{

+		}

+

+		[Test]

+		public void SendReceiveBytesMessage(

+			[Values(MsgDeliveryMode.Persistent, MsgDeliveryMode.NonPersistent)]

+			MsgDeliveryMode deliveryMode)

+		{

+			base.SendReceiveBytesMessage(deliveryMode, DEFAULT_TEST_QUEUE);

+		}

+

+        [Test]

+        public void SendReceiveBytesMessageContent(

+			[Values(MsgDeliveryMode.Persistent, MsgDeliveryMode.NonPersistent)]

+			MsgDeliveryMode deliveryMode)

+        {

+			base.SendReceiveBytesMessageContent(deliveryMode, DEFAULT_TEST_QUEUE);

+        }

+	}

+}

diff --git a/src/test/csharp/XMSConnectionTest.cs b/src/test/csharp/XMSConnectionTest.cs
new file mode 100644
index 0000000..10b778b
--- /dev/null
+++ b/src/test/csharp/XMSConnectionTest.cs
@@ -0,0 +1,104 @@
+/*

+ * 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.Test;

+using NUnit.Framework;

+

+namespace Apache.NMS.XMS.Test

+{

+	[TestFixture]

+	public class XMSConnectionTest : ConnectionTest

+	{

+		protected static string DEFAULT_TEST_QUEUE = "defaultTestQueue";

+		protected static string DEFAULT_TEST_TOPIC = "defaultTestTopic";

+

+		public XMSConnectionTest()

+			: base(new XMSTestSupport())

+		{

+		}

+

+		[SetUp]

+		public override void SetUp()

+		{

+			base.SetUp();

+		}

+	

+		[TearDown]

+		public override void TearDown()

+		{

+			base.TearDown();

+		}

+	

+		/// <summary>

+		/// Verify that it is possible to create multiple connections to the broker.

+		/// There was a bug in the connection factory which set the clientId member which made

+		/// it impossible to create an additional connection.

+		/// </summary>

+		[Test]

+		public override void TestTwoConnections()

+		{

+			base.TestTwoConnections();

+		}

+	

+		[Test]

+		public void TestCreateAndDisposeWithConsumer(

+			[Values(true, false)]

+			bool disposeConsumer)

+		{

+			base.TestCreateAndDisposeWithConsumer(disposeConsumer, DEFAULT_TEST_QUEUE);

+		}

+	

+		[Test]

+		public void TestCreateAndDisposeWithProducer(

+			[Values(true, false)]

+			bool disposeProducer)

+		{

+			base.TestCreateAndDisposeWithProducer(disposeProducer, DEFAULT_TEST_QUEUE);

+		}

+	

+		[Test]

+		public void TestStartAfterSend(

+			[Values(MsgDeliveryMode.Persistent, MsgDeliveryMode.NonPersistent)]

+			MsgDeliveryMode deliveryMode,

+			[Values(DestinationType.Queue, DestinationType.Topic)]

+			DestinationType destinationType)

+		{

+			base.TestStartAfterSend(deliveryMode, destinationType,

+				destinationType == DestinationType.Queue ? DEFAULT_TEST_QUEUE : DEFAULT_TEST_TOPIC);

+		}

+

+		/// <summary>

+		/// Tests if the consumer receives the messages that were sent before the

+		/// connection was started.

+		/// </summary>

+		[Test]

+		public void TestStoppedConsumerHoldsMessagesTillStarted()

+		{

+			base.TestStoppedConsumerHoldsMessagesTillStarted(DEFAULT_TEST_TOPIC);

+		}

+	

+		/// <summary>

+		/// Tests if the consumer is able to receive messages eveb when the

+		/// connecction restarts multiple times.

+		/// </summary>

+		[Test]

+		public void TestMultipleConnectionStops()

+		{

+			base.TestMultipleConnectionStops(DEFAULT_TEST_TOPIC);

+		}

+	}

+}

diff --git a/src/test/csharp/XMSConsumerTest.cs b/src/test/csharp/XMSConsumerTest.cs
new file mode 100644
index 0000000..522dfe2
--- /dev/null
+++ b/src/test/csharp/XMSConsumerTest.cs
@@ -0,0 +1,153 @@
+/*

+ * 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.Test;

+using NUnit.Framework;

+

+namespace Apache.NMS.XMS.Test

+{

+	[TestFixture]

+	public class XMSConsumerTest : ConsumerTest

+	{

+		protected static string DEFAULT_TEST_QUEUE = "defaultTestQueue";

+		protected static string DEFAULT_TEST_TOPIC = "defaultTestTopic";

+

+		public XMSConsumerTest()

+			: base(new XMSTestSupport())

+		{

+		}

+

+// The .NET CF does not have the ability to interrupt threads, so this test is impossible.

+#if !NETCF

+		[Test]

+		public override void TestNoTimeoutConsumer(

+			[Values(AcknowledgementMode.AutoAcknowledge, AcknowledgementMode.ClientAcknowledge,

+				AcknowledgementMode.DupsOkAcknowledge, AcknowledgementMode.Transactional)]

+			AcknowledgementMode ackMode)

+		{

+			base.TestNoTimeoutConsumer(ackMode);

+		}

+

+		[Test]

+		public override void TestSyncReceiveConsumerClose(

+			[Values(AcknowledgementMode.AutoAcknowledge, AcknowledgementMode.ClientAcknowledge,

+				AcknowledgementMode.DupsOkAcknowledge, AcknowledgementMode.Transactional)]

+			AcknowledgementMode ackMode)

+		{

+			base.TestSyncReceiveConsumerClose(ackMode);

+		}

+

+		[Test]

+		public override void TestDoChangeSentMessage(

+			[Values(AcknowledgementMode.AutoAcknowledge, AcknowledgementMode.ClientAcknowledge,

+				AcknowledgementMode.DupsOkAcknowledge, AcknowledgementMode.Transactional)]

+			AcknowledgementMode ackMode,

+			[Values(true, false)] bool doClear)

+		{

+			base.TestDoChangeSentMessage(ackMode, doClear);

+		}

+

+		[Test]

+		public override void TestConsumerReceiveBeforeMessageDispatched(

+			[Values(AcknowledgementMode.AutoAcknowledge, AcknowledgementMode.ClientAcknowledge,

+				AcknowledgementMode.DupsOkAcknowledge, AcknowledgementMode.Transactional)]

+			AcknowledgementMode ackMode)

+		{

+			base.TestConsumerReceiveBeforeMessageDispatched(ackMode);

+		}

+

+		[Test]

+		public void TestDontStart(

+			[Values(MsgDeliveryMode.NonPersistent)]

+			MsgDeliveryMode deliveryMode,

+			[Values(DestinationType.Queue, DestinationType.Topic)]

+			DestinationType destinationType)

+		{

+			base.TestDontStart(deliveryMode, destinationType,

+				destinationType == DestinationType.Queue ? DEFAULT_TEST_QUEUE : DEFAULT_TEST_TOPIC);

+		}

+

+		[Test]

+		public void TestSendReceiveTransacted(

+			[Values(MsgDeliveryMode.NonPersistent, MsgDeliveryMode.Persistent)]

+			MsgDeliveryMode deliveryMode,

+			[Values(DestinationType.Queue, DestinationType.Topic, DestinationType.TemporaryQueue, DestinationType.TemporaryTopic)]

+			DestinationType destinationType)

+		{

+			string testDestinationRef;

+			switch(destinationType)

+			{

+			case DestinationType.Queue: testDestinationRef = DEFAULT_TEST_QUEUE; break;

+			case DestinationType.Topic: testDestinationRef = DEFAULT_TEST_TOPIC; break;

+			default:                    testDestinationRef = "";                 break;

+			}

+

+			base.TestSendReceiveTransacted(deliveryMode, destinationType, testDestinationRef);

+		}

+

+		[Test]

+		public void TestAckedMessageAreConsumed()

+		{

+			base.TestAckedMessageAreConsumed(DEFAULT_TEST_QUEUE);

+		}

+

+		[Test]

+		public void TestLastMessageAcked()

+		{

+			base.TestLastMessageAcked(DEFAULT_TEST_QUEUE);

+		}

+

+		[Test]

+		public void TestUnAckedMessageAreNotConsumedOnSessionClose()

+		{

+			base.TestUnAckedMessageAreNotConsumedOnSessionClose(DEFAULT_TEST_QUEUE);

+		}

+

+		[Test]

+		public void TestAsyncAckedMessageAreConsumed()

+		{

+			base.TestAsyncAckedMessageAreConsumed(DEFAULT_TEST_QUEUE);

+		}

+

+		[Test]

+		public void TestAsyncUnAckedMessageAreNotConsumedOnSessionClose()

+		{

+			base.TestAsyncUnAckedMessageAreNotConsumedOnSessionClose(DEFAULT_TEST_QUEUE);

+		}

+

+		[Test]

+		public override void TestAddRemoveAsnycMessageListener()

+		{

+			base.TestAddRemoveAsnycMessageListener();

+		}

+

+		[Test]

+		public override void TestReceiveNoWait(

+			[Values(AcknowledgementMode.AutoAcknowledge, AcknowledgementMode.ClientAcknowledge,

+				AcknowledgementMode.DupsOkAcknowledge, AcknowledgementMode.Transactional)]

+			AcknowledgementMode ackMode,

+			[Values(MsgDeliveryMode.NonPersistent, MsgDeliveryMode.Persistent)]

+			MsgDeliveryMode deliveryMode)

+		{

+			base.TestReceiveNoWait(ackMode, deliveryMode);

+		}

+

+#endif

+

+    }

+}

diff --git a/src/test/csharp/XMSDurableTest.cs b/src/test/csharp/XMSDurableTest.cs
new file mode 100644
index 0000000..994ecf8
--- /dev/null
+++ b/src/test/csharp/XMSDurableTest.cs
@@ -0,0 +1,71 @@
+/*

+ * 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.Test;

+using NUnit.Framework;

+

+namespace Apache.NMS.XMS.Test

+{

+	[TestFixture]

+	public class XMSDurableTest : DurableTest

+	{

+		protected static string DEFAULT_TEST_QUEUE = "defaultTestQueue";

+		protected static string DEFAULT_TEST_TOPIC = "defaultTestTopic";

+		protected static string DURABLE_TEST_TOPIC = "durableConsumerTestTopic";

+

+		public XMSDurableTest()

+			: base(new XMSTestSupport())

+		{

+		}

+		

+		[SetUp]

+		public override void SetUp()

+		{

+			base.SetUp();

+		}

+

+		[Test]

+		public void TestSendWhileClosed(

+			[Values(AcknowledgementMode.AutoAcknowledge, AcknowledgementMode.ClientAcknowledge,

+				AcknowledgementMode.DupsOkAcknowledge, AcknowledgementMode.Transactional)]

+			AcknowledgementMode ackMode)

+		{

+			base.TestSendWhileClosed(ackMode, DEFAULT_TEST_TOPIC);

+	    }		

+		

+		[Test]

+		public void TestDurableConsumerSelectorChange(

+			[Values(AcknowledgementMode.AutoAcknowledge, AcknowledgementMode.ClientAcknowledge,

+				AcknowledgementMode.DupsOkAcknowledge, AcknowledgementMode.Transactional)]

+			AcknowledgementMode ackMode)

+		{

+			base.TestDurableConsumerSelectorChange(ackMode, DEFAULT_TEST_TOPIC);

+		}

+

+		[Test]

+		public void TestDurableConsumer(

+			[Values(AcknowledgementMode.AutoAcknowledge, AcknowledgementMode.ClientAcknowledge,

+				AcknowledgementMode.DupsOkAcknowledge, AcknowledgementMode.Transactional)]

+			AcknowledgementMode ackMode)

+		{

+			string testDurableTopicURI = GetDestinationURI(DestinationType.Topic, DURABLE_TEST_TOPIC);

+

+			base.TestDurableConsumer(ackMode, testDurableTopicURI); 

+		}

+	}

+}

diff --git a/src/test/csharp/XMSForeignMessageTransformationTest.cs b/src/test/csharp/XMSForeignMessageTransformationTest.cs
new file mode 100644
index 0000000..0b6d144
--- /dev/null
+++ b/src/test/csharp/XMSForeignMessageTransformationTest.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.Util;

+using Apache.NMS.Test;

+using NUnit.Framework;

+

+namespace Apache.NMS.XMS.Test

+{

+    [TestFixture]

+    public class XMSForeignMessageTransformationTest : ForeignMessageTransformationTest

+    {

+		protected static string DEFAULT_TEST_TOPIC = "defaultTestTopic";

+

+		public XMSForeignMessageTransformationTest()

+			: base(new XMSTestSupport())

+		{

+		}

+

+		[Test]

+		public void TestSendReceiveForeignMessage(

+			[Values(MsgDeliveryMode.Persistent, MsgDeliveryMode.NonPersistent)]

+			MsgDeliveryMode deliveryMode)

+		{

+			base.TestSendReceiveForeignMessage(deliveryMode, DEFAULT_TEST_TOPIC);

+		}

+

+		[Test]

+		public void TestSendReceiveForeignTextMessage(

+			[Values(MsgDeliveryMode.Persistent, MsgDeliveryMode.NonPersistent)]

+			MsgDeliveryMode deliveryMode)

+		{

+			base.TestSendReceiveForeignTextMessage(deliveryMode, DEFAULT_TEST_TOPIC);

+		}

+

+		[Test]

+		public void TestSendReceiveForeignBytesMessage(

+			[Values(MsgDeliveryMode.Persistent, MsgDeliveryMode.NonPersistent)]

+			MsgDeliveryMode deliveryMode)

+		{

+			base.TestSendReceiveForeignBytesMessage(deliveryMode, DEFAULT_TEST_TOPIC);

+		}

+

+		[Test]

+		public void TestSendReceiveForeignMapMessage(

+			[Values(MsgDeliveryMode.Persistent, MsgDeliveryMode.NonPersistent)]

+			MsgDeliveryMode deliveryMode)

+		{

+			base.TestSendReceiveForeignMapMessage(deliveryMode, DEFAULT_TEST_TOPIC);

+		}

+

+		[Test]

+		public void TestSendReceiveForeignStreamMessage(

+			[Values(MsgDeliveryMode.Persistent, MsgDeliveryMode.NonPersistent)]

+			MsgDeliveryMode deliveryMode)

+		{

+			base.TestSendReceiveForeignStreamMessage(deliveryMode, DEFAULT_TEST_TOPIC);

+		}

+	}

+}

+

diff --git a/src/test/csharp/XMSMapMessageTest.cs b/src/test/csharp/XMSMapMessageTest.cs
new file mode 100644
index 0000000..c92cd89
--- /dev/null
+++ b/src/test/csharp/XMSMapMessageTest.cs
@@ -0,0 +1,49 @@
+/*

+ * 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.Test;

+using NUnit.Framework;

+

+namespace Apache.NMS.XMS.Test

+{

+    [TestFixture]

+    public class XMSMapMessageTest : MapMessageTest

+    {

+		protected static string DEFAULT_TEST_QUEUE = "defaultTestQueue";

+

+		public XMSMapMessageTest()

+			: base(new XMSTestSupport())

+		{

+		}

+

+        [Test]

+        public void TestSendReceiveMapMessage(

+            [Values(MsgDeliveryMode.Persistent, MsgDeliveryMode.NonPersistent)]

+            MsgDeliveryMode deliveryMode)

+        {

+            base.TestSendReceiveMapMessage(deliveryMode, DEFAULT_TEST_QUEUE);

+        }

+

+        [Test]

+        public void TestSendReceiveNestedMapMessage(

+            [Values(MsgDeliveryMode.Persistent, MsgDeliveryMode.NonPersistent)]

+            MsgDeliveryMode deliveryMode)

+        {

+            base.TestSendReceiveNestedMapMessage(deliveryMode, DEFAULT_TEST_QUEUE);

+        }

+    }

+}

diff --git a/src/test/csharp/XMSMessageSelectorTest.cs b/src/test/csharp/XMSMessageSelectorTest.cs
new file mode 100644
index 0000000..179bbf9
--- /dev/null
+++ b/src/test/csharp/XMSMessageSelectorTest.cs
@@ -0,0 +1,60 @@
+/*

+ * 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.Test;

+using NUnit.Framework;

+

+namespace Apache.NMS.XMS.Test

+{

+	[TestFixture]

+	[Category("LongRunning")]

+	public class XMSMessageSelectorTest : MessageSelectorTest

+	{

+		protected const string SELECTOR_TEST_QUEUE = "messageSelectorTestQueue";

+		protected const string SELECTOR_TEST_TOPIC = "messageSelectorTestTopic";

+

+		public XMSMessageSelectorTest()

+			: base(new XMSTestSupport())

+		{

+		}

+

+		[Test]

+		public override void TestFilterIgnoredMessages(

+			[Values(SELECTOR_TEST_QUEUE, SELECTOR_TEST_TOPIC)]

+			string testDestinationRef)

+		{

+			string testDestinationURI = GetDestinationURI(

+				testDestinationRef == SELECTOR_TEST_QUEUE ? DestinationType.Queue : DestinationType.Topic,

+				testDestinationRef);

+

+			base.TestFilterIgnoredMessages(testDestinationURI);

+		}

+

+		[Test]

+		public override void TestFilterIgnoredMessagesSlowConsumer(

+			[Values(SELECTOR_TEST_QUEUE, SELECTOR_TEST_TOPIC)]

+			string testDestinationRef)

+		{

+			string testDestinationURI = GetDestinationURI(

+				testDestinationRef == SELECTOR_TEST_QUEUE ? DestinationType.Queue : DestinationType.Topic,

+				testDestinationRef);

+

+			base.TestFilterIgnoredMessagesSlowConsumer(testDestinationURI);

+		}

+	}

+}

diff --git a/src/test/csharp/XMSMessageTest.cs b/src/test/csharp/XMSMessageTest.cs
new file mode 100644
index 0000000..9e2f367
--- /dev/null
+++ b/src/test/csharp/XMSMessageTest.cs
@@ -0,0 +1,42 @@
+/*

+ * 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.Test;

+using NUnit.Framework;

+

+namespace Apache.NMS.XMS.Test

+{

+	[TestFixture]

+	public class XMSMessageTest : MessageTest

+	{

+		protected static string DEFAULT_TEST_QUEUE = "defaultTestQueue";

+

+		public XMSMessageTest()

+			: base(new XMSTestSupport())

+		{

+		}

+

+		[Test]

+		public void TestSendReceiveMessageProperties(

+			[Values(MsgDeliveryMode.Persistent, MsgDeliveryMode.NonPersistent)]

+			MsgDeliveryMode deliveryMode)

+		{

+			base.TestSendReceiveMessageProperties(deliveryMode, DEFAULT_TEST_QUEUE);

+		}

+	}

+}

+

diff --git a/src/test/csharp/XMSMessageTransformerTest.cs b/src/test/csharp/XMSMessageTransformerTest.cs
new file mode 100644
index 0000000..58e8b54
--- /dev/null
+++ b/src/test/csharp/XMSMessageTransformerTest.cs
@@ -0,0 +1,48 @@
+/*

+ * 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.Test;

+using NUnit.Framework;

+

+namespace Apache.NMS.XMS.Test

+{

+	[TestFixture]

+	public class XMSMessageTransformerTest : MessageTransformerTest

+	{

+		public XMSMessageTransformerTest()

+			: base(new XMSTestSupport())

+		{

+		}

+				

+		[Test]

+		public override void TestProducerTransformer(

+			[Values(MsgDeliveryMode.Persistent, MsgDeliveryMode.NonPersistent)]

+			MsgDeliveryMode deliveryMode)

+		{

+			base.TestProducerTransformer(deliveryMode);

+		}

+		

+		[Test]

+		public override void TestConsumerTransformer(

+			[Values(MsgDeliveryMode.Persistent, MsgDeliveryMode.NonPersistent)]

+			MsgDeliveryMode deliveryMode)

+		{

+			base.TestConsumerTransformer(deliveryMode);

+		}

+	}

+}

+

diff --git a/src/test/csharp/XMSNMSPropertyTest.cs b/src/test/csharp/XMSNMSPropertyTest.cs
new file mode 100644
index 0000000..eed608a
--- /dev/null
+++ b/src/test/csharp/XMSNMSPropertyTest.cs
@@ -0,0 +1,41 @@
+/*

+ * 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.Test;

+using NUnit.Framework;

+

+namespace Apache.NMS.XMS.Test

+{

+	[TestFixture]

+	public class XMSNMSPropertyTest : NMSPropertyTest

+	{

+		protected static string DEFAULT_TEST_QUEUE = "defaultTestQueue";

+

+		public XMSNMSPropertyTest()

+			: base(new XMSTestSupport())

+		{

+		}

+

+		[Test]

+		public void TestSendReceiveNMSProperties(

+			[Values(MsgDeliveryMode.Persistent, MsgDeliveryMode.NonPersistent)]

+			MsgDeliveryMode deliveryMode)

+		{

+			base.TestSendReceiveNMSProperties(deliveryMode, DEFAULT_TEST_QUEUE);

+		}

+	}

+}

diff --git a/src/test/csharp/XMSProducerTest.cs b/src/test/csharp/XMSProducerTest.cs
new file mode 100644
index 0000000..58ce283
--- /dev/null
+++ b/src/test/csharp/XMSProducerTest.cs
@@ -0,0 +1,49 @@
+/*

+ * 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.Test;

+using NUnit.Framework;

+

+namespace Apache.NMS.XMS.Test

+{

+	[TestFixture]

+	public class XMSProducerTest : ProducerTest

+	{

+		public XMSProducerTest()

+			: base(new NMSTestSupport())

+		{

+		}

+

+        [Test]

+        public override void TestProducerSendToNullDestinationWithoutDefault()

+        {

+            base.TestProducerSendToNullDestinationWithoutDefault();

+        }

+

+        [Test]

+        public override void TestProducerSendToNullDestinationWithDefault()

+        {

+            base.TestProducerSendToNullDestinationWithDefault();

+        }

+

+		[Test]

+		public override void TestProducerSendToNonDefaultDestination()

+		{

+            base.TestProducerSendToNonDefaultDestination();

+        }

+	}

+}

diff --git a/src/test/csharp/XMSRequestResponseTest.cs b/src/test/csharp/XMSRequestResponseTest.cs
new file mode 100644
index 0000000..0d96e29
--- /dev/null
+++ b/src/test/csharp/XMSRequestResponseTest.cs
@@ -0,0 +1,41 @@
+/*

+ * 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.Test;

+using NUnit.Framework;

+

+namespace Apache.NMS.XMS.Test

+{

+	[TestFixture]

+	public class XMSRequestResponseTest : RequestResponseTest

+	{

+		protected static string DEFAULT_TEST_QUEUE = "defaultTestQueue";

+

+		public XMSRequestResponseTest()

+			: base(new XMSTestSupport())

+		{

+		}

+

+		[Test]

+		[Category("RequestResponse")]		

+		public void TestRequestResponseMessaging()

+		{

+			base.TestRequestResponseMessaging(DEFAULT_TEST_QUEUE);

+		}

+	}

+}

+

diff --git a/src/test/csharp/XMSStreamMessageTest.cs b/src/test/csharp/XMSStreamMessageTest.cs
new file mode 100644
index 0000000..8331c2e
--- /dev/null
+++ b/src/test/csharp/XMSStreamMessageTest.cs
@@ -0,0 +1,41 @@
+/*

+ * 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.Test;

+using NUnit.Framework;

+

+namespace Apache.NMS.XMS.Test

+{

+	[TestFixture]

+	public class XMSStreamMessageTest : StreamMessageTest

+	{

+		protected static string DEFAULT_TEST_QUEUE = "defaultTestQueue";

+

+		public XMSStreamMessageTest()

+			: base(new XMSTestSupport())

+		{

+		}

+

+		[Test]

+		public void TestSendReceiveStreamMessage(

+			[Values(MsgDeliveryMode.Persistent, MsgDeliveryMode.NonPersistent)]

+			MsgDeliveryMode deliveryMode)

+		{

+			base.TestSendReceiveStreamMessage(deliveryMode, DEFAULT_TEST_QUEUE);

+		}

+	}

+}

diff --git a/src/test/csharp/XMSTempDestinationDeletionTest.cs b/src/test/csharp/XMSTempDestinationDeletionTest.cs
new file mode 100644
index 0000000..e9d5f45
--- /dev/null
+++ b/src/test/csharp/XMSTempDestinationDeletionTest.cs
@@ -0,0 +1,55 @@
+/*

+ * 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.Test;

+using NUnit.Framework;

+

+namespace Apache.NMS.XMS.Test

+{

+	[TestFixture]

+	public class XMSTempDestinationDeletionTest : TempDestinationDeletionTest

+	{

+		protected const string DELETION_TEST_QUEUE = "deletionTestQueue";

+		protected const string DELETION_TEST_TOPIC = "deletionTestTopic";

+		protected const string DELETION_TEST_TEMP_QUEUE = "deletionTestTempQueue";

+		protected const string DELETION_TEST_TEMP_TOPIC = "deletionTestTempTopic";

+

+		public XMSTempDestinationDeletionTest()

+			: base(new XMSTestSupport())

+		{

+		}

+

+		[Test]

+		public override void TestTempDestinationDeletion(

+			[Values(MsgDeliveryMode.Persistent, MsgDeliveryMode.NonPersistent)]

+			MsgDeliveryMode deliveryMode,

+			[Values(DELETION_TEST_QUEUE, DELETION_TEST_TOPIC, DELETION_TEST_TEMP_QUEUE, DELETION_TEST_TEMP_TOPIC)]

+			string testDestinationRef)

+		{

+            DestinationType type;

+			if     (testDestinationRef == DELETION_TEST_QUEUE)      type = DestinationType.Queue;

+			else if(testDestinationRef == DELETION_TEST_TOPIC)      type = DestinationType.Topic;

+			else if(testDestinationRef == DELETION_TEST_TEMP_QUEUE) type = DestinationType.TemporaryQueue;

+			else                                                    type = DestinationType.TemporaryTopic;

+

+			string testDestinationURI = GetDestinationURI(type, testDestinationRef);

+

+			base.TestTempDestinationDeletion(deliveryMode, testDestinationURI);

+		}

+	}

+}

diff --git a/src/test/csharp/XMSTempDestinationTest.cs b/src/test/csharp/XMSTempDestinationTest.cs
new file mode 100644
index 0000000..25d09bb
--- /dev/null
+++ b/src/test/csharp/XMSTempDestinationTest.cs
@@ -0,0 +1,67 @@
+/*

+ * 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.Test;

+using NUnit.Framework;

+

+namespace Apache.NMS.XMS.Test

+{

+    [TestFixture]

+    public class XMSTempDestinationTest : TempDestinationTest

+    {

+		public XMSTempDestinationTest()

+			: base(new XMSTestSupport())

+		{

+		}

+

+        [SetUp]

+        public override void SetUp()

+        {

+            base.SetUp();

+        }

+

+        [TearDown]

+        public override void TearDown()

+        {

+            base.TearDown();

+        }

+

+        [Test]

+        public override void TestTempDestOnlyConsumedByLocalConn()

+        {

+            base.TestTempDestOnlyConsumedByLocalConn();

+        }

+

+        [Test]

+        public override void TestTempQueueHoldsMessagesWithConsumers()

+        {

+            base.TestTempQueueHoldsMessagesWithConsumers();

+        }

+

+        [Test]

+        public override void TestTempQueueHoldsMessagesWithoutConsumers()

+        {

+            base.TestTempQueueHoldsMessagesWithoutConsumers();

+        }

+

+        [Test]

+        public override void TestTmpQueueWorksUnderLoad()

+        {

+            base.TestTmpQueueWorksUnderLoad();

+        }

+    }

+}

diff --git a/src/test/csharp/XMSTestSupport.cs b/src/test/csharp/XMSTestSupport.cs
new file mode 100644
index 0000000..556012e
--- /dev/null
+++ b/src/test/csharp/XMSTestSupport.cs
@@ -0,0 +1,132 @@
+/*

+ * 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.Xml;

+using Apache.NMS.Test;

+using Apache.NMS.Util;

+using NUnit.Framework;

+

+using Apache.NMS.XMS;

+

+namespace Apache.NMS.XMS.Test

+{

+	/// <summary>

+	/// Useful class for test cases support.

+	/// </summary>

+	public class XMSTestSupport : NMSTestSupport

+	{

+		/// <summary>

+		/// Gets the environment variable name for the configuration file path.

+		/// </summary>

+		/// <returns>Environment variable name</returns>

+		public override string GetConfigEnvVarName()

+		{

+			return "XMSTESTCONFIGPATH";

+		}

+

+		/// <summary>

+		/// Gets the default name for the configuration filename.

+		/// </summary>

+		/// <returns>Default name of the configuration filename</returns>

+		public override string GetDefaultConfigFileName()

+		{

+			return "xmsprovider-test.config";

+		}

+

+		/// <summary>

+		/// Gets a new client id.

+		/// </summary>

+		/// <returns>Client id</returns>

+		public override string GetTestClientId()

+		{

+			return base.GetTestClientId();

+			//return null;

+		}

+

+		/// <summary>

+		/// Create a new connection to the broker.

+		/// </summary>

+		/// <param name="newClientId">Client ID of the new connection.</param>

+		/// <returns>New connection</returns>

+		public override IConnection CreateConnection(string newClientId)

+		{

+			IConnection newConnection;

+

+			// IBM.XMS throws an exception if attempting to set the ClientId

+			// on the Connection after it was created.

+			// In a multithreaded environment, it would probably be best to

+			// create as many factories as client ids, rather than change the

+			// client id on the factory before creating a connection. Plus it

+			// wouldn't be a good idea to protect the code section through a

+			// semaphore, since connections creation takes a long time to be

+			// performed.

+			if(newClientId != null)

+			{

+				((Apache.NMS.XMS.ConnectionFactory)Factory).ClientId = newClientId;

+			}

+

+			if(this.userName == null)

+			{

+				newConnection = Factory.CreateConnection();

+			}

+			else

+			{

+				newConnection = Factory.CreateConnection(userName, passWord);

+			}

+

+			Assert.IsNotNull(newConnection, "Connection not created");

+

+			return newConnection;

+		}

+

+		ISession cleanupSession = null;

+		/// <summary>

+		/// Gets a clear destination. This will try to delete an existing

+		/// destination and re-create it.

+		/// </summary>

+		/// <param name="session">Session</param>

+		/// <param name="destinationURI">Destination URI</param>

+		/// <returns>Clear destination</returns>

+		public override IDestination GetClearDestination(ISession session,

+			string destinationURI)

+		{

+			IDestination destination = SessionUtil.GetDestination(session, destinationURI);

+

+			// Destination exists. Can't use the given session to clean up:

+			// once used synchronously, IBM XMS doesn't allow the session to be

+			// used asynchronously. Therefore, we create a specific synchronous

+			// session to perform cleanups.

+			if(cleanupSession == null)

+			{

+				IConnection cleanupConnection = CreateConnection("Cleanup");

+				cleanupSession = cleanupConnection.CreateSession();

+			}

+

+			IDestination cleanupDestination = SessionUtil.GetDestination(cleanupSession, destinationURI);

+

+			using(IMessageConsumer consumer = cleanupSession.CreateConsumer(destination))

+			{

+				while(consumer.Receive(TimeSpan.FromMilliseconds(750)) != null)

+				{

+				}

+			}

+

+			return destination;

+		}

+

+	}

+}

diff --git a/src/test/csharp/XMSTextMessageTest.cs b/src/test/csharp/XMSTextMessageTest.cs
new file mode 100644
index 0000000..bfbfd77
--- /dev/null
+++ b/src/test/csharp/XMSTextMessageTest.cs
@@ -0,0 +1,41 @@
+/*

+ * 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.Test;

+using NUnit.Framework;

+

+namespace Apache.NMS.XMS.Test

+{

+	[TestFixture]

+	public class XMSTextMessageTest : TextMessageTest

+	{

+		protected static string DEFAULT_TEST_QUEUE = "defaultTestQueue";

+

+		public XMSTextMessageTest()

+			: base(new XMSTestSupport())

+		{

+		}

+

+		[Test]

+		public void TestSendReceiveTextMessage(

+			[Values(MsgDeliveryMode.Persistent, MsgDeliveryMode.NonPersistent)]

+			MsgDeliveryMode deliveryMode)

+		{

+			base.TestSendReceiveTextMessage(deliveryMode, DEFAULT_TEST_QUEUE);

+		}

+	}

+}

diff --git a/src/test/csharp/XMSTransactionTest.cs b/src/test/csharp/XMSTransactionTest.cs
new file mode 100644
index 0000000..f369c4f
--- /dev/null
+++ b/src/test/csharp/XMSTransactionTest.cs
@@ -0,0 +1,115 @@
+/*

+ * 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.Test;

+using NUnit.Framework;

+

+namespace Apache.NMS.XMS.Test

+{

+    [TestFixture]

+    public class XMSTransactionTest : TransactionTest

+    {

+        protected static string TRANSACTION_TEST_QUEUE = "transactionTestQueue";

+

+		public XMSTransactionTest()

+			: base(new XMSTestSupport())

+		{

+		}

+

+        [Test]

+        public void TestSendRollback(

+			[Values(MsgDeliveryMode.Persistent, MsgDeliveryMode.NonPersistent)]

+			MsgDeliveryMode deliveryMode)

+        {

+            base.TestSendRollback(deliveryMode, TRANSACTION_TEST_QUEUE);

+        }

+

+        [Test]

+        public void TestSendSessionClose(

+			[Values(MsgDeliveryMode.Persistent, MsgDeliveryMode.NonPersistent)]

+			MsgDeliveryMode deliveryMode)

+        {

+            base.TestSendSessionClose(deliveryMode, TRANSACTION_TEST_QUEUE);

+        }

+

+        [Test]

+        public void TestReceiveRollback(

+			[Values(MsgDeliveryMode.Persistent, MsgDeliveryMode.NonPersistent)]

+			MsgDeliveryMode deliveryMode)

+        {

+            base.TestReceiveRollback(deliveryMode, TRANSACTION_TEST_QUEUE);

+        }

+

+

+        [Test]

+        public void TestReceiveTwoThenRollback(

+			[Values(MsgDeliveryMode.Persistent, MsgDeliveryMode.NonPersistent)]

+			MsgDeliveryMode deliveryMode)

+        {

+            base.TestReceiveTwoThenRollback(deliveryMode, TRANSACTION_TEST_QUEUE);

+        }

+

+        [Test]

+        public void TestSendCommitNonTransaction(

+			[Values(AcknowledgementMode.AutoAcknowledge, AcknowledgementMode.ClientAcknowledge)]

+			AcknowledgementMode ackMode,

+			[Values(MsgDeliveryMode.Persistent, MsgDeliveryMode.NonPersistent)]

+			MsgDeliveryMode deliveryMode)

+        {

+            base.TestSendCommitNonTransaction(ackMode, deliveryMode, TRANSACTION_TEST_QUEUE);

+        }

+

+        [Test]

+        public void TestReceiveCommitNonTransaction(

+			[Values(AcknowledgementMode.AutoAcknowledge, AcknowledgementMode.ClientAcknowledge)]

+			AcknowledgementMode ackMode,

+			[Values(MsgDeliveryMode.Persistent, MsgDeliveryMode.NonPersistent)]

+			MsgDeliveryMode deliveryMode)

+		{

+            base.TestReceiveCommitNonTransaction(ackMode, deliveryMode, TRANSACTION_TEST_QUEUE);

+        }

+

+        [Test]

+        public void TestReceiveRollbackNonTransaction(

+			[Values(AcknowledgementMode.AutoAcknowledge, AcknowledgementMode.ClientAcknowledge)]

+			AcknowledgementMode ackMode,

+			[Values(MsgDeliveryMode.Persistent, MsgDeliveryMode.NonPersistent)]

+			MsgDeliveryMode deliveryMode)

+		{

+            base.TestReceiveRollbackNonTransaction(ackMode, deliveryMode, TRANSACTION_TEST_QUEUE);

+        }

+

+        [Test]

+        public void TestRedispatchOfRolledbackTx(

+			[Values(MsgDeliveryMode.Persistent, MsgDeliveryMode.NonPersistent)]

+			MsgDeliveryMode deliveryMode)

+        {

+            base.TestRedispatchOfRolledbackTx(deliveryMode, TRANSACTION_TEST_QUEUE);

+        }

+

+        [Test]

+        public void TestRedispatchOfUncommittedTx(

+			[Values(MsgDeliveryMode.Persistent, MsgDeliveryMode.NonPersistent)]

+			MsgDeliveryMode deliveryMode)

+        {

+            base.TestRedispatchOfUncommittedTx(deliveryMode, TRANSACTION_TEST_QUEUE);

+        }

+    }

+}

+

+

diff --git a/src/test/csharp/XMSXmlMessageTest.cs b/src/test/csharp/XMSXmlMessageTest.cs
new file mode 100644
index 0000000..db0c80a
--- /dev/null
+++ b/src/test/csharp/XMSXmlMessageTest.cs
@@ -0,0 +1,52 @@
+/*

+ * 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.Test;

+using NUnit.Framework;

+

+namespace Apache.NMS.XMS.Test

+{

+	[TestFixture]

+	public class XMSXmlMessageTest : XmlMessageTest

+	{

+		protected static string DEFAULT_TEST_QUEUE = "defaultTestQueue";

+

+		public XMSXmlMessageTest()

+			: base(new XMSTestSupport())

+		{

+		}

+

+#if NET_3_5 || MONO

+

+		[Test]

+		public void TestSendReceiveXmlMessage_Net35()

+		{

+			base.TestSendReceiveXmlMessage_Net35(DEFAULT_TEST_QUEUE);

+		}

+

+#else

+

+		// Test the obsolete API versions until they are completely removed.

+		[Test]

+		public void SendReceiveXmlMessage()

+		{

+			base.TestSendReceiveXmlMessage(DEFAULT_TEST_QUEUE);

+		}

+

+#endif

+	}

+}

diff --git a/src/test/csharp/XmlMessageTest.cs b/src/test/csharp/XmlMessageTest.cs
new file mode 100644
index 0000000..ebbb202
--- /dev/null
+++ b/src/test/csharp/XmlMessageTest.cs
@@ -0,0 +1,186 @@
+/*

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

+{

+	// For ease of cross-platform exchange of information, you might generate objects from

+	// an XSD file using XSDObjectGen. However, C# has built-in support for serializing.

+	// All of the XML attributes that are commented out are optional, but give you fine-grained

+	// control over the serialized format if you need it.

+

+	// [Serializable]

+	public enum CheckType

+	{

+		// [XmlEnum(Name = "message")]

+		message,

+		// [XmlEnum(Name = "command")]

+		command,

+		// [XmlEnum(Name = "response")]

+		response

+	}

+

+	// [XmlRoot(ElementName = "NMSTestXmlType1", IsNullable = false), Serializable]

+	public class NMSTestXmlType1

+	{

+		// [XmlElement(ElementName = "crcCheck", IsNullable = false, DataType = "int")]

+		public int crcCheck;

+

+		// [XmlElement(Type = typeof(CheckType), ElementName = "checkType", IsNullable = false)]

+		public CheckType checkType;

+

+		public NMSTestXmlType1()

+		{

+			crcCheck = 0;

+			checkType = CheckType.message;

+		}

+	}

+

+	// [XmlRoot(ElementName = "NMSTestXmlType2", IsNullable = false), Serializable]

+	public class NMSTestXmlType2

+	{

+		// [XmlElement(ElementName = "stringCheck", IsNullable = false, DataType = "string")]

+		public string stringCheck;

+

+		public NMSTestXmlType2()

+		{

+			stringCheck = String.Empty;

+		}

+	}

+

+	//[TestFixture]

+	public class XmlMessageTest : NMSTest

+	{

+		public XmlMessageTest(NMSTestSupport testSupport)

+			: base(testSupport)

+		{

+		}

+

+#if NET_3_5 || MONO

+

+		//[Test]

+		public virtual void TestSendReceiveXmlMessage_Net35(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))

+					{

+						NMSTestXmlType1 srcIntObject = new NMSTestXmlType1();

+						srcIntObject.crcCheck = 0xbadf00d;

+						srcIntObject.checkType = CheckType.command;

+						producer.Send(srcIntObject);

+

+						NMSTestXmlType2 srcStringObject = new NMSTestXmlType2();

+						srcStringObject.stringCheck = "BadFood";

+						producer.Send(srcStringObject);

+

+						// Demonstrate the ability to generically handle multiple object types

+						// sent to the same consumer.  If only one object type is ever sent to

+						// the destination, then a simple inline cast is all that is necessary

+						// when calling the NMSConvert.FromXmlMessage() function.

+

+						for(int index = 0; index < 2; index++)

+						{

+							object receivedObject = consumer.Receive(receiveTimeout).ToObject();

+							Assert.IsNotNull(receivedObject, "Failed to retrieve XML message object.");

+

+							if(receivedObject is NMSTestXmlType1)

+							{

+								NMSTestXmlType1 destObject = (NMSTestXmlType1) receivedObject;

+								Assert.AreEqual(srcIntObject.crcCheck, destObject.crcCheck, "CRC integer mis-match.");

+								Assert.AreEqual(srcIntObject.checkType, destObject.checkType, "Check type mis-match.");

+							}

+							else if(receivedObject is NMSTestXmlType2)

+							{

+								NMSTestXmlType2 destObject = (NMSTestXmlType2) receivedObject;

+								Assert.AreEqual(srcStringObject.stringCheck, destObject.stringCheck, "CRC string mis-match.");

+							}

+							else

+							{

+								Assert.Fail("Invalid object type.");

+							}

+						}

+					}

+				}

+			}

+		}

+

+#else

+

+		// Test the obsolete API versions until they are completely removed.

+		//[Test]

+		public virtual void TestSendReceiveXmlMessage(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))

+					{

+						NMSTestXmlType1 srcIntObject = new NMSTestXmlType1();

+						srcIntObject.crcCheck = 0xbadf00d;

+						srcIntObject.checkType = CheckType.command;

+						producer.Send(NMSConvert.ToXmlMessage(session, srcIntObject));

+

+						NMSTestXmlType2 srcStringObject = new NMSTestXmlType2();

+						srcStringObject.stringCheck = "BadFood";

+						producer.Send(NMSConvert.ToXmlMessage(session, srcStringObject));

+

+						// Demonstrate the ability to generically handle multiple object types

+						// sent to the same consumer.  If only one object type is ever sent to

+						// the destination, then a simple inline cast is all that is necessary

+						// when calling the NMSConvert.FromXmlMessage() function.

+

+						for(int index = 0; index < 2; index++)

+						{

+							object receivedObject = NMSConvert.FromXmlMessage(consumer.Receive(receiveTimeout));

+							Assert.IsNotNull(receivedObject, "Failed to retrieve XML message object.");

+

+							if(receivedObject is NMSTestXmlType1)

+							{

+								NMSTestXmlType1 destObject = (NMSTestXmlType1) receivedObject;

+								Assert.AreEqual(srcIntObject.crcCheck, destObject.crcCheck, "CRC integer mis-match.");

+								Assert.AreEqual(srcIntObject.checkType, destObject.checkType, "Check type mis-match.");

+							}

+							else if(receivedObject is NMSTestXmlType2)

+							{

+								NMSTestXmlType2 destObject = (NMSTestXmlType2) receivedObject;

+								Assert.AreEqual(srcStringObject.stringCheck, destObject.stringCheck, "CRC string mis-match.");

+							}

+							else

+							{

+								Assert.Fail("Invalid object type.");

+							}

+						}

+					}

+				}

+			}

+		}

+

+#endif

+	}

+}

diff --git a/vs2013-xms-test.csproj b/vs2013-xms-test.csproj
new file mode 100644
index 0000000..ccdcca0
--- /dev/null
+++ b/vs2013-xms-test.csproj
@@ -0,0 +1,196 @@
+<?xml version="1.0" encoding="utf-8"?>

+<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003" ToolsVersion="12.0">

+  <PropertyGroup>

+    <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>

+    <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>

+    <ProductVersion>9.0.30729</ProductVersion>

+    <SchemaVersion>2.0</SchemaVersion>

+    <ProjectGuid>{EB943C69-2C9B-45E7-B95B-FB916E7057ED}</ProjectGuid>

+    <OutputType>Library</OutputType>

+    <RootNamespace>Apache.NMS.XMS.Test</RootNamespace>

+    <AssemblyName>Apache.NMS.XMS.Test</AssemblyName>

+    <WarningLevel>4</WarningLevel>

+    <StartupObject>

+    </StartupObject>

+    <FileUpgradeFlags>

+    </FileUpgradeFlags>

+    <OldToolsVersion>3.5</OldToolsVersion>

+    <UpgradeBackupLocation>

+    </UpgradeBackupLocation>

+    <IsWebBootstrapper>false</IsWebBootstrapper>

+    <SignAssembly>true</SignAssembly>

+    <AssemblyOriginatorKeyFile>keyfile\NMSKey.snk</AssemblyOriginatorKeyFile>

+    <SccProjectName>Svn</SccProjectName>

+    <SccLocalPath>Svn</SccLocalPath>

+    <SccAuxPath>Svn</SccAuxPath>

+    <SccProvider>SubversionScc</SccProvider>

+    <RunPostBuildEvent>OnOutputUpdated</RunPostBuildEvent>

+    <TargetFrameworkVersion>v4.0</TargetFrameworkVersion>

+    <PublishUrl>publish\</PublishUrl>

+    <Install>true</Install>

+    <InstallFrom>Disk</InstallFrom>

+    <UpdateEnabled>false</UpdateEnabled>

+    <UpdateMode>Foreground</UpdateMode>

+    <UpdateInterval>7</UpdateInterval>

+    <UpdateIntervalUnits>Days</UpdateIntervalUnits>

+    <UpdatePeriodically>false</UpdatePeriodically>

+    <UpdateRequired>false</UpdateRequired>

+    <MapFileExtensions>true</MapFileExtensions>

+    <ApplicationRevision>0</ApplicationRevision>

+    <ApplicationVersion>1.0.0.%2a</ApplicationVersion>

+    <UseApplicationTrust>false</UseApplicationTrust>

+    <BootstrapperEnabled>true</BootstrapperEnabled>

+    <TargetFrameworkProfile />

+  </PropertyGroup>

+  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">

+    <DebugSymbols>true</DebugSymbols>

+    <DebugType>full</DebugType>

+    <Optimize>false</Optimize>

+    <OutputPath>build\net-4.0\debug\</OutputPath>

+    <DefineConstants>TRACE;DEBUG;NET,NET_4_0</DefineConstants>

+    <AllowUnsafeBlocks>false</AllowUnsafeBlocks>

+    <NoWarn>3016</NoWarn>

+  </PropertyGroup>

+  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">

+    <DebugSymbols>true</DebugSymbols>

+    <Optimize>true</Optimize>

+    <OutputPath>build\net-4.0\release\</OutputPath>

+    <DefineConstants>TRACE;NET,NET_4_0</DefineConstants>

+    <AllowUnsafeBlocks>false</AllowUnsafeBlocks>

+    <DebugType>full</DebugType>

+    <NoWarn>3016</NoWarn>

+  </PropertyGroup>

+  <ItemGroup>

+    <Reference Include="Apache.NMS">

+      <SpecificVersion>False</SpecificVersion>

+      <HintPath>lib\Apache.NMS\net-4.0\Apache.NMS.dll</HintPath>

+    </Reference>

+    <Reference Include="Apache.NMS.Test">

+      <SpecificVersion>False</SpecificVersion>

+      <HintPath>lib\Apache.NMS\net-4.0\Apache.NMS.Test.dll</HintPath>

+    </Reference>

+    <Reference Include="nunit.framework">

+      <SpecificVersion>False</SpecificVersion>

+      <HintPath>lib\NUnit\net-4.0\nunit.framework.dll</HintPath>

+    </Reference>

+    <Reference Include="System" />

+    <Reference Include="System.Xml" />

+  </ItemGroup>

+  <ItemGroup>

+    <Compile Include="src\test\csharp\CommonAssemblyInfo.cs" />

+    <Compile Include="src\test\csharp\AsyncConsumeTest.cs" />

+    <Compile Include="src\test\csharp\BadConsumeTest.cs" />

+    <Compile Include="src\test\csharp\BytesMessageTest.cs" />

+    <Compile Include="src\test\csharp\CommonAssemblyInfo.cs" />

+    <Compile Include="src\test\csharp\ConnectionTest.cs" />

+    <Compile Include="src\test\csharp\ConsumerTest.cs" />

+    <Compile Include="src\test\csharp\DurableTest.cs" />

+    <Compile Include="src\test\csharp\EndianBinaryReaderTest.cs" />

+    <Compile Include="src\test\csharp\EndianBinaryWriterTest.cs" />

+    <Compile Include="src\test\csharp\EndianTest.cs" />

+    <Compile Include="src\test\csharp\ForeignMessageTransformationTest.cs" />

+    <Compile Include="src\test\csharp\MapMessageTest.cs" />

+    <Compile Include="src\test\csharp\MessageSelectorTest.cs" />

+    <Compile Include="src\test\csharp\MessageTest.cs" />

+    <Compile Include="src\test\csharp\MessageTransformerTest.cs" />

+    <Compile Include="src\test\csharp\NMSPropertyTest.cs" />

+    <Compile Include="src\test\csharp\NMSTest.cs" />

+    <Compile Include="src\test\csharp\NMSTestSupport.cs" />

+    <Compile Include="src\test\csharp\NMSTracer.cs" />

+    <Compile Include="src\test\csharp\PrimitiveMapTest.cs" />

+    <Compile Include="src\test\csharp\ProducerTest.cs" />

+    <Compile Include="src\test\csharp\RedeliveryPolicyTest.cs" />

+    <Compile Include="src\test\csharp\RequestResponseTest.cs" />

+    <Compile Include="src\test\csharp\StreamMessageTest.cs" />

+    <Compile Include="src\test\csharp\TempDestinationDeletionTest.cs" />

+    <Compile Include="src\test\csharp\TempDestinationTest.cs" />

+    <Compile Include="src\test\csharp\TextMessageTest.cs" />

+    <Compile Include="src\test\csharp\TransactionTest.cs" />

+    <Compile Include="src\test\csharp\XmlMessageTest.cs" />

+    <Compile Include="src\test\csharp\XMSAsyncConsumeTest.cs" />

+    <Compile Include="src\test\csharp\XMSBadConsumeTest.cs" />

+    <Compile Include="src\test\csharp\XMSBytesMessageTest.cs" />

+    <Compile Include="src\test\csharp\XMSConnectionTest.cs" />

+    <Compile Include="src\test\csharp\XMSConsumerTest.cs" />

+    <Compile Include="src\test\csharp\XMSDurableTest.cs" />

+    <Compile Include="src\test\csharp\XMSForeignMessageTransformationTest.cs" />

+    <Compile Include="src\test\csharp\XMSMapMessageTest.cs" />

+    <Compile Include="src\test\csharp\XMSMessageSelectorTest.cs" />

+    <Compile Include="src\test\csharp\XMSMessageTest.cs" />

+    <Compile Include="src\test\csharp\XMSMessageTransformerTest.cs" />

+    <Compile Include="src\test\csharp\XMSNMSPropertyTest.cs" />

+    <Compile Include="src\test\csharp\XMSProducerTest.cs" />

+    <Compile Include="src\test\csharp\XMSRequestResponseTest.cs" />

+    <Compile Include="src\test\csharp\XMSStreamMessageTest.cs" />

+    <Compile Include="src\test\csharp\XMSTempDestinationDeletionTest.cs" />

+    <Compile Include="src\test\csharp\XMSTempDestinationTest.cs" />

+    <Compile Include="src\test\csharp\XMSTestSupport.cs" />

+    <Compile Include="src\test\csharp\XMSTextMessageTest.cs" />

+    <Compile Include="src\test\csharp\XMSTransactionTest.cs" />

+    <Compile Include="src\test\csharp\XMSXmlMessageTest.cs" />

+    <Compile Include="src\test\csharp\Commands\BytesMessage.cs" />

+    <Compile Include="src\test\csharp\Commands\Destination.cs" />

+    <Compile Include="src\test\csharp\Commands\MapMessage.cs" />

+    <Compile Include="src\test\csharp\Commands\Message.cs" />

+    <Compile Include="src\test\csharp\Commands\ObjectMessage.cs" />

+    <Compile Include="src\test\csharp\Commands\Queue.cs" />

+    <Compile Include="src\test\csharp\Commands\StreamMessage.cs" />

+    <Compile Include="src\test\csharp\Commands\TempDestination.cs" />

+    <Compile Include="src\test\csharp\Commands\TempQueue.cs" />

+    <Compile Include="src\test\csharp\Commands\TempTopic.cs" />

+    <Compile Include="src\test\csharp\Commands\TextMessage.cs" />

+    <Compile Include="src\test\csharp\Commands\Topic.cs" />

+  </ItemGroup>

+  <ItemGroup>

+    <BootstrapperPackage Include="Microsoft.Net.Client.3.5">

+      <Visible>False</Visible>

+      <ProductName>.NET Framework 3.5 SP1 Client Profile</ProductName>

+      <Install>false</Install>

+    </BootstrapperPackage>

+    <BootstrapperPackage Include="Microsoft.Net.Framework.2.0">

+      <Visible>False</Visible>

+      <ProductName>.NET Framework 2.0 %28x86%29</ProductName>

+      <Install>true</Install>

+    </BootstrapperPackage>

+    <BootstrapperPackage Include="Microsoft.Net.Framework.3.0">

+      <Visible>False</Visible>

+      <ProductName>.NET Framework 3.0 %28x86%29</ProductName>

+      <Install>false</Install>

+    </BootstrapperPackage>

+    <BootstrapperPackage Include="Microsoft.Net.Framework.3.5">

+      <Visible>False</Visible>

+      <ProductName>.NET Framework 3.5</ProductName>

+      <Install>false</Install>

+    </BootstrapperPackage>

+    <BootstrapperPackage Include="Microsoft.Net.Framework.3.5.SP1">

+      <Visible>False</Visible>

+      <ProductName>.NET Framework 3.5 SP1</ProductName>

+      <Install>false</Install>

+    </BootstrapperPackage>

+  </ItemGroup>

+  <ItemGroup>

+    <None Include="Apache.NMS.XMS.Test.nunit">

+      <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>

+      <SubType>Designer</SubType>

+    </None>

+    <None Include="keyfile\XMSKey.snk" />

+    <Content Include="xmsprovider-test.config">

+      <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>

+      <SubType>Designer</SubType>

+    </Content>

+  </ItemGroup>

+  <ItemGroup>

+    <Service Include="{82A7F48D-3B50-4B1E-B82E-3ADA8210C358}" />

+  </ItemGroup>

+  <ItemGroup>

+    <ProjectReference Include="vs2013-xms.csproj">

+      <Project>{2af5ebb5-9873-4b35-a8fc-8b6e74242767}</Project>

+      <Name>vs2013-xms</Name>

+    </ProjectReference>

+  </ItemGroup>

+  <Import Project="$(MSBuildBinPath)\Microsoft.CSHARP.Targets" />

+  <PropertyGroup>

+    <PostBuildEvent>cd $(ProjectDir)

+nant -nologo -q install-all -D:compile.skip=true</PostBuildEvent>

+  </PropertyGroup>

+</Project>
\ No newline at end of file
diff --git a/vs2013-xms.csproj b/vs2013-xms.csproj
new file mode 100644
index 0000000..86fbfc9
--- /dev/null
+++ b/vs2013-xms.csproj
@@ -0,0 +1,146 @@
+<?xml version="1.0" encoding="utf-8"?>

+<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003" ToolsVersion="12.0">

+  <PropertyGroup>

+    <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>

+    <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>

+    <ProductVersion>9.0.30729</ProductVersion>

+    <SchemaVersion>2.0</SchemaVersion>

+    <ProjectGuid>{2AF5EBB5-9873-4B35-A8FC-8B6E74242767}</ProjectGuid>

+    <OutputType>Library</OutputType>

+    <RootNamespace>Apache.NMS.XMS</RootNamespace>

+    <AssemblyName>Apache.NMS.XMS</AssemblyName>

+    <FileUpgradeFlags>

+    </FileUpgradeFlags>

+    <OldToolsVersion>3.5</OldToolsVersion>

+    <UpgradeBackupLocation>

+    </UpgradeBackupLocation>

+    <IsWebBootstrapper>false</IsWebBootstrapper>

+    <SignAssembly>true</SignAssembly>

+    <AssemblyOriginatorKeyFile>keyfile\NMSKey.snk</AssemblyOriginatorKeyFile>

+    <SccProjectName>Svn</SccProjectName>

+    <SccLocalPath>Svn</SccLocalPath>

+    <SccAuxPath>Svn</SccAuxPath>

+    <SccProvider>SubversionScc</SccProvider>

+    <RunPostBuildEvent>OnOutputUpdated</RunPostBuildEvent>

+    <TargetFrameworkVersion>v4.0</TargetFrameworkVersion>

+    <PublishUrl>publish\</PublishUrl>

+    <Install>true</Install>

+    <InstallFrom>Disk</InstallFrom>

+    <UpdateEnabled>false</UpdateEnabled>

+    <UpdateMode>Foreground</UpdateMode>

+    <UpdateInterval>7</UpdateInterval>

+    <UpdateIntervalUnits>Days</UpdateIntervalUnits>

+    <UpdatePeriodically>false</UpdatePeriodically>

+    <UpdateRequired>false</UpdateRequired>

+    <MapFileExtensions>true</MapFileExtensions>

+    <ApplicationRevision>0</ApplicationRevision>

+    <ApplicationVersion>1.0.0.%2a</ApplicationVersion>

+    <UseApplicationTrust>false</UseApplicationTrust>

+    <BootstrapperEnabled>true</BootstrapperEnabled>

+    <TargetFrameworkProfile />

+  </PropertyGroup>

+  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">

+    <DebugSymbols>true</DebugSymbols>

+    <DebugType>full</DebugType>

+    <Optimize>false</Optimize>

+    <OutputPath>build\net-4.0\debug\</OutputPath>

+    <DefineConstants>TRACE;DEBUG;NET,NET_4_0</DefineConstants>

+    <ErrorReport>prompt</ErrorReport>

+    <WarningLevel>4</WarningLevel>

+  </PropertyGroup>

+  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">

+    <DebugType>full</DebugType>

+    <Optimize>true</Optimize>

+    <OutputPath>build\net-4.0\release\</OutputPath>

+    <DefineConstants>TRACE;NET,NET_4_0</DefineConstants>

+    <ErrorReport>none</ErrorReport>

+    <WarningLevel>4</WarningLevel>

+    <DebugSymbols>true</DebugSymbols>

+  </PropertyGroup>

+  <ItemGroup>

+    <Reference Include="Apache.NMS">

+      <SpecificVersion>False</SpecificVersion>

+      <HintPath>lib\Apache.NMS\net-4.0\Apache.NMS.dll</HintPath>

+    </Reference>

+    <Reference Include="System" />

+    <Reference Include="System.Data" />

+    <Reference Include="System.Xml" />

+    <Reference Include="IBM.XMS">

+      <SpecificVersion>False</SpecificVersion>

+      <HintPath>lib\IBM.XMS\net-4.0\IBM.XMS.dll</HintPath>

+    </Reference>

+  </ItemGroup>

+  <ItemGroup>

+    <Compile Include="src\main\csharp\BytesMessage.cs" />

+    <Compile Include="src\main\csharp\CommonAssemblyInfo.cs" />

+    <Compile Include="src\main\csharp\Connection.cs" />

+    <Compile Include="src\main\csharp\ConnectionFactory.cs" />

+    <Compile Include="src\main\csharp\ConnectionMetaData.cs" />

+    <Compile Include="src\main\csharp\Destination.cs" />

+    <Compile Include="src\main\csharp\InitialContext.cs" />

+    <Compile Include="src\main\csharp\MapMessage.cs" />

+    <Compile Include="src\main\csharp\Message.cs" />

+    <Compile Include="src\main\csharp\MessageConsumer.cs" />

+    <Compile Include="src\main\csharp\MessageProducer.cs" />

+    <Compile Include="src\main\csharp\MessageProperties.cs" />

+    <Compile Include="src\main\csharp\ObjectMessage.cs" />

+    <Compile Include="src\main\csharp\Queue.cs" />

+    <Compile Include="src\main\csharp\QueueBrowser.cs" />

+    <Compile Include="src\main\csharp\Session.cs" />

+    <Compile Include="src\main\csharp\StreamMessage.cs" />

+    <Compile Include="src\main\csharp\TemporaryQueue.cs" />

+    <Compile Include="src\main\csharp\TemporaryTopic.cs" />

+    <Compile Include="src\main\csharp\TextMessage.cs" />

+    <Compile Include="src\main\csharp\Topic.cs" />

+    <Compile Include="src\main\csharp\Util\Dispatcher.cs" />

+    <Compile Include="src\main\csharp\Util\ExceptionUtil.cs" />

+    <Compile Include="src\main\csharp\Util\IntrospectionSupport.cs" />

+    <Compile Include="src\main\csharp\Util\UriAttributeAttribute.cs" />

+    <Compile Include="src\main\csharp\Util\XMSConvert.cs" />

+    <Compile Include="src\main\csharp\Util\XMSEnum.cs" />

+  </ItemGroup>

+  <ItemGroup>

+    <None Include="keyfile\XMSKey.snk" />

+  </ItemGroup>

+  <ItemGroup>

+    <BootstrapperPackage Include="Microsoft.Net.Client.3.5">

+      <Visible>False</Visible>

+      <ProductName>.NET Framework 3.5 SP1 Client Profile</ProductName>

+      <Install>false</Install>

+    </BootstrapperPackage>

+    <BootstrapperPackage Include="Microsoft.Net.Framework.2.0">

+      <Visible>False</Visible>

+      <ProductName>.NET Framework 2.0 %28x86%29</ProductName>

+      <Install>true</Install>

+    </BootstrapperPackage>

+    <BootstrapperPackage Include="Microsoft.Net.Framework.3.0">

+      <Visible>False</Visible>

+      <ProductName>.NET Framework 3.0 %28x86%29</ProductName>

+      <Install>false</Install>

+    </BootstrapperPackage>

+    <BootstrapperPackage Include="Microsoft.Net.Framework.3.5">

+      <Visible>False</Visible>

+      <ProductName>.NET Framework 3.5</ProductName>

+      <Install>false</Install>

+    </BootstrapperPackage>

+    <BootstrapperPackage Include="Microsoft.Net.Framework.3.5.SP1">

+      <Visible>False</Visible>

+      <ProductName>.NET Framework 3.5 SP1</ProductName>

+      <Install>false</Install>

+    </BootstrapperPackage>

+  </ItemGroup>

+  <Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" />

+  <!-- To modify your build process, add your task inside one of the targets below and uncomment it. 
+       Other similar extension points exist, see Microsoft.Common.targets.
+  <Target Name="BeforeBuild">
+  </Target>
+  <Target Name="AfterBuild">
+  </Target>
+  -->

+  <PropertyGroup>

+    <PreBuildEvent>cd $(ProjectDir)

+nant -nologo download-vendor -D:vendor.build.config=$(ConfigurationName) -D:vendor.build.framework=net-4.0</PreBuildEvent>

+    <PostBuildEvent>cd $(ProjectDir)

+nant -nologo -q install-all -D:compile.skip=true</PostBuildEvent>

+  </PropertyGroup>

+</Project>
\ No newline at end of file
diff --git a/vs2013-xms.sln b/vs2013-xms.sln
new file mode 100644
index 0000000..64bfb8e
--- /dev/null
+++ b/vs2013-xms.sln
@@ -0,0 +1,32 @@
+

+Microsoft Visual Studio Solution File, Format Version 12.00

+# Visual Studio 2013

+VisualStudioVersion = 12.0.40629.0

+MinimumVisualStudioVersion = 10.0.40219.1

+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "vs2013-xms", "vs2013-xms.csproj", "{2AF5EBB5-9873-4B35-A8FC-8B6E74242767}"

+EndProject

+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "vs2013-xms-test", "vs2013-xms-test.csproj", "{EB943C69-2C9B-45E7-B95B-FB916E7057ED}"

+EndProject

+Global

+	GlobalSection(SubversionScc) = preSolution

+		Svn-Managed = True

+		Manager = AnkhSVN - Subversion Support for Visual Studio

+	EndGlobalSection

+	GlobalSection(SolutionConfigurationPlatforms) = preSolution

+		Debug|Any CPU = Debug|Any CPU

+		Release|Any CPU = Release|Any CPU

+	EndGlobalSection

+	GlobalSection(ProjectConfigurationPlatforms) = postSolution

+		{2AF5EBB5-9873-4B35-A8FC-8B6E74242767}.Debug|Any CPU.ActiveCfg = Debug|Any CPU

+		{2AF5EBB5-9873-4B35-A8FC-8B6E74242767}.Debug|Any CPU.Build.0 = Debug|Any CPU

+		{2AF5EBB5-9873-4B35-A8FC-8B6E74242767}.Release|Any CPU.ActiveCfg = Release|Any CPU

+		{2AF5EBB5-9873-4B35-A8FC-8B6E74242767}.Release|Any CPU.Build.0 = Release|Any CPU

+		{EB943C69-2C9B-45E7-B95B-FB916E7057ED}.Debug|Any CPU.ActiveCfg = Debug|Any CPU

+		{EB943C69-2C9B-45E7-B95B-FB916E7057ED}.Debug|Any CPU.Build.0 = Debug|Any CPU

+		{EB943C69-2C9B-45E7-B95B-FB916E7057ED}.Release|Any CPU.ActiveCfg = Release|Any CPU

+		{EB943C69-2C9B-45E7-B95B-FB916E7057ED}.Release|Any CPU.Build.0 = Release|Any CPU

+	EndGlobalSection

+	GlobalSection(SolutionProperties) = preSolution

+		HideSolutionNode = FALSE

+	EndGlobalSection

+EndGlobal

diff --git a/xmsprovider-test.config b/xmsprovider-test.config
new file mode 100644
index 0000000..496545f
--- /dev/null
+++ b/xmsprovider-test.config
@@ -0,0 +1,33 @@
+<?xml version="1.0" encoding="utf-8" ?>
+<!--
+* 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.
+-->
+<configuration>
+	<testURI value="xms:wmq://localhost:1414">
+		<userName value="guest"/>
+		<passWord value="guest"/>
+		<defaultTestQueue value="queue://TEST.QUEUE"/>
+		<defaultTestTopic value="topic://TEST.TOPIC"/>
+		<durableConsumerTestTopic value="topic://TEST.DURABLE.CONSUMER.TOPIC"/>
+		<messageSelectorTestQueue value="queue://TEST.SELECTOR.MESSAGE.QUEUE"/>
+		<messageSelectorTestTopic value="topic://TEST.SELECTOR.MESSAGE.TOPIC"/>
+		<deletionTestQueue value="queue://TEST.DELETION.QUEUE"/>
+		<deletionTestTopic value="topic://TEST.DELETION.TOPIC"/>
+		<deletionTestTempQueue value="temp-queue://TEST.DELETION.TEMP.QUEUE"/>
+		<deletionTestTempTopic value="temp-topic://TEST.DELETION.TEMP.TOPIC"/>
+		<transactionTestQueue value="queue://TEST.TRANSACTION.QUEUE"/>
+	</testURI>
+</configuration>