[AMQ-9239] Host joram jms unit tests ahead of converting to jakarta.jms (#1002)

Merging now for jakarta work, may backout later
diff --git a/activemq-amqp/pom.xml b/activemq-amqp/pom.xml
index b06e35a..996512d 100644
--- a/activemq-amqp/pom.xml
+++ b/activemq-amqp/pom.xml
@@ -71,9 +71,9 @@
 
     <!--  Joram JMS conformance tests -->
     <dependency>
-      <groupId>org.fusesource.joram-jms-tests</groupId>
-      <artifactId>joram-jms-tests</artifactId>
-      <version>1.0</version>
+      <groupId>org.apache.activemq.tooling</groupId>
+      <artifactId>activemq-joram-jms-tests</artifactId>
+      <version>${project.version}</version>
       <scope>test</scope>
     </dependency>
     <dependency>
diff --git a/activemq-tooling/activemq-joram-jms-tests/pom.xml b/activemq-tooling/activemq-joram-jms-tests/pom.xml
new file mode 100644
index 0000000..b496fd8
--- /dev/null
+++ b/activemq-tooling/activemq-joram-jms-tests/pom.xml
@@ -0,0 +1,62 @@
+<?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.
+-->
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
+
+  <modelVersion>4.0.0</modelVersion>
+
+  <parent>
+    <groupId>org.apache.activemq.tooling</groupId>
+    <artifactId>activemq-tooling</artifactId>
+    <version>5.19.0-SNAPSHOT</version>
+  </parent>
+
+  <artifactId>activemq-joram-jms-tests</artifactId>
+
+  <name>ActiveMQ :: Joram JMS Tests</name>
+  <description>Maven artifact of the Joram JMS tests</description>
+
+  <developers>
+    <developer>
+      <id>chirino</id>
+      <name>Hiram Chirino</name>
+      <email>hiram@hiramchirino.com</email>
+      <url>http://hiramchirino.com</url>
+      <timezone>GMT-5</timezone>
+    </developer>
+    <developer>
+      <id>mattrpav</id>
+      <name>Matt Pavlovich</name>
+      <email>mattrpav@apache.org</email>
+      <timezone>GMT-6</timezone>
+    </developer>
+  </developers>
+
+  <dependencies>
+    <dependency>
+      <groupId>jakarta.jms</groupId>
+      <artifactId>jakarta.jms-api</artifactId>
+      <scope>provided</scope>
+    </dependency>
+    <dependency>
+      <groupId>junit</groupId>
+      <artifactId>junit</artifactId>
+      <scope>provided</scope>
+    </dependency>
+  </dependencies>
+
+</project>
diff --git a/activemq-tooling/activemq-joram-jms-tests/src/main/java/org/objectweb/jtests/jms/admin/Admin.java b/activemq-tooling/activemq-joram-jms-tests/src/main/java/org/objectweb/jtests/jms/admin/Admin.java
new file mode 100644
index 0000000..9bcef68
--- /dev/null
+++ b/activemq-tooling/activemq-joram-jms-tests/src/main/java/org/objectweb/jtests/jms/admin/Admin.java
@@ -0,0 +1,140 @@
+/*
+ * Copyright 2009 Red Hat, Inc.
+ * Red Hat 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.
+ */
+
+package org.objectweb.jtests.jms.admin;
+
+import javax.naming.Context;
+import javax.naming.NamingException;
+
+/**
+ * Simple Administration interface.
+ * <br />
+ * JMS Provider has to implement this 
+ * simple interface to be able to use the test suite.
+ */
+public interface Admin
+{
+
+   /**
+    * Returns the name of the JMS Provider.
+    *
+    * @return name of the JMS Provider
+    */
+   public String getName();
+
+   /** 
+    * Returns an <code>Context</code> for the JMS Provider.
+    *
+    * @return an <code>Context</code> for the JMS Provider.
+    */
+   public Context createContext() throws NamingException;
+
+   /** 
+    * Creates a <code>ConnectionFactory</code> and makes it available 
+    *from JNDI with name <code>name</code>.
+    *
+    * @since JMS 1.1
+    * @param name JNDI name of the <code>ConnectionFactory</code>
+    */
+   public void createConnectionFactory(String name);
+
+   /** 
+    * Creates a <code>QueueConnectionFactory</code> and makes it available 
+    *from JNDI with name <code>name</code>.
+    *
+    * @param name JNDI name of the <code>QueueConnectionFactory</code>
+    */
+   public void createQueueConnectionFactory(String name);
+
+   /** 
+    * Creates a <code>TopicConnectionFactory</code> and makes it available 
+    *from JNDI with name <code>name</code>.
+    *
+    * @param name JNDI name of the <code>TopicConnectionFactory</code>
+    */
+   public void createTopicConnectionFactory(String name);
+
+   /** 
+    * Creates a <code>Queue</code> and makes it available 
+    *from JNDI with name <code>name</code>.
+    *
+    * @param name JNDI name of the <code>Queue</code>
+    */
+   public void createQueue(String name);
+
+   /** 
+    * Creates a <code>Topic</code> and makes it available 
+    *from JNDI with name <code>name</code>.
+    *
+    * @param name JNDI name of the <code>Topic</code>
+    */
+   public void createTopic(String name);
+
+   /** 
+    * Removes the <code>Queue</code> of name <code>name</code> from JNDI and deletes it
+    *
+    * @param name JNDI name of the <code>Queue</code>
+    */
+   public void deleteQueue(String name);
+
+   /** 
+    * Removes the <code>Topic</code> of name <code>name</code> from JNDI and deletes it
+    *
+    * @param name JNDI name of the <code>Topic</code>
+    */
+   public void deleteTopic(String name);
+
+   /** 
+    * Removes the <code>ConnectionFactory</code> of name <code>name</code> from JNDI and deletes it
+    *
+    * @since JMS 1.1
+    * @param name JNDI name of the <code>ConnectionFactory</code>
+    */
+   public void deleteConnectionFactory(String name);
+
+   /** 
+    * Removes the <code>QueueConnectionFactory</code> of name <code>name</code> from JNDI and deletes it
+    *
+    * @param name JNDI name of the <code>QueueConnectionFactory</code>
+    */
+   public void deleteQueueConnectionFactory(String name);
+
+   /** 
+    * Removes the <code>TopicConnectionFactory</code> of name <code>name</code> from JNDI and deletes it
+    *
+    * @param name JNDI name of the <code>TopicConnectionFactory</code>
+    */
+   public void deleteTopicConnectionFactory(String name);
+
+   /**
+    * Optional method to start the server embedded (instead of running an external server)
+    */
+   public void startServer() throws Exception;
+
+   /**
+    * Optional method to stop the server embedded (instead of running an external server)
+    */
+   public void stopServer() throws Exception;
+
+   /**
+    * Optional method for processing to be made after the Admin is instantiated and before
+    * it is used to create the administrated objects
+    */
+   void start() throws Exception;
+
+   /**
+    * Optional method for processing to be made after the administrated objects have been cleaned up
+    */
+   void stop() throws Exception;
+
+}
diff --git a/activemq-tooling/activemq-joram-jms-tests/src/main/java/org/objectweb/jtests/jms/admin/AdminFactory.java b/activemq-tooling/activemq-joram-jms-tests/src/main/java/org/objectweb/jtests/jms/admin/AdminFactory.java
new file mode 100644
index 0000000..5a8d5e7
--- /dev/null
+++ b/activemq-tooling/activemq-joram-jms-tests/src/main/java/org/objectweb/jtests/jms/admin/AdminFactory.java
@@ -0,0 +1,51 @@
+/*
+ * Copyright 2009 Red Hat, Inc.
+ * Red Hat 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.
+ */
+
+package org.objectweb.jtests.jms.admin;
+
+import java.util.Properties;
+
+public class AdminFactory
+{
+   private static final String PROP_NAME = "jms.provider.admin.class";
+
+   protected static String getAdminClassName(final Properties props)
+   {
+      String adminClassName = props.getProperty(AdminFactory.PROP_NAME);
+      return adminClassName;
+   }
+
+   public static Admin getAdmin(final Properties props)
+   {
+      String adminClassName = AdminFactory.getAdminClassName(props);
+      Admin admin = null;
+      if (adminClassName == null)
+      {
+         throw new RuntimeException("Property " + AdminFactory.PROP_NAME + " has not been found in input props");
+      }
+      try
+      {
+         Class adminClass = Class.forName(adminClassName);
+         admin = (Admin)adminClass.newInstance();
+      }
+      catch (ClassNotFoundException e)
+      {
+         throw new RuntimeException("Class " + adminClassName + " not found.", e);
+      }
+      catch (Exception e)
+      {
+         throw new RuntimeException(e);
+      }
+      return admin;
+   }
+}
diff --git a/activemq-tooling/activemq-joram-jms-tests/src/main/java/org/objectweb/jtests/jms/admin/package.html b/activemq-tooling/activemq-joram-jms-tests/src/main/java/org/objectweb/jtests/jms/admin/package.html
new file mode 100644
index 0000000..e05fbd1
--- /dev/null
+++ b/activemq-tooling/activemq-joram-jms-tests/src/main/java/org/objectweb/jtests/jms/admin/package.html
@@ -0,0 +1,25 @@
+ <!--
+    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.
+--> 
+  <body>
+    Administration classes and interfaces used by the test suite to
+    manageJMS administrated object in a provider-independent way. 
+    <br />
+    Each JMS Provider has to implement the very simple Admin interface to be able to
+    use the test suite (see <a
+      href="http://www.objectweb.org/joram/current/doc/tests/index.html">documentation</a>).
+  </body>
+
diff --git a/activemq-tooling/activemq-joram-jms-tests/src/main/java/org/objectweb/jtests/jms/conform/connection/ConnectionTest.java b/activemq-tooling/activemq-joram-jms-tests/src/main/java/org/objectweb/jtests/jms/conform/connection/ConnectionTest.java
new file mode 100644
index 0000000..0042e45
--- /dev/null
+++ b/activemq-tooling/activemq-joram-jms-tests/src/main/java/org/objectweb/jtests/jms/conform/connection/ConnectionTest.java
@@ -0,0 +1,238 @@
+/*
+ * Copyright 2009 Red Hat, Inc.
+ * Red Hat 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.
+ */
+
+package org.objectweb.jtests.jms.conform.connection;
+
+import javax.jms.JMSException;
+import javax.jms.Message;
+import javax.jms.MessageListener;
+import javax.jms.Session;
+import javax.jms.TextMessage;
+
+import junit.framework.Assert;
+import junit.framework.Test;
+import junit.framework.TestSuite;
+
+import org.objectweb.jtests.jms.framework.PTPTestCase;
+import org.objectweb.jtests.jms.framework.TestConfig;
+
+/**
+ * Test connections.
+ * 
+ * See JMS specifications, sec. 4.3.5 Closing a Connection
+ *
+ * @author Jeff Mesnil (jmesnil@gmail.com)
+ * @version $Id: ConnectionTest.java,v 1.2 2007/06/15 20:55:20 csuconic Exp $
+ */
+public class ConnectionTest extends PTPTestCase
+{
+
+   /**
+    * Test that invoking the <code>acknowledge()</code> method of a received message 
+    * from a closed connection's session must throw an <code>IllegalStateException</code>.
+    */
+   public void testAcknowledge()
+   {
+      try
+      {
+         receiverConnection.stop();
+         receiverSession = receiverConnection.createQueueSession(false, Session.CLIENT_ACKNOWLEDGE);
+         receiver.close(); // Before assigning a new receiver, we need to close the old one...
+         // Not closing it could cause load balancing between receivers.
+         // Not having this close might be valid for JORAM or JBossMQ, but it's not valid for HornetQ (and still legal)
+
+         receiver = receiverSession.createReceiver(receiverQueue);
+         receiverConnection.start();
+
+         Message message = senderSession.createMessage();
+         sender.send(message);
+
+         Message m = receiver.receive(TestConfig.TIMEOUT);
+         receiverConnection.close();
+         m.acknowledge();
+         Assert.fail("sec. 4.3.5 Invoking the acknowledge method of a received message from a closed " + "connection's session must throw a [javax.jms.]IllegalStateException.\n");
+      }
+      catch (javax.jms.IllegalStateException e)
+      {
+      }
+      catch (JMSException e)
+      {
+         Assert.fail("sec. 4.3.5 Invoking the acknowledge method of a received message from a closed " + "connection's session must throw a [javax.jms.]IllegalStateException, not a " +
+                     e);
+      }
+      catch (java.lang.IllegalStateException e)
+      {
+         Assert.fail("sec. 4.3.5 Invoking the acknowledge method of a received message from a closed " + "connection's session must throw an [javax.jms.]IllegalStateException "
+                     + "[not a java.lang.IllegalStateException]");
+      }
+   }
+
+   /**
+    * Test that an attempt to use a <code>Connection</code> which has been closed 
+    * throws a <code>javax.jms.IllegalStateException</code>.
+    */
+   public void testUseClosedConnection()
+   {
+      try
+      {
+         senderConnection.close();
+         senderConnection.createQueueSession(false, Session.AUTO_ACKNOWLEDGE);
+         Assert.fail("Should raise a javax.jms.IllegalStateException");
+      }
+      catch (javax.jms.IllegalStateException e)
+      {
+      }
+      catch (JMSException e)
+      {
+         Assert.fail("Should raise a javax.jms.IllegalStateException, not a " + e);
+      }
+      catch (java.lang.IllegalStateException e)
+      {
+         Assert.fail("Should raise a javax.jms.IllegalStateException, not a java.lang.IllegalStateException");
+      }
+   }
+
+   /**
+    * Test that a <code>MessageProducer</code> can send messages while a 
+    * <code>Connection</code> is stopped.
+    */
+   public void testMessageSentWhenConnectionClosed()
+   {
+      try
+      {
+         senderConnection.stop();
+         Message message = senderSession.createTextMessage();
+         sender.send(message);
+
+         receiver.receive(TestConfig.TIMEOUT);
+      }
+      catch (JMSException e)
+      {
+         fail(e);
+      }
+   }
+
+   /**
+    * Test that closing a closed connectiondoes not throw an exception.
+    */
+   public void testCloseClosedConnection()
+   {
+      try
+      {
+         // senderConnection is already started
+         // we close it once
+         senderConnection.close();
+         // we close it a second time
+         senderConnection.close();
+      }
+      catch (Exception e)
+      {
+         Assert.fail("sec. 4.3.5 Closing a closed connection must not throw an exception.\n");
+      }
+   }
+
+   /**
+    * Test that starting a started connection is ignored
+    */
+   public void testStartStartedConnection()
+   {
+      try
+      {
+         // senderConnection is already started
+         // start it again should be ignored
+         senderConnection.start();
+      }
+      catch (JMSException e)
+      {
+         fail(e);
+      }
+   }
+
+   /**
+    * Test that stopping a stopped connection is ignored
+    */
+   public void testStopStoppedConnection()
+   {
+      try
+      {
+         // senderConnection is started
+         // we stop it once
+         senderConnection.stop();
+         // stopping it a second time is ignored
+         senderConnection.stop();
+      }
+      catch (JMSException e)
+      {
+         fail(e);
+      }
+   }
+
+   /**
+    * Test that delivery of message is stopped if the message consumer connection is stopped
+    */
+   public void testStopConsumerConnection()
+   {
+      try
+      {
+         receiverConnection.stop();
+
+         receiver.setMessageListener(new MessageListener()
+         {
+            public void onMessage(final Message m)
+            {
+               try
+               {
+                  Assert.fail("The message must not be received, the consumer connection is stopped");
+                  Assert.assertEquals("test", ((TextMessage)m).getText());
+               }
+               catch (JMSException e)
+               {
+                  fail(e);
+               }
+            }
+         });
+
+         TextMessage message = senderSession.createTextMessage();
+         message.setText("test");
+         sender.send(message);
+         synchronized (this)
+         {
+            try
+            {
+               wait(1000);
+            }
+            catch (Exception e)
+            {
+               fail(e);
+            }
+         }
+      }
+      catch (JMSException e)
+      {
+         fail(e);
+      }
+   }
+
+   /** 
+    * Method to use this class in a Test suite
+    */
+   public static Test suite()
+   {
+      return new TestSuite(ConnectionTest.class);
+   }
+
+   public ConnectionTest(final String name)
+   {
+      super(name);
+   }
+}
diff --git a/activemq-tooling/activemq-joram-jms-tests/src/main/java/org/objectweb/jtests/jms/conform/connection/TopicConnectionTest.java b/activemq-tooling/activemq-joram-jms-tests/src/main/java/org/objectweb/jtests/jms/conform/connection/TopicConnectionTest.java
new file mode 100644
index 0000000..dfe5982
--- /dev/null
+++ b/activemq-tooling/activemq-joram-jms-tests/src/main/java/org/objectweb/jtests/jms/conform/connection/TopicConnectionTest.java
@@ -0,0 +1,171 @@
+/*
+ * Copyright 2009 Red Hat, Inc.
+ * Red Hat 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.
+ */
+
+package org.objectweb.jtests.jms.conform.connection;
+
+import javax.jms.JMSException;
+
+import junit.framework.Assert;
+import junit.framework.Test;
+import junit.framework.TestSuite;
+
+import org.objectweb.jtests.jms.framework.PubSubTestCase;
+
+/**
+ * Test topic-specific connection features.
+ *
+ * Test setting of client ID which is relevant only for Durable Subscribtion
+ */
+
+public class TopicConnectionTest extends PubSubTestCase
+{
+
+   /**
+    * Test that a call to <code>setClientID</code> will throw an 
+    * <code>IllegalStateException</code> if a client ID has already been set
+    * see JMS javadoc 
+    * http://java.sun.com/j2ee/sdk_1.3/techdocs/api/javax/jms/Connection.html#setClientID(java.lang.String)
+    */
+   public void testSetClientID_1()
+   {
+      try
+      {
+         // we start from a clean state for the connection
+         subscriberConnection.close();
+         subscriberConnection = null;
+
+         subscriberConnection = subscriberTCF.createTopicConnection();
+         // if the JMS provider does not set a client ID, we do.
+         if (subscriberConnection.getClientID() == null)
+         {
+            subscriberConnection.setClientID("testSetClientID_1");
+            Assert.assertEquals("testSetClientID_1", subscriberConnection.getClientID());
+         }
+         // now the connection has a client ID (either "testSetClientID_1" or one set by the provider
+         Assert.assertTrue(subscriberConnection.getClientID() != null);
+
+         // a attempt to set a client ID should now throw an IllegalStateException
+         subscriberConnection.setClientID("another client ID");
+         Assert.fail("Should raise a javax.jms.IllegalStateException");
+      }
+      catch (javax.jms.IllegalStateException e)
+      {
+      }
+      catch (JMSException e)
+      {
+         Assert.fail("Should raise a javax.jms.IllegalStateException, not a " + e);
+      }
+      catch (java.lang.IllegalStateException e)
+      {
+         Assert.fail("Should raise a javax.jms.IllegalStateException, not a java.lang.IllegalStateException");
+      }
+   }
+
+   /** 
+    * Test that a call to <code>setClientID</code> can occur only after connection creation 
+    * and before any other action on the connection.
+    * <em>This test is relevant only if the ID is set by the JMS client</em>
+    * see JMS javadoc 
+    * http://java.sun.com/j2ee/sdk_1.3/techdocs/api/javax/jms/Connection.html#setClientID(java.lang.String)
+    */
+   public void testSetClientID_2()
+   {
+      try
+      {
+         // we start from a clean state for the first connection
+         subscriberConnection.close();
+         subscriberConnection = null;
+
+         subscriberConnection = subscriberTCF.createTopicConnection();
+         // if the JMS provider has set a client ID, this test is not relevant
+         if (subscriberConnection.getClientID() != null)
+         {
+            return;
+         }
+
+         // we start the connection
+         subscriberConnection.start();
+
+         // an attempt to set the client ID now should throw a IllegalStateException
+         subscriberConnection.setClientID("testSetClientID_2");
+         Assert.fail("Should throw a javax.jms.IllegalStateException");
+      }
+      catch (javax.jms.IllegalStateException e)
+      {
+      }
+      catch (JMSException e)
+      {
+         Assert.fail("Should raise a javax.jms.IllegalStateException, not a " + e);
+      }
+      catch (java.lang.IllegalStateException e)
+      {
+         Assert.fail("Should raise a javax.jms.IllegalStateException, not a java.lang.IllegalStateException");
+      }
+   }
+
+   /**
+    * Test that if another connection with the same clientID is already running when 
+    * <code>setClientID</code> is called, the JMS provider should detect the duplicate
+    * ID and throw an <code>InvalidClientIDException</code>
+    * <em>This test is relevant only if the ID is set by the JMS client</em>
+    * see JMS javadoc 
+    * http://java.sun.com/j2ee/sdk_1.3/techdocs/api/javax/jms/Connection.html#setClientID(java.lang.String)
+    * 
+    *... This test is not valid... as getClientID is caleld before setClientID
+    */
+   /*public void testSetClientID_3()
+   {
+      try
+      {
+         // we start from a clean state for the first connection
+         subscriberConnection.close();
+         subscriberConnection = null;
+
+         subscriberConnection = subscriberTCF.createTopicConnection();
+         // if the JMS provider has set a client ID, this test is not relevant
+         if (subscriberConnection.getClientID() != null)
+         {
+            return;
+         }
+         // the JMS provider has not set a client ID, so we do
+         subscriberConnection.setClientID("testSetClientID_3");
+         assertEquals("testSetClientID_3", subscriberConnection.getClientID());
+
+         // we create a new connection and try to set the same ID than for subscriberConnection
+         TopicConnection connection_2 = subscriberTCF.createTopicConnection();
+         assertTrue(connection_2.getClientID() == null);
+         connection_2.setClientID("testSetClientID_3");
+         fail("Should throw a javax.jms.InvalidClientIDException");
+      }
+      catch (InvalidClientIDException e)
+      {
+      }
+      catch (JMSException e)
+      {
+         fail(e);
+      }
+   }*/
+
+   /** 
+    * Method to use this class in a Test suite
+    */
+   public static Test suite()
+   {
+      return new TestSuite(TopicConnectionTest.class);
+   }
+
+   public TopicConnectionTest(final String name)
+   {
+      super(name);
+   }
+}
diff --git a/activemq-tooling/activemq-joram-jms-tests/src/main/java/org/objectweb/jtests/jms/conform/connection/package.html b/activemq-tooling/activemq-joram-jms-tests/src/main/java/org/objectweb/jtests/jms/conform/connection/package.html
new file mode 100644
index 0000000..4ff102e
--- /dev/null
+++ b/activemq-tooling/activemq-joram-jms-tests/src/main/java/org/objectweb/jtests/jms/conform/connection/package.html
@@ -0,0 +1,19 @@
+<!--
+    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.
+-->
+  <body>
+    Tests JMS <em>Connection</em> features.
+  </body>
diff --git a/activemq-tooling/activemq-joram-jms-tests/src/main/java/org/objectweb/jtests/jms/conform/message/MessageBodyTest.java b/activemq-tooling/activemq-joram-jms-tests/src/main/java/org/objectweb/jtests/jms/conform/message/MessageBodyTest.java
new file mode 100644
index 0000000..aca2dfd
--- /dev/null
+++ b/activemq-tooling/activemq-joram-jms-tests/src/main/java/org/objectweb/jtests/jms/conform/message/MessageBodyTest.java
@@ -0,0 +1,133 @@
+/*
+ * Copyright 2009 Red Hat, Inc.
+ * Red Hat 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.
+ */
+
+package org.objectweb.jtests.jms.conform.message;
+
+import javax.jms.JMSException;
+import javax.jms.Message;
+import javax.jms.MessageNotWriteableException;
+import javax.jms.TextMessage;
+
+import junit.framework.Assert;
+import junit.framework.Test;
+import junit.framework.TestSuite;
+
+import org.objectweb.jtests.jms.framework.PTPTestCase;
+import org.objectweb.jtests.jms.framework.TestConfig;
+
+/**
+ * Tests on message body.
+ *
+ * @author Jeff Mesnil (jmesnil@gmail.com)
+ * @version $Id: MessageBodyTest.java,v 1.1 2007/03/29 04:28:37 starksm Exp $
+ */
+public class MessageBodyTest extends PTPTestCase
+{
+   
+   /** 
+    * Method to use this class in a Test suite
+    */
+   public static Test suite()
+   {
+      return new TestSuite(MessageBodyTest.class);
+   }
+
+
+   /**
+    * Test that the <code>TextMessage.clearBody()</code> method does nto clear the 
+    * message properties.
+    */
+   public void testClearBody_2()
+   {
+      try
+      {
+         TextMessage message = senderSession.createTextMessage();
+         message.setStringProperty("prop", "foo");
+         message.clearBody();
+         Assert.assertEquals("sec. 3.11.1 Clearing a message's body does not clear its property entries.\n",
+                             "foo",
+                             message.getStringProperty("prop"));
+      }
+      catch (JMSException e)
+      {
+         fail(e);
+      }
+   }
+
+   /**
+    * Test that the <code>TextMessage.clearBody()</code> effectively clear the body of the message
+    */
+   public void testClearBody_1()
+   {
+      try
+      {
+         TextMessage message = senderSession.createTextMessage();
+         message.setText("bar");
+         message.clearBody();
+         Assert.assertEquals("sec. 3 .11.1 the clearBody method of Message resets the value of the message body " + "to the 'empty' initial message value as set by the message type's create "
+                                      + "method provided by Session.\n",
+                             null,
+                             message.getText());
+      }
+      catch (JMSException e)
+      {
+         fail(e);
+      }
+   }
+
+   /**
+    * Test that a call to the <code>TextMessage.setText()</code> method on a 
+    * received message raises a <code>javax.jms.MessageNotWriteableException</code>.
+    */
+   public void testWriteOnReceivedBody()
+   {
+      try
+      {
+         TextMessage message = senderSession.createTextMessage();
+         message.setText("foo");
+         sender.send(message);
+
+         Message m = receiver.receive(TestConfig.TIMEOUT);
+         Assert.assertTrue("The message should be an instance of TextMessage.\n", m instanceof TextMessage);
+         TextMessage msg = (TextMessage)m;
+         msg.setText("bar");
+         Assert.fail("should raise a MessageNotWriteableException (sec. 3.11.2)");
+      }
+      catch (MessageNotWriteableException e)
+      {
+      }
+      catch (JMSException e)
+      {
+         fail(e);
+      }
+   }
+
+   public MessageBodyTest(final String name)
+   {
+      super(name);
+   }
+
+   @Override
+   protected void setUp() throws Exception
+   {
+
+      super.setUp();
+   }
+
+   @Override
+   protected void tearDown() throws Exception
+   {
+      super.tearDown();
+
+   }
+}
diff --git a/activemq-tooling/activemq-joram-jms-tests/src/main/java/org/objectweb/jtests/jms/conform/message/MessageDefaultTest.java b/activemq-tooling/activemq-joram-jms-tests/src/main/java/org/objectweb/jtests/jms/conform/message/MessageDefaultTest.java
new file mode 100644
index 0000000..d9a1d6c
--- /dev/null
+++ b/activemq-tooling/activemq-joram-jms-tests/src/main/java/org/objectweb/jtests/jms/conform/message/MessageDefaultTest.java
@@ -0,0 +1,66 @@
+/*
+ * Copyright 2009 Red Hat, Inc.
+ * Red Hat 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.
+ */
+
+package org.objectweb.jtests.jms.conform.message;
+
+import javax.jms.DeliveryMode;
+import javax.jms.Message;
+
+import junit.framework.Assert;
+import junit.framework.Test;
+import junit.framework.TestSuite;
+
+import org.objectweb.jtests.jms.framework.JMSTestCase;
+
+/**
+ * Test the default constants of the <code>javax.jms.Message</code> interface.
+ *
+ * @author Jeff Mesnil (jmesnil@gmail.com)
+ * @version $Id: MessageDefaultTest.java,v 1.1 2007/03/29 04:28:37 starksm Exp $
+ */
+public class MessageDefaultTest extends JMSTestCase
+{
+
+   /**
+    * test that the <code>DEFAULT_DELIVERY_MODE</code> of <code>javax.jms.Message</code>
+    * corresponds to <code>javax.jms.Delivery.PERSISTENT</code>.
+    */
+   public void testDEFAULT_DELIVERY_MODE()
+   {
+      Assert.assertEquals("The delivery mode is persistent by default.\n",
+                          DeliveryMode.PERSISTENT,
+                          Message.DEFAULT_DELIVERY_MODE);
+   }
+
+   /**
+    * test that the <code>DEFAULT_PRIORITY</code> of <code>javax.jms.Message</code>
+    * corresponds to 4.
+    */
+   public void testDEFAULT_PRIORITY()
+   {
+      Assert.assertEquals("The default priority is 4.\n", 4, Message.DEFAULT_PRIORITY);
+   }
+
+   /** 
+    * Method to use this class in a Test suite
+    */
+   public static Test suite()
+   {
+      return new TestSuite(MessageDefaultTest.class);
+   }
+
+   public MessageDefaultTest(final String name)
+   {
+      super(name);
+   }
+}
diff --git a/activemq-tooling/activemq-joram-jms-tests/src/main/java/org/objectweb/jtests/jms/conform/message/MessageTypeTest.java b/activemq-tooling/activemq-joram-jms-tests/src/main/java/org/objectweb/jtests/jms/conform/message/MessageTypeTest.java
new file mode 100644
index 0000000..f507388
--- /dev/null
+++ b/activemq-tooling/activemq-joram-jms-tests/src/main/java/org/objectweb/jtests/jms/conform/message/MessageTypeTest.java
@@ -0,0 +1,410 @@
+/*
+ * Copyright 2009 Red Hat, Inc.
+ * Red Hat 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.
+ */
+
+package org.objectweb.jtests.jms.conform.message;
+
+import java.util.Enumeration;
+import java.util.Vector;
+
+import javax.jms.BytesMessage;
+import javax.jms.JMSException;
+import javax.jms.MapMessage;
+import javax.jms.Message;
+import javax.jms.ObjectMessage;
+import javax.jms.StreamMessage;
+import javax.jms.TextMessage;
+
+import junit.framework.Assert;
+import junit.framework.Test;
+import junit.framework.TestSuite;
+
+import org.objectweb.jtests.jms.framework.PTPTestCase;
+import org.objectweb.jtests.jms.framework.TestConfig;
+
+/**
+ * Test the different types of messages provided by JMS.
+ * <br />
+ * JMS provides 6 types of messages which differs by the type of their body:
+ * <ol>
+ *   <li><code>Message</code> which doesn't have a body</li>
+ *   <li><code>TextMessage</code> with a <code>String</code> as body</li>
+ *   <li><code>ObjectMessage</code> with any <code>Object</code> as body</li>
+ *   <li><code>BytesMessage</code> with a body made of <code>bytes</code></li>
+ *   <li><code>MapMessage</code> with name-value pairs of Java primitives in its body</li>
+ *   <li><code>StreamMessage</code> with a stream of Java primitives as body</li>
+ *  </ol>
+ * <br />
+ * For each of this type of message, we test that a message can be sent and received
+ * with an empty body or not.
+ * 
+ * @author Jeff Mesnil (jmesnil@gmail.com)
+ * @version $Id: MessageTypeTest.java,v 1.1 2007/03/29 04:28:37 starksm Exp $
+ */
+public class MessageTypeTest extends PTPTestCase
+{
+
+   /**
+    * Send a <code>StreamMessage</code> with 2 Java primitives in its body (a <code>
+    * String</code> and a <code>double</code>).
+    * <br />
+    * Receive it and test that the values of the primitives of the body are correct
+    */
+   public void testStreamMessage_2()
+   {
+      try
+      {
+         StreamMessage message = senderSession.createStreamMessage();
+         message.writeString("pi");
+         message.writeDouble(3.14159);
+         sender.send(message);
+
+         Message m = receiver.receive(TestConfig.TIMEOUT);
+         Assert.assertTrue("The message should be an instance of StreamMessage.\n", m instanceof StreamMessage);
+         StreamMessage msg = (StreamMessage)m;
+         Assert.assertEquals("pi", msg.readString());
+         Assert.assertEquals(3.14159, msg.readDouble(), 0);
+      }
+      catch (JMSException e)
+      {
+         fail(e);
+      }
+   }
+
+   /**
+    * Send a <code>StreamMessage</code> with an empty body.
+    * <br />
+    * Receive it and test if the message is effectively an instance of 
+    * <code>StreamMessage</code>
+    */
+   public void testStreamMessage_1()
+   {
+      try
+      {
+         StreamMessage message = senderSession.createStreamMessage();
+         sender.send(message);
+
+         Message msg = receiver.receive(TestConfig.TIMEOUT);
+         Assert.assertTrue("The message should be an instance of StreamMessage.\n", msg instanceof StreamMessage);
+      }
+      catch (JMSException e)
+      {
+         fail(e);
+      }
+   }
+
+   /**
+    * Test in MapMessage the conversion between <code>getObject("foo")</code> and
+    * <code>getDouble("foo")</code> (the later returning a java.lang.Double and the former a double)
+    */
+   public void testMapMessageConversion()
+   {
+      try
+      {
+         MapMessage message = senderSession.createMapMessage();
+         message.setDouble("pi", 3.14159);
+         sender.send(message);
+
+         Message m = receiver.receive(TestConfig.TIMEOUT);
+         Assert.assertTrue("The message should be an instance of MapMessage.\n", m instanceof MapMessage);
+         MapMessage msg = (MapMessage)m;
+         Assert.assertTrue(msg.getObject("pi") instanceof Double);
+         Assert.assertEquals(3.14159, ((Double)msg.getObject("pi")).doubleValue(), 0);
+         Assert.assertEquals(3.14159, msg.getDouble("pi"), 0);
+      }
+      catch (JMSException e)
+      {
+         fail(e);
+      }
+   }
+
+   /**
+    * Test that the if the name parameter of the set methods of a <code>MapMessage</code> is <code>null</code>, 
+    * the method must throw the error <code>java.lang.IllegalArgumentException</code>.
+    * <br />
+    * @since JMS 1.1
+    */
+   public void testNullInSetMethodsForMapMessage()
+   {
+      try
+      {
+         MapMessage message = senderSession.createMapMessage();
+         message.setBoolean(null, true);
+         Assert.fail("Should throw an IllegalArgumentException");
+      }
+      catch (IllegalArgumentException e)
+      {
+      }
+      catch (JMSException e)
+      {
+         Assert.fail("Should throw an IllegalArgumentException, not a" + e);
+      }
+   }
+
+   /**
+    * Test that the if the name parameter of the set methods of a <code>MapMessage</code> is an empty String,
+    * the method must throw the error <code>java.lang.IllegalArgumentException</code>.
+    * <br />
+    * @since JMS 1.1
+    */
+   public void testEmptyStringInSetMethodsForMapMessage()
+   {
+      try
+      {
+         MapMessage message = senderSession.createMapMessage();
+         message.setBoolean("", true);
+         Assert.fail("Should throw an IllegalArgumentException");
+      }
+      catch (IllegalArgumentException e)
+      {
+      }
+      catch (JMSException e)
+      {
+         Assert.fail("Should throw an IllegalArgumentException, not a" + e);
+      }
+   }
+
+   /**
+    * Test that the <code>MapMessage.getMapNames()</code> method returns an
+    * empty <code>Enumeration</code> when no map has been defined before.
+    * <br />
+    * Also test that the same method returns the correct names of the map.
+    */
+   public void testgetMapNames()
+   {
+      try
+      {
+         MapMessage message = senderSession.createMapMessage();
+         Enumeration e = message.getMapNames();
+         Assert.assertTrue("No map yet defined.\n", !e.hasMoreElements());
+         message.setDouble("pi", 3.14159);
+         e = message.getMapNames();
+         Assert.assertEquals("pi", (String)e.nextElement());
+      }
+      catch (JMSException e)
+      {
+         fail(e);
+      }
+   }
+
+   /**
+    * Send a <code>MapMessage</code> with 2 Java primitives in its body (a <code>
+    * String</code> and a <code>double</code>).
+    * <br />
+    * Receive it and test that the values of the primitives of the body are correct
+    */
+   public void testMapMessage_2()
+   {
+      try
+      {
+         MapMessage message = senderSession.createMapMessage();
+         message.setString("name", "pi");
+         message.setDouble("value", 3.14159);
+         sender.send(message);
+
+         Message m = receiver.receive(TestConfig.TIMEOUT);
+         Assert.assertTrue("The message should be an instance of MapMessage.\n", m instanceof MapMessage);
+         MapMessage msg = (MapMessage)m;
+         Assert.assertEquals("pi", msg.getString("name"));
+         Assert.assertEquals(3.14159, msg.getDouble("value"), 0);
+      }
+      catch (JMSException e)
+      {
+         fail(e);
+      }
+   }
+
+   /**
+    * Send a <code>MapMessage</code> with an empty body.
+    * <br />
+    * Receive it and test if the message is effectively an instance of 
+    * <code>MapMessage</code>
+    */
+   public void testMapMessage_1()
+   {
+      try
+      {
+         MapMessage message = senderSession.createMapMessage();
+         sender.send(message);
+
+         Message msg = receiver.receive(TestConfig.TIMEOUT);
+         Assert.assertTrue("The message should be an instance of MapMessage.\n", msg instanceof MapMessage);
+      }
+      catch (JMSException e)
+      {
+         fail(e);
+      }
+   }
+
+   /**
+    * Send an <code>ObjectMessage</code> with a <code>Vector</code> (composed of a <code>
+    * String</code> and a <code>double</code>) in its body.
+    * <br />
+    * Receive it and test that the values of the primitives of the body are correct
+    */
+   public void testObjectMessage_2()
+   {
+      try
+      {
+         Vector vector = new Vector();
+         vector.add("pi");
+         vector.add(new Double(3.14159));
+
+         ObjectMessage message = senderSession.createObjectMessage();
+         message.setObject(vector);
+         sender.send(message);
+
+         Message m = receiver.receive(TestConfig.TIMEOUT);
+         Assert.assertTrue("The message should be an instance of ObjectMessage.\n", m instanceof ObjectMessage);
+         ObjectMessage msg = (ObjectMessage)m;
+         Assert.assertEquals(vector, msg.getObject());
+      }
+      catch (JMSException e)
+      {
+         fail(e);
+      }
+   }
+
+   /**
+    * Send a <code>ObjectMessage</code> with an empty body.
+    * <br />
+    * Receive it and test if the message is effectively an instance of 
+    * <code>ObjectMessage</code>
+    */
+   public void testObjectMessage_1()
+   {
+      try
+      {
+         ObjectMessage message = senderSession.createObjectMessage();
+         sender.send(message);
+
+         Message msg = receiver.receive(TestConfig.TIMEOUT);
+         Assert.assertTrue("The message should be an instance of ObjectMessage.\n", msg instanceof ObjectMessage);
+      }
+      catch (JMSException e)
+      {
+         fail(e);
+      }
+   }
+
+   /**
+    * Send a <code>BytesMessage</code> with 2 Java primitives in its body (a <code>
+    * String</code> and a <code>double</code>).
+    * <br />
+    * Receive it and test that the values of the primitives of the body are correct
+    */
+   public void testBytesMessage_2()
+   {
+      try
+      {
+         byte[] bytes = new String("pi").getBytes();
+         BytesMessage message = senderSession.createBytesMessage();
+         message.writeBytes(bytes);
+         message.writeDouble(3.14159);
+         sender.send(message);
+
+         Message m = receiver.receive(TestConfig.TIMEOUT);
+         Assert.assertTrue("The message should be an instance of BytesMessage.\n", m instanceof BytesMessage);
+         BytesMessage msg = (BytesMessage)m;
+         byte[] receivedBytes = new byte[bytes.length];
+         msg.readBytes(receivedBytes);
+         Assert.assertEquals(new String(bytes), new String(receivedBytes));
+         Assert.assertEquals(3.14159, msg.readDouble(), 0);
+      }
+      catch (JMSException e)
+      {
+         fail(e);
+      }
+   }
+
+   /**
+    * Send a <code>BytesMessage</code> with an empty body.
+    * <br />
+    * Receive it and test if the message is effectively an instance of 
+    * <code>BytesMessage</code>
+    */
+   public void testBytesMessage_1()
+   {
+      try
+      {
+         BytesMessage message = senderSession.createBytesMessage();
+         sender.send(message);
+
+         Message msg = receiver.receive(TestConfig.TIMEOUT);
+         Assert.assertTrue("The message should be an instance of BytesMessage.\n", msg instanceof BytesMessage);
+      }
+      catch (JMSException e)
+      {
+         fail(e);
+      }
+   }
+
+   /**
+    * Send a <code>TextMessage</code> with a <code>String</code> in its body.
+    * <br />
+    * Receive it and test that the received <code>String</code> corresponds to
+    * the sent one.
+    */
+   public void testTextMessage_2()
+   {
+      try
+      {
+         TextMessage message = senderSession.createTextMessage();
+         message.setText("testTextMessage_2");
+         sender.send(message);
+
+         Message m = receiver.receive(TestConfig.TIMEOUT);
+         Assert.assertTrue("The message should be an instance of TextMessage.\n", m instanceof TextMessage);
+         TextMessage msg = (TextMessage)m;
+         Assert.assertEquals("testTextMessage_2", msg.getText());
+      }
+      catch (JMSException e)
+      {
+         fail(e);
+      }
+   }
+
+   /**
+    * Send a <code>TextMessage</code> with an empty body.
+    * <br />
+    * Receive it and test if the message is effectively an instance of 
+    * <code>TextMessage</code>
+    */
+   public void testTextMessage_1()
+   {
+      try
+      {
+         TextMessage message = senderSession.createTextMessage();
+         sender.send(message);
+
+         Message msg = receiver.receive(TestConfig.TIMEOUT);
+         Assert.assertTrue("The message should be an instance of TextMessage.\n", msg instanceof TextMessage);
+      }
+      catch (JMSException e)
+      {
+         fail(e);
+      }
+   }
+
+   /** 
+    * Method to use this class in a Test suite
+    */
+   public static Test suite()
+   {
+      return new TestSuite(MessageTypeTest.class);
+   }
+
+   public MessageTypeTest(final String name)
+   {
+      super(name);
+   }
+}
diff --git a/activemq-tooling/activemq-joram-jms-tests/src/main/java/org/objectweb/jtests/jms/conform/message/headers/MessageHeaderTest.java b/activemq-tooling/activemq-joram-jms-tests/src/main/java/org/objectweb/jtests/jms/conform/message/headers/MessageHeaderTest.java
new file mode 100644
index 0000000..680ccda
--- /dev/null
+++ b/activemq-tooling/activemq-joram-jms-tests/src/main/java/org/objectweb/jtests/jms/conform/message/headers/MessageHeaderTest.java
@@ -0,0 +1,296 @@
+/*
+ * Copyright 2009 Red Hat, Inc.
+ * Red Hat 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.
+ */
+
+package org.objectweb.jtests.jms.conform.message.headers;
+
+import javax.jms.DeliveryMode;
+import javax.jms.Destination;
+import javax.jms.JMSException;
+import javax.jms.Message;
+import javax.jms.Queue;
+import javax.jms.TemporaryQueue;
+import javax.naming.Context;
+import javax.naming.NamingException;
+
+import junit.framework.Assert;
+import junit.framework.Test;
+import junit.framework.TestSuite;
+
+import org.objectweb.jtests.jms.framework.PTPTestCase;
+import org.objectweb.jtests.jms.framework.TestConfig;
+
+/**
+ * Test the headers of a message
+ *
+ * @author Jeff Mesnil (jmesnil@gmail.com)
+ * @version $Id: MessageHeaderTest.java,v 1.1 2007/03/29 04:28:36 starksm Exp $
+ */
+public class MessageHeaderTest extends PTPTestCase
+{
+
+   /**
+    * Test that the <code>MessageProducer.setPriority()</code> changes effectively
+    * priority of the message.
+    */
+   public void testJMSPriority_2()
+   {
+      try
+      {
+         Message message = senderSession.createMessage();
+         sender.send(message);
+         sender.setPriority(9);
+         sender.send(message);
+         Assert.assertEquals("sec. 3.4.9 After completion of the send it holds the value specified by the " + "method sending the message.\n",
+                             9,
+                             message.getJMSPriority());
+
+         receiver.receive(TestConfig.TIMEOUT);
+      }
+      catch (JMSException e)
+      {
+         fail(e);
+      }
+   }
+
+   /**
+    * Test that the priority set by <code>Message.setJMSPriority()</code> is ignored when a 
+    * message is sent and that it holds the value specified when sending the message (i.e. 
+    * <code>Message.DEFAULT_PRIORITY</code> in this test).
+    */
+   public void testJMSPriority_1()
+   {
+      try
+      {
+         Message message = senderSession.createMessage();
+         message.setJMSPriority(0);
+         sender.send(message);
+         Assert.assertTrue("sec. 3.4.9 When a message is sent this value is ignored.\n", message.getJMSPriority() != 0);
+         Assert.assertEquals("sec. 3.4.9 After completion of the send it holds the value specified by the " + "method sending the message.\n",
+                             Message.DEFAULT_PRIORITY,
+                             message.getJMSPriority());
+
+         receiver.receive(TestConfig.TIMEOUT);
+      }
+      catch (JMSException e)
+      {
+         fail(e);
+      }
+   }
+
+   /**
+    * Test that the value of the <code>JMSExpiration<code> header field is the same
+    * for the sent message and the received one.
+    */
+   public void testJMSExpiration()
+   {
+      try
+      {
+         Message message = senderSession.createMessage();
+         sender.send(message);
+
+         Message msg = receiver.receive(TestConfig.TIMEOUT);
+         Assert.assertEquals("sec. 3.4.9 When a message is received its JMSExpiration header field contains this same " + "value [i.e. set on return of the send method].\n",
+                             message.getJMSExpiration(),
+                             msg.getJMSExpiration());
+      }
+      catch (JMSException e)
+      {
+         fail(e);
+      }
+   }
+
+   /**
+    * Test that the <code>JMSMessageID</code> is set by the provider when the <code>send</code> method returns 
+    * and that it starts with <code>"ID:"</code>.
+    */
+   public void testJMSMessageID_2()
+   {
+      try
+      {
+         Message message = senderSession.createMessage();
+         sender.send(message);
+         Assert.assertTrue("sec. 3.4.3 When the send method returns it contains a provider-assigned value.\n",
+                           message.getJMSMessageID() != null);
+         Assert.assertTrue("sec. 3.4.3 All JMSMessageID values must start with the prefix 'ID:'.\n",
+                           message.getJMSMessageID().startsWith("ID:"));
+
+         Message msg = receiver.receive(TestConfig.TIMEOUT);
+         Assert.assertTrue("sec. 3.4.3 All JMSMessageID values must start with the prefix 'ID:'.\n",
+                           msg.getJMSMessageID().startsWith("ID:"));
+      }
+      catch (JMSException e)
+      {
+         fail(e);
+      }
+   }
+
+   /**
+    * Test that the <code>JMSMessageID</code> header field value is 
+    * ignored when the message is sent.
+    */
+   public void testJMSMessageID_1()
+   {
+      try
+      {
+         Message message = senderSession.createMessage();
+         message.setJMSMessageID("ID:foo");
+         sender.send(message);
+         Assert.assertTrue("sec. 3.4.3 When a message is sent this value is ignored.\n",
+                           message.getJMSMessageID() != "ID:foo");
+         receiver.receive(TestConfig.TIMEOUT);
+      }
+      catch (JMSException e)
+      {
+         fail(e);
+      }
+   }
+
+   /**
+    * Test that the <code>JMSDeliveryMode</code> header field value is ignored
+    * when the message is sent and that it holds the value specified by the sending 
+    * method (i.e. <code>Message.DEFAULT_DELIVERY_MODE</code> in this test when the message is received.
+    */
+   public void testJMSDeliveryMode()
+   {
+      try
+      {
+         // sender has been created with the DEFAULT_DELIVERY_MODE which is PERSISTENT
+         Assert.assertEquals(DeliveryMode.PERSISTENT, sender.getDeliveryMode());
+         Message message = senderSession.createMessage();
+         // send a message specfiying NON_PERSISTENT for the JMSDeliveryMode header field
+         message.setJMSDeliveryMode(DeliveryMode.NON_PERSISTENT);
+         sender.send(message);
+         Assert.assertTrue("sec. 3.4.2 When a message is sent this value is ignored",
+                           message.getJMSDeliveryMode() != DeliveryMode.NON_PERSISTENT);
+         Assert.assertEquals("sec. 3.4.2 After completion of the send it holds the delivery mode specified " + "by the sending method (persistent by default).\n",
+                             Message.DEFAULT_DELIVERY_MODE,
+                             message.getJMSDeliveryMode());
+
+         receiver.receive(TestConfig.TIMEOUT);
+      }
+      catch (JMSException e)
+      {
+         fail(e);
+      }
+   }
+
+   /**
+    * Test that the <code>JMSDestination</code> header field value is ignored when the message
+    * is sent and that after completion of the sending method, it holds the <code>Destination</code>
+    * specified by the sending method.
+    * Also test that the value of the header on the received message is the same that on the sent message.
+    */
+   public void testJMSDestination()
+   {
+      try
+      {
+         admin.createQueue("anotherQueue");
+         Context ctx = admin.createContext();
+         Queue anotherQueue = (Queue)ctx.lookup("anotherQueue");
+         Assert.assertTrue(anotherQueue != senderQueue);
+
+         // set the JMSDestination header field to the anotherQueue Destination
+         Message message = senderSession.createMessage();
+         message.setJMSDestination(anotherQueue);
+         sender.send(message);
+         Assert.assertTrue("sec. 3.4.1 When a message is sent this value is ignored.\n",
+                           message.getJMSDestination() != anotherQueue);
+         Assert.assertEquals("sec. 3.4.1 After completion of the send it holds the destination object specified " + "by the sending method.\n",
+                             senderQueue,
+                             message.getJMSDestination());
+
+         Message msg = receiver.receive(TestConfig.TIMEOUT);
+         Assert.assertEquals("sec. 3.4.1 When a message is received, its destination value must be equivalent  " + " to the value assigned when it was sent.\n",
+                             ((Queue)message.getJMSDestination()).getQueueName(),
+                             ((Queue)msg.getJMSDestination()).getQueueName());
+
+         admin.deleteQueue("anotherQueue");
+      }
+      catch (JMSException e)
+      {
+         fail(e);
+      }
+      catch (NamingException e)
+      {
+         Assert.fail(e.getMessage());
+      }
+   }
+
+   /**
+    * Test that a <code>Destination</code> set by the <code>setJMSReplyTo()</code>
+    * method on a sended message corresponds to the <code>Destination</code> get by 
+    * the </code>getJMSReplyTo()</code> method.
+    */
+   public void testJMSReplyTo_1()
+   {
+      try
+      {
+         Message message = senderSession.createMessage();
+         message.setJMSReplyTo(senderQueue);
+         sender.send(message);
+
+         Message msg = receiver.receive(TestConfig.TIMEOUT);
+         Destination dest = msg.getJMSReplyTo();
+         Assert.assertTrue("JMS ReplyTo header field should be a Queue", dest instanceof Queue);
+         Queue replyTo = (Queue)dest;
+         Assert.assertEquals("JMS ReplyTo header field should be equals to the sender queue",
+                             replyTo.getQueueName(),
+                             senderQueue.getQueueName());
+      }
+      catch (JMSException e)
+      {
+         fail(e);
+      }
+   }
+
+   /** 
+    * Test that if the JMS ReplyTo header field has been set as a <code>TemporaryQueue</code>,
+    * it will be rightly get also as a <code>TemporaryQueue</code> 
+    * (and not only as a <code>Queue</code>).
+    */
+   public void testJMSReplyTo_2()
+   {
+      try
+      {
+         TemporaryQueue tempQueue = senderSession.createTemporaryQueue();
+         Message message = senderSession.createMessage();
+         message.setJMSReplyTo(tempQueue);
+         sender.send(message);
+
+         Message msg = receiver.receive(TestConfig.TIMEOUT);
+         Destination dest = msg.getJMSReplyTo();
+         Assert.assertTrue("JMS ReplyTo header field should be a TemporaryQueue", dest instanceof TemporaryQueue);
+         Queue replyTo = (Queue)dest;
+         Assert.assertEquals("JMS ReplyTo header field should be equals to the temporary queue",
+                             replyTo.getQueueName(),
+                             tempQueue.getQueueName());
+      }
+      catch (JMSException e)
+      {
+         fail(e);
+      }
+   }
+
+   /** 
+    * Method to use this class in a Test suite
+    */
+   public static Test suite()
+   {
+      return new TestSuite(MessageHeaderTest.class);
+   }
+
+   public MessageHeaderTest(final String name)
+   {
+      super(name);
+   }
+}
diff --git a/activemq-tooling/activemq-joram-jms-tests/src/main/java/org/objectweb/jtests/jms/conform/message/headers/package.html b/activemq-tooling/activemq-joram-jms-tests/src/main/java/org/objectweb/jtests/jms/conform/message/headers/package.html
new file mode 100644
index 0000000..73b1d8e
--- /dev/null
+++ b/activemq-tooling/activemq-joram-jms-tests/src/main/java/org/objectweb/jtests/jms/conform/message/headers/package.html
@@ -0,0 +1,19 @@
+<!--
+    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.
+-->
+  <body>
+    Tests JMS <em>Message Header Fields</em> features.
+  </body>
diff --git a/activemq-tooling/activemq-joram-jms-tests/src/main/java/org/objectweb/jtests/jms/conform/message/package.html b/activemq-tooling/activemq-joram-jms-tests/src/main/java/org/objectweb/jtests/jms/conform/message/package.html
new file mode 100644
index 0000000..3b8f515
--- /dev/null
+++ b/activemq-tooling/activemq-joram-jms-tests/src/main/java/org/objectweb/jtests/jms/conform/message/package.html
@@ -0,0 +1,19 @@
+<!--
+    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.
+--> 
+  <body>
+    Tests JMS <em>Message</em> features.
+  </body>
diff --git a/activemq-tooling/activemq-joram-jms-tests/src/main/java/org/objectweb/jtests/jms/conform/message/properties/JMSXPropertyTest.java b/activemq-tooling/activemq-joram-jms-tests/src/main/java/org/objectweb/jtests/jms/conform/message/properties/JMSXPropertyTest.java
new file mode 100644
index 0000000..b0a8577
--- /dev/null
+++ b/activemq-tooling/activemq-joram-jms-tests/src/main/java/org/objectweb/jtests/jms/conform/message/properties/JMSXPropertyTest.java
@@ -0,0 +1,201 @@
+/*
+ * Copyright 2009 Red Hat, Inc.
+ * Red Hat 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.
+ */
+
+package org.objectweb.jtests.jms.conform.message.properties;
+
+import java.util.Enumeration;
+
+import javax.jms.ConnectionMetaData;
+import javax.jms.JMSException;
+import javax.jms.Message;
+import javax.jms.TextMessage;
+
+import junit.framework.Assert;
+import junit.framework.Test;
+import junit.framework.TestSuite;
+
+import org.objectweb.jtests.jms.framework.PTPTestCase;
+import org.objectweb.jtests.jms.framework.TestConfig;
+
+/**
+ * Test the JMSX defined properties.
+ * <br />
+ *  See JMS Specification, sec. 3.5.9 JMS Defined Properties
+ *
+ * @author Jeff Mesnil (jmesnil@gmail.com)
+ * @version $Id: JMSXPropertyTest.java,v 1.2 2007/06/19 23:32:34 csuconic Exp $
+ */
+public class JMSXPropertyTest extends PTPTestCase
+{
+
+   /**
+    * Test that the JMSX property <code>JMSXGroupID</code> is supported.
+    */
+   public void testSupportsJMSXGroupID()
+   {
+      try
+      {
+         boolean found = false;
+         ConnectionMetaData metaData = senderConnection.getMetaData();
+         Enumeration enumeration = metaData.getJMSXPropertyNames();
+         while (enumeration.hasMoreElements())
+         {
+            String jmsxPropertyName = (String)enumeration.nextElement();
+            if (jmsxPropertyName.equals("JMSXGroupID"))
+            {
+               found = true;
+            }
+         }
+         Assert.assertTrue("JMSXGroupID property is not supported", found);
+      }
+      catch (JMSException e)
+      {
+         fail(e);
+      }
+   }
+
+   /**
+    * Test that the JMSX property <code>JMSXGroupID</code> works
+    */
+   public void testJMSXGroupID_1()
+   {
+      try
+      {
+         String groupID = "testSupportsJMSXGroupID_1:group";
+         TextMessage message = senderSession.createTextMessage();
+         message.setStringProperty("JMSXGroupID", groupID);
+         message.setText("testSupportsJMSXGroupID_1");
+         sender.send(message);
+
+         Message m = receiver.receive(TestConfig.TIMEOUT);
+         Assert.assertTrue(m instanceof TextMessage);
+         TextMessage msg = (TextMessage)m;
+         Assert.assertEquals(groupID, msg.getStringProperty("JMSXGroupID"));
+         Assert.assertEquals("testSupportsJMSXGroupID_1", msg.getText());
+      }
+      catch (JMSException e)
+      {
+         fail(e);
+      }
+   }
+
+   /**
+    * Test that the JMSX property <code>JMSXDeliveryCount</code> works.
+    */
+   public void testJMSXDeliveryCount() throws Exception
+   {
+      if (!supportsJMSXDeliveryCount())
+      {
+         return;
+      }
+
+      try
+      {
+         senderConnection.stop();
+         // senderSession has been created as non transacted
+         // we create it again but as a transacted session
+         senderSession = senderConnection.createQueueSession(true, 0);
+         Assert.assertEquals(true, senderSession.getTransacted());
+         // we create again the sender
+         sender = senderSession.createSender(senderQueue);
+         senderConnection.start();
+
+         receiverConnection.stop();
+         // receiverSession has been created as non transacted
+         // we create it again but as a transacted session
+         receiverSession = receiverConnection.createQueueSession(true, 0);
+         Assert.assertEquals(true, receiverSession.getTransacted());
+         // we create again the receiver
+         if (receiver != null)
+         {
+            receiver.close();
+         }
+         receiver = receiverSession.createReceiver(receiverQueue);
+         receiverConnection.start();
+
+         // we send a message...
+         TextMessage message = senderSession.createTextMessage();
+         message.setText("testJMSXDeliveryCount");
+         sender.send(message);
+         // ... and commit the *producer* transaction
+         senderSession.commit();
+
+         // we receive a message...
+         Message m = receiver.receive(TestConfig.TIMEOUT);
+         Assert.assertTrue(m != null);
+         Assert.assertTrue(m instanceof TextMessage);
+         TextMessage msg = (TextMessage)m;
+         // ... which is the one which was sent...
+         Assert.assertEquals("testJMSXDeliveryCount", msg.getText());
+         // ...and has not been redelivered
+         Assert.assertEquals(false, msg.getJMSRedelivered());
+         // ... so it has been delivered once
+         int jmsxDeliveryCount = msg.getIntProperty("JMSXDeliveryCount");
+         Assert.assertEquals(1, jmsxDeliveryCount);
+         // we rollback the *consumer* transaction
+         receiverSession.rollback();
+
+         // we receive again a message
+         m = receiver.receive(TestConfig.TIMEOUT);
+         Assert.assertTrue(m != null);
+         Assert.assertTrue(m instanceof TextMessage);
+         msg = (TextMessage)m;
+         // ... which is still the one which was sent...
+         Assert.assertEquals("testJMSXDeliveryCount", msg.getText());
+         // .. but this time, it has been redelivered
+         Assert.assertEquals(true, msg.getJMSRedelivered());
+         // ... so it has been delivered a second time
+         jmsxDeliveryCount = msg.getIntProperty("JMSXDeliveryCount");
+         Assert.assertEquals(2, jmsxDeliveryCount);
+      }
+      catch (JMSException e)
+      {
+         fail(e);
+      }
+      catch (Exception e)
+      {
+         fail(e);
+      }
+   }
+
+   /**
+    * checks if the JMSX property <code>JMSXDeliveryCount</code> is supported.
+    */
+   private boolean supportsJMSXDeliveryCount() throws Exception
+   {
+      ConnectionMetaData metaData = senderConnection.getMetaData();
+      Enumeration enumeration = metaData.getJMSXPropertyNames();
+      while (enumeration.hasMoreElements())
+      {
+         String jmsxPropertyName = (String)enumeration.nextElement();
+         if (jmsxPropertyName.equals("JMSXDeliveryCount"))
+         {
+            return true;
+         }
+      }
+      return false;
+   }
+
+   /** 
+    * Method to use this class in a Test suite
+    */
+   public static Test suite()
+   {
+      return new TestSuite(JMSXPropertyTest.class);
+   }
+
+   public JMSXPropertyTest(final String name)
+   {
+      super(name);
+   }
+}
diff --git a/activemq-tooling/activemq-joram-jms-tests/src/main/java/org/objectweb/jtests/jms/conform/message/properties/MessagePropertyConversionTest.java b/activemq-tooling/activemq-joram-jms-tests/src/main/java/org/objectweb/jtests/jms/conform/message/properties/MessagePropertyConversionTest.java
new file mode 100644
index 0000000..0b39d4c
--- /dev/null
+++ b/activemq-tooling/activemq-joram-jms-tests/src/main/java/org/objectweb/jtests/jms/conform/message/properties/MessagePropertyConversionTest.java
@@ -0,0 +1,1561 @@
+/*
+ * Copyright 2009 Red Hat, Inc.
+ * Red Hat 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.
+ */
+
+package org.objectweb.jtests.jms.conform.message.properties;
+
+import javax.jms.JMSException;
+import javax.jms.Message;
+import javax.jms.MessageFormatException;
+
+import junit.framework.Assert;
+import junit.framework.Test;
+import junit.framework.TestSuite;
+
+import org.objectweb.jtests.jms.framework.PTPTestCase;
+
+/**
+ * Test the conversion of primitive types for the <code>javax.jms.Message</code> properties.
+ * <br />
+ * See JMS Specification, sec. 3.5.4 Property Value Conversion and the corresponding table (p.33-34).
+ * <br />
+ * The method name <code>testXXX2YYY</code> means that we test if a property
+ * which has been set as a <code>XXX</code> type can be read as a <code>YYY</code> type, 
+ * where <code>XXX</code> and <code>YYY</code> can be <code>boolean, byte, short, long, float
+ * double</code> or <code>String</code>.
+ *
+ * <pre>
+ *          ---------------------------------------------------------------|
+ *          | boolean | byte | short | int | long | float | double | String| 
+ * |-----------------------------------------------------------------------|
+ * |boolean |    X                                                     X   |
+ * |byte    |            X       X      X     X                        X   |
+ * |short   |                    X      X     X                        X   |
+ * |int     |                           X     X                        X   |
+ * |long    |                                 X                        X   |
+ * |float   |                                         X       X        X   |
+ * |double  |                                                 X        X   |
+ * |String  |    Y       Y       Y      Y     Y       Y       Y        X   |
+ * |-----------------------------------------------------------------------|
+ * </pre>
+ * A value set as the row type can be read as the column type.
+ * <br />
+ * The unmarked cases must throw a <code>javax.jms.MessageFormatException</code>
+ * <br />
+ * The cases marked with a Y should throw a <code>java.lang.MessageFormatException</code> <strong>if</strong> the
+ * String is not a correct representation of the column type (otherwise, it returns the property). 
+ *
+ * @author Jeff Mesnil (jmesnil@gmail.com)
+ * @version $Id: MessagePropertyConversionTest.java,v 1.1 2007/03/29 04:28:34 starksm Exp $
+ */
+public class MessagePropertyConversionTest extends PTPTestCase
+{
+
+   /**
+    * if a property is set as a <code>java.lang.String</code>, 
+    * it can also be read as a <code>java.lang.String</code>.
+    */
+   public void testString2String()
+   {
+      try
+      {
+         Message message = senderSession.createMessage();
+         message.setStringProperty("pi", "3.14159");
+         Assert.assertEquals("3.14159", message.getStringProperty("pi"));
+      }
+      catch (JMSException e)
+      {
+         fail(e);
+      }
+   }
+
+   /**
+    * if a property is set as a <code>java.lang.String</code>, 
+    * to get it as a <code>double</code> throws a <code>java.lang.NuberFormatException</code>
+    * if the <code>String</code> is not a correct representation for a <code>double</code> 
+    * (e.g. <code>"not a number"</code>).
+    */
+   public void testString2Double_2()
+   {
+      try
+      {
+         Message message = senderSession.createMessage();
+         message.setStringProperty("pi", "not_a_number");
+         message.getDoubleProperty("pi");
+         Assert.fail("sec. 3.5.4 The String to numeric conversions must throw the java.lang.NumberFormatException " + " if the numeric's valueOf() method does not accept the String value as a valid representation.\n");
+      }
+      catch (java.lang.NumberFormatException e)
+      {
+      }
+      catch (JMSException e)
+      {
+         fail(e);
+      }
+   }
+
+   /**
+    * if a property is set as a <code>java.lang.String</code>, 
+    * it can also be read as a <code>double</code> as long as the <code>String</code>
+    * is a correct representation of a <code>double</code> (e.g. <code>"3.14159"</code>).
+    */
+   public void testString2Double_1()
+   {
+      try
+      {
+         Message message = senderSession.createMessage();
+         message.setStringProperty("pi", "3.14159");
+         Assert.assertEquals(3.14159, message.getDoubleProperty("pi"), 0);
+      }
+      catch (JMSException e)
+      {
+         fail(e);
+      }
+   }
+
+   /**
+    * if a property is set as a <code>java.lang.String</code>, 
+    * to get it as a <code>float</code> throws a <code>java.lang.NuberFormatException</code>
+    * if the <code>String</code> is not a correct representation for a <code>float</code> 
+    * (e.g. <code>"not_a_number"</code>).
+    */
+   public void testString2Float_2()
+   {
+      try
+      {
+         Message message = senderSession.createMessage();
+         message.setStringProperty("pi", "not_a_number");
+         message.getFloatProperty("pi");
+         Assert.fail("sec. 3.5.4 The String to numeric conversions must throw the java.lang.NumberFormatException " + " if the numeric's valueOf() method does not accept the String value as a valid representation.\n");
+      }
+      catch (java.lang.NumberFormatException e)
+      {
+      }
+      catch (JMSException e)
+      {
+         fail(e);
+      }
+   }
+
+   /**
+    * if a property is set as a <code>java.lang.String</code>, 
+    * it can also be read as a <code>float</code> as long as the <code>String</code>
+    * is a correct representation of a <code>float</code> (e.g. <code>"3.14159"</code>).
+    */
+   public void testString2Float_1()
+   {
+      try
+      {
+         Message message = senderSession.createMessage();
+         message.setStringProperty("pi", "3.14159");
+         Assert.assertEquals(3.14159F, message.getFloatProperty("pi"), 0);
+      }
+      catch (JMSException e)
+      {
+         fail(e);
+      }
+   }
+
+   /**
+    * if a property is set as a <code>java.lang.String</code>, 
+    * to get it as a <code>long</code> throws a <code>java.lang.NuberFormatException</code>
+    * if the <code>String</code> is not a correct representation for a <code>long</code> 
+    * (e.g. <code>"3.14159"</code>).
+    */
+   public void testString2Long_2()
+   {
+      try
+      {
+         Message message = senderSession.createMessage();
+         message.setStringProperty("pi", "3.14159");
+         message.getLongProperty("pi");
+         Assert.fail("sec. 3.5.4 The String to numeric conversions must throw the java.lang.NumberFormatException " + " if the numeric's valueOf() method does not accept the String value as a valid representation.\n");
+      }
+      catch (java.lang.NumberFormatException e)
+      {
+      }
+      catch (JMSException e)
+      {
+         fail(e);
+      }
+   }
+
+   /**
+    * if a property is set as a <code>java.lang.String</code>, 
+    * it can also be read as a <code>long</code> as long as the <code>String</code>
+    * is a correct representation of a <code>long</code> (e.g. <code>"0"</code>).
+    */
+   public void testString2Long_1()
+   {
+      try
+      {
+         Message message = senderSession.createMessage();
+         message.setStringProperty("prop", "0");
+         Assert.assertEquals(0l, message.getLongProperty("prop"));
+      }
+      catch (JMSException e)
+      {
+         fail(e);
+      }
+   }
+
+   /**
+    * if a property is set as a <code>java.lang.String</code>, 
+    * to get it as a <code>int</code> throws a <code>java.lang.NuberFormatException</code>
+    * if the <code>String</code> is not a correct representation for a <code>int</code> 
+    * (e.g. <code>"3.14159"</code>).
+    */
+   public void testString2Int_2()
+   {
+      try
+      {
+         Message message = senderSession.createMessage();
+         message.setStringProperty("pi", "3.14159");
+         message.getIntProperty("pi");
+         Assert.fail("sec. 3.5.4 The String to numeric conversions must throw the java.lang.NumberFormatException " + " if the numeric's valueOf() method does not accept the String value as a valid representation.\n");
+      }
+      catch (java.lang.NumberFormatException e)
+      {
+      }
+      catch (JMSException e)
+      {
+         fail(e);
+      }
+   }
+
+   /**
+    * if a property is set as a <code>java.lang.String</code>, 
+    * it can also be read as a <code>int</code> as long as the <code>String</code>
+    * is a correct representation of a <code>int</code> (e.g. <code>"0"</code>).
+    */
+   public void testString2Int_1()
+   {
+      try
+      {
+         Message message = senderSession.createMessage();
+         message.setStringProperty("prop", "0");
+         Assert.assertEquals(0, message.getIntProperty("prop"));
+      }
+      catch (JMSException e)
+      {
+         fail(e);
+      }
+   }
+
+   /**
+    * if a property is set as a <code>java.lang.String</code>, 
+    * to get it as a <code>short</code> throws a <code>java.lang.NuberFormatException</code>
+    * if the <code>String</code> is not a correct representation for a <code>short</code> 
+    * (e.g. <code>"3.14159"</code>).
+    */
+   public void testString2Short_2()
+   {
+      try
+      {
+         Message message = senderSession.createMessage();
+         message.setStringProperty("pi", "3.14159");
+         message.getShortProperty("pi");
+         Assert.fail("sec. 3.5.4 The String to numeric conversions must throw the java.lang.NumberFormatException " + " if the numeric's valueOf() method does not accept the String value as a valid representation.\n");
+      }
+      catch (java.lang.NumberFormatException e)
+      {
+      }
+      catch (JMSException e)
+      {
+         fail(e);
+      }
+   }
+
+   /**
+    * if a property is set as a <code>java.lang.String</code>, 
+    * it can also be read as a <code>short</code> as long as the <code>String</code>
+    * is a correct representation of a <code>short</code> (e.g. <code>"0"</code>).
+    */
+   public void testString2Short_1()
+   {
+      try
+      {
+         Message message = senderSession.createMessage();
+         message.setStringProperty("prop", "0");
+         Assert.assertEquals((short)0, message.getShortProperty("prop"));
+      }
+      catch (JMSException e)
+      {
+         fail(e);
+      }
+   }
+
+   /**
+    * if a property is set as a <code>java.lang.String</code>, 
+    * to get it as a <code>byte</code> throws a <code>java.lang.NuberFormatException</code>
+    * if the <code>String</code> is not a correct representation for a <code>byte</code> 
+    * (e.g. <code>"3.14159"</code>).
+    */
+   public void testString2Byte_2()
+   {
+      try
+      {
+         Message message = senderSession.createMessage();
+         message.setStringProperty("pi", "3.14159");
+         message.getByteProperty("pi");
+         Assert.fail("sec. 3.5.4 The String to numeric conversions must throw the java.lang.NumberFormatException " + " if the numeric's valueOf() method does not accept the String value as a valid representation.\n");
+      }
+      catch (java.lang.NumberFormatException e)
+      {
+      }
+      catch (JMSException e)
+      {
+         fail(e);
+      }
+   }
+
+   /**
+    * if a property is set as a <code>java.lang.String</code>, 
+    * it can also be read as a <code>byte</code> if the <code>String</code>
+    * is a correct representation of a <code>byte</code> (e.g. <code>"0"</code>).
+    */
+   public void testString2Byte_1()
+   {
+      try
+      {
+         Message message = senderSession.createMessage();
+         message.setStringProperty("prop", "0");
+         Assert.assertEquals((byte)0, message.getByteProperty("prop"));
+      }
+      catch (JMSException e)
+      {
+         fail(e);
+      }
+   }
+
+   /**
+    * if a property is set as a <code>java.lang.String</code>, 
+    * to get it as a <code>boolean</code> returns <code>true</code> if the property is not 
+    * null and is equal, ignoring case, to the string "true" (.eg. "True" is ok), else it
+    * returns <code>false</code> (e.g. "test")
+    */
+   public void testString2Boolean_2()
+   {
+      try
+      {
+         Message message = senderSession.createMessage();
+         message.setStringProperty("prop", "test");
+         Assert.assertEquals(false, message.getBooleanProperty("prop"));
+      }
+      catch (MessageFormatException e)
+      {
+      }
+      catch (JMSException e)
+      {
+         fail(e);
+      }
+   }
+
+   /**
+    * if a property is set as a <code>java.lang.String</code>, 
+    * it can also be read as a <code>boolean</code> if the <code>String</code>
+    * is a correct representation of a <code>boolean</code> (e.g. <code>"true"</code>).
+    */
+   public void testString2Boolean_1()
+   {
+      try
+      {
+         Message message = senderSession.createMessage();
+         message.setStringProperty("prop", "true");
+         Assert.assertEquals(true, message.getBooleanProperty("prop"));
+      }
+      catch (JMSException e)
+      {
+         fail(e);
+      }
+   }
+
+   /**
+    * if a property is set as a <code>double</code>, 
+    * it can also be read as a <code>java.lang.String</code>.
+    */
+   public void testDouble2String()
+   {
+      try
+      {
+         Message message = senderSession.createMessage();
+         message.setDoubleProperty("prop", 127.0);
+         Assert.assertEquals("127.0", message.getStringProperty("prop"));
+      }
+      catch (JMSException e)
+      {
+         fail(e);
+      }
+   }
+
+   /**
+    * if a property is set as a <code>double</code>, 
+    * it can also be read as a <code>double</code>.
+    */
+   public void testDouble2Double()
+   {
+      try
+      {
+         Message message = senderSession.createMessage();
+         message.setDoubleProperty("prop", 127.0);
+         Assert.assertEquals(127.0, message.getDoubleProperty("prop"), 0);
+      }
+      catch (JMSException e)
+      {
+         fail(e);
+      }
+   }
+
+   /**
+    * if a property is set as a <code>double</code>, 
+    * to get is as a <code>float</code> throws a <code>javax.jms.MessageFormatException</code>.
+    */
+   public void testDouble2Float()
+   {
+      try
+      {
+         Message message = senderSession.createMessage();
+         message.setDoubleProperty("prop", 127.0);
+         message.getFloatProperty("prop");
+         Assert.fail("sec. 3.5.4 The unmarked cases [of Table 0-4] should raise a JMS MessageFormatException.\n");
+      }
+      catch (MessageFormatException e)
+      {
+      }
+      catch (JMSException e)
+      {
+         fail(e);
+      }
+   }
+
+   /**
+    * if a property is set as a <code>double</code>, 
+    * to get is as a <code>long</code> throws a <code>javax.jms.MessageFormatException</code>.
+    */
+   public void testDouble2Long()
+   {
+      try
+      {
+         Message message = senderSession.createMessage();
+         message.setDoubleProperty("prop", 127.0);
+         message.getLongProperty("prop");
+         Assert.fail("sec. 3.5.4 The unmarked cases [of Table 0-4] should raise a JMS MessageFormatException.\n");
+      }
+      catch (MessageFormatException e)
+      {
+      }
+      catch (JMSException e)
+      {
+         fail(e);
+      }
+   }
+
+   /**
+    * if a property is set as a <code>double</code>, 
+    * to get is as an <code>int</code> throws a <code>javax.jms.MessageFormatException</code>.
+    */
+   public void testDouble2Int()
+   {
+      try
+      {
+         Message message = senderSession.createMessage();
+         message.setDoubleProperty("prop", 127.0);
+         message.getIntProperty("prop");
+         Assert.fail("sec. 3.5.4 The unmarked cases [of Table 0-4] should raise a JMS MessageFormatException.\n");
+      }
+      catch (MessageFormatException e)
+      {
+      }
+      catch (JMSException e)
+      {
+         fail(e);
+      }
+   }
+
+   /**
+    * if a property is set as a <code>double</code>, 
+    * to get is as a <code>short</code> throws a <code>javax.jms.MessageFormatException</code>.
+    */
+   public void testDouble2Short()
+   {
+      try
+      {
+         Message message = senderSession.createMessage();
+         // store a value that can't be converted to short
+         message.setDoubleProperty("prop", 127.0);
+         message.getShortProperty("prop");
+         Assert.fail("sec. 3.5.4 The unmarked cases [of Table 0-4] should raise a JMS MessageFormatException.\n");
+      }
+      catch (MessageFormatException e)
+      {
+      }
+      catch (JMSException e)
+      {
+         fail(e);
+      }
+   }
+
+   /**
+    * if a property is set as a <code>double</code>, 
+    * to get is as a <code>byte</code> throws a <code>javax.jms.MessageFormatException</code>.
+    */
+   public void testDouble2Byte()
+   {
+      try
+      {
+         Message message = senderSession.createMessage();
+         // store a value that can't be converted to byte
+         message.setDoubleProperty("prop", 127.0);
+         message.getByteProperty("prop");
+         Assert.fail("sec. 3.5.4 The unmarked cases [of Table 0-4] should raise a JMS MessageFormatException.\n");
+      }
+      catch (MessageFormatException e)
+      {
+      }
+      catch (JMSException e)
+      {
+         fail(e);
+      }
+   }
+
+   /**
+    * if a property is set as a <code>double</code>, 
+    * to get is as a <code>boolean</code> throws a <code>javax.jms.MessageFormatException</code>.
+    */
+   public void testDouble2Boolean()
+   {
+      try
+      {
+         Message message = senderSession.createMessage();
+         // store a value that can be converted to boolean
+         message.setDoubleProperty("prop", 127.0);
+         message.getBooleanProperty("prop");
+         Assert.fail("sec. 3.5.4 The unmarked cases [of Table 0-4] should raise a JMS MessageFormatException.\n");
+      }
+      catch (MessageFormatException e)
+      {
+      }
+      catch (JMSException e)
+      {
+         fail(e);
+      }
+   }
+
+   /**
+    * if a property is set as a <code>float</code>, 
+    * it can also be read as a <code>String</code>.
+    */
+   public void testFloat2String()
+   {
+      try
+      {
+         Message message = senderSession.createMessage();
+         message.setFloatProperty("prop", 127.0F);
+         Assert.assertEquals("127.0", message.getStringProperty("prop"));
+      }
+      catch (JMSException e)
+      {
+         fail(e);
+      }
+   }
+
+   /**
+    * if a property is set as a <code>float</code>, 
+    * it can also be read as a <code>double</code>.
+    */
+   public void testFloat2Double()
+   {
+      try
+      {
+         Message message = senderSession.createMessage();
+         message.setFloatProperty("prop", 127.0F);
+         Assert.assertEquals(127.0, message.getDoubleProperty("prop"), 0);
+      }
+      catch (JMSException e)
+      {
+         fail(e);
+      }
+   }
+
+   /**
+    * if a property is set as a <code>float</code>, 
+    * it can also be read as a <code>float</code>.
+    */
+   public void testFloat2Float()
+   {
+      try
+      {
+         Message message = senderSession.createMessage();
+         message.setFloatProperty("prop", 127.0F);
+         Assert.assertEquals(127.0F, message.getFloatProperty("prop"), 0);
+      }
+      catch (JMSException e)
+      {
+         fail(e);
+      }
+   }
+
+   /**
+    * if a property is set as a <code>float</code>, 
+    * to get is as a <code>long</code> throws a <code>javax.jms.MessageFormatException</code>.
+    */
+   public void testFloat2Long()
+   {
+      try
+      {
+         Message message = senderSession.createMessage();
+         message.setFloatProperty("prop", 127.0F);
+         message.getLongProperty("prop");
+         Assert.fail("sec. 3.5.4 The unmarked cases [of Table 0-4] should raise a JMS MessageFormatException.\n");
+      }
+      catch (MessageFormatException e)
+      {
+      }
+      catch (JMSException e)
+      {
+         fail(e);
+      }
+   }
+
+   /**
+    * if a property is set as a <code>float</code>, 
+    * to get is as a <code>int</code> throws a <code>javax.jms.MessageFormatException</code>.
+    */
+   public void testFloat2Int()
+   {
+      try
+      {
+         Message message = senderSession.createMessage();
+         message.setFloatProperty("prop", 127.0F);
+         message.getIntProperty("prop");
+         Assert.fail("sec. 3.5.4 The unmarked cases [of Table 0-4] should raise a JMS MessageFormatException.\n");
+      }
+      catch (MessageFormatException e)
+      {
+      }
+      catch (JMSException e)
+      {
+         fail(e);
+      }
+   }
+
+   /**
+    * if a property is set as a <code>float</code>, 
+    * to get is as a <code>short</code> throws a <code>javax.jms.MessageFormatException</code>.
+    */
+   public void testFloat2Short()
+   {
+      try
+      {
+         Message message = senderSession.createMessage();
+         // store a value that can't be converted to short
+         message.setFloatProperty("prop", 127.0F);
+         message.getShortProperty("prop");
+         Assert.fail("sec. 3.5.4 The unmarked cases [of Table 0-4] should raise a JMS MessageFormatException.\n");
+      }
+      catch (MessageFormatException e)
+      {
+      }
+      catch (JMSException e)
+      {
+         fail(e);
+      }
+   }
+
+   /**
+    * if a property is set as a <code>float</code>, 
+    * to get is as a <code>byte</code> throws a <code>javax.jms.MessageFormatException</code>.
+    */
+   public void testFloat2Byte()
+   {
+      try
+      {
+         Message message = senderSession.createMessage();
+         // store a value that can't be converted to byte
+         message.setFloatProperty("prop", 127.0F);
+         message.getByteProperty("prop");
+         Assert.fail("sec. 3.5.4 The unmarked cases [of Table 0-4] should raise a JMS MessageFormatException.\n");
+      }
+      catch (MessageFormatException e)
+      {
+      }
+      catch (JMSException e)
+      {
+         fail(e);
+      }
+   }
+
+   /**
+    * if a property is set as a <code>float</code>, 
+    * to get is as a <code>boolean</code> throws a <code>javax.jms.MessageFormatException</code>.
+    */
+   public void testFloat2Boolean()
+   {
+      try
+      {
+         Message message = senderSession.createMessage();
+         // store a value that can be converted to boolean
+         message.setFloatProperty("prop", 127.0F);
+         message.getBooleanProperty("prop");
+         Assert.fail("sec. 3.5.4 The unmarked cases [of Table 0-4] should raise a JMS MessageFormatException.\n");
+      }
+      catch (MessageFormatException e)
+      {
+      }
+      catch (JMSException e)
+      {
+         fail(e);
+      }
+   }
+
+   /**
+    * if a property is set as a <code>long</code>, 
+    * it can also be read as a <code>String</code>.
+    */
+   public void testLong2String()
+   {
+      try
+      {
+         Message message = senderSession.createMessage();
+         message.setLongProperty("prop", 127L);
+         Assert.assertEquals("127", message.getStringProperty("prop"));
+      }
+      catch (JMSException e)
+      {
+         fail(e);
+      }
+   }
+
+   /**
+    * if a property is set as a <code>long</code>, 
+    * to get is as a <code>double</code> throws a <code>javax.jms.MessageFormatException</code>.
+    */
+   public void testLong2Double()
+   {
+      try
+      {
+         Message message = senderSession.createMessage();
+         message.setLongProperty("prop", 127L);
+         message.getDoubleProperty("prop");
+         Assert.fail("sec. 3.5.4 The unmarked cases [of Table 0-4] should raise a JMS MessageFormatException.\n");
+      }
+      catch (MessageFormatException e)
+      {
+      }
+      catch (JMSException e)
+      {
+         fail(e);
+      }
+   }
+
+   /**
+    * if a property is set as a <code>long</code>, 
+    * to get is as a <code>float</code> throws a <code>javax.jms.MessageFormatException</code>.
+    */
+   public void testLong2Float()
+   {
+      try
+      {
+         Message message = senderSession.createMessage();
+         message.setLongProperty("prop", 127L);
+         message.getFloatProperty("prop");
+         Assert.fail("sec. 3.5.4 The unmarked cases [of Table 0-4] should raise a JMS MessageFormatException.\n");
+      }
+      catch (MessageFormatException e)
+      {
+      }
+      catch (JMSException e)
+      {
+         fail(e);
+      }
+   }
+
+   /**
+    * if a property is set as a <code>long</code>, 
+    * it can also be read as a <code>long</code>.
+    */
+   public void testLong2Long()
+   {
+      try
+      {
+         Message message = senderSession.createMessage();
+         message.setLongProperty("prop", 127L);
+         Assert.assertEquals(127L, message.getLongProperty("prop"));
+      }
+      catch (JMSException e)
+      {
+         fail(e);
+      }
+   }
+
+   /**
+    * if a property is set as a <code>long</code>, 
+    * to get is as an <code>int</code> throws a <code>javax.jms.MessageFormatException</code>.
+    */
+   public void testLong2Int()
+   {
+      try
+      {
+         Message message = senderSession.createMessage();
+         message.setLongProperty("prop", 127L);
+         message.getIntProperty("prop");
+         Assert.fail("sec. 3.5.4 The unmarked cases [of Table 0-4] should raise a JMS MessageFormatException.\n");
+      }
+      catch (MessageFormatException e)
+      {
+      }
+      catch (JMSException e)
+      {
+         fail(e);
+      }
+   }
+
+   /**
+    * if a property is set as a <code>long</code>, 
+    * to get is as a <code>short</code> throws a <code>javax.jms.MessageFormatException</code>.
+    */
+   public void testLong2Short()
+   {
+      try
+      {
+         Message message = senderSession.createMessage();
+         // store a value that can't be converted to short
+         message.setLongProperty("prop", 127L);
+         message.getShortProperty("prop");
+         Assert.fail("sec. 3.5.4 The unmarked cases [of Table 0-4] should raise a JMS MessageFormatException.\n");
+      }
+      catch (MessageFormatException e)
+      {
+      }
+      catch (JMSException e)
+      {
+         fail(e);
+      }
+   }
+
+   /**
+    * if a property is set as a <code>long</code>, 
+    * to get is as a <code>byte</code> throws a <code>javax.jms.MessageFormatException</code>.
+    */
+   public void testLong2Byte()
+   {
+      try
+      {
+         Message message = senderSession.createMessage();
+         // store a value that can't be converted to byte
+         message.setLongProperty("prop", 127L);
+         message.getByteProperty("prop");
+         Assert.fail("sec. 3.5.4 The unmarked cases [of Table 0-4] should raise a JMS MessageFormatException.\n");
+      }
+      catch (MessageFormatException e)
+      {
+      }
+      catch (JMSException e)
+      {
+         fail(e);
+      }
+   }
+
+   /**
+    * if a property is set as a <code>long</code>, 
+    * to get is as a <code>boolean</code> throws a <code>javax.jms.MessageFormatException</code>.
+    */
+   public void testLong2Boolean()
+   {
+      try
+      {
+         Message message = senderSession.createMessage();
+         // store a value that can be converted to boolean
+         message.setLongProperty("prop", 127L);
+         message.getBooleanProperty("prop");
+         Assert.fail("sec. 3.5.4 The unmarked cases [of Table 0-4] should raise a JMS MessageFormatException.\n");
+      }
+      catch (MessageFormatException e)
+      {
+      }
+      catch (JMSException e)
+      {
+         fail(e);
+      }
+   }
+
+   /**
+    * if a property is set as an <code>int</code>, 
+    * it can also be read as a <code>String</code>.
+    */
+   public void testInt2String()
+   {
+      try
+      {
+         Message message = senderSession.createMessage();
+         message.setIntProperty("prop", 127);
+         Assert.assertEquals("127", message.getStringProperty("prop"));
+      }
+      catch (JMSException e)
+      {
+         fail(e);
+      }
+   }
+
+   /**
+    * if a property is set as a <code>int</code>, 
+    * to get is as a <code>double</code> throws a <code>javax.jms.MessageFormatException</code>.
+    */
+   public void testInt2Double()
+   {
+      try
+      {
+         Message message = senderSession.createMessage();
+         message.setIntProperty("prop", 127);
+         message.getDoubleProperty("prop");
+         Assert.fail("sec. 3.5.4 The unmarked cases [of Table 0-4] should raise a JMS MessageFormatException.\n");
+      }
+      catch (MessageFormatException e)
+      {
+      }
+      catch (JMSException e)
+      {
+         fail(e);
+      }
+   }
+
+   /**
+    * if a property is set as a <code>int</code>, 
+    * to get is as a <code>float</code> throws a <code>javax.jms.MessageFormatException</code>.
+    */
+   public void testInt2Float()
+   {
+      try
+      {
+         Message message = senderSession.createMessage();
+         message.setIntProperty("prop", 127);
+         message.getFloatProperty("prop");
+         Assert.fail("sec. 3.5.4 The unmarked cases [of Table 0-4] should raise a JMS MessageFormatException.\n");
+      }
+      catch (MessageFormatException e)
+      {
+      }
+      catch (JMSException e)
+      {
+         fail(e);
+      }
+   }
+
+   /**
+    * if a property is set as an <code>int</code>, 
+    * it can also be read as a <code>long</code>.
+    */
+   public void testInt2Long()
+   {
+      try
+      {
+         Message message = senderSession.createMessage();
+         message.setIntProperty("prop", 127);
+         Assert.assertEquals(127L, message.getLongProperty("prop"));
+      }
+      catch (JMSException e)
+      {
+         fail(e);
+      }
+   }
+
+   /**
+    * if a property is set as an <code>int</code>, 
+    * it can also be read as an <code>int</code>.
+    */
+   public void testInt2Int()
+   {
+      try
+      {
+         Message message = senderSession.createMessage();
+         message.setIntProperty("prop", 127);
+         Assert.assertEquals(127, message.getIntProperty("prop"));
+      }
+      catch (JMSException e)
+      {
+         fail(e);
+      }
+   }
+
+   /**
+    * if a property is set as a <code>int</code>, 
+    * to get is as a <code>short</code> throws a <code>javax.jms.MessageFormatException</code>.
+    */
+   public void testInt2Short()
+   {
+      try
+      {
+         Message message = senderSession.createMessage();
+         // store a value that can't be converted to short
+         message.setIntProperty("prop", Integer.MAX_VALUE);
+         message.getShortProperty("prop");
+         Assert.fail("sec. 3.5.4 The unmarked cases [of Table 0-4] should raise a JMS MessageFormatException.\n");
+      }
+      catch (MessageFormatException e)
+      {
+      }
+      catch (JMSException e)
+      {
+         fail(e);
+      }
+   }
+
+   /**
+    * if a property is set as a <code>int</code>, 
+    * to get is as a <code>byte</code> throws a <code>javax.jms.MessageFormatException</code>.
+    */
+   public void testInt2Byte()
+   {
+      try
+      {
+         Message message = senderSession.createMessage();
+         // store a value that can't be converted to byte
+         message.setIntProperty("prop", Integer.MAX_VALUE);
+         message.getByteProperty("prop");
+         Assert.fail("sec. 3.5.4 The unmarked cases [of Table 0-4] should raise a JMS MessageFormatException.\n");
+      }
+      catch (MessageFormatException e)
+      {
+      }
+      catch (JMSException e)
+      {
+         fail(e);
+      }
+   }
+
+   /**
+    * if a property is set as a <code>int</code>, 
+    * to get is as a <code>boolean</code> throws a <code>javax.jms.MessageFormatException</code>.
+    */
+   public void testInt2Boolean()
+   {
+      try
+      {
+         Message message = senderSession.createMessage();
+         // store a value that can be converted to boolean
+         message.setIntProperty("prop", Integer.MAX_VALUE);
+         message.getBooleanProperty("prop");
+         Assert.fail("sec. 3.5.4 The unmarked cases [of Table 0-4] should raise a JMS MessageFormatException.\n");
+      }
+      catch (MessageFormatException e)
+      {
+      }
+      catch (JMSException e)
+      {
+         fail(e);
+      }
+   }
+
+   /**
+    * if a property is set as a <code>short</code>, 
+    * it can also be read as a <code>String</code>.
+    */
+   public void testShort2String()
+   {
+      try
+      {
+         Message message = senderSession.createMessage();
+         message.setShortProperty("prop", (short)127);
+         Assert.assertEquals("127", message.getStringProperty("prop"));
+      }
+      catch (JMSException e)
+      {
+         fail(e);
+      }
+   }
+
+   /**
+    * if a property is set as a <code>short</code>, 
+    * to get is as a <code>double</code> throws a <code>javax.jms.MessageFormatException</code>.
+    */
+   public void testShort2Double()
+   {
+      try
+      {
+         Message message = senderSession.createMessage();
+         message.setShortProperty("prop", (short)127);
+         message.getDoubleProperty("prop");
+         Assert.fail("sec. 3.5.4 The unmarked cases [of Table 0-4] should raise a JMS MessageFormatException.\n");
+      }
+      catch (MessageFormatException e)
+      {
+      }
+      catch (JMSException e)
+      {
+         fail(e);
+      }
+   }
+
+   /**
+    * if a property is set as a <code>short</code>, 
+    * to get is as a <code>float</code> throws a <code>javax.jms.MessageFormatException</code>.
+    */
+   public void testShort2Float()
+   {
+      try
+      {
+         Message message = senderSession.createMessage();
+         message.setShortProperty("prop", (short)127);
+         message.getFloatProperty("prop");
+         Assert.fail("sec. 3.5.4 The unmarked cases [of Table 0-4] should raise a JMS MessageFormatException.\n");
+      }
+      catch (MessageFormatException e)
+      {
+      }
+      catch (JMSException e)
+      {
+         fail(e);
+      }
+   }
+
+   /**
+    * if a property is set as a <code>short</code>, 
+    * it can also be read as a <code>long</code>.
+    */
+   public void testShort2Long()
+   {
+      try
+      {
+         Message message = senderSession.createMessage();
+         message.setShortProperty("prop", (short)127);
+         Assert.assertEquals(127L, message.getLongProperty("prop"));
+      }
+      catch (JMSException e)
+      {
+         fail(e);
+      }
+   }
+
+   /**
+    * if a property is set as a <code>short</code>, 
+    * it can also be read as an <code>int</code>.
+    */
+   public void testShort2Int()
+   {
+      try
+      {
+         Message message = senderSession.createMessage();
+         message.setShortProperty("prop", (short)127);
+         Assert.assertEquals(127, message.getIntProperty("prop"));
+      }
+      catch (JMSException e)
+      {
+         fail(e);
+      }
+   }
+
+   /**
+    * if a property is set as a <code>short</code>, 
+    * it can also be read as a <code>short</code>.
+    */
+   public void testShort2Short()
+   {
+      try
+      {
+         Message message = senderSession.createMessage();
+         message.setShortProperty("prop", (short)127);
+         Assert.assertEquals((short)127, message.getShortProperty("prop"));
+      }
+      catch (JMSException e)
+      {
+         fail(e);
+      }
+   }
+
+   /**
+    * if a property is set as a <code>short</code>, 
+    * to get is as a <code>byte</code> throws a <code>javax.jms.MessageFormatException</code>.
+    */
+   public void testShort2Byte()
+   {
+      try
+      {
+         Message message = senderSession.createMessage();
+         message.setShortProperty("prop", (short)127);
+         message.getByteProperty("prop");
+         Assert.fail("sec. 3.5.4 The unmarked cases [of Table 0-4] should raise a JMS MessageFormatException.\n");
+      }
+      catch (MessageFormatException e)
+      {
+      }
+      catch (JMSException e)
+      {
+         fail(e);
+      }
+   }
+
+   /**
+    * if a property is set as a <code>short</code>, 
+    * to get is as a <code>boolean</code> throws a <code>javax.jms.MessageFormatException</code>.
+    */
+   public void testShort2Boolean()
+   {
+      try
+      {
+         Message message = senderSession.createMessage();
+         // store a value that can't be converted to boolean
+         message.setShortProperty("prop", (short)127);
+         message.getBooleanProperty("prop");
+         Assert.fail("sec. 3.5.4 The unmarked cases [of Table 0-4] should raise a JMS MessageFormatException.\n");
+      }
+      catch (MessageFormatException e)
+      {
+      }
+      catch (JMSException e)
+      {
+         fail(e);
+      }
+   }
+
+   /**
+    * if a property is set as a <code>byte</code>, 
+    * it can also be read as a <code>String</code>.
+    */
+   public void testByte2String()
+   {
+      try
+      {
+         Message message = senderSession.createMessage();
+         message.setByteProperty("prop", (byte)127);
+         Assert.assertEquals("127", message.getStringProperty("prop"));
+      }
+      catch (JMSException e)
+      {
+         fail(e);
+      }
+   }
+
+   /**
+    * if a property is set as a <code>byte</code>, 
+    * to get is as a <code>double</code> throws a <code>javax.jms.MessageFormatException</code>.
+    */
+   public void testByte2Double()
+   {
+      try
+      {
+         Message message = senderSession.createMessage();
+         message.setByteProperty("prop", (byte)127);
+         message.getDoubleProperty("prop");
+         Assert.fail("sec. 3.5.4 The unmarked cases [of Table 0-4] should raise a JMS MessageFormatException.\n");
+      }
+      catch (MessageFormatException e)
+      {
+      }
+      catch (JMSException e)
+      {
+         fail(e);
+      }
+   }
+
+   /**
+    * if a property is set as a <code>byte</code>, 
+    * to get is as a <code>float</code> throws a <code>javax.jms.MessageFormatException</code>.
+    */
+   public void testByte2Float()
+   {
+      try
+      {
+         Message message = senderSession.createMessage();
+         message.setByteProperty("prop", (byte)127);
+         message.getFloatProperty("prop");
+         Assert.fail("sec. 3.5.4 The unmarked cases [of Table 0-4] should raise a JMS MessageFormatException.\n");
+      }
+      catch (MessageFormatException e)
+      {
+      }
+      catch (JMSException e)
+      {
+         fail(e);
+      }
+   }
+
+   /**
+    * if a property is set as a <code>byte</code>, 
+    * it can also be read as a <code>long</code>.
+    */
+   public void testByte2Long()
+   {
+      try
+      {
+         Message message = senderSession.createMessage();
+         message.setByteProperty("prop", (byte)127);
+         Assert.assertEquals(127L, message.getLongProperty("prop"));
+      }
+      catch (JMSException e)
+      {
+         fail(e);
+      }
+   }
+
+   /**
+    * if a property is set as a <code>byte</code>, 
+    * it can also be read as an <code>int</code>.
+    */
+   public void testByte2Int()
+   {
+      try
+      {
+         Message message = senderSession.createMessage();
+         message.setByteProperty("prop", (byte)127);
+         Assert.assertEquals(127, message.getIntProperty("prop"));
+      }
+      catch (JMSException e)
+      {
+         fail(e);
+      }
+   }
+
+   /**
+    * if a property is set as a <code>byte</code>, 
+    * it can also be read as a <code>short</code>.
+    */
+   public void testByte2Short()
+   {
+      try
+      {
+         Message message = senderSession.createMessage();
+         message.setByteProperty("prop", (byte)127);
+         Assert.assertEquals((short)127, message.getShortProperty("prop"));
+      }
+      catch (JMSException e)
+      {
+         fail(e);
+      }
+   }
+
+   /**
+    * if a property is set as a <code>byte</code>, 
+    * it can also be read as a <code>byte</code>.
+    */
+   public void testByte2Byte()
+   {
+      try
+      {
+         Message message = senderSession.createMessage();
+         message.setByteProperty("prop", (byte)127);
+         Assert.assertEquals((byte)127, message.getByteProperty("prop"));
+      }
+      catch (JMSException e)
+      {
+         fail(e);
+      }
+   }
+
+   /**
+    * if a property is set as a <code>byte</code>, 
+    * to get is as a <code>boolean</code> throws a <code>javax.jms.MessageFormatException</code>.
+    */
+   public void testByte2Boolean()
+   {
+      try
+      {
+         Message message = senderSession.createMessage();
+         // store a value that can't be converted to boolean
+         message.setByteProperty("prop", (byte)127);
+         message.getBooleanProperty("prop");
+         Assert.fail("sec. 3.5.4 The unmarked cases [of Table 0-4] should raise a JMS MessageFormatException.\n");
+      }
+      catch (MessageFormatException e)
+      {
+      }
+      catch (JMSException e)
+      {
+         fail(e);
+      }
+   }
+
+   /**
+    * if a property is set as a <code>boolean</code>, 
+    * it can also be read as a <code>String</code>.
+    */
+   public void testBoolean2String()
+   {
+      try
+      {
+         Message message = senderSession.createMessage();
+         message.setBooleanProperty("prop", true);
+         Assert.assertEquals("true", message.getStringProperty("prop"));
+      }
+      catch (JMSException e)
+      {
+         fail(e);
+      }
+   }
+
+   /**
+    * if a property is set as a <code>boolean</code>, 
+    * to get is as a <code>double</code> throws a <code>javax.jms.MessageFormatException</code>.
+    */
+   public void testBoolean2Double()
+   {
+      try
+      {
+         Message message = senderSession.createMessage();
+         // store a value that can't be converted to double
+         message.setBooleanProperty("prop", true);
+         message.getDoubleProperty("prop");
+         Assert.fail("sec. 3.5.4 The unmarked cases [of Table 0-4] should raise a JMS MessageFormatException.\n");
+      }
+      catch (MessageFormatException e)
+      {
+      }
+      catch (JMSException e)
+      {
+         fail(e);
+      }
+   }
+
+   /**
+    * if a property is set as a <code>boolean</code>, 
+    * to get is as a <code>float</code> throws a <code>javax.jms.MessageFormatException</code>.
+    */
+   public void testBoolean2Float()
+   {
+      try
+      {
+         Message message = senderSession.createMessage();
+         // store a value that can't be converted to float
+         message.setBooleanProperty("prop", true);
+         message.getFloatProperty("prop");
+         Assert.fail("sec. 3.5.4 The unmarked cases [of Table 0-4] should raise a JMS MessageFormatException.\n");
+      }
+      catch (MessageFormatException e)
+      {
+      }
+      catch (JMSException e)
+      {
+         fail(e);
+      }
+   }
+
+   /**
+    * if a property is set as a <code>boolean</code>, 
+    * to get is as a <code>long</code> throws a <code>javax.jms.MessageFormatException</code>.
+    */
+   public void testBoolean2Long()
+   {
+      try
+      {
+         Message message = senderSession.createMessage();
+         // store a value that can't be converted to long
+         message.setBooleanProperty("true", true);
+         message.getLongProperty("true");
+         Assert.fail("sec. 3.5.4 The unmarked cases [of Table 0-4] should raise a JMS MessageFormatException.\n");
+      }
+      catch (MessageFormatException e)
+      {
+      }
+      catch (JMSException e)
+      {
+         fail(e);
+      }
+   }
+
+   /**
+    * if a property is set as a <code>boolean</code>, 
+    * to get is as a <code>int</code> throws a <code>javax.jms.MessageFormatException</code>.
+    */
+   public void testBoolean2Int()
+   {
+      try
+      {
+         Message message = senderSession.createMessage();
+         // store a value that can't be converted to int
+         message.setBooleanProperty("prop", true);
+         message.getIntProperty("prop");
+         Assert.fail("sec. 3.5.4 The unmarked cases [of Table 0-4] should raise a JMS MessageFormatException.\n");
+      }
+      catch (MessageFormatException e)
+      {
+      }
+      catch (JMSException e)
+      {
+         fail(e);
+      }
+   }
+
+   /**
+    * if a property is set as a <code>boolean</code>, 
+    * to get is as a <code>short</code> throws a <code>javax.jms.MessageFormatException</code>.
+    */
+   public void testBoolean2Short()
+   {
+      try
+      {
+         Message message = senderSession.createMessage();
+         // store a value that can't be converted to short
+         message.setBooleanProperty("prop", true);
+         message.getShortProperty("prop");
+         Assert.fail("sec. 3.5.4 The unmarked cases [of Table 0-4] should raise a JMS MessageFormatException.\n");
+      }
+      catch (MessageFormatException e)
+      {
+      }
+      catch (JMSException e)
+      {
+         fail(e);
+      }
+   }
+
+   /**
+    * if a property is set as a <code>boolean</code>, 
+    * to get is as a <code>byte</code> throws a <code>javax.jms.MessageFormatException</code>.
+    */
+   public void testBoolean2Byte()
+   {
+      try
+      {
+         Message message = senderSession.createMessage();
+         // store a value that can't be converted to byte
+         message.setBooleanProperty("prop", true);
+         message.getByteProperty("prop");
+         Assert.fail("sec. 3.5.4 The unmarked cases [of Table 0-4] should raise a JMS MessageFormatException.\n");
+      }
+      catch (MessageFormatException e)
+      {
+      }
+      catch (JMSException e)
+      {
+         fail(e);
+      }
+   }
+
+   /**
+    * if a property is set as a <code>boolean</code>, 
+    * it can also be read as a <code>boolean</code>.
+    */
+   public void testBoolean2Boolean()
+   {
+      try
+      {
+         Message message = senderSession.createMessage();
+         message.setBooleanProperty("prop", true);
+         Assert.assertEquals(true, message.getBooleanProperty("prop"));
+      }
+      catch (JMSException e)
+      {
+         fail(e);
+      }
+   }
+
+   /** 
+    * Method to use this class in a Test suite
+    */
+   public static Test suite()
+   {
+      return new TestSuite(MessagePropertyConversionTest.class);
+   }
+
+   public MessagePropertyConversionTest(final String name)
+   {
+      super(name);
+   }
+}
diff --git a/activemq-tooling/activemq-joram-jms-tests/src/main/java/org/objectweb/jtests/jms/conform/message/properties/MessagePropertyTest.java b/activemq-tooling/activemq-joram-jms-tests/src/main/java/org/objectweb/jtests/jms/conform/message/properties/MessagePropertyTest.java
new file mode 100644
index 0000000..151f980
--- /dev/null
+++ b/activemq-tooling/activemq-joram-jms-tests/src/main/java/org/objectweb/jtests/jms/conform/message/properties/MessagePropertyTest.java
@@ -0,0 +1,380 @@
+/*
+ * Copyright 2009 Red Hat, Inc.
+ * Red Hat 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.
+ */
+
+package org.objectweb.jtests.jms.conform.message.properties;
+
+import java.util.Enumeration;
+import java.util.Vector;
+
+import javax.jms.JMSException;
+import javax.jms.Message;
+import javax.jms.MessageFormatException;
+import javax.jms.TextMessage;
+
+import junit.framework.Assert;
+import junit.framework.Test;
+import junit.framework.TestSuite;
+
+import org.objectweb.jtests.jms.framework.PTPTestCase;
+
+/**
+ * Test the <code>javax.jms.Message</code> properties.
+ * <br />
+ *  See JMS Specification, sec. 3.5 Message Properties (p.32-37)
+ *
+ * @author Jeff Mesnil (jmesnil@gmail.com)
+ * @version $Id: MessagePropertyTest.java,v 1.1 2007/03/29 04:28:34 starksm Exp $
+ */
+public class MessagePropertyTest extends PTPTestCase
+{
+
+   /**
+    * Test that any other class than <code>Boolean, Byte, Short, Integer, Long,
+    * Float, Double</code> and <code>String</code> used in the <code>Message.setObjectProperty()</code>
+    * method throws a <code>javax.jms.MessageFormatException</code>.
+    */
+   public void testSetObjectProperty_2()
+   {
+      try
+      {
+         Message message = senderSession.createMessage();
+         message.setObjectProperty("prop", new Vector());
+         Assert.fail("sec. 3.5.5 An attempt to use any other class [than Boolean, Byte,...,String] must throw " + "a JMS MessageFormatException.\n");
+      }
+      catch (MessageFormatException e)
+      {
+      }
+      catch (JMSException e)
+      {
+         Assert.fail("Should throw a javax.jms.MessageFormatException, not a " + e);
+      }
+   }
+
+   /**
+    * if a property is set as a <code>Float</code> with the <code>Message.setObjectProperty()</code>
+    * method, it can be retrieve directly as a <code>double</code> by <code>Message.getFloatProperty()</code>
+    */
+   public void testSetObjectProperty_1()
+   {
+      try
+      {
+         Message message = senderSession.createMessage();
+         message.setObjectProperty("pi", new Float(3.14159f));
+         Assert.assertEquals(3.14159f, message.getFloatProperty("pi"), 0);
+      }
+      catch (JMSException e)
+      {
+         fail(e);
+      }
+   }
+
+   /**
+    * Test that a <code>null</code> value is returned by the <code>Message.getObjectProperty()</code> method
+    * if a property by the specified name does not exits.
+    */
+   public void testGetObjectProperty()
+   {
+      try
+      {
+         Message message = senderSession.createMessage();
+         Assert.assertEquals("sec. 3.5.5 A null value is returned [by the getObjectProperty method] if a property by the specified " + "name does not exits.\n",
+                             null,
+                             message.getObjectProperty("prop"));
+      }
+      catch (JMSException e)
+      {
+         fail(e);
+      }
+   }
+
+   /**
+    * Test that a <code>null</code> value is returned by the <code>Message.getStringProperty()</code> method
+    * if a property by the specified name does not exits.
+    */
+   public void testGetStringProperty()
+   {
+      try
+      {
+         Message message = senderSession.createMessage();
+         Assert.assertEquals("sec. 3.5.5 A null value is returned [by the getStringProperty method] if a property by the specified " + "name does not exits.\n",
+                             null,
+                             message.getStringProperty("prop"));
+      }
+      catch (JMSException e)
+      {
+         fail(e);
+      }
+   }
+
+   /** 
+    * Test that an attempt to get a <code>double</code> property which does not exist throw
+    * a <code>java.lang.NullPointerException</code>
+    */
+   public void testGetDoubleProperty()
+   {
+      try
+      {
+         Message message = senderSession.createMessage();
+         message.getDoubleProperty("prop");
+         Assert.fail("Should raise a NullPointerException.\n");
+      }
+      catch (NullPointerException e)
+      {
+      }
+      catch (JMSException e)
+      {
+         fail(e);
+      }
+   }
+
+   /** 
+    * Test that an attempt to get a <code>float</code> property which does not exist throw
+    * a <code>java.lang.NullPointerException</code>
+    */
+   public void testGetFloatProperty()
+   {
+      try
+      {
+         Message message = senderSession.createMessage();
+         message.getFloatProperty("prop");
+         Assert.fail("Should raise a NullPointerException.\n");
+      }
+      catch (NullPointerException e)
+      {
+      }
+      catch (JMSException e)
+      {
+         fail(e);
+      }
+   }
+
+   /** 
+    * Test that an attempt to get a <code>long</code> property which does not exist throw
+    * a <code>java.lang.NumberFormatException</code>
+    */
+   public void testGetLongProperty()
+   {
+      try
+      {
+         Message message = senderSession.createMessage();
+         message.getLongProperty("prop");
+         Assert.fail("Should raise a NumberFormatException.\n");
+      }
+      catch (NumberFormatException e)
+      {
+      }
+      catch (JMSException e)
+      {
+         fail(e);
+      }
+   }
+
+   /** 
+    * Test that an attempt to get a <code>int</code> property which does not exist throw
+    * a <code>java.lang.NumberFormatException</code>
+    */
+   public void testGetIntProperty()
+   {
+      try
+      {
+         Message message = senderSession.createMessage();
+         message.getIntProperty("prop");
+         Assert.fail("Should raise a NumberFormatException.\n");
+      }
+      catch (NumberFormatException e)
+      {
+      }
+      catch (JMSException e)
+      {
+         fail(e);
+      }
+   }
+
+   /** 
+    * Test that an attempt to get a <code>short</code> property which does not exist throw
+    * a <code>java.lang.NumberFormatException</code>
+    */
+   public void testGetShortProperty()
+   {
+      try
+      {
+         Message message = senderSession.createMessage();
+         message.getShortProperty("prop");
+         Assert.fail("Should raise a NumberFormatException.\n");
+      }
+      catch (NumberFormatException e)
+      {
+      }
+      catch (JMSException e)
+      {
+         fail(e);
+      }
+   }
+
+   /** 
+    * Test that an attempt to get a <code>byte</code> property which does not exist throw
+    * a <code>java.lang.NumberFormatException</code>
+    */
+   public void testGetByteProperty()
+   {
+      try
+      {
+         Message message = senderSession.createMessage();
+         message.getByteProperty("prop");
+         Assert.fail("Should raise a NumberFormatException.\n");
+      }
+      catch (NumberFormatException e)
+      {
+      }
+      catch (JMSException e)
+      {
+         fail(e);
+      }
+   }
+
+   /** 
+    * Test that an attempt to get a <code>boolean</code> property which does not exist 
+    * returns <code>false</code>
+    */
+   public void testGetBooleanProperty()
+   {
+      try
+      {
+         Message message = senderSession.createMessage();
+         Assert.assertEquals(false, message.getBooleanProperty("prop"));
+      }
+      catch (JMSException e)
+      {
+         fail(e);
+      }
+   }
+
+   /**
+    * Test that the <code>Message.getPropertyNames()</code> method does not return
+    * the name of the JMS standard header fields (e.g. <code>JMSCorrelationID</code>).
+    */
+   public void testGetPropertyNames()
+   {
+      try
+      {
+         Message message = senderSession.createMessage();
+         message.setJMSCorrelationID("foo");
+         Enumeration enumeration = message.getPropertyNames();
+         while (enumeration.hasMoreElements())
+         {
+            String propName = (String)enumeration.nextElement();
+            boolean valid = !propName.startsWith("JMS") || propName.startsWith("JMSX");
+            Assert.assertTrue("sec. 3.5.6 The getPropertyNames method does not return the names of " + "the JMS standard header field [e.g. JMSCorrelationID]: " +
+                                       propName,
+                              valid);
+         }
+      }
+      catch (JMSException e)
+      {
+         fail(e);
+      }
+   }
+
+   /**
+    * Test that the <code>Message.getPropertyNames()</code> methods.
+    */
+   public void testPropertyIteration()
+   {
+      try
+      {
+         Message message = senderSession.createMessage();
+         Enumeration enumeration = message.getPropertyNames();
+         // there can be some properties already defined (e.g. JMSXDeliveryCount)
+         int originalCount = 0;
+         while (enumeration.hasMoreElements())
+         {
+            enumeration.nextElement();
+            originalCount++;
+         }
+         message.setDoubleProperty("pi", 3.14159);
+         enumeration = message.getPropertyNames();
+         boolean foundPiProperty = false;
+         int newCount = 0;
+         while (enumeration.hasMoreElements())
+         {
+            String propName = (String)enumeration.nextElement();
+            newCount++;
+            if ("pi".equals(propName))
+            {
+               foundPiProperty = true;
+            }
+         }
+         Assert.assertEquals(originalCount + 1, newCount);
+         Assert.assertTrue(foundPiProperty);
+      }
+      catch (JMSException e)
+      {
+         fail(e);
+      }
+   }
+
+   /**
+    * Test that the <code>Message.clearProperties()</code> method does not clear the
+    * value of the Message's body.
+    */
+   public void testClearProperties_2()
+   {
+      try
+      {
+         TextMessage message = senderSession.createTextMessage();
+         message.setText("foo");
+         message.clearProperties();
+         Assert.assertEquals("sec. 3.5.7 Clearing a message's  property entries does not clear the value of its body.\n",
+                             "foo",
+                             message.getText());
+      }
+      catch (JMSException e)
+      {
+         fail(e);
+      }
+   }
+
+   /**
+    * Test that the <code>Message.clearProperties()</code> method deletes all the 
+    * properties of the Message.
+    */
+   public void testClearProperties_1()
+   {
+      try
+      {
+         TextMessage message = senderSession.createTextMessage();
+         message.setStringProperty("prop", "foo");
+         message.clearProperties();
+         Assert.assertEquals("sec. 3.5.7 A message's properties are deleted by the clearProperties method.\n",
+                             null,
+                             message.getStringProperty("prop"));
+      }
+      catch (JMSException e)
+      {
+         fail(e);
+      }
+   }
+
+   /** 
+    * Method to use this class in a Test suite
+    */
+   public static Test suite()
+   {
+      return new TestSuite(MessagePropertyTest.class);
+   }
+
+   public MessagePropertyTest(final String name)
+   {
+      super(name);
+   }
+}
diff --git a/activemq-tooling/activemq-joram-jms-tests/src/main/java/org/objectweb/jtests/jms/conform/message/properties/package.html b/activemq-tooling/activemq-joram-jms-tests/src/main/java/org/objectweb/jtests/jms/conform/message/properties/package.html
new file mode 100644
index 0000000..70d7b7b
--- /dev/null
+++ b/activemq-tooling/activemq-joram-jms-tests/src/main/java/org/objectweb/jtests/jms/conform/message/properties/package.html
@@ -0,0 +1,19 @@
+<!--
+    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.
+-->
+  <body>
+    Tests JMS <em>Message Properties</em> features.
+  </body>
diff --git a/activemq-tooling/activemq-joram-jms-tests/src/main/java/org/objectweb/jtests/jms/conform/queue/QueueBrowserTest.java b/activemq-tooling/activemq-joram-jms-tests/src/main/java/org/objectweb/jtests/jms/conform/queue/QueueBrowserTest.java
new file mode 100644
index 0000000..359d991
--- /dev/null
+++ b/activemq-tooling/activemq-joram-jms-tests/src/main/java/org/objectweb/jtests/jms/conform/queue/QueueBrowserTest.java
@@ -0,0 +1,196 @@
+/*
+ * Copyright 2009 Red Hat, Inc.
+ * Red Hat 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.
+ */
+
+package org.objectweb.jtests.jms.conform.queue;
+
+import java.util.Enumeration;
+
+import javax.jms.JMSException;
+import javax.jms.Message;
+import javax.jms.QueueBrowser;
+import javax.jms.TextMessage;
+
+import junit.framework.Assert;
+import junit.framework.Test;
+import junit.framework.TestSuite;
+
+import org.objectweb.jtests.jms.framework.PTPTestCase;
+import org.objectweb.jtests.jms.framework.TestConfig;
+
+/**
+ * Test the <code>javax.jms.QueueBrowser</code> features.
+ *
+ * @author Jeff Mesnil (jmesnil@gmail.com)
+ * @version $Id: QueueBrowserTest.java,v 1.2 2007/06/19 23:32:35 csuconic Exp $
+ */
+public class QueueBrowserTest extends PTPTestCase
+{
+
+   /**
+    * The <code>QueueBrowser</code> of the receiver's session
+    */
+   protected QueueBrowser receiverBrowser;
+
+   /**
+    * The <code>QueueBrowser</code> of the sender's session
+    */
+   protected QueueBrowser senderBrowser;
+
+   /**
+    * Test the <code>QueueBrowser</code> of the sender.
+    */
+   public void testSenderBrowser()
+   {
+      try
+      {
+         TextMessage message_1 = senderSession.createTextMessage();
+         message_1.setText("testBrowser:message_1");
+         TextMessage message_2 = senderSession.createTextMessage();
+         message_2.setText("testBrowser:message_2");
+
+         receiver.close();
+
+         // send two messages...
+         sender.send(message_1);
+         sender.send(message_2);
+
+         // ask the browser to browse the sender's session
+         Enumeration enumeration = senderBrowser.getEnumeration();
+         int count = 0;
+         while (enumeration.hasMoreElements())
+         {
+            // one more message in the queue
+            count++;
+            // check that the message in the queue is one of the two which where sent
+            Object obj = enumeration.nextElement();
+            Assert.assertTrue(obj instanceof TextMessage);
+            TextMessage msg = (TextMessage)obj;
+            Assert.assertTrue(msg.getText().startsWith("testBrowser:message_"));
+         }
+         // check that there is effectively 2 messages in the queue
+         Assert.assertEquals(2, count);
+
+         receiver = receiverSession.createReceiver(receiverQueue);
+         // receive the first message...
+         Message m = receiver.receive(TestConfig.TIMEOUT);
+         // ... and check it is the first which was sent.
+         Assert.assertTrue(m instanceof TextMessage);
+         TextMessage msg = (TextMessage)m;
+         Assert.assertEquals("testBrowser:message_1", msg.getText());
+
+         // receive the second message...
+         m = receiver.receive(TestConfig.TIMEOUT);
+         // ... and check it is the second which was sent.
+         Assert.assertTrue(m instanceof TextMessage);
+         msg = (TextMessage)m;
+         Assert.assertEquals("testBrowser:message_2", msg.getText());
+
+         // ask the browser to browse the sender's session
+         enumeration = receiverBrowser.getEnumeration();
+         // check that there is no messages in the queue
+         // (the two messages have been acknowledged and so removed
+         // from the queue)
+         Assert.assertTrue(!enumeration.hasMoreElements());
+      }
+      catch (JMSException e)
+      {
+         fail(e);
+      }
+   }
+
+   /**
+    * Test that a <code>QueueBrowser</cdeo> created with a message selector
+    * browses only the messages matching this selector.
+    */
+   public void testBrowserWithMessageSelector()
+   {
+      try
+      {
+         senderBrowser = senderSession.createBrowser(senderQueue, "pi = 3.14159");
+
+         receiver.close();
+
+         TextMessage message_1 = senderSession.createTextMessage();
+         message_1.setText("testBrowserWithMessageSelector:message_1");
+         TextMessage message_2 = senderSession.createTextMessage();
+         message_2.setDoubleProperty("pi", 3.14159);
+         message_2.setText("testBrowserWithMessageSelector:message_2");
+
+         sender.send(message_1);
+         sender.send(message_2);
+
+         Enumeration enumeration = senderBrowser.getEnumeration();
+         int count = 0;
+         while (enumeration.hasMoreElements())
+         {
+            count++;
+            Object obj = enumeration.nextElement();
+            Assert.assertTrue(obj instanceof TextMessage);
+            TextMessage msg = (TextMessage)obj;
+            Assert.assertEquals("testBrowserWithMessageSelector:message_2", msg.getText());
+         }
+         Assert.assertEquals(1, count);
+      }
+      catch (JMSException e)
+      {
+         fail(e);
+      }
+   }
+
+   @Override
+   public void setUp() throws Exception
+   {
+      try
+      {
+         super.setUp();
+         receiverBrowser = receiverSession.createBrowser(receiverQueue);
+         senderBrowser = senderSession.createBrowser(senderQueue);
+      }
+      catch (JMSException e)
+      {
+         throw new RuntimeException(e);
+      }
+   }
+
+   @Override
+   public void tearDown() throws Exception
+   {
+      try
+      {
+         receiverBrowser.close();
+         senderBrowser.close();
+         super.tearDown();
+      }
+      catch (JMSException ignored)
+      {
+      }
+      finally
+      {
+         receiverBrowser = null;
+         senderBrowser = null;
+      }
+   }
+
+   /** 
+    * Method to use this class in a Test suite
+    */
+   public static Test suite()
+   {
+      return new TestSuite(QueueBrowserTest.class);
+   }
+
+   public QueueBrowserTest(final String name)
+   {
+      super(name);
+   }
+}
diff --git a/activemq-tooling/activemq-joram-jms-tests/src/main/java/org/objectweb/jtests/jms/conform/queue/TemporaryQueueTest.java b/activemq-tooling/activemq-joram-jms-tests/src/main/java/org/objectweb/jtests/jms/conform/queue/TemporaryQueueTest.java
new file mode 100644
index 0000000..98f5a75
--- /dev/null
+++ b/activemq-tooling/activemq-joram-jms-tests/src/main/java/org/objectweb/jtests/jms/conform/queue/TemporaryQueueTest.java
@@ -0,0 +1,89 @@
+/*
+ * Copyright 2009 Red Hat, Inc.
+ * Red Hat 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.
+ */
+
+package org.objectweb.jtests.jms.conform.queue;
+
+import javax.jms.JMSException;
+import javax.jms.Message;
+import javax.jms.QueueReceiver;
+import javax.jms.TemporaryQueue;
+import javax.jms.TextMessage;
+
+import junit.framework.Assert;
+import junit.framework.Test;
+import junit.framework.TestSuite;
+
+import org.objectweb.jtests.jms.framework.PTPTestCase;
+import org.objectweb.jtests.jms.framework.TestConfig;
+
+/**
+ * Test the <code>javax.jms.TemporaryQueue</code> features.
+ *
+ * @author Jeff Mesnil (jmesnil@gmail.com)
+ * @version $Id: TemporaryQueueTest.java,v 1.1 2007/03/29 04:28:37 starksm Exp $
+ */
+public class TemporaryQueueTest extends PTPTestCase
+{
+
+   private TemporaryQueue tempQueue;
+
+   private QueueReceiver tempReceiver;
+
+   /**
+    * Test a TemporaryQueue
+    */
+   public void testTemporaryQueue()
+   {
+      try
+      {
+         // we stop both sender and receiver connections
+         senderConnection.stop();
+         receiverConnection.stop();
+         // we create a temporary queue to receive messages
+         tempQueue = receiverSession.createTemporaryQueue();
+         // we recreate the sender because it has been
+         // already created with a Destination as parameter
+         sender = senderSession.createSender(null);
+         // we create a receiver on the temporary queue
+         tempReceiver = receiverSession.createReceiver(tempQueue);
+         receiverConnection.start();
+         senderConnection.start();
+
+         TextMessage message = senderSession.createTextMessage();
+         message.setText("testTemporaryQueue");
+         sender.send(tempQueue, message);
+
+         Message m = tempReceiver.receive(TestConfig.TIMEOUT);
+         Assert.assertTrue(m instanceof TextMessage);
+         TextMessage msg = (TextMessage)m;
+         Assert.assertEquals("testTemporaryQueue", msg.getText());
+      }
+      catch (JMSException e)
+      {
+         fail(e);
+      }
+   }
+
+   /** 
+    * Method to use this class in a Test suite
+    */
+   public static Test suite()
+   {
+      return new TestSuite(TemporaryQueueTest.class);
+   }
+
+   public TemporaryQueueTest(final String name)
+   {
+      super(name);
+   }
+}
diff --git a/activemq-tooling/activemq-joram-jms-tests/src/main/java/org/objectweb/jtests/jms/conform/queue/package.html b/activemq-tooling/activemq-joram-jms-tests/src/main/java/org/objectweb/jtests/jms/conform/queue/package.html
new file mode 100644
index 0000000..872bdcb
--- /dev/null
+++ b/activemq-tooling/activemq-joram-jms-tests/src/main/java/org/objectweb/jtests/jms/conform/queue/package.html
@@ -0,0 +1,19 @@
+<!--
+    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.
+-->
+  <body>
+    Tests JMS <em>Queue</em> features.
+  </body>
diff --git a/activemq-tooling/activemq-joram-jms-tests/src/main/java/org/objectweb/jtests/jms/conform/selector/SelectorSyntaxTest.java b/activemq-tooling/activemq-joram-jms-tests/src/main/java/org/objectweb/jtests/jms/conform/selector/SelectorSyntaxTest.java
new file mode 100644
index 0000000..8f6ef12
--- /dev/null
+++ b/activemq-tooling/activemq-joram-jms-tests/src/main/java/org/objectweb/jtests/jms/conform/selector/SelectorSyntaxTest.java
@@ -0,0 +1,426 @@
+/*
+ * Copyright 2009 Red Hat, Inc.
+ * Red Hat 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.
+ */
+
+package org.objectweb.jtests.jms.conform.selector;
+
+import javax.jms.InvalidSelectorException;
+import javax.jms.JMSException;
+
+import junit.framework.Assert;
+import junit.framework.Test;
+import junit.framework.TestSuite;
+
+import org.objectweb.jtests.jms.framework.PTPTestCase;
+
+/**
+ * Test the syntax of of message selector of JMS
+ *
+ * @author Jeff Mesnil (jmesnil@gmail.com)
+ * @version $Id: SelectorSyntaxTest.java,v 1.1 2007/03/29 04:28:35 starksm Exp $
+ */
+public class SelectorSyntaxTest extends PTPTestCase
+{
+   /**
+    * Test that identifiers that start with a valid Java identifier start character are valid.
+    * A valid identifier means that the method <code>Character.isJavaIdentifierStart</code> returns 
+    * <code>true</code> for this identifier first character.
+    * 
+    * @see <a href="http://java.sun.com/j2se/1.3/docs/api/java/lang/Character.html#isJavaIdentifierStart(char)">Character.isJavaIdentifierStart(char)</a>
+    */
+   public void testValidIdentifiersStart()
+   {
+      String identifier = null;
+      try
+      {
+         identifier = "_correct";
+         Assert.assertTrue(identifier + " starts with an invalid Java identifier start character",
+                           Character.isJavaIdentifierStart(identifier.charAt(0)));
+         receiver = receiverSession.createReceiver(receiverQueue, identifier + " IS NULL");
+
+         identifier = "$correct";
+         Assert.assertTrue(identifier + " starts with an invalid Java identifier start character",
+                           Character.isJavaIdentifierStart(identifier.charAt(0)));
+         receiver = receiverSession.createReceiver(receiverQueue, identifier + " IS NULL");
+      }
+      catch (JMSException e)
+      {
+         Assert.fail(identifier + " is a correct identifier. \n" + e);
+      }
+   }
+
+   /**
+    * Test that identifiers that start with an invalid Java identifier start character are invalid.       
+    * 
+    * @see #testValidIdentifiersStart()
+    */
+   public void testInvalidIdentifiersStart()
+   {
+      String identifier = null;
+      try
+      {
+         identifier = "1uncorrect";
+
+         Assert.assertTrue(identifier + " starts with an invalid Java identifier start character",
+                           !Character.isJavaIdentifierStart(identifier.charAt(0)));
+         receiver = receiverSession.createReceiver(receiverQueue, identifier + " IS NULL");
+         Assert.fail(identifier + " starts with an invalid Java identifier start character");
+      }
+      catch (JMSException e)
+      {
+      }
+
+      try
+      {
+         identifier = "%uncorrect";
+
+         Assert.assertTrue(identifier + " starts with an invalid Java identifier start character",
+                           !Character.isJavaIdentifierStart(identifier.charAt(0)));
+         receiver = receiverSession.createReceiver(receiverQueue, identifier + " IS NULL");
+         Assert.fail(identifier + " starts with an invalid Java identifier start character");
+      }
+      catch (JMSException e)
+      {
+      }
+
+   }
+
+   /**
+    * Test that message selector can be an empty string.
+    */
+   public void testEmptyStringAsSelector()
+   {
+      try
+      {
+         receiver = receiverSession.createReceiver(receiverQueue, "");
+      }
+      catch (JMSException e)
+      {
+         fail(e);
+      }
+   }
+
+   /**
+    * Test that identifiers can't be <code>NULL</code>.
+    */
+   public void testIdentifierNULL()
+   {
+      try
+      {
+         receiver = receiverSession.createReceiver(receiverQueue, "NULL = ZERO");
+         Assert.fail("NULL is not a valid identifier");
+      }
+      catch (InvalidSelectorException e)
+      {
+      }
+      catch (JMSException e)
+      {
+         fail(e);
+      }
+   }
+
+   /**
+    * Test that identifiers can't be <code>TRUE</code>.
+    */
+   public void testIdentifierTRUE()
+   {
+      try
+      {
+         receiver = receiverSession.createReceiver(receiverQueue, "TRUE > 0");
+         Assert.fail("TRUE is not a valid identifier");
+      }
+      catch (JMSException e)
+      {
+      }
+   }
+
+   /**
+    * Test that identifiers can't be <code>FALSE</code>.
+    */
+   public void testIdentifierFALSE()
+   {
+      try
+      {
+         receiver = receiverSession.createReceiver(receiverQueue, "FALSE > 0");
+         Assert.fail("FALSE is not a valid identifier");
+      }
+      catch (JMSException e)
+      {
+      }
+   }
+
+   /**
+    * Test that identifiers can't be <code>NOT</code>.
+    */
+   public void testIdentifierNOT()
+   {
+      try
+      {
+         receiver = receiverSession.createReceiver(receiverQueue, "NOT > 0");
+         Assert.fail("NOT is not a valid identifier");
+      }
+      catch (JMSException e)
+      {
+      }
+   }
+
+   /**
+    * Test that identifiers can't be <code>AND</code>.
+    */
+   public void testIdentifierAND()
+   {
+      try
+      {
+         receiver = receiverSession.createReceiver(receiverQueue, "AND > 0");
+         Assert.fail("AND is not a valid identifier");
+      }
+      catch (JMSException e)
+      {
+      }
+   }
+
+   /**
+    * Test that identifiers can't be <code>OR</code>.
+    */
+   public void testIdentifierOR()
+   {
+      try
+      {
+         receiver = receiverSession.createReceiver(receiverQueue, "OR > 0");
+         Assert.fail("OR is not a valid identifier");
+      }
+      catch (JMSException e)
+      {
+      }
+   }
+
+   /**
+    * Test that identifiers can't be <code>BETWEEN</code>.
+    */
+   public void testIdentifierBETWEEN()
+   {
+      try
+      {
+         receiver = receiverSession.createReceiver(receiverQueue, "BETWEEN > 0");
+         Assert.fail("BETWEEN is not a valid identifier");
+      }
+      catch (JMSException e)
+      {
+      }
+   }
+
+   /**
+    * Test that identifiers can't be <code>LIKE</code>.
+    */
+   public void testIdentifierLIKE()
+   {
+      try
+      {
+         receiver = receiverSession.createReceiver(receiverQueue, "LIKE > 0");
+         Assert.fail("LIKE is not a valid identifier");
+      }
+      catch (JMSException e)
+      {
+      }
+   }
+
+   /**
+    * Test that identifiers can't be <code>IN</code>.
+    */
+   public void testIdentifierIN()
+   {
+      try
+      {
+         receiver = receiverSession.createReceiver(receiverQueue, "IN > 0");
+         Assert.fail("IN is not a valid identifier");
+      }
+      catch (JMSException e)
+      {
+      }
+   }
+
+   /**
+    * Test that identifiers can't be <code>IS</code>.
+    */
+   public void testIdentifierIS()
+   {
+      try
+      {
+         receiver = receiverSession.createReceiver(receiverQueue, "IS > 0");
+         Assert.fail("IS is not a valid identifier");
+      }
+      catch (JMSException e)
+      {
+      }
+   }
+
+   /**
+    * Test that identifiers can't be <code>ESCAPE</code>.
+    */
+   public void testIdentifierESCAPE()
+   {
+      try
+      {
+         receiver = receiverSession.createReceiver(receiverQueue, "ESCAPE > 0");
+         Assert.fail("ESCAPE is not a valid identifier");
+      }
+      catch (JMSException e)
+      {
+      }
+   }
+
+   /**
+    * Test syntax of "<em>identifier</em> IS [NOT] NULL"
+    */
+   public void testNull()
+   {
+      try
+      {
+         receiver = receiverSession.createReceiver(receiverQueue, "prop_name IS NULL");
+         receiver = receiverSession.createReceiver(receiverQueue, "prop_name IS NOT NULL");
+      }
+      catch (JMSException e)
+      {
+         fail(e);
+      }
+   }
+
+   /**
+    * Test syntax of "<em>identifier</em> [NOT] LIKE <em>pattern-value</em> [ESCAPE <em>escape-character</em>]"
+    */
+   public void testLike()
+   {
+      try
+      {
+         receiver = receiverSession.createReceiver(receiverQueue, "phone LIKE '12%3'");
+         receiver = receiverSession.createReceiver(receiverQueue, "word LIKE 'l_se'");
+         receiver = receiverSession.createReceiver(receiverQueue, "underscored LIKE '\\_%' ESCAPE '\\'");
+         receiver = receiverSession.createReceiver(receiverQueue, "phone NOT LIKE '12%3'");
+      }
+      catch (JMSException e)
+      {
+         fail(e);
+      }
+   }
+
+   /**
+    * Test syntax of "<em>identifier</em> [NOT] IN (<em>string-literal1</em>, <em>string-literal2</em>,...)"
+    */
+   public void testIn()
+   {
+      try
+      {
+         receiver = receiverSession.createReceiver(receiverQueue, "Country IN ('UK', 'US', 'France')");
+         receiver = receiverSession.createReceiver(receiverQueue, "Country NOT IN ('UK', 'US', 'France')");
+      }
+      catch (JMSException e)
+      {
+         fail(e);
+      }
+   }
+
+   /**
+    * Test syntax of "<em>arithmetic-expr1</em> [NOT] BETWEEN <em>arithmetic-expr2</em> and <em>arithmetic-expr3</em>"
+    */
+   public void testBetween()
+   {
+      try
+      {
+         receiver = receiverSession.createReceiver(receiverQueue, "age BETWEEN 15 and 19");
+         receiver = receiverSession.createReceiver(receiverQueue, "age NOT BETWEEN 15 and 19");
+      }
+      catch (JMSException e)
+      {
+         fail(e);
+      }
+   }
+
+   /**
+    * Test diffent syntax for approximate numeric literal (+6.2, -95.7, 7.)
+    */
+   public void testApproximateNumericLiteral()
+   {
+      try
+      {
+         receiver = receiverSession.createReceiver(receiverQueue, "average = +6.2");
+         receiver = receiverSession.createReceiver(receiverQueue, "average = -95.7");
+         receiver = receiverSession.createReceiver(receiverQueue, "average = 7.");
+      }
+      catch (JMSException e)
+      {
+         fail(e);
+      }
+   }
+
+   /**
+    * Test diffent syntax for exact numeric literal (+62, -957, 57)
+    */
+   public void testExactNumericLiteral()
+   {
+      try
+      {
+         receiver = receiverSession.createReceiver(receiverQueue, "average = +62");
+         receiver = receiverSession.createReceiver(receiverQueue, "max = -957");
+         receiver = receiverSession.createReceiver(receiverQueue, "max = 57");
+      }
+      catch (JMSException e)
+      {
+         fail(e);
+      }
+   }
+
+   /**
+    * Test diffent syntax for zero as an exact or an approximate numeric literal (0, 0.0, 0.)
+    */
+   public void testZero()
+   {
+      try
+      {
+         receiver = receiverSession.createReceiver(receiverQueue, "max = 0");
+         receiver = receiverSession.createReceiver(receiverQueue, "max = 0.0");
+         receiver = receiverSession.createReceiver(receiverQueue, "max = 0.");
+      }
+      catch (JMSException e)
+      {
+         fail(e);
+      }
+   }
+
+   /**
+    * Test diffent syntax for string literal ('literal' and 'literal''s')
+    */
+   public void testString()
+   {
+      try
+      {
+         receiver = receiverSession.createReceiver(receiverQueue, "string = 'literal'");
+         receiver = receiverSession.createReceiver(receiverQueue, "string = 'literal''s'");
+      }
+      catch (JMSException e)
+      {
+         fail(e);
+      }
+   }
+
+   /** 
+    * Method to use this class in a Test suite
+    */
+   public static Test suite()
+   {
+      return new TestSuite(SelectorSyntaxTest.class);
+   }
+
+   public SelectorSyntaxTest(final String name)
+   {
+      super(name);
+   }
+}
diff --git a/activemq-tooling/activemq-joram-jms-tests/src/main/java/org/objectweb/jtests/jms/conform/selector/SelectorTest.java b/activemq-tooling/activemq-joram-jms-tests/src/main/java/org/objectweb/jtests/jms/conform/selector/SelectorTest.java
new file mode 100644
index 0000000..974244b
--- /dev/null
+++ b/activemq-tooling/activemq-joram-jms-tests/src/main/java/org/objectweb/jtests/jms/conform/selector/SelectorTest.java
@@ -0,0 +1,459 @@
+/*
+ * Copyright 2009 Red Hat, Inc.
+ * Red Hat 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.
+ */
+
+package org.objectweb.jtests.jms.conform.selector;
+
+import javax.jms.DeliveryMode;
+import javax.jms.TextMessage;
+
+import junit.framework.Assert;
+import junit.framework.Test;
+import junit.framework.TestSuite;
+
+import org.objectweb.jtests.jms.framework.PTPTestCase;
+import org.objectweb.jtests.jms.framework.TestConfig;
+
+/**
+ * Test the message selector features of JMS
+ *
+ * @author Jeff Mesnil (jmesnil@)
+ * @version $Id: SelectorTest.java,v 1.3 2007/10/02 14:59:35 csuconic Exp $
+ */
+public class SelectorTest extends PTPTestCase
+{
+
+   /**
+    * Test that an empty string as a message selector indicates that there
+    * is no message selector for the message consumer.
+    */
+   public void testEmptyStringAsSelector() throws Exception
+   {
+      if (receiver != null)
+      {
+         receiver.close();
+      }
+      receiver = receiverSession.createReceiver(receiverQueue, "");
+
+      TextMessage message = senderSession.createTextMessage();
+      message.setText("testEmptyStringAsSelector");
+      sender.send(message);
+
+      TextMessage msg = (TextMessage)receiver.receive(TestConfig.TIMEOUT);
+      Assert.assertTrue("No message was received", msg != null);
+      Assert.assertEquals("testEmptyStringAsSelector", msg.getText());
+   }
+
+   /**
+    * Tats that String literals are well handled by the message selector.
+    * <br />
+    * <ul>
+    *   <li><code>"string = 'literal''s;"</code> is <code>true</code> for "literal's" and <code>false</code> for "literal"</li>
+    * </ul>
+    */
+
+   public void testStringLiterals() throws Exception
+   {
+      if (receiver != null)
+      {
+         receiver.close();
+      }
+      receiver = receiverSession.createReceiver(receiverQueue, "string = 'literal''s'");
+
+      TextMessage dummyMessage = senderSession.createTextMessage();
+      dummyMessage.setStringProperty("string", "literal");
+      dummyMessage.setText("testStringLiterals:1");
+      sender.send(dummyMessage);
+
+      TextMessage message = senderSession.createTextMessage();
+      message.setStringProperty("string", "literal's");
+      message.setText("testStringLiterals:2");
+      sender.send(message);
+
+      TextMessage msg = (TextMessage)receiver.receive(TestConfig.TIMEOUT);
+      Assert.assertTrue("No message was received", msg != null);
+      Assert.assertEquals("testStringLiterals:2", msg.getText());
+   }
+
+   /**
+    * Test that the JMS property <code>JMSDeliveryMode</code> is treated as having the values <code>'PERSISTENT'</code>
+    * or <code>'NON_PERSISTENT'</code> when used in a message selector (chapter 3.8.1.3).
+    */
+   public void testJMSDeliveryModeInSelector() throws Exception
+   {
+      if (receiver != null)
+      {
+         receiver.close();
+      }
+      receiver = receiverSession.createReceiver(receiverQueue, "JMSDeliveryMode = 'PERSISTENT'");
+
+      TextMessage dummyMessage = senderSession.createTextMessage();
+      dummyMessage.setText("testJMSDeliveryModeInSelector:1");
+      // send a dummy message in *non persistent* mode
+      sender.send(dummyMessage, DeliveryMode.NON_PERSISTENT, sender.getPriority(), sender.getTimeToLive());
+
+      TextMessage message = senderSession.createTextMessage();
+      message.setText("testJMSDeliveryModeInSelector:2");
+      // send a message in *persistent*
+      sender.send(message, DeliveryMode.PERSISTENT, sender.getPriority(), sender.getTimeToLive());
+
+      TextMessage msg = (TextMessage)receiver.receive(TestConfig.TIMEOUT);
+      Assert.assertTrue("No message was received", msg != null);
+      // only the message sent in persistent mode should be received.
+      Assert.assertEquals(DeliveryMode.PERSISTENT, msg.getJMSDeliveryMode());
+      Assert.assertEquals("testJMSDeliveryModeInSelector:2", msg.getText());
+   }
+
+   /**
+    * Test that conversions that apply to the <code>get</code> methods for properties do not
+    * apply when a property is used in a message selector expression.
+    * Based on the example of chapter 3.8.1.1 about identifiers.
+    */
+   public void testIdentifierConversion() throws Exception
+   {
+      if (receiver != null)
+      {
+         receiver.close();
+      }
+      receiver = receiverSession.createReceiver(receiverQueue, "NumberOfOrders > 1");
+
+      TextMessage dummyMessage = senderSession.createTextMessage();
+      dummyMessage.setStringProperty("NumberOfOrders", "2");
+      dummyMessage.setText("testIdentifierConversion:1");
+      sender.send(dummyMessage);
+
+      TextMessage message = senderSession.createTextMessage();
+      message.setIntProperty("NumberOfOrders", 2);
+      message.setText("testIdentifierConversion:2");
+      sender.send(message);
+
+      TextMessage msg = (TextMessage)receiver.receive(TestConfig.TIMEOUT);
+      Assert.assertEquals("testIdentifierConversion:2", msg.getText());
+   }
+
+   /**
+    * Test the message selector using the filter example provided by the JMS specifications.
+    * <br />
+    * <ul>
+    *   <li><code>"JMSType = 'car' AND color = 'blue' AND weight > 2500"</code></li>
+    * </ul>
+    */
+   public void testSelectorExampleFromSpecs() throws Exception
+   {
+      if (receiver != null)
+      {
+         receiver.close();
+      }
+      receiver = receiverSession.createReceiver(receiverQueue, "JMSType = 'car' AND color = 'blue' AND weight > 2500");
+
+      TextMessage dummyMessage = senderSession.createTextMessage();
+      dummyMessage.setJMSType("car");
+      dummyMessage.setStringProperty("color", "red");
+      dummyMessage.setLongProperty("weight", 3000);
+      dummyMessage.setText("testSelectorExampleFromSpecs:1");
+      sender.send(dummyMessage);
+
+      TextMessage message = senderSession.createTextMessage();
+      message.setJMSType("car");
+      message.setStringProperty("color", "blue");
+      message.setLongProperty("weight", 3000);
+      message.setText("testSelectorExampleFromSpecs:2");
+      sender.send(message);
+
+      TextMessage msg = (TextMessage)receiver.receive(TestConfig.TIMEOUT);
+      Assert.assertEquals("testSelectorExampleFromSpecs:2", msg.getText());
+   }
+
+   /**
+    * Test the ">" condition in message selector.
+    * <br />
+    * <ul>
+    *   <li><code>"weight > 2500"</code> is <code>true</code> for 3000 and <code>false</code> for 1000</li>
+    * </ul>
+    */
+   public void testGreaterThan() throws Exception
+   {
+      if (receiver != null)
+      {
+         receiver.close();
+      }
+      receiver = receiverSession.createReceiver(receiverQueue, "weight > 2500");
+
+      TextMessage dummyMessage = senderSession.createTextMessage();
+      dummyMessage.setLongProperty("weight", 1000);
+      dummyMessage.setText("testGreaterThan:1");
+      sender.send(dummyMessage);
+
+      TextMessage message = senderSession.createTextMessage();
+      message.setLongProperty("weight", 3000);
+      message.setText("testGreaterThan:2");
+      sender.send(message);
+
+      TextMessage msg = (TextMessage)receiver.receive(TestConfig.TIMEOUT);
+      Assert.assertEquals("testGreaterThan:2", msg.getText());
+   }
+
+   /**
+    * Test the "=" condition in message selector.
+    * <br />
+    * <ul>
+    *   <li><code>"weight = 2500"</code>  is <code>true</code> for 2500 and <code>false</code> for 1000</li>
+    * </ul>
+    */
+   public void testEquals() throws Exception
+   {
+      if (receiver != null)
+      {
+         receiver.close();
+      }
+      receiver = receiverSession.createReceiver(receiverQueue, "weight = 2500");
+
+      TextMessage dummyMessage = senderSession.createTextMessage();
+      dummyMessage.setLongProperty("weight", 1000);
+      dummyMessage.setText("testEquals:1");
+      sender.send(dummyMessage);
+
+      TextMessage message = senderSession.createTextMessage();
+      message.setLongProperty("weight", 2500);
+      message.setText("testEquals:2");
+      sender.send(message);
+
+      TextMessage msg = (TextMessage)receiver.receive(TestConfig.TIMEOUT);
+      Assert.assertEquals("testEquals:2", msg.getText());
+   }
+
+   /**
+    * Test the "<>" (not equal) condition in message selector.
+    * <br />
+    * <ul>
+    *   <li><code>"weight <> 2500"</code>  is <code>true</code> for 1000 and <code>false</code> for 2500</li>
+    * </ul>
+    */
+   public void testNotEquals() throws Exception
+   {
+      if (receiver != null)
+      {
+         receiver.close();
+      }
+      receiver = receiverSession.createReceiver(receiverQueue, "weight <> 2500");
+
+      TextMessage dummyMessage = senderSession.createTextMessage();
+      dummyMessage.setLongProperty("weight", 2500);
+      dummyMessage.setText("testEquals:1");
+      sender.send(dummyMessage);
+
+      TextMessage message = senderSession.createTextMessage();
+      message.setLongProperty("weight", 1000);
+      message.setText("testEquals:2");
+      sender.send(message);
+
+      TextMessage msg = (TextMessage)receiver.receive(TestConfig.TIMEOUT);
+      Assert.assertEquals("testEquals:2", msg.getText());
+   }
+
+   /**
+    * Test the BETWEEN condition in message selector.
+    * <br />
+    * <ul>
+    *   <li>"age BETWEEN 15 and 19" is <code>true</code> for 17 and <code>false</code> for 20</li>
+    * </ul>
+    */
+   public void testBetween() throws Exception
+   {
+      if (receiver != null)
+      {
+         receiver.close();
+      }
+      receiver = receiverSession.createReceiver(receiverQueue, "age BETWEEN 15 and 19");
+
+      TextMessage dummyMessage = senderSession.createTextMessage();
+      dummyMessage.setIntProperty("age", 20);
+      dummyMessage.setText("testBetween:1");
+      sender.send(dummyMessage);
+
+      TextMessage message = senderSession.createTextMessage();
+      message.setIntProperty("age", 17);
+      message.setText("testBetween:2");
+      sender.send(message);
+
+      TextMessage msg = (TextMessage)receiver.receive(TestConfig.TIMEOUT);
+      Assert.assertTrue("Message not received", msg != null);
+      Assert.assertTrue("Message of another test: " + msg.getText(), msg.getText().startsWith("testBetween"));
+      Assert.assertEquals("testBetween:2", msg.getText());
+   }
+
+   /**
+    * Test the IN condition in message selector.
+    * <br />
+    * <ul>
+    *   <li>"Country IN ('UK', 'US', 'France')" is <code>true</code> for 'UK' and <code>false</code> for 'Peru'</li>
+    * </ul>
+    */
+   public void testIn() throws Exception
+   {
+      if (receiver != null)
+      {
+         receiver.close();
+      }
+      receiver = receiverSession.createReceiver(receiverQueue, "Country IN ('UK', 'US', 'France')");
+
+      TextMessage dummyMessage = senderSession.createTextMessage();
+      dummyMessage.setStringProperty("Country", "Peru");
+      dummyMessage.setText("testIn:1");
+      sender.send(dummyMessage);
+
+      TextMessage message = senderSession.createTextMessage();
+      message.setStringProperty("Country", "UK");
+      message.setText("testIn:2");
+      sender.send(message);
+
+      TextMessage msg = (TextMessage)receiver.receive(TestConfig.TIMEOUT);
+      Assert.assertTrue("Message not received", msg != null);
+      Assert.assertTrue("Message of another test: " + msg.getText(), msg.getText().startsWith("testIn"));
+      Assert.assertEquals("testIn:2", msg.getText());
+   }
+
+   /**
+    * Test the LIKE ... ESCAPE condition in message selector
+    * <br />
+    * <ul>
+    *   <li>"underscored LIKE '\_%' ESCAPE '\'" is <code>true</code> for '_foo' and <code>false</code> for 'bar'</li>
+    * </ul>
+    */
+   public void testLikeEscape() throws Exception
+   {
+      if (receiver != null)
+      {
+         receiver.close();
+      }
+      receiver = receiverSession.createReceiver(receiverQueue, "underscored LIKE '\\_%' ESCAPE '\\'");
+
+      TextMessage dummyMessage = senderSession.createTextMessage();
+      dummyMessage.setStringProperty("underscored", "bar");
+      dummyMessage.setText("testLikeEscape:1");
+      sender.send(dummyMessage);
+
+      TextMessage message = senderSession.createTextMessage();
+      message.setStringProperty("underscored", "_foo");
+      message.setText("testLikeEscape:2");
+      sender.send(message);
+
+      TextMessage msg = (TextMessage)receiver.receive(TestConfig.TIMEOUT);
+      Assert.assertTrue("Message not received", msg != null);
+      Assert.assertTrue("Message of another test: " + msg.getText(), msg.getText().startsWith("testLikeEscape"));
+      Assert.assertEquals("testLikeEscape:2", msg.getText());
+   }
+
+   /**
+    * Test the LIKE condition with '_' in the pattern.
+    * <br />
+    * <ul>
+    *   <li>"word LIKE 'l_se'" is <code>true</code> for 'lose' and <code>false</code> for 'loose'</li>
+    * </ul>
+    */
+   public void testLike_2() throws Exception
+   {
+      if (receiver != null)
+      {
+         receiver.close();
+      }
+      receiver = receiverSession.createReceiver(receiverQueue, "word LIKE 'l_se'");
+
+      TextMessage dummyMessage = senderSession.createTextMessage();
+      dummyMessage.setStringProperty("word", "loose");
+      dummyMessage.setText("testLike_2:1");
+      sender.send(dummyMessage);
+
+      TextMessage message = senderSession.createTextMessage();
+      message.setStringProperty("word", "lose");
+      message.setText("testLike_2:2");
+      sender.send(message);
+
+      TextMessage msg = (TextMessage)receiver.receive(TestConfig.TIMEOUT);
+      Assert.assertTrue("Message not received", msg != null);
+      Assert.assertTrue("Message of another test: " + msg.getText(), msg.getText().startsWith("testLike_2"));
+      Assert.assertEquals("testLike_2:2", msg.getText());
+   }
+
+   /**
+    * Test the LIKE condition with '%' in the pattern.
+    * <br />
+    * <ul>
+    *   <li>"phone LIKE '12%3'" is <code>true</code> for '12993' and <code>false</code> for '1234'</li>
+    * </ul>
+    */
+   public void testLike_1() throws Exception
+   {
+      if (receiver != null)
+      {
+         receiver.close();
+      }
+      receiver = receiverSession.createReceiver(receiverQueue, "phone LIKE '12%3'");
+
+      TextMessage dummyMessage = senderSession.createTextMessage();
+      dummyMessage.setStringProperty("phone", "1234");
+      dummyMessage.setText("testLike_1:1");
+      sender.send(dummyMessage);
+
+      TextMessage message = senderSession.createTextMessage();
+      message.setStringProperty("phone", "12993");
+      message.setText("testLike_1:2");
+      sender.send(message);
+
+      TextMessage msg = (TextMessage)receiver.receive(TestConfig.TIMEOUT);
+      Assert.assertTrue("Message not received", msg != null);
+      Assert.assertTrue("Message of another test: " + msg.getText(), msg.getText().startsWith("testLike_1"));
+      Assert.assertEquals("testLike_1:2", msg.getText());
+   }
+
+   /**
+    * Test the <code>NULL</code> value in message selector.
+    * <br />
+    * <ul>
+    *   <li><code>"prop IS NULL"</code></li>
+    * </ul>
+    */
+   public void testNull() throws Exception
+   {
+      if (receiver != null)
+      {
+         receiver.close();
+      }
+      receiver = receiverSession.createReceiver(receiverQueue, "prop_name IS NULL");
+
+      TextMessage dummyMessage = senderSession.createTextMessage();
+      dummyMessage.setStringProperty("prop_name", "not null");
+      dummyMessage.setText("testNull:1");
+      sender.send(dummyMessage);
+
+      TextMessage message = senderSession.createTextMessage();
+      message.setText("testNull:2");
+      sender.send(message);
+
+      TextMessage msg = (TextMessage)receiver.receive(TestConfig.TIMEOUT);
+      Assert.assertTrue(msg != null);
+      Assert.assertEquals("testNull:2", msg.getText());
+   }
+
+   /** 
+    * Method to use this class in a Test suite
+    */
+   public static Test suite()
+   {
+      return new TestSuite(SelectorTest.class);
+   }
+
+   public SelectorTest(final String name)
+   {
+      super(name);
+   }
+}
diff --git a/activemq-tooling/activemq-joram-jms-tests/src/main/java/org/objectweb/jtests/jms/conform/selector/package.html b/activemq-tooling/activemq-joram-jms-tests/src/main/java/org/objectweb/jtests/jms/conform/selector/package.html
new file mode 100644
index 0000000..8332f77
--- /dev/null
+++ b/activemq-tooling/activemq-joram-jms-tests/src/main/java/org/objectweb/jtests/jms/conform/selector/package.html
@@ -0,0 +1,19 @@
+<!--
+    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.
+--> 
+  <body>
+    Tests JMS <em>Selector</em> features.
+  </body>
diff --git a/activemq-tooling/activemq-joram-jms-tests/src/main/java/org/objectweb/jtests/jms/conform/session/QueueSessionTest.java b/activemq-tooling/activemq-joram-jms-tests/src/main/java/org/objectweb/jtests/jms/conform/session/QueueSessionTest.java
new file mode 100644
index 0000000..a99ee7d
--- /dev/null
+++ b/activemq-tooling/activemq-joram-jms-tests/src/main/java/org/objectweb/jtests/jms/conform/session/QueueSessionTest.java
@@ -0,0 +1,201 @@
+/*
+ * Copyright 2009 Red Hat, Inc.
+ * Red Hat 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.
+ */
+
+package org.objectweb.jtests.jms.conform.session;
+
+import javax.jms.InvalidDestinationException;
+import javax.jms.InvalidSelectorException;
+import javax.jms.JMSException;
+import javax.jms.Message;
+import javax.jms.Queue;
+import javax.jms.TextMessage;
+
+import junit.framework.Assert;
+import junit.framework.Test;
+import junit.framework.TestSuite;
+
+import org.objectweb.jtests.jms.framework.PTPTestCase;
+import org.objectweb.jtests.jms.framework.TestConfig;
+
+/**
+ * Test queue sessions
+ * <br />
+ * See JMS specifications, sec. 4.4 Session
+ * 
+ * @author Jeff Mesnil (jmesnil@gmail.com)
+ * @version $Id: QueueSessionTest.java,v 1.2 2007/06/19 23:32:35 csuconic Exp $
+ */
+public class QueueSessionTest extends PTPTestCase
+{
+
+   /**
+    * Test that if we rollback a transaction which has consumed a message,
+    * the message is effectively redelivered.
+    */
+   public void testRollbackRececeivedMessage()
+   {
+      try
+      {
+         senderConnection.stop();
+         // senderSession has been created as non transacted
+         // we create it again but as a transacted session
+         senderSession = senderConnection.createQueueSession(true, 0);
+         Assert.assertEquals(true, senderSession.getTransacted());
+         // we create again the sender
+         sender = senderSession.createSender(senderQueue);
+         senderConnection.start();
+
+         receiverConnection.stop();
+         // receiverSession has been created as non transacted
+         // we create it again but as a transacted session
+         receiverSession = receiverConnection.createQueueSession(true, 0);
+         Assert.assertEquals(true, receiverSession.getTransacted());
+
+         if (receiver != null)
+         {
+            receiver.close();
+         }
+         // we create again the receiver
+         receiver = receiverSession.createReceiver(receiverQueue);
+         receiverConnection.start();
+
+         // we send a message...
+         TextMessage message = senderSession.createTextMessage();
+         message.setText("testRollbackRececeivedMessage");
+         sender.send(message);
+         // ... and commit the *producer* transaction
+         senderSession.commit();
+
+         // we receive a message...
+         Message m = receiver.receive(TestConfig.TIMEOUT);
+         Assert.assertTrue(m != null);
+         Assert.assertTrue(m instanceof TextMessage);
+         TextMessage msg = (TextMessage)m;
+         // ... which is the one which was sent...
+         Assert.assertEquals("testRollbackRececeivedMessage", msg.getText());
+         // ...and has not been redelivered
+         Assert.assertEquals(false, msg.getJMSRedelivered());
+
+         // we rollback the *consumer* transaction
+         receiverSession.rollback();
+
+         // we receive again a message
+         m = receiver.receive(TestConfig.TIMEOUT);
+         Assert.assertTrue(m != null);
+         Assert.assertTrue(m instanceof TextMessage);
+         msg = (TextMessage)m;
+         // ... which is still the one which was sent...
+         Assert.assertEquals("testRollbackRececeivedMessage", msg.getText());
+         // .. but this time, it has been redelivered
+         Assert.assertEquals(true, msg.getJMSRedelivered());
+
+      }
+      catch (Exception e)
+      {
+         fail(e);
+      }
+   }
+
+   /**
+    * Test that a call to the <code>createBrowser()</code> method with an invalid
+    * messaeg session throws a <code>javax.jms.InvalidSelectorException</code>.
+    */
+   public void testCreateBrowser_2()
+   {
+      try
+      {
+         senderSession.createBrowser(senderQueue, "definitely not a message selector!");
+         Assert.fail("Should throw a javax.jms.InvalidSelectorException.\n");
+      }
+      catch (InvalidSelectorException e)
+      {
+      }
+      catch (JMSException e)
+      {
+         Assert.fail("Should throw a javax.jms.InvalidSelectorException, not a " + e);
+      }
+   }
+
+   /**
+    * Test that a call to the <code>createBrowser()</code> method with an invalid
+    * <code>Queue</code> throws a <code>javax.jms.InvalidDestinationException</code>.
+    */
+   public void testCreateBrowser_1()
+   {
+      try
+      {
+         senderSession.createBrowser((Queue)null);
+         Assert.fail("Should throw a javax.jms.InvalidDestinationException.\n");
+      }
+      catch (InvalidDestinationException e)
+      {
+      }
+      catch (JMSException e)
+      {
+         Assert.fail("Should throw a javax.jms.InvalidDestinationException, not a " + e);
+      }
+   }
+
+   /**
+    * Test that a call to the <code>createReceiver()</code> method with an invalid
+    * message selector throws a <code>javax.jms.InvalidSelectorException</code>.
+    */
+   public void testCreateReceiver_2()
+   {
+      try
+      {
+         receiver = senderSession.createReceiver(senderQueue, "definitely not a message selector!");
+         Assert.fail("Should throw a javax.jms.InvalidSelectorException.\n");
+      }
+      catch (InvalidSelectorException e)
+      {
+      }
+      catch (JMSException e)
+      {
+         Assert.fail("Should throw a javax.jms.InvalidSelectorException, not a " + e);
+      }
+   }
+
+   /**
+    * Test that a call to the <code>createReceiver()</code> method with an invalid
+    * <code>Queue</code> throws a <code>javax.jms.InvalidDestinationException</code>>
+    */
+   public void testCreateReceiver_1()
+   {
+      try
+      {
+         receiver = senderSession.createReceiver((Queue)null);
+         Assert.fail("Should throw a javax.jms.InvalidDestinationException.\n");
+      }
+      catch (InvalidDestinationException e)
+      {
+      }
+      catch (JMSException e)
+      {
+         Assert.fail("Should throw a javax.jms.InvalidDestinationException, not a " + e);
+      }
+   }
+
+   /** 
+    * Method to use this class in a Test suite
+    */
+   public static Test suite()
+   {
+      return new TestSuite(QueueSessionTest.class);
+   }
+
+   public QueueSessionTest(final String name)
+   {
+      super(name);
+   }
+}
diff --git a/activemq-tooling/activemq-joram-jms-tests/src/main/java/org/objectweb/jtests/jms/conform/session/SessionTest.java b/activemq-tooling/activemq-joram-jms-tests/src/main/java/org/objectweb/jtests/jms/conform/session/SessionTest.java
new file mode 100644
index 0000000..09582b0
--- /dev/null
+++ b/activemq-tooling/activemq-joram-jms-tests/src/main/java/org/objectweb/jtests/jms/conform/session/SessionTest.java
@@ -0,0 +1,327 @@
+/*
+ * Copyright 2009 Red Hat, Inc.
+ * Red Hat 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.
+ */
+
+package org.objectweb.jtests.jms.conform.session;
+
+import javax.jms.JMSException;
+import javax.jms.Message;
+import javax.jms.Session;
+import javax.jms.TextMessage;
+
+import junit.framework.Assert;
+import junit.framework.Test;
+import junit.framework.TestSuite;
+
+import org.objectweb.jtests.jms.framework.PTPTestCase;
+import org.objectweb.jtests.jms.framework.TestConfig;
+
+/**
+ * Test sessions
+ * <br />
+ * See JMS specifications, sec. 4.4 Session
+ * 
+ * @author Jeff Mesnil (jmesnil@gmail.com)
+ * @version $Id: SessionTest.java,v 1.2 2007/06/19 23:32:35 csuconic Exp $
+ */
+public class SessionTest extends PTPTestCase
+{
+
+   /**
+    * Test that an attempt to call the <code>recover()</code> method on a 
+    * <strong>transacted </strong> <code>Session</code> throws a 
+    * <code>javax.jms.IllegalStateException</code>.
+    */
+   public void testRecoverTransactedSession()
+   {
+      try
+      {
+         // senderSession has been created as non transacted
+         Assert.assertEquals(false, senderSession.getTransacted());
+         // we create it again but as a transacted session
+         senderSession = senderConnection.createQueueSession(true, 0);
+         Assert.assertEquals(true, senderSession.getTransacted());
+         senderSession.recover();
+         Assert.fail("Should raise an IllegalStateException, the session is not transacted.\n");
+      }
+      catch (javax.jms.IllegalStateException e)
+      {
+      }
+      catch (java.lang.IllegalStateException e)
+      {
+         Assert.fail("Should raise a javax.jms.IllegalStateException, not a java.lang.IllegalStateException.\n");
+      }
+      catch (Exception e)
+      {
+         Assert.fail("Should raise a javax.jms.IllegalStateException, not a " + e);
+      }
+   }
+
+   /**
+    * Test that a call to the <code>rollback()</code> method on a 
+    * <strong>transacted</strong> <code>Session</code> rollbacks all
+    * the messages sent in the transaction.
+    */
+   public void testRollbackTransactedSession()
+   {
+      try
+      {
+         // re-create senderSession as a transacted session
+         senderSession = senderConnection.createQueueSession(true, 0);
+         sender = senderSession.createSender(senderQueue);
+         Assert.assertEquals(true, senderSession.getTransacted());
+
+         TextMessage message = senderSession.createTextMessage();
+         message.setText("testRollbackTransactedSession");
+         // send a message within a transacted session
+         sender.send(message);
+
+         // rollback the transaction -> the sent message shouldn't be received
+         senderSession.rollback();
+
+         TextMessage m = (TextMessage)receiver.receiveNoWait();
+         // test that no message has been received
+         Assert.assertEquals(null, m);
+      }
+      catch (Exception e)
+      {
+         fail(e);
+      }
+   }
+
+   /**
+    * Test that a call to the <code>rollback()</code> method on a 
+    * <strong>transacted</strong> <code>Session</code> rollbacks all
+    * the messages sent in the transaction.
+    */
+   public void testCommitTransactedSession()
+   {
+      try
+      {
+         // re-create senderSession as a transacted session
+         senderSession = senderConnection.createQueueSession(true, 0);
+         sender = senderSession.createSender(senderQueue);
+         Assert.assertEquals(true, senderSession.getTransacted());
+
+         TextMessage message = senderSession.createTextMessage();
+         message.setText("testCommitTransactedSession");
+         // send a message within a transacted session
+         sender.send(message);
+
+         TextMessage m = (TextMessage)receiver.receiveNoWait();
+         // test that no message has been received (the transaction has not been committed yet)
+         Assert.assertEquals(null, m);
+
+         // commit the transaction -> the sent message should be received
+         senderSession.commit();
+
+         m = (TextMessage)receiver.receive(TestConfig.TIMEOUT);
+         Assert.assertTrue(m != null);
+         Assert.assertEquals("testCommitTransactedSession", m.getText());
+      }
+      catch (Exception e)
+      {
+         fail(e);
+      }
+   }
+
+   /**
+    * Test that an attempt to call the <code>roolback()</code> method on a 
+    * <strong>non transacted</strong> <code>Session</code> throws a 
+    * <code>javax.jms.IllegalStateException</code>.
+    */
+   public void testRollbackNonTransactedSession()
+   {
+      try
+      {
+         // senderSession has been created as non transacted in the setUp() method
+         Assert.assertEquals(false, senderSession.getTransacted());
+         senderSession.rollback();
+         Assert.fail("Should raise an IllegalStateException, the session is not transacted.\n");
+      }
+      catch (javax.jms.IllegalStateException e)
+      {
+      }
+      catch (java.lang.IllegalStateException e)
+      {
+         Assert.fail("Should raise a javax.jms.IllegalStateException, not a java.lang.IllegalStateException.\n");
+      }
+      catch (Exception e)
+      {
+         Assert.fail("Should raise a javax.jms.IllegalStateException, not a " + e);
+      }
+   }
+
+   /**
+    * Test that an attempt to call the <code>commit()</code> method on a 
+    * <strong>non transacted</strong> <code>Session</code> throws a 
+    * <code>javax.jms.IllegalStateException</code>.
+    */
+   public void testCommitNonTransactedSession()
+   {
+      try
+      {
+         // senderSession has been created as non transacted in the setUp() method
+         Assert.assertEquals(false, senderSession.getTransacted());
+         senderSession.commit();
+         Assert.fail("Should raise an IllegalStateException, the session is not transacted.\n");
+      }
+      catch (javax.jms.IllegalStateException e)
+      {
+      }
+      catch (java.lang.IllegalStateException e)
+      {
+         Assert.fail("Should raise a javax.jms.IllegalStateException, not a java.lang.IllegalStateException.\n");
+      }
+      catch (Exception e)
+      {
+         Assert.fail("Should raise a javax.jms.IllegalStateException, not a " + e);
+      }
+   }
+
+   /**
+    * Test that the <code>getTransacted()</code> method of a <code>Session</code> returns <code>true</code>
+    * if the session is transacted, <code>false</code> else.
+    */
+   public void testGetTransacted()
+   {
+      try
+      {
+         // senderSession has been created as non transacted
+         Assert.assertEquals(false, senderSession.getTransacted());
+         // we re-create senderSession as a transacted session
+         senderSession = senderConnection.createQueueSession(true, Session.AUTO_ACKNOWLEDGE);
+         Assert.assertEquals(true, senderSession.getTransacted());
+      }
+      catch (Exception e)
+      {
+         fail(e);
+      }
+   }
+
+   /**
+    * Test that invoking the <code>acknowledge()</code> method of a received message 
+    * from a closed session must throw an <code>IllegalStateException</code>.
+    */
+   public void testAcknowledge()
+   {
+      try
+      {
+         if (receiverSession != null)
+         {
+            receiverSession.close();
+         }
+         receiverSession = receiverConnection.createQueueSession(false, Session.CLIENT_ACKNOWLEDGE);
+         receiver = receiverSession.createReceiver(receiverQueue);
+
+         Message message = senderSession.createMessage();
+         sender.send(message);
+
+         Message m = receiver.receive(TestConfig.TIMEOUT);
+         receiverSession.close();
+         m.acknowledge();
+         Assert.fail("sec. 4.4.1 Invoking the acknowledge method of a received message from a closed " + " session must throw an [javax.jms.]IllegalStateException.\n");
+      }
+      catch (javax.jms.IllegalStateException e)
+      {
+      }
+      catch (JMSException e)
+      {
+         Assert.fail("Should raise a javax.jms.IllegalStateException, not a " + e);
+      }
+      catch (java.lang.IllegalStateException e)
+      {
+         Assert.fail("sec. 4.4.1 Invoking the acknowledge method of a received message from a closed " + "session must throw an [javax.jms.]IllegalStateException, "
+                     + "[not a java.lang.IllegalStateException]");
+      }
+   }
+
+   /** 
+    * Test that it is valid to use message objects created or received via the [closed] session with the
+    * exception of a received message <code>acknowledge()</code> method.
+    */
+   public void testUseMessage()
+   {
+      try
+      {
+         TextMessage message = senderSession.createTextMessage();
+         message.setText("testUseMessage");
+         sender.send(message);
+
+         TextMessage m = (TextMessage)receiver.receive(TestConfig.TIMEOUT);
+         receiverSession.close();
+         Assert.assertEquals("testUseMessage", m.getText());
+      }
+      catch (Exception e)
+      {
+         Assert.fail("sec. 4.4.1 It is valid to continue to use message objects created or received via " + "the [closed] session.\n");
+      }
+   }
+
+   /**
+    * Test that an attempt to use a <code>Session</code> which has been closed
+    * throws a <code>javax.jms.IllegalStateException</code>.
+    */
+   public void testUsedClosedSession()
+   {
+      try
+      {
+         senderSession.close();
+         senderSession.createMessage();
+         Assert.fail("sec. 4.4.1 An attempt to use [a closed session] must throw a [javax.jms.]IllegalStateException.\n");
+      }
+      catch (javax.jms.IllegalStateException e)
+      {
+      }
+      catch (JMSException e)
+      {
+         Assert.fail("Should raise a javax.jms.IllegalStateException, not a " + e);
+      }
+      catch (java.lang.IllegalStateException e)
+      {
+         Assert.fail("Should raise a javax.jms.IllegalStateException, not a java.lang.IllegalStateException");
+      }
+   }
+
+   /**
+    * Test that closing a closed session does <strong>not</strong> throw
+    * an exception.
+    */
+   public void testCloseClosedSession()
+   {
+      try
+      {
+         // senderSession is already started
+         // we close it once
+         senderSession.close();
+         // we close it a second time
+         senderSession.close();
+      }
+      catch (Exception e)
+      {
+         Assert.fail("sec. 4.4.1 Closing a closed session must NOT throw an exception.\n");
+      }
+   }
+
+   /** 
+    * Method to use this class in a Test suite
+    */
+   public static Test suite()
+   {
+      return new TestSuite(SessionTest.class);
+   }
+
+   public SessionTest(final String name)
+   {
+      super(name);
+   }
+}
diff --git a/activemq-tooling/activemq-joram-jms-tests/src/main/java/org/objectweb/jtests/jms/conform/session/TopicSessionTest.java b/activemq-tooling/activemq-joram-jms-tests/src/main/java/org/objectweb/jtests/jms/conform/session/TopicSessionTest.java
new file mode 100644
index 0000000..80c321b
--- /dev/null
+++ b/activemq-tooling/activemq-joram-jms-tests/src/main/java/org/objectweb/jtests/jms/conform/session/TopicSessionTest.java
@@ -0,0 +1,242 @@
+/*
+ * Copyright 2009 Red Hat, Inc.
+ * Red Hat 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.
+ */
+
+package org.objectweb.jtests.jms.conform.session;
+
+import javax.jms.InvalidDestinationException;
+import javax.jms.InvalidSelectorException;
+import javax.jms.JMSException;
+import javax.jms.Message;
+import javax.jms.Session;
+import javax.jms.TextMessage;
+import javax.jms.Topic;
+
+import junit.framework.Assert;
+import junit.framework.Test;
+import junit.framework.TestSuite;
+
+import org.objectweb.jtests.jms.framework.PubSubTestCase;
+import org.objectweb.jtests.jms.framework.TestConfig;
+
+/**
+ * Test topic sessions
+ * <br />
+ * See JMS specifications, sec. 4.4 Session
+ * 
+ * @author Jeff Mesnil (jmesnil@gmail.com)
+ * @version $Id: TopicSessionTest.java,v 1.2 2007/06/19 23:32:35 csuconic Exp $
+ */
+public class TopicSessionTest extends PubSubTestCase
+{
+
+   /**
+    * Test that if we rollback a transaction which has consumed a message,
+    * the message is effectively redelivered.
+    */
+   public void testRollbackReceivedMessage()
+   {
+      try
+      {
+         publisherConnection.stop();
+         // publisherSession has been declared has non transacted
+         // we recreate it as a transacted session
+         publisherSession = publisherConnection.createTopicSession(true, 0);
+         Assert.assertEquals(true, publisherSession.getTransacted());
+         // we also recreate the publisher
+         publisher = publisherSession.createPublisher(publisherTopic);
+         publisherConnection.start();
+
+         subscriberConnection.stop();
+         // subscriberSession has been declared has non transacted
+         // we recreate it as a transacted session
+         subscriberSession = subscriberConnection.createTopicSession(true, 0);
+         Assert.assertEquals(true, subscriberSession.getTransacted());
+         // we also recreate the subscriber
+         subscriber = subscriberSession.createSubscriber(subscriberTopic);
+         subscriberConnection.start();
+
+         // we create a message...
+         TextMessage message = publisherSession.createTextMessage();
+         message.setText("testRollbackReceivedMessage");
+         // ... publish it ...
+         publisher.publish(message);
+         // ... and commit the transaction
+         publisherSession.commit();
+
+         // we receive it
+         Message msg1 = subscriber.receive(TestConfig.TIMEOUT);
+         Assert.assertTrue("no message received", msg1 != null);
+         Assert.assertTrue(msg1 instanceof TextMessage);
+         Assert.assertEquals("testRollbackReceivedMessage", ((TextMessage)msg1).getText());
+
+         // we rollback the transaction of subscriberSession
+         subscriberSession.rollback();
+
+         // we expect to receive a second time the message
+         Message msg2 = subscriber.receive(TestConfig.TIMEOUT);
+         Assert.assertTrue("no message received after rollbacking subscriber session.", msg2 != null);
+         Assert.assertTrue(msg2 instanceof TextMessage);
+         Assert.assertEquals("testRollbackReceivedMessage", ((TextMessage)msg2).getText());
+
+         // finally we commit the subscriberSession transaction
+         subscriberSession.commit();
+      }
+      catch (Exception e)
+      {
+         fail(e);
+      }
+   }
+
+   /**
+    * Test that a durable subscriber effectively receives the messages sent to its
+    * topic while it was inactive.
+    */
+   public void testDurableSubscriber()
+   {
+      try
+      {
+         subscriber = subscriberSession.createDurableSubscriber(subscriberTopic, "testTopic");
+         subscriberConnection.close();
+         subscriberConnection = null;
+
+         TextMessage message = publisherSession.createTextMessage();
+         message.setText("test");
+         publisher.publish(message);
+
+         subscriberConnection = subscriberTCF.createTopicConnection();
+         subscriberConnection.setClientID("subscriberConnection");
+         subscriberSession = subscriberConnection.createTopicSession(false, Session.AUTO_ACKNOWLEDGE);
+         subscriber = subscriberSession.createDurableSubscriber(subscriberTopic, "testTopic");
+         subscriberConnection.start();
+
+         TextMessage m = (TextMessage)subscriber.receive(TestConfig.TIMEOUT);
+         Assert.assertTrue(m != null);
+         Assert.assertEquals("test", m.getText());
+      }
+      catch (JMSException e)
+      {
+         fail(e);
+      }
+   }
+
+   /**
+    * Test the unsubscription of a durable subscriber.
+    */
+   public void testUnsubscribe()
+   {
+      try
+      {
+         subscriber = subscriberSession.createDurableSubscriber(subscriberTopic, "topic");
+         subscriber.close();
+         // nothing should happen when unsubscribing the durable subscriber
+         subscriberSession.unsubscribe("topic");
+      }
+      catch (JMSException e)
+      {
+         fail(e);
+      }
+   }
+
+   /**
+    * Test that a call to the <code>createDurableSubscriber()</code> method with an invalid
+    * message selector throws a <code>javax.jms.InvalidSelectorException</code>.
+    */
+   public void testCreateDurableSubscriber_2()
+   {
+      try
+      {
+         subscriberSession.createDurableSubscriber(subscriberTopic, "topic", "definitely not a message selector!", true);
+         Assert.fail("Should throw a javax.jms.InvalidSelectorException.\n");
+      }
+      catch (InvalidSelectorException e)
+      {
+      }
+      catch (JMSException e)
+      {
+         Assert.fail("Should throw a javax.jms.InvalidSelectorException, not a " + e);
+      }
+   }
+
+   /**
+    * Test that a call to the <code>createDurableSubscriber()</code> method with an invalid
+    * <code>Topic</code> throws a <code>javax.jms.InvalidDestinationException</code>.
+    */
+   public void testCreateDurableSubscriber_1()
+   {
+      try
+      {
+         subscriberSession.createDurableSubscriber((Topic)null, "topic");
+         Assert.fail("Should throw a javax.jms.InvalidDestinationException.\n");
+      }
+      catch (InvalidDestinationException e)
+      {
+      }
+      catch (JMSException e)
+      {
+         Assert.fail("Should throw a javax.jms.InvalidDestinationException, not a " + e);
+      }
+   }
+
+   /**
+    * Test that a call to the <code>createSubscriber()</code> method with an invalid
+    * message selector throws a <code>javax.jms.InvalidSelectorException</code>.
+    */
+   public void testCreateSubscriber_2()
+   {
+      try
+      {
+         subscriberSession.createSubscriber(subscriberTopic, "definitely not a message selector!", true);
+         Assert.fail("Should throw a javax.jms.InvalidSelectorException.\n");
+      }
+      catch (InvalidSelectorException e)
+      {
+      }
+      catch (JMSException e)
+      {
+         Assert.fail("Should throw a javax.jms.InvalidSelectorException, not a " + e);
+      }
+   }
+
+   /**
+    * Test that a call to the <code>createSubscriber()</code> method with an invalid
+    * <code>Topic</code> throws a <code>javax.jms.InvalidDestinationException</code>.
+    */
+   public void testCreateSubscriber_1()
+   {
+      try
+      {
+         subscriberSession.createSubscriber((Topic)null);
+         Assert.fail("Should throw a javax.jms.InvalidDestinationException.\n");
+      }
+      catch (InvalidDestinationException e)
+      {
+      }
+      catch (JMSException e)
+      {
+         Assert.fail("Should throw a javax.jms.InvalidDestinationException, not a " + e);
+      }
+   }
+
+   /** 
+    * Method to use this class in a Test suite
+    */
+   public static Test suite()
+   {
+      return new TestSuite(TopicSessionTest.class);
+   }
+
+   public TopicSessionTest(final String name)
+   {
+      super(name);
+   }
+}
diff --git a/activemq-tooling/activemq-joram-jms-tests/src/main/java/org/objectweb/jtests/jms/conform/session/UnifiedSessionTest.java b/activemq-tooling/activemq-joram-jms-tests/src/main/java/org/objectweb/jtests/jms/conform/session/UnifiedSessionTest.java
new file mode 100644
index 0000000..12a6c1e
--- /dev/null
+++ b/activemq-tooling/activemq-joram-jms-tests/src/main/java/org/objectweb/jtests/jms/conform/session/UnifiedSessionTest.java
@@ -0,0 +1,307 @@
+/*
+ * Copyright 2009 Red Hat, Inc.
+ * Red Hat 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.
+ */
+
+package org.objectweb.jtests.jms.conform.session;
+
+import javax.jms.JMSException;
+import javax.jms.QueueConnection;
+import javax.jms.QueueSession;
+import javax.jms.ServerSessionPool;
+import javax.jms.Session;
+import javax.jms.TopicConnection;
+import javax.jms.TopicSession;
+
+import junit.framework.Assert;
+import junit.framework.Test;
+import junit.framework.TestSuite;
+
+import org.objectweb.jtests.jms.framework.UnifiedTestCase;
+
+/**
+ * Test unified JMS 1.1 sessions.
+ * <br />
+ * See JMS 1.1 specifications
+ * 
+ * @author Jeff Mesnil (jmesnil@gmail.com)
+ * @version $Id: UnifiedSessionTest.java,v 1.1 2007/03/29 04:28:37 starksm Exp $
+ * @since JMS 1.1
+ */
+public class UnifiedSessionTest extends UnifiedTestCase
+{
+
+   /**
+    * QueueConnection
+    */
+   protected QueueConnection queueConnection;
+
+   /**
+    * QueueSession (non transacted, AUTO_ACKNOWLEDGE)
+    */
+   protected QueueSession queueSession;
+
+   /**
+    * TopicConnection
+    */
+   protected TopicConnection topicConnection;
+
+   /**
+    * TopicSession (non transacted, AUTO_ACKNOWLEDGE)
+    */
+   protected TopicSession topicSession;
+
+   /**
+    * Test that a call to <code>createDurableConnectionConsumer()</code> method 
+    * on a <code>QueueConnection</code> throws a 
+    * <code>javax.jms.IllegalStateException</code>.
+    * (see JMS 1.1 specs, table 4-1).
+    * 
+    * @since JMS 1.1
+    */
+   public void testCreateDurableConnectionConsumerOnQueueConnection()
+   {
+      try
+      {
+         queueConnection.createDurableConnectionConsumer(topic, "subscriptionName", "", (ServerSessionPool)null, 1);
+         Assert.fail("Should throw a javax.jms.IllegalStateException");
+      }
+      catch (javax.jms.IllegalStateException e)
+      {
+      }
+      catch (JMSException e)
+      {
+         Assert.fail("Should throw a javax.jms.IllegalStateException, not a " + e);
+      }
+   }
+
+   /**
+    * Test that a call to <code>createDurableSubscriber()</code> method 
+    * on a <code>QueueSession</code> throws a 
+    * <code>javax.jms.IllegalStateException</code>.
+    * (see JMS 1.1 specs, table 4-1).
+    * 
+    * @since JMS 1.1
+    */
+   public void testCreateDurableSubscriberOnQueueSession()
+   {
+      try
+      {
+         queueSession.createDurableSubscriber(topic, "subscriptionName");
+         Assert.fail("Should throw a javax.jms.IllegalStateException");
+      }
+      catch (javax.jms.IllegalStateException e)
+      {
+      }
+      catch (JMSException e)
+      {
+         Assert.fail("Should throw a javax.jms.IllegalStateException, not a " + e);
+      }
+   }
+
+   /**
+    * Test that a call to <code>createTemporaryTopic()</code> method 
+    * on a <code>QueueSession</code> throws a 
+    * <code>javax.jms.IllegalStateException</code>.
+    * (see JMS 1.1 specs, table 4-1).
+    * 
+    * @since JMS 1.1
+    */
+   public void testCreateTemporaryTopicOnQueueSession()
+   {
+      try
+      {
+         queueSession.createTemporaryTopic();
+         Assert.fail("Should throw a javax.jms.IllegalStateException");
+      }
+      catch (javax.jms.IllegalStateException e)
+      {
+      }
+      catch (JMSException e)
+      {
+         Assert.fail("Should throw a javax.jms.IllegalStateException, not a " + e);
+      }
+   }
+
+   /**
+    * Test that a call to <code>createTopic()</code> method 
+    * on a <code>QueueSession</code> throws a 
+    * <code>javax.jms.IllegalStateException</code>.
+    * (see JMS 1.1 specs, table 4-1).
+    * 
+    * @since JMS 1.1
+    */
+   public void testCreateTopicOnQueueSession()
+   {
+      try
+      {
+         queueSession.createTopic("topic_name");
+         Assert.fail("Should throw a javax.jms.IllegalStateException");
+      }
+      catch (javax.jms.IllegalStateException e)
+      {
+      }
+      catch (JMSException e)
+      {
+         Assert.fail("Should throw a javax.jms.IllegalStateException, not a " + e);
+      }
+   }
+
+   /**
+    * Test that a call to <code>unsubscribe()</code> method 
+    * on a <code>QueueSession</code> throws a 
+    * <code>javax.jms.IllegalStateException</code>.
+    * (see JMS 1.1 specs, table 4-1).
+    * 
+    * @since JMS 1.1
+    */
+   public void testUnsubscribeOnQueueSession()
+   {
+      try
+      {
+         queueSession.unsubscribe("subscriptionName");
+         Assert.fail("Should throw a javax.jms.IllegalStateException");
+      }
+      catch (javax.jms.IllegalStateException e)
+      {
+      }
+      catch (JMSException e)
+      {
+         Assert.fail("Should throw a javax.jms.IllegalStateException, not a " + e);
+      }
+   }
+
+   /**
+    * Test that a call to <code>createBrowser()</code> method 
+    * on a <code>TopicSession</code> throws a 
+    * <code>javax.jms.IllegalStateException</code>.
+    * (see JMS 1.1 specs, table 4-1).
+    * 
+    * @since JMS 1.1
+    */
+   public void testCreateBrowserOnTopicSession()
+   {
+      try
+      {
+         topicSession.createBrowser(queue);
+         Assert.fail("Should throw a javax.jms.IllegalStateException");
+      }
+      catch (javax.jms.IllegalStateException e)
+      {
+      }
+      catch (JMSException e)
+      {
+         Assert.fail("Should throw a javax.jms.IllegalStateException, not a " + e);
+      }
+   }
+
+   /**
+    * Test that a call to <code>createQueue()</code> method 
+    * on a <code>TopicSession</code> throws a 
+    * <code>javax.jms.IllegalStateException</code>.
+    * (see JMS 1.1 specs, table 4-1).
+    * 
+    * @since JMS 1.1
+    */
+   public void testCreateQueueOnTopicSession()
+   {
+      try
+      {
+         topicSession.createQueue("queue_name");
+         Assert.fail("Should throw a javax.jms.IllegalStateException");
+      }
+      catch (javax.jms.IllegalStateException e)
+      {
+      }
+      catch (JMSException e)
+      {
+         Assert.fail("Should throw a javax.jms.IllegalStateException, not a " + e);
+      }
+   }
+
+   /**
+    * Test that a call to <code>createTemporaryQueue()</code> method 
+    * on a <code>TopicSession</code> throws a 
+    * <code>javax.jms.IllegalStateException</code>.
+    * (see JMS 1.1 specs, table 4-1).
+    * 
+    * @since JMS 1.1
+    */
+   public void testCreateTemporaryQueueOnTopicSession()
+   {
+      try
+      {
+         topicSession.createTemporaryQueue();
+         Assert.fail("Should throw a javax.jms.IllegalStateException");
+      }
+      catch (javax.jms.IllegalStateException e)
+      {
+      }
+      catch (JMSException e)
+      {
+         Assert.fail("Should throw a javax.jms.IllegalStateException, not a " + e);
+      }
+   }
+
+   @Override
+   public void setUp() throws Exception
+   {
+      super.setUp();
+      try
+      {
+         queueConnection = queueConnectionFactory.createQueueConnection();
+         queueSession = queueConnection.createQueueSession(false, Session.AUTO_ACKNOWLEDGE);
+         topicConnection = topicConnectionFactory.createTopicConnection();
+         topicSession = topicConnection.createTopicSession(false, Session.AUTO_ACKNOWLEDGE);
+
+         queueConnection.start();
+         topicConnection.start();
+      }
+      catch (Exception e)
+      {
+         throw new RuntimeException(e);
+      }
+   }
+
+   @Override
+   public void tearDown() throws Exception
+   {
+      try
+      {
+         queueConnection.close();
+         topicConnection.close();
+      }
+      catch (Exception ignored)
+      {
+      }
+      finally
+      {
+         queueConnection = null;
+         queueSession = null;
+         topicConnection = null;
+         topicSession = null;
+         super.tearDown();
+      }
+   }
+
+   /** 
+    * Method to use this class in a Test suite
+    */
+   public static Test suite()
+   {
+      return new TestSuite(UnifiedSessionTest.class);
+   }
+
+   public UnifiedSessionTest(final String name)
+   {
+      super(name);
+   }
+}
diff --git a/activemq-tooling/activemq-joram-jms-tests/src/main/java/org/objectweb/jtests/jms/conform/session/package.html b/activemq-tooling/activemq-joram-jms-tests/src/main/java/org/objectweb/jtests/jms/conform/session/package.html
new file mode 100644
index 0000000..8a72383
--- /dev/null
+++ b/activemq-tooling/activemq-joram-jms-tests/src/main/java/org/objectweb/jtests/jms/conform/session/package.html
@@ -0,0 +1,20 @@
+<!--
+    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.
+-->
+  <body>
+    Tests JMS <em>Session</em> features.
+  </body>
+  
diff --git a/activemq-tooling/activemq-joram-jms-tests/src/main/java/org/objectweb/jtests/jms/conform/topic/TemporaryTopicTest.java b/activemq-tooling/activemq-joram-jms-tests/src/main/java/org/objectweb/jtests/jms/conform/topic/TemporaryTopicTest.java
new file mode 100644
index 0000000..8c3e68c
--- /dev/null
+++ b/activemq-tooling/activemq-joram-jms-tests/src/main/java/org/objectweb/jtests/jms/conform/topic/TemporaryTopicTest.java
@@ -0,0 +1,89 @@
+/*
+ * Copyright 2009 Red Hat, Inc.
+ * Red Hat 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.
+ */
+
+package org.objectweb.jtests.jms.conform.topic;
+
+import javax.jms.JMSException;
+import javax.jms.Message;
+import javax.jms.TemporaryTopic;
+import javax.jms.TextMessage;
+import javax.jms.TopicSubscriber;
+
+import junit.framework.Assert;
+import junit.framework.Test;
+import junit.framework.TestSuite;
+
+import org.objectweb.jtests.jms.framework.PubSubTestCase;
+import org.objectweb.jtests.jms.framework.TestConfig;
+
+/**
+ * Test the <code>javax.jms.TemporaryTopic</code> features.
+ *
+ * @author Jeff Mesnil (jmesnil@gmail.com)
+ * @version $Id: TemporaryTopicTest.java,v 1.1 2007/03/29 04:28:34 starksm Exp $
+ */
+public class TemporaryTopicTest extends PubSubTestCase
+{
+
+   private TemporaryTopic tempTopic;
+
+   private TopicSubscriber tempSubscriber;
+
+   /**
+    * Test a TemporaryTopic
+    */
+   public void testTemporaryTopic()
+   {
+      try
+      {
+         // we stop both publisher and subscriber connections
+         publisherConnection.stop();
+         subscriberConnection.stop();
+         // we create a temporary topic to receive messages
+         tempTopic = subscriberSession.createTemporaryTopic();
+         // we recreate the sender because it has been
+         // already created with another Destination as parameter
+         publisher = publisherSession.createPublisher(tempTopic);
+         // we create a temporary subscriber on the temporary topic
+         tempSubscriber = subscriberSession.createSubscriber(tempTopic);
+         subscriberConnection.start();
+         publisherConnection.start();
+
+         TextMessage message = publisherSession.createTextMessage();
+         message.setText("testTemporaryTopic");
+         publisher.publish(message);
+
+         Message m = tempSubscriber.receive(TestConfig.TIMEOUT);
+         Assert.assertTrue(m instanceof TextMessage);
+         TextMessage msg = (TextMessage)m;
+         Assert.assertEquals("testTemporaryTopic", msg.getText());
+      }
+      catch (JMSException e)
+      {
+         fail(e);
+      }
+   }
+
+   /** 
+    * Method to use this class in a Test suite
+    */
+   public static Test suite()
+   {
+      return new TestSuite(TemporaryTopicTest.class);
+   }
+
+   public TemporaryTopicTest(final String name)
+   {
+      super(name);
+   }
+}
diff --git a/activemq-tooling/activemq-joram-jms-tests/src/main/java/org/objectweb/jtests/jms/conform/topic/package.html b/activemq-tooling/activemq-joram-jms-tests/src/main/java/org/objectweb/jtests/jms/conform/topic/package.html
new file mode 100644
index 0000000..67dba99
--- /dev/null
+++ b/activemq-tooling/activemq-joram-jms-tests/src/main/java/org/objectweb/jtests/jms/conform/topic/package.html
@@ -0,0 +1,19 @@
+<!--
+    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.
+-->  
+  <body>
+    Tests JMS <em>Topic</em> features.
+  </body>
diff --git a/activemq-tooling/activemq-joram-jms-tests/src/main/java/org/objectweb/jtests/jms/framework/JMSTestCase.java b/activemq-tooling/activemq-joram-jms-tests/src/main/java/org/objectweb/jtests/jms/framework/JMSTestCase.java
new file mode 100644
index 0000000..d140fa2
--- /dev/null
+++ b/activemq-tooling/activemq-joram-jms-tests/src/main/java/org/objectweb/jtests/jms/framework/JMSTestCase.java
@@ -0,0 +1,121 @@
+/*
+ * Copyright 2009 Red Hat, Inc.
+ * Red Hat 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.
+ */
+
+package org.objectweb.jtests.jms.framework;
+
+import java.io.IOException;
+import java.util.Properties;
+
+import javax.jms.JMSException;
+
+import junit.framework.TestCase;
+
+import org.objectweb.jtests.jms.admin.Admin;
+import org.objectweb.jtests.jms.admin.AdminFactory;
+
+/**
+ * Class extending <code>junit.framework.TestCase</code> to
+ * provide a new <code>fail()</code> method with an <code>Exception</code>
+ * as parameter.
+ *<br />
+ * Every Test Case for JMS should extend this class instead of <code>junit.framework.TestCase</code>
+ *
+ * @author Jeff Mesnil (jmesnil@gmail.com)
+ * @version $Id: JMSTestCase.java,v 1.2 2007/07/19 21:20:08 csuconic Exp $
+ */
+public abstract class JMSTestCase extends TestCase
+{
+   public static final String PROP_FILE_NAME = "provider.properties";
+
+   public static boolean startServer = true;
+
+   protected Admin admin;
+
+   /**
+    * Fails a test with an exception which will be used for a message.
+    *
+    * If the exception is an instance of <code>javax.jms.JMSException</code>, the
+    * message of the failure will contained both the JMSException and its linked exception
+    * (provided there's one).
+    */
+   public void fail(final Exception e)
+   {
+      if (e instanceof javax.jms.JMSException)
+      {
+         JMSException exception = (JMSException)e;
+         String message = e.toString();
+         Exception linkedException = exception.getLinkedException();
+         if (linkedException != null)
+         {
+            message += " [linked exception: " + linkedException + "]";
+         }
+         super.fail(message);
+      }
+      else
+      {
+         super.fail(e.getMessage());
+      }
+   }
+
+   public JMSTestCase(final String name)
+   {
+      super(name);
+   }
+
+   /**
+    * Should be overriden
+    * @return
+    */
+   protected Properties getProviderProperties() throws IOException
+   {
+      Properties props = new Properties();
+      props.load(getClass().getClassLoader().getResourceAsStream(System.getProperty("joram.jms.test.file", JMSTestCase.PROP_FILE_NAME)));
+      return props;
+   }
+
+   @Override
+   protected void setUp() throws Exception
+   {
+      super.setUp();
+
+      // Admin step
+      // gets the provider administration wrapper...
+      Properties props = getProviderProperties();
+      admin = AdminFactory.getAdmin(props);
+
+      if (startServer)
+      {
+         admin.startServer();
+      }
+      admin.start();
+   }
+
+   @Override
+   protected void tearDown() throws Exception
+   {
+      try
+      {
+         admin.stop();
+
+         if (startServer)
+         {
+            admin.stopServer();
+         }
+      }
+      finally
+      {
+         super.tearDown();
+      }
+   }
+
+}
diff --git a/activemq-tooling/activemq-joram-jms-tests/src/main/java/org/objectweb/jtests/jms/framework/PTPTestCase.java b/activemq-tooling/activemq-joram-jms-tests/src/main/java/org/objectweb/jtests/jms/framework/PTPTestCase.java
new file mode 100644
index 0000000..fbf136e
--- /dev/null
+++ b/activemq-tooling/activemq-joram-jms-tests/src/main/java/org/objectweb/jtests/jms/framework/PTPTestCase.java
@@ -0,0 +1,178 @@
+/*
+ * Copyright 2009 Red Hat, Inc.
+ * Red Hat 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.
+ */
+
+package org.objectweb.jtests.jms.framework;
+
+import javax.jms.Queue;
+import javax.jms.QueueConnection;
+import javax.jms.QueueConnectionFactory;
+import javax.jms.QueueReceiver;
+import javax.jms.QueueSender;
+import javax.jms.QueueSession;
+import javax.jms.Session;
+import javax.naming.Context;
+
+/**
+ * Creates convenient Point to Point JMS objects which can be needed for tests.
+ * <br />
+ * This class defines the setUp and tearDown methods so
+ * that JMS administrated objects and  other "ready to use" PTP objects (that is to say queues,
+ * sessions, senders and receviers) are available conveniently for the test cases.
+ * <br />
+ * Classes which want that convenience should extend <code>PTPTestCase</code> instead of 
+ * <code>JMSTestCase</code>.
+ *
+ * @author Jeff Mesnil (jmesnil@gmail.com)
+ * @version $Id: PTPTestCase.java,v 1.1 2007/03/29 04:28:35 starksm Exp $
+ */
+public abstract class PTPTestCase extends JMSTestCase
+{
+
+   protected Context ctx;
+
+   private static final String QCF_NAME = "testQCF";
+
+   private static final String QUEUE_NAME = "testJoramQueue";
+
+   /**
+    * Queue used by a sender
+    */
+   protected Queue senderQueue;
+
+   /**
+    * Sender on queue
+    */
+   protected QueueSender sender;
+
+   /**
+    * QueueConnectionFactory of the sender
+    */
+   protected QueueConnectionFactory senderQCF;
+
+   /**
+    * QueueConnection of the sender
+    */
+   protected QueueConnection senderConnection;
+
+   /**
+    * QueueSession of the sender (non transacted, AUTO_ACKNOWLEDGE)
+    */
+   protected QueueSession senderSession;
+
+   /**
+    * Queue used by a receiver
+    */
+   protected Queue receiverQueue;
+
+   /**
+    * Receiver on queue
+    */
+   protected QueueReceiver receiver;
+
+   /**
+    * QueueConnectionFactory of the receiver
+    */
+   protected QueueConnectionFactory receiverQCF;
+
+   /**
+    * QueueConnection of the receiver
+    */
+   protected QueueConnection receiverConnection;
+
+   /**
+    * QueueSession of the receiver (non transacted, AUTO_ACKNOWLEDGE)
+    */
+   protected QueueSession receiverSession;
+
+   /**
+    * Create all administrated objects connections and sessions ready to use for tests.
+    * <br />
+    * Start connections.
+    */
+   @Override
+   protected void setUp() throws Exception
+   {
+      super.setUp();
+
+      try
+      {
+         // ...and creates administrated objects and binds them
+         admin.createQueueConnectionFactory(PTPTestCase.QCF_NAME);
+         admin.createQueue(PTPTestCase.QUEUE_NAME);
+
+         // end of admin step, start of JMS client step
+         ctx = admin.createContext();
+
+         senderQCF = (QueueConnectionFactory)ctx.lookup(PTPTestCase.QCF_NAME);
+         senderQueue = (Queue)ctx.lookup(PTPTestCase.QUEUE_NAME);
+         senderConnection = senderQCF.createQueueConnection();
+         senderSession = senderConnection.createQueueSession(false, Session.AUTO_ACKNOWLEDGE);
+         sender = senderSession.createSender(senderQueue);
+
+         receiverQCF = (QueueConnectionFactory)ctx.lookup(PTPTestCase.QCF_NAME);
+         receiverQueue = (Queue)ctx.lookup(PTPTestCase.QUEUE_NAME);
+         receiverConnection = receiverQCF.createQueueConnection();
+         receiverSession = receiverConnection.createQueueSession(false, Session.AUTO_ACKNOWLEDGE);
+         receiver = receiverSession.createReceiver(receiverQueue);
+
+         senderConnection.start();
+         receiverConnection.start();
+         // end of client step
+      }
+      catch (Exception e)
+      {
+         throw new RuntimeException(e);
+      }
+   }
+
+   /**
+    *  Close connections and delete administrated objects
+    */
+   @Override
+   protected void tearDown() throws Exception
+   {
+      try
+      {
+         senderConnection.close();
+         receiverConnection.close();
+
+         admin.deleteQueueConnectionFactory(PTPTestCase.QCF_NAME);
+         admin.deleteQueue(PTPTestCase.QUEUE_NAME);
+      }
+      catch (Exception ignored)
+      {
+         ignored.printStackTrace();
+      }
+      finally
+      {
+         senderQueue = null;
+         sender = null;
+         senderQCF = null;
+         senderSession = null;
+         senderConnection = null;
+
+         receiverQueue = null;
+         receiver = null;
+         receiverQCF = null;
+         receiverSession = null;
+         receiverConnection = null;
+      }
+
+      super.tearDown();
+   }
+
+   public PTPTestCase(final String name)
+   {
+      super(name);
+   }
+}
diff --git a/activemq-tooling/activemq-joram-jms-tests/src/main/java/org/objectweb/jtests/jms/framework/PubSubTestCase.java b/activemq-tooling/activemq-joram-jms-tests/src/main/java/org/objectweb/jtests/jms/framework/PubSubTestCase.java
new file mode 100644
index 0000000..6502ea6
--- /dev/null
+++ b/activemq-tooling/activemq-joram-jms-tests/src/main/java/org/objectweb/jtests/jms/framework/PubSubTestCase.java
@@ -0,0 +1,180 @@
+/*
+ * Copyright 2009 Red Hat, Inc.
+ * Red Hat 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.
+ */
+
+package org.objectweb.jtests.jms.framework;
+
+import javax.jms.Session;
+import javax.jms.Topic;
+import javax.jms.TopicConnection;
+import javax.jms.TopicConnectionFactory;
+import javax.jms.TopicPublisher;
+import javax.jms.TopicSession;
+import javax.jms.TopicSubscriber;
+import javax.naming.Context;
+
+/**
+ * Creates convenient JMS Publish/Subscribe objects which can be needed for tests.
+ * <br />
+ * This class defines the setUp and tearDown methods so
+ * that JMS administrated objects and  other "ready to use" Pub/Sub objects (that is to say topics,
+ * sessions, publishers and subscribers) are available conveniently for the test cases.
+ * <br />
+ * Classes which want that convenience should extend <code>PubSubTestCase</code> instead of 
+ * <code>JMSTestCase</code>.
+ *
+ * @author Jeff Mesnil (jmesnil@gmail.com)
+ * @version $Id: PubSubTestCase.java,v 1.2 2007/06/19 23:32:35 csuconic Exp $
+ */
+public abstract class PubSubTestCase extends JMSTestCase
+{
+
+   private Context ctx;
+
+   private static final String TCF_NAME = "testTCF";
+
+   private static final String TOPIC_NAME = "testJoramTopic";
+
+   /**
+    * Topic used by a publisher
+    */
+   protected Topic publisherTopic;
+
+   /**
+    * Publisher on queue
+    */
+   protected TopicPublisher publisher;
+
+   /**
+    * TopicConnectionFactory of the publisher
+    */
+   protected TopicConnectionFactory publisherTCF;
+
+   /**
+    * TopicConnection of the publisher
+    */
+   protected TopicConnection publisherConnection;
+
+   /**
+    * TopicSession of the publisher (non transacted, AUTO_ACKNOWLEDGE)
+    */
+   protected TopicSession publisherSession;
+
+   /**
+    * Topic used by a subscriber
+    */
+   protected Topic subscriberTopic;
+
+   /**
+    * Subscriber on queue
+    */
+   protected TopicSubscriber subscriber;
+
+   /**
+    * TopicConnectionFactory of the subscriber
+    */
+   protected TopicConnectionFactory subscriberTCF;
+
+   /**
+    * TopicConnection of the subscriber
+    */
+   protected TopicConnection subscriberConnection;
+
+   /**
+    * TopicSession of the subscriber (non transacted, AUTO_ACKNOWLEDGE)
+    */
+   protected TopicSession subscriberSession;
+
+   /**
+    * Create all administrated objects connections and sessions ready to use for tests.
+    * <br />
+    * Start connections.
+    */
+   @Override
+   protected void setUp() throws Exception
+   {
+      super.setUp();
+
+      try
+      {
+         // ...and creates administrated objects and binds them
+         admin.createTopicConnectionFactory(PubSubTestCase.TCF_NAME);
+         admin.createTopic(PubSubTestCase.TOPIC_NAME);
+
+         // end of admin step, start of JMS client step
+         ctx = admin.createContext();
+
+         publisherTCF = (TopicConnectionFactory)ctx.lookup(PubSubTestCase.TCF_NAME);
+         publisherTopic = (Topic)ctx.lookup(PubSubTestCase.TOPIC_NAME);
+         publisherConnection = publisherTCF.createTopicConnection();
+         publisherConnection.setClientID("publisherConnection");
+         publisherSession = publisherConnection.createTopicSession(false, Session.AUTO_ACKNOWLEDGE);
+         publisher = publisherSession.createPublisher(publisherTopic);
+
+         subscriberTCF = (TopicConnectionFactory)ctx.lookup(PubSubTestCase.TCF_NAME);
+         subscriberTopic = (Topic)ctx.lookup(PubSubTestCase.TOPIC_NAME);
+         subscriberConnection = subscriberTCF.createTopicConnection();
+         subscriberConnection.setClientID("subscriberConnection");
+         subscriberSession = subscriberConnection.createTopicSession(false, Session.AUTO_ACKNOWLEDGE);
+         subscriber = subscriberSession.createSubscriber(subscriberTopic);
+
+         publisherConnection.start();
+         subscriberConnection.start();
+         // end of client step
+      }
+      catch (Exception e)
+      {
+         throw new RuntimeException(e);
+      }
+   }
+
+   /**
+    *  Close connections and delete administrated objects
+    */
+   @Override
+   protected void tearDown() throws Exception
+   {
+      try
+      {
+         publisherConnection.close();
+         subscriberConnection.close();
+
+         admin.deleteTopicConnectionFactory(PubSubTestCase.TCF_NAME);
+         admin.deleteTopic(PubSubTestCase.TOPIC_NAME);
+      }
+      catch (Exception ignored)
+      {
+        ignored.printStackTrace();
+      }
+      finally
+      {
+         publisherTopic = null;
+         publisher = null;
+         publisherTCF = null;
+         publisherSession = null;
+         publisherConnection = null;
+
+         subscriberTopic = null;
+         subscriber = null;
+         subscriberTCF = null;
+         subscriberSession = null;
+         subscriberConnection = null;
+      }
+
+      super.tearDown();
+   }
+
+   public PubSubTestCase(final String name)
+   {
+      super(name);
+   }
+}
diff --git a/activemq-tooling/activemq-joram-jms-tests/src/main/java/org/objectweb/jtests/jms/framework/TestConfig.java b/activemq-tooling/activemq-joram-jms-tests/src/main/java/org/objectweb/jtests/jms/framework/TestConfig.java
new file mode 100644
index 0000000..8732719
--- /dev/null
+++ b/activemq-tooling/activemq-joram-jms-tests/src/main/java/org/objectweb/jtests/jms/framework/TestConfig.java
@@ -0,0 +1,59 @@
+/*
+ * Copyright 2009 Red Hat, Inc.
+ * Red Hat 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.
+ */
+
+package org.objectweb.jtests.jms.framework;
+
+import java.util.Properties;
+
+/**
+ * Class used to provide configurable options in a convenient way
+ *
+ * @author Jeff Mesnil (jmesnil@gmail.com)
+ * @version $Id: TestConfig.java,v 1.2 2007/06/14 18:39:51 csuconic Exp $
+ */
+public class TestConfig
+{
+   // name of the configuration file
+   private static final String PROP_FILE_NAME = "test.properties";
+
+   // name of the timeout property
+   private static final String PROP_NAME = "timeout";
+
+   /**
+    * timeout value used by <code>receive</code> method in the tests. 
+    * the value is specified in the <code>config/test.properties</code> file.
+    */
+   public static final long TIMEOUT;
+
+   static
+   {
+      // load tests.properties
+      long tempTimeOut = 0;
+      try
+      {
+         Properties props = new Properties();
+         props.load(ClassLoader.getSystemResourceAsStream(TestConfig.PROP_FILE_NAME));
+         System.out.println("Found " + TestConfig.PROP_FILE_NAME);
+         tempTimeOut = Long.parseLong(props.getProperty(TestConfig.PROP_NAME, "0"));
+      }
+      catch (Exception e)
+      {
+         e.printStackTrace();
+         tempTimeOut = 30000;
+      }
+      finally
+      {
+         TIMEOUT = tempTimeOut;
+      }
+   }
+}
diff --git a/activemq-tooling/activemq-joram-jms-tests/src/main/java/org/objectweb/jtests/jms/framework/UnifiedTestCase.java b/activemq-tooling/activemq-joram-jms-tests/src/main/java/org/objectweb/jtests/jms/framework/UnifiedTestCase.java
new file mode 100644
index 0000000..b8901ab
--- /dev/null
+++ b/activemq-tooling/activemq-joram-jms-tests/src/main/java/org/objectweb/jtests/jms/framework/UnifiedTestCase.java
@@ -0,0 +1,247 @@
+/*
+ * Copyright 2009 Red Hat, Inc.
+ * Red Hat 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.
+ */
+
+package org.objectweb.jtests.jms.framework;
+
+import javax.jms.Connection;
+import javax.jms.ConnectionFactory;
+import javax.jms.Destination;
+import javax.jms.MessageConsumer;
+import javax.jms.MessageProducer;
+import javax.jms.Queue;
+import javax.jms.QueueConnectionFactory;
+import javax.jms.Session;
+import javax.jms.Topic;
+import javax.jms.TopicConnectionFactory;
+import javax.naming.Context;
+
+
+/**
+ * Creates convenient Unified JMS 1.1 objects which can be needed for tests.
+ * <br />
+ * This class defines the setUp and tearDown methods so
+ * that JMS administrated objects and  other "ready to use" JMS objects (that is to say destinations,
+ * sessions, producers and consumers) are available conveniently for the test cases.
+ * <br />
+ * Classes which want that convenience should extend <code>UnifiedTestCase</code> instead of 
+ * <code>JMSTestCase</code>.
+ *
+ * @author Jeff Mesnil (jmesnil@gmail.com)
+ * @version $Id: UnifiedTestCase.java,v 1.1 2007/03/29 04:28:35 starksm Exp $
+ * @since JMS 1.1
+ */
+public abstract class UnifiedTestCase extends JMSTestCase
+{
+
+   protected Context ctx;
+
+   private static final String CF_NAME = "testCF";
+
+   private static final String TCF_NAME = "testTCF";
+
+   private static final String QCF_NAME = "testQCF";
+
+   private static final String DESTINATION_NAME = "testDestination";
+
+   private static final String QUEUE_NAME = "testJoramQueue";
+
+   private static final String TOPIC_NAME = "testJoramTopic";
+
+   // //////////////////
+   // Unified Domain //
+   // //////////////////
+
+   /**
+    * Destination used by a producer
+    */
+   protected Destination producerDestination;
+
+   /**
+    * Producer
+    */
+   protected MessageProducer producer;
+
+   /**
+    * ConnectionFactory of the producer
+    */
+   protected ConnectionFactory producerCF;
+
+   /**
+    * Connection of the producer
+    */
+   protected Connection producerConnection;
+
+   /**
+    * Session of the producer (non transacted, AUTO_ACKNOWLEDGE)
+    */
+   protected Session producerSession;
+
+   /**
+    * Destination used by a consumer
+    */
+   protected Destination consumerDestination;
+
+   /**
+    * Consumer on destination
+    */
+   protected MessageConsumer consumer;
+
+   /**
+    * ConnectionFactory of the consumer
+    */
+   protected ConnectionFactory consumerCF;
+
+   /**
+    * Connection of the consumer
+    */
+   protected Connection consumerConnection;
+
+   /**
+    * Session of the consumer (non transacted, AUTO_ACKNOWLEDGE)
+    */
+   protected Session consumerSession;
+
+   // //////////////
+   // PTP Domain //
+   // //////////////
+
+   /**
+    * QueueConnectionFactory
+    */
+   protected QueueConnectionFactory queueConnectionFactory;
+
+   /**
+    * Queue
+    */
+   protected Queue queue;
+
+   // //////////////////
+   // Pub/Sub Domain //
+   // //////////////////
+
+   /**
+    * TopicConnectionFactory
+    */
+   protected TopicConnectionFactory topicConnectionFactory;
+
+   /**
+    * Topic
+    */
+   protected Topic topic;
+
+   /**
+    * Create all administrated objects connections and sessions ready to use for tests.
+    * <br />
+    * Start connections.
+    */
+   @Override
+   protected void setUp() throws Exception
+   {
+      super.setUp();
+
+      try
+      {
+         // ...and creates administrated objects and binds them
+         admin.createConnectionFactory(UnifiedTestCase.CF_NAME);
+         admin.createQueueConnectionFactory(UnifiedTestCase.QCF_NAME);
+         admin.createTopicConnectionFactory(UnifiedTestCase.TCF_NAME);
+         // destination for unified domain is a queue
+         admin.createQueue(UnifiedTestCase.DESTINATION_NAME);
+         admin.createQueue(UnifiedTestCase.QUEUE_NAME);
+         admin.createTopic(UnifiedTestCase.TOPIC_NAME);
+
+         // end of admin step, start of JMS client step
+         ctx = admin.createContext();
+
+         producerCF = (ConnectionFactory)ctx.lookup(UnifiedTestCase.CF_NAME);
+         // we see destination of the unified domain as a javax.jms.Destination
+         // instead of a javax.jms.Queue to be more generic
+         producerDestination = (Destination)ctx.lookup(UnifiedTestCase.DESTINATION_NAME);
+         producerConnection = producerCF.createConnection();
+         producerSession = producerConnection.createSession(false, Session.AUTO_ACKNOWLEDGE);
+         producer = producerSession.createProducer(producerDestination);
+
+         consumerCF = (ConnectionFactory)ctx.lookup(UnifiedTestCase.CF_NAME);
+         // we see destination of the unified domain as a javax.jms.Destination
+         // instead of a javax.jms.Queue to be more generic
+         consumerDestination = (Destination)ctx.lookup(UnifiedTestCase.DESTINATION_NAME);
+         consumerConnection = consumerCF.createConnection();
+         consumerSession = consumerConnection.createSession(false, Session.AUTO_ACKNOWLEDGE);
+         consumer = consumerSession.createConsumer(consumerDestination);
+
+         queueConnectionFactory = (QueueConnectionFactory)ctx.lookup(UnifiedTestCase.QCF_NAME);
+         queue = (Queue)ctx.lookup(UnifiedTestCase.QUEUE_NAME);
+
+         topicConnectionFactory = (TopicConnectionFactory)ctx.lookup(UnifiedTestCase.TCF_NAME);
+         topic = (Topic)ctx.lookup(UnifiedTestCase.TOPIC_NAME);
+
+         producerConnection.start();
+         consumerConnection.start();
+         // end of client step
+      }
+      catch (Exception e)
+      {
+         throw new RuntimeException(e);
+      }
+   }
+
+   /**
+    *  Close connections and delete administrated objects
+    */
+   @Override
+   protected void tearDown() throws Exception
+   {
+      try
+      {
+         consumerConnection.close();
+         producerConnection.close();
+
+         admin.deleteConnectionFactory(UnifiedTestCase.CF_NAME);
+         admin.deleteQueueConnectionFactory(UnifiedTestCase.QCF_NAME);
+         admin.deleteTopicConnectionFactory(UnifiedTestCase.TCF_NAME);
+         admin.deleteQueue(UnifiedTestCase.DESTINATION_NAME);
+         admin.deleteQueue(UnifiedTestCase.QUEUE_NAME);
+         admin.deleteTopic(UnifiedTestCase.TOPIC_NAME);
+      }
+      catch (Exception ignored)
+      {
+      }
+      finally
+      {
+         producerDestination = null;
+         producer = null;
+         producerCF = null;
+         producerSession = null;
+         producerConnection = null;
+
+         consumerDestination = null;
+         consumer = null;
+         consumerCF = null;
+         consumerSession = null;
+         consumerConnection = null;
+
+         queueConnectionFactory = null;
+         queue = null;
+
+         topicConnectionFactory = null;
+         topic = null;
+      }
+
+      super.tearDown();
+   }
+
+   public UnifiedTestCase(final String name)
+   {
+      super(name);
+   }
+}
diff --git a/activemq-tooling/activemq-joram-jms-tests/src/main/java/org/objectweb/jtests/jms/framework/package.html b/activemq-tooling/activemq-joram-jms-tests/src/main/java/org/objectweb/jtests/jms/framework/package.html
new file mode 100644
index 0000000..33f716c
--- /dev/null
+++ b/activemq-tooling/activemq-joram-jms-tests/src/main/java/org/objectweb/jtests/jms/framework/package.html
@@ -0,0 +1,19 @@
+<!--
+    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.
+-->
+<body>
+Extension of JUnit Testing framework to take into account JMS specific features.
+</body>
diff --git a/activemq-tooling/pom.xml b/activemq-tooling/pom.xml
index 9fafada..43a1bea 100644
--- a/activemq-tooling/pom.xml
+++ b/activemq-tooling/pom.xml
@@ -35,5 +35,6 @@
     <module>activemq-perf-maven-plugin</module>
     <module>activemq-maven-plugin</module>
     <module>activemq-junit</module>
+    <module>activemq-joram-jms-tests</module>
   </modules>
 </project>
diff --git a/activemq-unit-tests/pom.xml b/activemq-unit-tests/pom.xml
index 3b88e83..bbe633c 100644
--- a/activemq-unit-tests/pom.xml
+++ b/activemq-unit-tests/pom.xml
@@ -244,9 +244,9 @@
 
     <!--  Joram JMS conformance tests -->
     <dependency>
-      <groupId>org.fusesource.joram-jms-tests</groupId>
-      <artifactId>joram-jms-tests</artifactId>
-      <version>1.0</version>
+      <groupId>org.apache.activemq.tooling</groupId>
+      <artifactId>activemq-joram-jms-tests</artifactId>
+      <version>${project.version}</version>
       <scope>test</scope>
     </dependency>
     <dependency>