[hornetq-commits] JBoss hornetq SVN: r9782 - in branches/hornetq-416: docs/user-manual/zh and 74 other directories.

do-not-reply at jboss.org do-not-reply at jboss.org
Wed Oct 13 03:38:26 EDT 2010


Author: gaohoward
Date: 2010-10-13 03:38:20 -0400 (Wed, 13 Oct 2010)
New Revision: 9782

Added:
   branches/hornetq-416/src/config/jboss-as-4/clustered/login-config.xml
   branches/hornetq-416/src/main/org/hornetq/core/protocol/stomp/StompDecoder.java
   branches/hornetq-416/src/main/org/hornetq/jms/client/HornetQJMSConnectionFactory.java
   branches/hornetq-416/src/main/org/hornetq/jms/client/HornetQQueueConnectionFactory.java
   branches/hornetq-416/src/main/org/hornetq/jms/client/HornetQTopicConnectionFactory.java
   branches/hornetq-416/src/main/org/hornetq/jms/client/HornetQXAConnectionFactory.java
   branches/hornetq-416/src/main/org/hornetq/jms/client/HornetQXAQueueConnectionFactory.java
   branches/hornetq-416/src/main/org/hornetq/jms/client/HornetQXATopicConnectionFactory.java
   branches/hornetq-416/src/main/org/hornetq/jms/server/impl/JMSFactoryType.java
   branches/hornetq-416/src/main/org/hornetq/spi/core/remoting/ReadyListener.java
   branches/hornetq-416/tests/src/org/hornetq/tests/integration/jms/client/AutoGroupingTest.java
   branches/hornetq-416/tests/src/org/hornetq/tests/integration/jms/client/GroupIDTest.java
   branches/hornetq-416/tests/src/org/hornetq/tests/integration/jms/client/GroupingTest.java
   branches/hornetq-416/tests/src/org/hornetq/tests/integration/jms/connection/ConcurrentSessionCloseTest.java
   branches/hornetq-416/tests/src/org/hornetq/tests/integration/stomp/StompConnectionCleanupTest.java
   branches/hornetq-416/tests/src/org/hornetq/tests/integration/stomp/StompTestBase.java
Removed:
   branches/hornetq-416/src/main/org/hornetq/core/protocol/stomp/StompFrameDecoder.java
Modified:
   branches/hornetq-416/docs/user-manual/en/appserver-integration.xml
   branches/hornetq-416/docs/user-manual/en/configuration-index.xml
   branches/hornetq-416/docs/user-manual/en/interoperability.xml
   branches/hornetq-416/docs/user-manual/en/using-jms.xml
   branches/hornetq-416/docs/user-manual/zh/configuration-index.xml
   branches/hornetq-416/docs/user-manual/zh/using-jms.xml
   branches/hornetq-416/examples/javaee/xarecovery/server/hornetq-jms.xml
   branches/hornetq-416/examples/jms/client-kickoff/server0/hornetq-jms.xml
   branches/hornetq-416/examples/jms/jms-bridge/server0/hornetq-jms.xml
   branches/hornetq-416/examples/jms/jms-bridge/server1/hornetq-jms.xml
   branches/hornetq-416/examples/jms/jms-bridge/src/org/hornetq/jms/example/JMSBridgeExample.java
   branches/hornetq-416/examples/jms/jmx/server0/hornetq-jms.xml
   branches/hornetq-416/examples/jms/management/server0/hornetq-jms.xml
   branches/hornetq-416/examples/jms/message-counters/server0/hornetq-jms.xml
   branches/hornetq-416/examples/jms/queue-requestor/server0/hornetq-jms.xml
   branches/hornetq-416/examples/jms/symmetric-cluster/src/org/hornetq/jms/example/SymmetricClusterExample.java
   branches/hornetq-416/examples/jms/xa-heuristic/server0/hornetq-jms.xml
   branches/hornetq-416/examples/jms/xa-receive/server0/hornetq-jms.xml
   branches/hornetq-416/examples/jms/xa-send/server0/hornetq-jms.xml
   branches/hornetq-416/examples/jms/xa-with-jta/server0/hornetq-jms.xml
   branches/hornetq-416/examples/soak/tx-restarts/server0/hornetq-jms.xml
   branches/hornetq-416/hornetq-rest/hornetq-rest/src/main/java/org/hornetq/rest/integration/HornetqBootstrapListener.java
   branches/hornetq-416/hornetq-rest/hornetq-rest/src/main/java/org/hornetq/rest/integration/RestMessagingBootstrapListener.java
   branches/hornetq-416/hornetq-rest/hornetq-rest/src/main/java/org/hornetq/rest/integration/ServletContextBindingRegistry.java
   branches/hornetq-416/hornetq-rest/hornetq-rest/src/main/java/org/hornetq/rest/queue/ConsumersResource.java
   branches/hornetq-416/hornetq-rest/hornetq-rest/src/main/java/org/hornetq/rest/queue/push/FilePushStore.java
   branches/hornetq-416/hornetq-rest/hornetq-rest/src/main/java/org/hornetq/rest/queue/push/PushConsumer.java
   branches/hornetq-416/hornetq-rest/hornetq-rest/src/main/java/org/hornetq/rest/queue/push/UriStrategy.java
   branches/hornetq-416/hornetq-rest/hornetq-rest/src/main/java/org/hornetq/rest/topic/FileTopicPushStore.java
   branches/hornetq-416/hornetq-rest/hornetq-rest/src/main/java/org/hornetq/rest/topic/SubscriptionsResource.java
   branches/hornetq-416/hornetq-rest/hornetq-rest/src/main/java/org/hornetq/rest/util/CustomHeaderLinkStrategy.java
   branches/hornetq-416/hornetq-rest/hornetq-rest/src/main/java/org/hornetq/rest/util/TimeoutTask.java
   branches/hornetq-416/hornetq-rest/hornetq-rest/src/test/java/org/hornetq/rest/test/JMSTest.java
   branches/hornetq-416/hornetq-rest/hornetq-rest/src/test/java/org/hornetq/rest/test/RawRestartTest.java
   branches/hornetq-416/hornetq-rest/hornetq-rest/src/test/java/org/hornetq/rest/test/TransformTest.java
   branches/hornetq-416/src/config/common/schema/hornetq-jms.xsd
   branches/hornetq-416/src/config/jboss-as-4/clustered/jms-ds.xml
   branches/hornetq-416/src/main/org/hornetq/api/core/client/HornetQClient.java
   branches/hornetq-416/src/main/org/hornetq/api/jms/HornetQJMSClient.java
   branches/hornetq-416/src/main/org/hornetq/core/client/impl/ClientConsumerImpl.java
   branches/hornetq-416/src/main/org/hornetq/core/client/impl/ClientSessionImpl.java
   branches/hornetq-416/src/main/org/hornetq/core/client/impl/FailoverManagerImpl.java
   branches/hornetq-416/src/main/org/hornetq/core/deployers/impl/FileConfigurationParser.java
   branches/hornetq-416/src/main/org/hornetq/core/paging/PagingStore.java
   branches/hornetq-416/src/main/org/hornetq/core/paging/impl/PageImpl.java
   branches/hornetq-416/src/main/org/hornetq/core/paging/impl/PagingManagerImpl.java
   branches/hornetq-416/src/main/org/hornetq/core/paging/impl/PagingStoreFactoryNIO.java
   branches/hornetq-416/src/main/org/hornetq/core/paging/impl/PagingStoreImpl.java
   branches/hornetq-416/src/main/org/hornetq/core/persistence/impl/journal/JournalStorageManager.java
   branches/hornetq-416/src/main/org/hornetq/core/postoffice/impl/PostOfficeImpl.java
   branches/hornetq-416/src/main/org/hornetq/core/protocol/core/ServerSessionPacketHandler.java
   branches/hornetq-416/src/main/org/hornetq/core/protocol/core/impl/CoreSessionCallback.java
   branches/hornetq-416/src/main/org/hornetq/core/protocol/core/impl/RemotingConnectionImpl.java
   branches/hornetq-416/src/main/org/hornetq/core/protocol/stomp/StompConnection.java
   branches/hornetq-416/src/main/org/hornetq/core/protocol/stomp/StompFrame.java
   branches/hornetq-416/src/main/org/hornetq/core/protocol/stomp/StompProtocolManager.java
   branches/hornetq-416/src/main/org/hornetq/core/protocol/stomp/StompSession.java
   branches/hornetq-416/src/main/org/hornetq/core/protocol/stomp/StompUtils.java
   branches/hornetq-416/src/main/org/hornetq/core/protocol/stomp/WebSocketStompFrameEncoder.java
   branches/hornetq-416/src/main/org/hornetq/core/remoting/impl/invm/InVMAcceptor.java
   branches/hornetq-416/src/main/org/hornetq/core/remoting/impl/invm/InVMConnection.java
   branches/hornetq-416/src/main/org/hornetq/core/remoting/impl/invm/InVMConnector.java
   branches/hornetq-416/src/main/org/hornetq/core/remoting/impl/netty/HornetQChannelHandler.java
   branches/hornetq-416/src/main/org/hornetq/core/remoting/impl/netty/NettyAcceptor.java
   branches/hornetq-416/src/main/org/hornetq/core/remoting/impl/netty/NettyConnection.java
   branches/hornetq-416/src/main/org/hornetq/core/remoting/impl/netty/NettyConnector.java
   branches/hornetq-416/src/main/org/hornetq/core/remoting/server/impl/RemotingServiceImpl.java
   branches/hornetq-416/src/main/org/hornetq/core/server/HornetQServer.java
   branches/hornetq-416/src/main/org/hornetq/core/server/impl/HornetQServerImpl.java
   branches/hornetq-416/src/main/org/hornetq/core/server/impl/ServerConsumerImpl.java
   branches/hornetq-416/src/main/org/hornetq/core/server/impl/ServerMessageImpl.java
   branches/hornetq-416/src/main/org/hornetq/core/server/impl/ServerSessionImpl.java
   branches/hornetq-416/src/main/org/hornetq/jms/bridge/ConnectionFactoryFactory.java
   branches/hornetq-416/src/main/org/hornetq/jms/bridge/impl/JMSBridgeImpl.java
   branches/hornetq-416/src/main/org/hornetq/jms/bridge/impl/JNDIConnectionFactoryFactory.java
   branches/hornetq-416/src/main/org/hornetq/jms/client/HornetQConnection.java
   branches/hornetq-416/src/main/org/hornetq/jms/client/HornetQConnectionFactory.java
   branches/hornetq-416/src/main/org/hornetq/jms/client/HornetQSession.java
   branches/hornetq-416/src/main/org/hornetq/jms/client/SelectorTranslator.java
   branches/hornetq-416/src/main/org/hornetq/jms/management/impl/JMSServerControlImpl.java
   branches/hornetq-416/src/main/org/hornetq/jms/server/JMSServerManager.java
   branches/hornetq-416/src/main/org/hornetq/jms/server/config/ConnectionFactoryConfiguration.java
   branches/hornetq-416/src/main/org/hornetq/jms/server/config/impl/ConnectionFactoryConfigurationImpl.java
   branches/hornetq-416/src/main/org/hornetq/jms/server/impl/JMSServerConfigParserImpl.java
   branches/hornetq-416/src/main/org/hornetq/jms/server/impl/JMSServerManagerImpl.java
   branches/hornetq-416/src/main/org/hornetq/ra/HornetQResourceAdapter.java
   branches/hornetq-416/src/main/org/hornetq/spi/core/protocol/RemotingConnection.java
   branches/hornetq-416/src/main/org/hornetq/spi/core/protocol/SessionCallback.java
   branches/hornetq-416/src/main/org/hornetq/spi/core/remoting/Connection.java
   branches/hornetq-416/src/main/org/hornetq/spi/core/remoting/ConnectionLifeCycleListener.java
   branches/hornetq-416/tests/jms-tests/config/hornetq-jms.xml
   branches/hornetq-416/tests/jms-tests/src/org/hornetq/jms/tests/CTSMiscellaneousTest.java
   branches/hornetq-416/tests/jms-tests/src/org/hornetq/jms/tests/ConnectionClosedTest.java
   branches/hornetq-416/tests/jms-tests/src/org/hornetq/jms/tests/ConnectionFactoryTest.java
   branches/hornetq-416/tests/jms-tests/src/org/hornetq/jms/tests/ConnectionTest.java
   branches/hornetq-416/tests/jms-tests/src/org/hornetq/jms/tests/HornetQServerTestCase.java
   branches/hornetq-416/tests/jms-tests/src/org/hornetq/jms/tests/JMSTestCase.java
   branches/hornetq-416/tests/jms-tests/src/org/hornetq/jms/tests/ReferenceableTest.java
   branches/hornetq-416/tests/jms-tests/src/org/hornetq/jms/tests/message/JMSXDeliveryCountTest.java
   branches/hornetq-416/tests/jms-tests/src/org/hornetq/jms/tests/selector/SelectorTest.java
   branches/hornetq-416/tests/jms-tests/src/org/hornetq/jms/tests/tools/container/LocalTestServer.java
   branches/hornetq-416/tests/joram-tests/src/org/hornetq/jms/HornetQAdmin.java
   branches/hornetq-416/tests/src/org/hornetq/tests/integration/client/PagingTest.java
   branches/hornetq-416/tests/src/org/hornetq/tests/integration/client/ReceiveImmediateTest.java
   branches/hornetq-416/tests/src/org/hornetq/tests/integration/cluster/failover/FailoverTest.java
   branches/hornetq-416/tests/src/org/hornetq/tests/integration/http/NettyHttpTest.java
   branches/hornetq-416/tests/src/org/hornetq/tests/integration/jms/FloodServerTest.java
   branches/hornetq-416/tests/src/org/hornetq/tests/integration/jms/HornetQConnectionFactoryTest.java
   branches/hornetq-416/tests/src/org/hornetq/tests/integration/jms/bridge/BridgeTestBase.java
   branches/hornetq-416/tests/src/org/hornetq/tests/integration/jms/bridge/JMSBridgeReconnectionTest.java
   branches/hornetq-416/tests/src/org/hornetq/tests/integration/jms/bridge/JMSBridgeTest.java
   branches/hornetq-416/tests/src/org/hornetq/tests/integration/jms/client/PreACKJMSTest.java
   branches/hornetq-416/tests/src/org/hornetq/tests/integration/jms/client/ReSendMessageTest.java
   branches/hornetq-416/tests/src/org/hornetq/tests/integration/jms/client/ReceiveNoWaitTest.java
   branches/hornetq-416/tests/src/org/hornetq/tests/integration/jms/client/SessionClosedOnRemotingConnectionFailureTest.java
   branches/hornetq-416/tests/src/org/hornetq/tests/integration/jms/client/TextMessageTest.java
   branches/hornetq-416/tests/src/org/hornetq/tests/integration/jms/cluster/JMSFailoverTest.java
   branches/hornetq-416/tests/src/org/hornetq/tests/integration/jms/divert/DivertAndACKClientTest.java
   branches/hornetq-416/tests/src/org/hornetq/tests/integration/jms/server/management/JMSUtil.java
   branches/hornetq-416/tests/src/org/hornetq/tests/integration/persistence/DeleteMessagesOnStartupTest.java
   branches/hornetq-416/tests/src/org/hornetq/tests/integration/spring/SpringIntegrationTest.java
   branches/hornetq-416/tests/src/org/hornetq/tests/integration/stomp/StompTest.java
   branches/hornetq-416/tests/src/org/hornetq/tests/timing/jms/bridge/impl/JMSBridgeImplTest.java
   branches/hornetq-416/tests/src/org/hornetq/tests/unit/core/deployers/impl/SecurityDeployerTest.java
   branches/hornetq-416/tests/src/org/hornetq/tests/unit/core/remoting/impl/netty/NettyAcceptorFactoryTest.java
   branches/hornetq-416/tests/src/org/hornetq/tests/unit/core/remoting/impl/netty/NettyAcceptorTest.java
   branches/hornetq-416/tests/src/org/hornetq/tests/unit/core/remoting/impl/netty/NettyConnectionTest.java
   branches/hornetq-416/tests/src/org/hornetq/tests/unit/core/remoting/impl/netty/NettyConnectorTest.java
   branches/hornetq-416/tests/src/org/hornetq/tests/unit/jms/client/SelectorTranslatorTest.java
   branches/hornetq-416/tests/src/org/hornetq/tests/util/JMSTestBase.java
Log:
update from trunk


Modified: branches/hornetq-416/docs/user-manual/en/appserver-integration.xml
===================================================================
--- branches/hornetq-416/docs/user-manual/en/appserver-integration.xml	2010-10-13 00:11:20 UTC (rev 9781)
+++ branches/hornetq-416/docs/user-manual/en/appserver-integration.xml	2010-10-13 07:38:20 UTC (rev 9782)
@@ -28,7 +28,7 @@
         outflow of messages sent from other JEE components, e.g. EJBs and Servlets.</para>
     <para>This section explains the basics behind configuring the different JEE components in the
         AS.</para>
-    <section>
+    <section id="configuring-mdbs">
         <title>Configuring Message-Driven Beans</title>
         <para>The delivery of messages to an MDB using HornetQ is configured on the JCA Adapter via
             a configuration file <literal>ra.xml</literal> which can be found under the <literal
@@ -980,6 +980,202 @@
        </section>
     </section>
     <section>
+        <title>Configuring the JBoss Application Server to connect to Remote HornetQ Server</title>
+        <para>This is a step by step guide on how to configure a JBoss application server that doesn't have HornetQ installed
+            to use a remote instance of HornetQ</para>
+        <section>
+            <title>Configuring Jboss 5</title>
+            <para>Firstly download and install JBoss AS 5 as per the JBoss installation guide and HornetQ as per the
+                HornetQ installation guide. After thatt he following steps are required</para>
+            <itemizedlist>
+                <listitem>
+                    <para>Copy the following jars from the HornetQ distribution to the <literal>lib</literal> directory of
+                    which ever JBossAs configuration you have chosen, i.e. <literal>default</literal>.</para>
+                    <itemizedlist>
+                        <listitem>
+                            <para>hornetq-core-client.jar</para>
+                        </listitem>
+                        <listitem>
+                            <para>hornetq-jms-client.jar</para>
+                        </listitem>
+                        <listitem>
+                            <para>hornetq-ra.jar (this can be found inside the <literal>hornetq-ra.rar</literal> archive)</para>
+                        </listitem>
+                        <listitem>
+                            <para>netty.jar</para>
+                        </listitem>
+                    </itemizedlist>
+                </listitem>
+                <listitem>
+                    <para>create the directories <literal>hornetq-ra.rar</literal> and <literal>hornetq-ra.rar/META-INF</literal>
+                        under the <literal>deploy</literal> directory in your JBoss config directory</para>
+                </listitem>
+                <listitem>
+                    <para>under the <literal>hornetq-ra.rar/META-INF</literal> create a <literal>ra.xml</literal> file or
+                    copy it from the HornetQ distribution (again it can be found in the <literal>hornetq-ra.rar</literal> archive)
+                    and configure it as follows</para>
+                    <programlisting>
+                        &lt;?xml version="1.0" encoding="UTF-8"?>
+
+                        &lt;connector xmlns="http://java.sun.com/xml/ns/j2ee"
+                                   xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+                                   xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee
+                                   http://java.sun.com/xml/ns/j2ee/connector_1_5.xsd"
+                                   version="1.5">
+
+                           &lt;description>HornetQ 2.0 Resource Adapter Alternate Configuration&lt;/description>
+                           &lt;display-name>HornetQ 2.0 Resource Adapter Alternate Configuration&lt;/display-name>
+
+                           &lt;vendor-name>Red Hat Middleware LLC&lt;/vendor-name>
+                           &lt;eis-type>JMS 1.1 Server&lt;/eis-type>
+                           &lt;resourceadapter-version>1.0&lt;/resourceadapter-version>
+
+                           &lt;license>
+                              &lt;description>
+                        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.
+                              &lt;/description>
+                              &lt;license-required>true&lt;/license-required>
+                           &lt;/license>
+
+                           &lt;resourceadapter>
+                              &lt;resourceadapter-class>org.hornetq.ra.HornetQResourceAdapter&lt;/resourceadapter-class>
+                              &lt;config-property>
+                                 &lt;description>The transport type&lt;/description>
+                                 &lt;config-property-name>ConnectorClassName&lt;/config-property-name>
+                                 &lt;config-property-type>java.lang.String&lt;/config-property-type>
+                                 &lt;config-property-value>org.hornetq.core.remoting.impl.netty.NettyConnectorFactory&lt;/config-property-value>
+                              &lt;/config-property>
+                              &lt;config-property>
+                                 &lt;description>The transport configuration. These values must be in the form of key=val;key=val;&lt;/description>
+                                 &lt;config-property-name>ConnectionParameters&lt;/config-property-name>
+                                 &lt;config-property-type>java.lang.String&lt;/config-property-type>
+                                 <emphasis role="bold"> &lt;config-property-value>host=127.0.0.1;port=5445&lt;/config-property-value></emphasis>
+                              &lt;/config-property>
+
+                              &lt;outbound-resourceadapter>
+                                 &lt;connection-definition>
+                                    &lt;managedconnectionfactory-class>org.hornetq.ra.HornetQRAManagedConnectionFactory&lt;/managedconnectionfactory-class>
+
+                                    &lt;config-property>
+                                       &lt;description>The default session type&lt;/description>
+                                       &lt;config-property-name>SessionDefaultType&lt;/config-property-name>
+                                       &lt;config-property-type>java.lang.String&lt;/config-property-type>
+                                       &lt;config-property-value>javax.jms.Queue&lt;/config-property-value>
+                                    &lt;/config-property>
+                                    &lt;config-property>
+                                       &lt;description>Try to obtain a lock within specified number of seconds; less than or equal to 0 disable this functionality&lt;/description>
+                                       &lt;config-property-name>UseTryLock&lt;/config-property-name>
+                                       &lt;config-property-type>java.lang.Integer&lt;/config-property-type>
+                                       &lt;config-property-value>0&lt;/config-property-value>
+                                    &lt;/config-property>
+
+                                    &lt;connectionfactory-interface>org.hornetq.ra.HornetQRAConnectionFactory&lt;/connectionfactory-interface>
+                                    &lt;connectionfactory-impl-class>org.hornetq.ra.HornetQRAConnectionFactoryImpl&lt;/connectionfactory-impl-class>
+                                    &lt;connection-interface>javax.jms.Session&lt;/connection-interface>
+                                    &lt;connection-impl-class>org.hornetq.ra.HornetQRASession&lt;/connection-impl-class>
+                                 &lt;/connection-definition>
+                                 &lt;transaction-support>XATransaction&lt;/transaction-support>
+                                 &lt;authentication-mechanism>
+                                    &lt;authentication-mechanism-type>BasicPassword&lt;/authentication-mechanism-type>
+                                    &lt;credential-interface>javax.resource.spi.security.PasswordCredential&lt;/credential-interface>
+                                 &lt;/authentication-mechanism>
+                                 &lt;reauthentication-support>false&lt;/reauthentication-support>
+                              &lt;/outbound-resourceadapter>
+
+                              &lt;inbound-resourceadapter>
+                                 &lt;messageadapter>
+                                    &lt;messagelistener>
+                                       &lt;messagelistener-type>javax.jms.MessageListener&lt;/messagelistener-type>
+                                       &lt;activationspec>
+                                          &lt;activationspec-class>org.hornetq.ra.inflow.HornetQActivationSpec&lt;/activationspec-class>
+                                          &lt;required-config-property>
+                                              &lt;config-property-name>destination&lt;/config-property-name>
+                                          &lt;/required-config-property>
+                                       &lt;/activationspec>
+                                    &lt;/messagelistener>
+                                 &lt;/messageadapter>
+                              &lt;/inbound-resourceadapter>
+
+                           &lt;/resourceadapter>
+                        &lt;/connector>
+
+                    </programlisting>
+                    <para>The important part of this configuration is the part in bold, i.e. &lt;config-property-value>host=127.0.0.1;port=5445&lt;/config-property-value>.
+                    This should be configured to the host and port of the remote HornetQ server.</para>
+                </listitem>
+            </itemizedlist>
+            <para>At this point you should be able to now deploy MDB's that consume from the remote server. You will however,
+                have to make sure that your MDB's have the annotation <literal>@ResourceAdapter("hornetq-ra.rar")</literal>
+            added, this is illustrated in the <xref linkend="configuring-mdbs">Configuring Message-Driven Beans</xref> section.
+            If you don't want to add this annotation then you can delete the generic resource adapter <literal>jms-ra.rar</literal>
+            and rename the <literal>hornetq-ra.rar</literal> to this.</para>
+            <para>If you also want to use the remote HornetQ server for outgoing connections, i.e. sending messages, then
+            do the following:</para>
+            <itemizedlist>
+                <listitem>
+                    <para>Create a file called <literal>hornetq-ds.xml</literal> in the <literal>deploy</literal> directory
+                    (in fact you can call this anything you want as long as it ends in <literal>-ds.xml</literal>). Then
+                        add the following:</para>
+                    <programlisting>
+                       &lt;connection-factories>
+                       &lt;!--
+                        JMS XA Resource adapter, use this for outbound JMS connections.
+                        Inbound connections are defined at the @MDB activation or at the resource-adapter properties.
+                       -->
+                       &lt;tx-connection-factory>
+                          &lt;jndi-name>RemoteJmsXA&lt;/jndi-name>
+                          &lt;xa-transaction/>
+                          &lt;rar-name>hornetq-ra.rar&lt;/rar-name>
+                          &lt;connection-definition>org.hornetq.ra.HornetQRAConnectionFactory&lt;/connection-definition>
+                          &lt;config-property name="SessionDefaultType" type="java.lang.String">javax.jms.Topic&lt;/config-property>
+                          &lt;config-property name="ConnectorClassName" type="java.lang.String">org.hornetq.core.remoting.impl.netty.NettyConnectorFactory&lt;/config-property>
+                          &lt;config-property name="ConnectionParameters" type="java.lang.String">host=127.0.0.1;port=5445&lt;/config-property>
+                          &lt;max-pool-size>20&lt;/max-pool-size>
+                       &lt;/tx-connection-factory>
+
+
+                    &lt;/connection-factories>
+                    </programlisting>
+                    <para>Again you will see that the host and port are configured here to match the remote HornetQ servers
+                        configuration. The other important attributes are:</para>
+                    <itemizedlist>
+                        <listitem>
+                            <para>jndi-name - This is the name used to look up the JMS connection factory from within your JEE client</para>
+                        </listitem>
+                        <listitem>
+                            <para>rar-name - This should match the directory that you created to hold the Resource Adapter
+                            configuration</para>
+                        </listitem>
+                    </itemizedlist>
+                </listitem>
+            </itemizedlist>
+            <para>Now you should be able to send messages using the JCA JMS connection pooling within an XA transaction.</para>
+        </section>
+        <section>
+            <title>Configuring Jboss 5</title>
+            <para>The steps to do this are exactly the same as for JBoss 4, you will have to create a jboss.xml definition
+                file for your MDB with the following entry</para>
+            <programlisting>
+                     &lt;message-driven>
+                         &lt;ejb-name>MyMDB&lt;/ejb-name>
+                         &lt;resource-adapter-name>jms-ra.rar&lt;/resource-adapter-name>
+                      &lt;/message-driven>
+            </programlisting>
+            <para>Also you will need to edit the <literal>standardjboss.xml</literal> and uncomment the section with the
+            following 'Uncomment to use JMS message inflow from jmsra.rar' and then comment out the invoker-proxy-binding
+            called 'message-driven-bean'</para>
+        </section>
+    </section>
+    <section>
         <title>High Availability JNDI (HA-JNDI)</title>
         <para>If you are using JNDI to look-up JMS queues, topics and connection factories from a
             cluster of servers, it is likely you will want to use HA-JNDI so that your JNDI look-ups

Modified: branches/hornetq-416/docs/user-manual/en/configuration-index.xml
===================================================================
--- branches/hornetq-416/docs/user-manual/en/configuration-index.xml	2010-10-13 00:11:20 UTC (rev 9781)
+++ branches/hornetq-416/docs/user-manual/en/configuration-index.xml	2010-10-13 07:38:20 UTC (rev 9782)
@@ -1018,6 +1018,22 @@
                     <colspec colname="c4" colnum="4"/>
                     <tbody>
                         <row>
+                            <entry id="configuration.connection-factory.signature">
+                               <link linkend="using-jms.configure.factory.types">connection-factory.signature (attribute)</link>
+                            </entry>
+                            <entry>String</entry>
+                            <entry>Type of connection factory</entry>
+                            <entry>generic</entry>
+                        </row>
+                        <row>
+                            <entry id="configuration.connection-factory.signature">
+                               <link linkend="using-jms.configure.factory.types">connection-factory.xa</link>
+                            </entry>
+                            <entry>Boolean</entry>
+                            <entry>If it is a XA connection factory</entry>
+                            <entry>false</entry>
+                        </row>
+                        <row>
                             <entry id="configuration.connection-factory.auto-group">
                                <link linkend="message-grouping.jmsconfigure">connection-factory.auto-group</link>
                             </entry>

Modified: branches/hornetq-416/docs/user-manual/en/interoperability.xml
===================================================================
--- branches/hornetq-416/docs/user-manual/en/interoperability.xml	2010-10-13 00:11:20 UTC (rev 9781)
+++ branches/hornetq-416/docs/user-manual/en/interoperability.xml	2010-10-13 07:38:20 UTC (rev 9782)
@@ -57,6 +57,18 @@
             When a Stomp client subscribes (or unsubscribes) for a destination (using a <literal>SUBSCRIBE</literal>
             or <literal>UNSUBSCRIBE</literal> frame), the destination is mapped to a HornetQ queue.</para>
         </section>
+      <section>
+        <title>STOMP and connection-ttl</title>
+        <para>Well behaved STOMP clients will always send a DISCONNECT frame before closing their connections. In this case the server
+          will clear up any server side resources such as sessions and consumers synchronously. However if STOMP clients exit without
+        sending a DISCONNECT frame or if they crash the server will have no way of knowing immediately whether the client is still alive
+        or not. STOMP connections therefore default to a connection-ttl value of 1 minute (see chapter on <link linkend="connection-ttl"
+          >connection-ttl</link> for more information. This value can be overridden using connection-ttl-override.
+        </para>
+        <note><para>Please note that the STOMP protocol does not contain any heartbeat frame. It is therefore the user's responsibility to make sure
+        data is sent within connection-ttl or the server will assume the client is dead and clean up server side resources.</para></note>
+      </section>
+      
         <section>
           <title>Stomp and JMS interoperabilty</title>
           <section>

Modified: branches/hornetq-416/docs/user-manual/en/using-jms.xml
===================================================================
--- branches/hornetq-416/docs/user-manual/en/using-jms.xml	2010-10-13 00:11:20 UTC (rev 9781)
+++ branches/hornetq-416/docs/user-manual/en/using-jms.xml	2010-10-13 07:38:20 UTC (rev 9782)
@@ -87,6 +87,82 @@
                 defines the transport and parameters used to actually connect to the server.</para>
         </note>
     </section>
+    <section id="using-jms.configure.factory.types">
+        <title>Connection Factory Types</title>
+        <para>The JMS API doc provides several connection factories for applications. HornetQ JMS users
+              can choose to configure the types for their connection factories. Each connection factory
+              has a <literal>signature</literal> attribute and a <literal>xa</literal> parameter, the
+              combination of which determines the type of the factory. Attribute <literal>signature</literal>
+              has three possible string values, i.e. <emphasis>generic</emphasis>, 
+              <emphasis>queue</emphasis> and <emphasis>topic</emphasis>; <literal>xa</literal> is a boolean
+              type parameter. The following table gives their configuration values for different 
+              connection factory interfaces.</para>
+        <table frame="topbot" id="using-jms.table.configure.factory.types">
+                <title>Configuration for Connection Factory Types</title>
+                <tgroup cols="3">
+                    <colspec colname="signature" colnum="1"/>
+                    <colspec colname="xa" colnum="2"/>
+                    <colspec colname="cftype" colnum="3"/>
+                    <thead>
+                        <row>
+                            <entry>signature</entry>
+                            <entry>xa</entry>
+                            <entry>Connection Factory Type</entry>
+                        </row>
+                    </thead>
+                    <tbody>
+                        <row>
+                            <entry>generic (default)</entry>
+                            <entry>false (default)</entry>
+                            <entry>javax.jms.ConnectionFactory</entry>
+                        </row>
+                        <row>
+                            <entry>generic</entry>
+                            <entry>true</entry>
+                            <entry>javax.jms.XAConnectionFactory</entry>
+                        </row>
+                        <row>
+                            <entry>queue</entry>
+                            <entry>false</entry>
+                            <entry>javax.jms.QueueConnectionFactory</entry>
+                        </row>
+                        <row>
+                            <entry>queue</entry>
+                            <entry>true</entry>
+                            <entry>javax.jms.XAQueueConnectionFactory</entry>
+                        </row>
+                        <row>
+                            <entry>topic</entry>
+                            <entry>false</entry>
+                            <entry>javax.jms.TopicConnectionFactory</entry>
+                        </row>
+                        <row>
+                            <entry>topic</entry>
+                            <entry>true</entry>
+                            <entry>javax.jms.XATopicConnectionFactory</entry>
+                        </row>
+                    </tbody>
+                </tgroup>
+            </table>
+            <para>As an example, the following configures an XAQueueConnectionFactory:</para>
+        <programlisting>
+&lt;configuration xmlns="urn:hornetq" 
+    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+    xsi:schemaLocation="urn:hornetq ../schemas/hornetq-jms.xsd "&gt;
+    
+    &lt;connection-factory name="ConnectionFactory" signature="queue"&gt;
+        &lt;xa>true&lt;/xa>
+        &lt;connectors>
+           &lt;connector-ref connector-name="netty"/&gt;
+        &lt;/connectors>
+        &lt;entries&gt;
+            &lt;entry name="ConnectionFactory"/&gt;           
+        &lt;/entries&gt;
+    &lt;/connection-factory&gt;
+&lt;/configuration&gt; 
+        </programlisting>
+
+    </section>
     <section>
         <title>JNDI configuration</title>
         <para>When using JNDI from the client side you need to specify a set of JNDI properties

Modified: branches/hornetq-416/docs/user-manual/zh/configuration-index.xml
===================================================================
--- branches/hornetq-416/docs/user-manual/zh/configuration-index.xml	2010-10-13 00:11:20 UTC (rev 9781)
+++ branches/hornetq-416/docs/user-manual/zh/configuration-index.xml	2010-10-13 07:38:20 UTC (rev 9782)
@@ -952,6 +952,22 @@
                             <entry/>
                         </row>
                         <row>
+                            <entry id="configuration.connection-factory.signature">
+                               <link linkend="using-jms.configure.factory.types">connection-factory.signature (属性)</link>
+                            </entry>
+                            <entry>String</entry>
+                            <entry>连接工厂的类型</entry>
+                            <entry>generic</entry>
+                        </row>
+                        <row>
+                            <entry id="configuration.connection-factory.signature">
+                               <link linkend="using-jms.configure.factory.types">connection-factory.xa</link>
+                            </entry>
+                            <entry>Boolean</entry>
+                            <entry>是否是XA类型的连接工厂</entry>
+                            <entry>false</entry>
+                        </row>
+                        <row>
                             <entry id="configuration.connection-factory.auto-group">
                                <link linkend="message-grouping.jmsconfigure">connection-factory.auto-group</link>
                             </entry>

Modified: branches/hornetq-416/docs/user-manual/zh/using-jms.xml
===================================================================
--- branches/hornetq-416/docs/user-manual/zh/using-jms.xml	2010-10-13 00:11:20 UTC (rev 9781)
+++ branches/hornetq-416/docs/user-manual/zh/using-jms.xml	2010-10-13 07:38:20 UTC (rev 9782)
@@ -72,6 +72,77 @@
                  <literal>hornetq-configuration.xml</literal> 中。它定义了采用何种传输与服务器连接。</para>
         </note>
     </section>
+    <section id="using-jms.configure.factory.types">
+        <title>连接工厂的类型</title>
+        <para>在JMS API文档中有几种不同类型的连接工厂供用户使用。HornetQ为用户提供了配置连接工厂类型的参数。用户可以通过
+              配置连接工厂的”signature"属性和"xa"参数来得到想要的类型。“singature"属性是字符串类型,它有三个可选值:
+              <emphasis>generic</emphasis>、<emphasis>queue</emphasis>和<emphasis>topic</emphasis>; 
+              <literal>xa</literal>是一个布尔型参数。下表给出了不同类型连接工厂对应的配置值:</para>
+        <table frame="topbot" id="using-jms.table.configure.factory.types">
+                <title>连接工厂类型的配置</title>
+                <tgroup cols="3">
+                    <colspec colname="signature" colnum="1"/>
+                    <colspec colname="xa" colnum="2"/>
+                    <colspec colname="cftype" colnum="3"/>
+                    <thead>
+                        <row>
+                            <entry>signature</entry>
+                            <entry>xa</entry>
+                            <entry>连接工厂的类型</entry>
+                        </row>
+                    </thead>
+                    <tbody>
+                        <row>
+                            <entry>generic (默认)</entry>
+                            <entry>false (默认)</entry>
+                            <entry>javax.jms.ConnectionFactory</entry>
+                        </row>
+                        <row>
+                            <entry>generic</entry>
+                            <entry>true</entry>
+                            <entry>javax.jms.XAConnectionFactory</entry>
+                        </row>
+                        <row>
+                            <entry>queue</entry>
+                            <entry>false</entry>
+                            <entry>javax.jms.QueueConnectionFactory</entry>
+                        </row>
+                        <row>
+                            <entry>queue</entry>
+                            <entry>true</entry>
+                            <entry>javax.jms.XAQueueConnectionFactory</entry>
+                        </row>
+                        <row>
+                            <entry>topic</entry>
+                            <entry>false</entry>
+                            <entry>javax.jms.TopicConnectionFactory</entry>
+                        </row>
+                        <row>
+                            <entry>topic</entry>
+                            <entry>true</entry>
+                            <entry>javax.jms.XATopicConnectionFactory</entry>
+                        </row>
+                    </tbody>
+                </tgroup>
+            </table>
+            <para>下面的例子配置了一个XAQueueConnectionFactory:</para>
+        <programlisting>
+&lt;configuration xmlns="urn:hornetq" 
+    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+    xsi:schemaLocation="urn:hornetq ../schemas/hornetq-jms.xsd "&gt;
+    
+    &lt;connection-factory name="ConnectionFactory" signature="queue"&gt;
+        &lt;xa>true&lt;/xa>
+        &lt;connectors>
+           &lt;connector-ref connector-name="netty"/&gt;
+        &lt;/connectors>
+        &lt;entries&gt;
+            &lt;entry name="ConnectionFactory"/&gt;           
+        &lt;/entries&gt;
+    &lt;/connection-factory&gt;
+&lt;/configuration&gt; 
+        </programlisting>
+    </section>
     <section>
         <title>JNDI的配置</title>
         <para>当客户端使用JNDI时需要定义一些JNDI的参数。这些参数主要用来确定JNDI服务的地址。这些参数通常保存在

Modified: branches/hornetq-416/examples/javaee/xarecovery/server/hornetq-jms.xml
===================================================================
--- branches/hornetq-416/examples/javaee/xarecovery/server/hornetq-jms.xml	2010-10-13 00:11:20 UTC (rev 9781)
+++ branches/hornetq-416/examples/javaee/xarecovery/server/hornetq-jms.xml	2010-10-13 07:38:20 UTC (rev 9782)
@@ -3,6 +3,7 @@
             xsi:schemaLocation="urn:hornetq /schema/hornetq-jms.xsd">
 
    <connection-factory name="ConnectionFactory">
+      <xa>true</xa>
       <connectors>
          <connector-ref connector-name="netty"/>
       </connectors>
@@ -16,4 +17,4 @@
    <queue name="testQueue">
       <entry name="/queue/testQueue"/>
    </queue>
-</configuration>
\ No newline at end of file
+</configuration>

Modified: branches/hornetq-416/examples/jms/client-kickoff/server0/hornetq-jms.xml
===================================================================
--- branches/hornetq-416/examples/jms/client-kickoff/server0/hornetq-jms.xml	2010-10-13 00:11:20 UTC (rev 9781)
+++ branches/hornetq-416/examples/jms/client-kickoff/server0/hornetq-jms.xml	2010-10-13 07:38:20 UTC (rev 9782)
@@ -2,7 +2,7 @@
             xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
             xsi:schemaLocation="urn:hornetq /schema/hornetq-jms.xsd">
    <!--the connection factory used by the example-->
-   <connection-factory name="ConnectionFactory">
+   <connection-factory name="ConnectionFactory" signature="queue">
       <connectors>
          <connector-ref connector-name="netty"/>
       </connectors>
@@ -11,4 +11,4 @@
       </entries>
    </connection-factory>
       
-</configuration>
\ No newline at end of file
+</configuration>

Modified: branches/hornetq-416/examples/jms/jms-bridge/server0/hornetq-jms.xml
===================================================================
--- branches/hornetq-416/examples/jms/jms-bridge/server0/hornetq-jms.xml	2010-10-13 00:11:20 UTC (rev 9781)
+++ branches/hornetq-416/examples/jms/jms-bridge/server0/hornetq-jms.xml	2010-10-13 07:38:20 UTC (rev 9782)
@@ -3,6 +3,7 @@
             xsi:schemaLocation="urn:hornetq /schema/hornetq-jms.xsd">
 
    <connection-factory name="ConnectionFactory">
+      <xa>true</xa>
       <connectors>
          <connector-ref connector-name="netty"/>
       </connectors>
@@ -11,6 +12,15 @@
       </entries>
    </connection-factory>
 
+   <connection-factory name="ClientConnectionFactory">
+      <connectors>
+         <connector-ref connector-name="netty"/>
+      </connectors>
+      <entries>
+         <entry name="/client/ConnectionFactory"/>
+      </entries>
+   </connection-factory>
+
    <topic name="topic">
       <entry name="/source/topic"/>
    </topic>

Modified: branches/hornetq-416/examples/jms/jms-bridge/server1/hornetq-jms.xml
===================================================================
--- branches/hornetq-416/examples/jms/jms-bridge/server1/hornetq-jms.xml	2010-10-13 00:11:20 UTC (rev 9781)
+++ branches/hornetq-416/examples/jms/jms-bridge/server1/hornetq-jms.xml	2010-10-13 07:38:20 UTC (rev 9782)
@@ -3,6 +3,7 @@
             xsi:schemaLocation="urn:hornetq /schema/hornetq-jms.xsd">
 
    <connection-factory name="ConnectionFactory">
+      <xa>true</xa>
       <connectors>
          <connector-ref connector-name="netty"/>
       </connectors>
@@ -11,6 +12,15 @@
       </entries>
    </connection-factory>
 
+   <connection-factory name="ClientConnectionFactory">
+      <connectors>
+         <connector-ref connector-name="netty"/>
+      </connectors>
+      <entries>
+         <entry name="/client/ConnectionFactory"/>
+      </entries>
+   </connection-factory>
+
    <queue name="target">
       <entry name="/target/queue"/>
    </queue>

Modified: branches/hornetq-416/examples/jms/jms-bridge/src/org/hornetq/jms/example/JMSBridgeExample.java
===================================================================
--- branches/hornetq-416/examples/jms/jms-bridge/src/org/hornetq/jms/example/JMSBridgeExample.java	2010-10-13 00:11:20 UTC (rev 9781)
+++ branches/hornetq-416/examples/jms/jms-bridge/src/org/hornetq/jms/example/JMSBridgeExample.java	2010-10-13 07:38:20 UTC (rev 9782)
@@ -55,7 +55,7 @@
       try
       {
          // Step 2. Lookup the *source* JMS resources
-         ConnectionFactory sourceConnectionFactory = (ConnectionFactory)sourceContext.lookup("/source/ConnectionFactory");
+         ConnectionFactory sourceConnectionFactory = (ConnectionFactory)sourceContext.lookup("/client/ConnectionFactory");
          Topic sourceTopic = (Topic)sourceContext.lookup("/source/topic");
 
          // Step 3. Create a connection, a session and a message producer for the *source* topic
@@ -75,7 +75,7 @@
          sourceConnection.close();
 
          // Step 6. Lookup the *target* JMS resources
-         ConnectionFactory targetConnectionFactory = (ConnectionFactory)targetContext.lookup("/target/ConnectionFactory");
+         ConnectionFactory targetConnectionFactory = (ConnectionFactory)targetContext.lookup("/client/ConnectionFactory");
          Queue targetQueue = (Queue)targetContext.lookup("/target/queue");
 
          // Step 7. Create a connection, a session and a message consumer for the *target* queue

Modified: branches/hornetq-416/examples/jms/jmx/server0/hornetq-jms.xml
===================================================================
--- branches/hornetq-416/examples/jms/jmx/server0/hornetq-jms.xml	2010-10-13 00:11:20 UTC (rev 9781)
+++ branches/hornetq-416/examples/jms/jmx/server0/hornetq-jms.xml	2010-10-13 07:38:20 UTC (rev 9782)
@@ -2,7 +2,7 @@
             xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
             xsi:schemaLocation="urn:hornetq /schema/hornetq-jms.xsd">
    <!--the connection factory used by the example-->
-   <connection-factory name="ConnectionFactory">
+   <connection-factory name="ConnectionFactory" signature="queue">
       <connectors>
          <connector-ref connector-name="netty"/>
       </connectors>
@@ -16,4 +16,4 @@
       <entry name="/queue/exampleQueue"/>
    </queue>
 
-</configuration>
\ No newline at end of file
+</configuration>

Modified: branches/hornetq-416/examples/jms/management/server0/hornetq-jms.xml
===================================================================
--- branches/hornetq-416/examples/jms/management/server0/hornetq-jms.xml	2010-10-13 00:11:20 UTC (rev 9781)
+++ branches/hornetq-416/examples/jms/management/server0/hornetq-jms.xml	2010-10-13 07:38:20 UTC (rev 9782)
@@ -2,7 +2,7 @@
             xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
             xsi:schemaLocation="urn:hornetq /schema/hornetq-jms.xsd">
    <!--the connection factory used by the example-->
-   <connection-factory name="ConnectionFactory">
+   <connection-factory name="ConnectionFactory" signature="queue">
       <connectors>
          <connector-ref connector-name="netty"/>
       </connectors>
@@ -15,4 +15,4 @@
    <queue name="exampleQueue">
       <entry name="/queue/exampleQueue"/>
    </queue>
-</configuration>
\ No newline at end of file
+</configuration>

Modified: branches/hornetq-416/examples/jms/message-counters/server0/hornetq-jms.xml
===================================================================
--- branches/hornetq-416/examples/jms/message-counters/server0/hornetq-jms.xml	2010-10-13 00:11:20 UTC (rev 9781)
+++ branches/hornetq-416/examples/jms/message-counters/server0/hornetq-jms.xml	2010-10-13 07:38:20 UTC (rev 9782)
@@ -2,7 +2,7 @@
             xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
             xsi:schemaLocation="urn:hornetq /schema/hornetq-jms.xsd">
    <!--the connection factory used by the example-->
-   <connection-factory name="ConnectionFactory">
+   <connection-factory name="ConnectionFactory" signature="queue">
       <connectors>
          <connector-ref connector-name="netty-connector"/>
       </connectors>
@@ -21,4 +21,4 @@
       <entry name="/queue/expiryQueue"/>
    </queue>
 
-</configuration>
\ No newline at end of file
+</configuration>

Modified: branches/hornetq-416/examples/jms/queue-requestor/server0/hornetq-jms.xml
===================================================================
--- branches/hornetq-416/examples/jms/queue-requestor/server0/hornetq-jms.xml	2010-10-13 00:11:20 UTC (rev 9781)
+++ branches/hornetq-416/examples/jms/queue-requestor/server0/hornetq-jms.xml	2010-10-13 07:38:20 UTC (rev 9782)
@@ -2,7 +2,7 @@
             xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
             xsi:schemaLocation="urn:hornetq /schema/hornetq-jms.xsd">
    <!--the connection factory used by the example-->
-   <connection-factory name="ConnectionFactory">
+   <connection-factory name="ConnectionFactory" signature="queue">
       <connectors>
          <connector-ref connector-name="netty-connector"/>
       </connectors>
@@ -16,4 +16,4 @@
       <entry name="/queue/exampleQueue"/>
    </queue>
 
-</configuration>
\ No newline at end of file
+</configuration>

Modified: branches/hornetq-416/examples/jms/symmetric-cluster/src/org/hornetq/jms/example/SymmetricClusterExample.java
===================================================================
--- branches/hornetq-416/examples/jms/symmetric-cluster/src/org/hornetq/jms/example/SymmetricClusterExample.java	2010-10-13 00:11:20 UTC (rev 9781)
+++ branches/hornetq-416/examples/jms/symmetric-cluster/src/org/hornetq/jms/example/SymmetricClusterExample.java	2010-10-13 07:38:20 UTC (rev 9782)
@@ -23,6 +23,7 @@
 
 import org.hornetq.api.jms.HornetQJMSClient;
 import org.hornetq.common.example.HornetQExample;
+import org.hornetq.jms.server.impl.JMSFactoryType;
 
 /**
  * This example demonstrates a cluster of three nodes set up in a symmetric topology - i.e. each node
@@ -79,7 +80,7 @@
          // connection factory directly we avoid having to worry about a JNDI look-up.
          // In an app server environment you could use HA-JNDI to lookup from the clustered JNDI servers without
          // having to know about a specific one.
-         ConnectionFactory cf = HornetQJMSClient.createConnectionFactory("231.7.7.7", 9876);
+         ConnectionFactory cf = (ConnectionFactory)HornetQJMSClient.createConnectionFactory("231.7.7.7", 9876, JMSFactoryType.CF);
 
          // We give a little while for each server to broadcast its whereabouts to the client
          Thread.sleep(2000);

Modified: branches/hornetq-416/examples/jms/xa-heuristic/server0/hornetq-jms.xml
===================================================================
--- branches/hornetq-416/examples/jms/xa-heuristic/server0/hornetq-jms.xml	2010-10-13 00:11:20 UTC (rev 9781)
+++ branches/hornetq-416/examples/jms/xa-heuristic/server0/hornetq-jms.xml	2010-10-13 07:38:20 UTC (rev 9782)
@@ -3,6 +3,7 @@
             xsi:schemaLocation="urn:hornetq /schema/hornetq-jms.xsd">
    <!--the connection factory used by the example-->
    <connection-factory name="ConnectionFactory">
+      <xa>true</xa>
       <connectors>
          <connector-ref connector-name="netty-connector"/>
       </connectors>
@@ -16,4 +17,4 @@
       <entry name="/queue/exampleQueue"/>
    </queue>
 
-</configuration>
\ No newline at end of file
+</configuration>

Modified: branches/hornetq-416/examples/jms/xa-receive/server0/hornetq-jms.xml
===================================================================
--- branches/hornetq-416/examples/jms/xa-receive/server0/hornetq-jms.xml	2010-10-13 00:11:20 UTC (rev 9781)
+++ branches/hornetq-416/examples/jms/xa-receive/server0/hornetq-jms.xml	2010-10-13 07:38:20 UTC (rev 9782)
@@ -3,6 +3,7 @@
             xsi:schemaLocation="urn:hornetq /schema/hornetq-jms.xsd">
    <!--the connection factory used by the example-->
    <connection-factory name="ConnectionFactory">
+      <xa>true</xa>
       <connectors>
          <connector-ref connector-name="netty-connector"/>
       </connectors>
@@ -16,4 +17,4 @@
       <entry name="/queue/exampleQueue"/>
    </queue>
 
-</configuration>
\ No newline at end of file
+</configuration>

Modified: branches/hornetq-416/examples/jms/xa-send/server0/hornetq-jms.xml
===================================================================
--- branches/hornetq-416/examples/jms/xa-send/server0/hornetq-jms.xml	2010-10-13 00:11:20 UTC (rev 9781)
+++ branches/hornetq-416/examples/jms/xa-send/server0/hornetq-jms.xml	2010-10-13 07:38:20 UTC (rev 9782)
@@ -3,6 +3,7 @@
             xsi:schemaLocation="urn:hornetq /schema/hornetq-jms.xsd">
    <!--the connection factory used by the example-->
    <connection-factory name="ConnectionFactory">
+      <xa>true</xa>
       <connectors>
          <connector-ref connector-name="netty-connector"/>
       </connectors>
@@ -16,4 +17,4 @@
       <entry name="/queue/exampleQueue"/>
    </queue>
 
-</configuration>
\ No newline at end of file
+</configuration>

Modified: branches/hornetq-416/examples/jms/xa-with-jta/server0/hornetq-jms.xml
===================================================================
--- branches/hornetq-416/examples/jms/xa-with-jta/server0/hornetq-jms.xml	2010-10-13 00:11:20 UTC (rev 9781)
+++ branches/hornetq-416/examples/jms/xa-with-jta/server0/hornetq-jms.xml	2010-10-13 07:38:20 UTC (rev 9782)
@@ -3,6 +3,7 @@
             xsi:schemaLocation="urn:hornetq /schema/hornetq-jms.xsd">
    <!--the connection factory used by the example-->
    <connection-factory name="ConnectionFactory">
+      <xa>true</xa>
       <connectors>
          <connector-ref connector-name="netty-connector"/>
       </connectors>
@@ -16,4 +17,4 @@
       <entry name="/queue/exampleQueue"/>
    </queue>
 
-</configuration>
\ No newline at end of file
+</configuration>

Modified: branches/hornetq-416/examples/soak/tx-restarts/server0/hornetq-jms.xml
===================================================================
--- branches/hornetq-416/examples/soak/tx-restarts/server0/hornetq-jms.xml	2010-10-13 00:11:20 UTC (rev 9781)
+++ branches/hornetq-416/examples/soak/tx-restarts/server0/hornetq-jms.xml	2010-10-13 07:38:20 UTC (rev 9782)
@@ -3,6 +3,7 @@
             xsi:schemaLocation="urn:hornetq /schema/hornetq-jms.xsd">
    <!--the connection factory used by the example-->
    <connection-factory name="ConnectionFactory">
+      <xa>true</xa>
       <connectors>
          <connector-ref connector-name="netty-connector"/>
       </connectors>

Modified: branches/hornetq-416/hornetq-rest/hornetq-rest/src/main/java/org/hornetq/rest/integration/HornetqBootstrapListener.java
===================================================================
--- branches/hornetq-416/hornetq-rest/hornetq-rest/src/main/java/org/hornetq/rest/integration/HornetqBootstrapListener.java	2010-10-13 00:11:20 UTC (rev 9781)
+++ branches/hornetq-416/hornetq-rest/hornetq-rest/src/main/java/org/hornetq/rest/integration/HornetqBootstrapListener.java	2010-10-13 07:38:20 UTC (rev 9782)
@@ -14,7 +14,6 @@
 {
    private EmbeddedJMS jms;
 
-   @Override
    public void contextInitialized(ServletContextEvent contextEvent)
    {
       ServletContext context = contextEvent.getServletContext();
@@ -30,7 +29,6 @@
       }
    }
 
-   @Override
    public void contextDestroyed(ServletContextEvent servletContextEvent)
    {
       try

Modified: branches/hornetq-416/hornetq-rest/hornetq-rest/src/main/java/org/hornetq/rest/integration/RestMessagingBootstrapListener.java
===================================================================
--- branches/hornetq-416/hornetq-rest/hornetq-rest/src/main/java/org/hornetq/rest/integration/RestMessagingBootstrapListener.java	2010-10-13 00:11:20 UTC (rev 9781)
+++ branches/hornetq-416/hornetq-rest/hornetq-rest/src/main/java/org/hornetq/rest/integration/RestMessagingBootstrapListener.java	2010-10-13 07:38:20 UTC (rev 9782)
@@ -16,7 +16,6 @@
 {
    MessageServiceManager manager;
 
-   @Override
    public void contextInitialized(ServletContextEvent contextEvent)
    {
       ServletContext context = contextEvent.getServletContext();
@@ -44,7 +43,6 @@
       }
    }
 
-   @Override
    public void contextDestroyed(ServletContextEvent servletContextEvent)
    {
       if (manager != null)

Modified: branches/hornetq-416/hornetq-rest/hornetq-rest/src/main/java/org/hornetq/rest/integration/ServletContextBindingRegistry.java
===================================================================
--- branches/hornetq-416/hornetq-rest/hornetq-rest/src/main/java/org/hornetq/rest/integration/ServletContextBindingRegistry.java	2010-10-13 00:11:20 UTC (rev 9781)
+++ branches/hornetq-416/hornetq-rest/hornetq-rest/src/main/java/org/hornetq/rest/integration/ServletContextBindingRegistry.java	2010-10-13 07:38:20 UTC (rev 9782)
@@ -17,37 +17,31 @@
       this.servletContext = servletContext;
    }
 
-   @Override
    public Object lookup(String name)
    {
       return servletContext.getAttribute(name);
    }
 
-   @Override
    public boolean bind(String name, Object obj)
    {
       servletContext.setAttribute(name, obj);
       return true;
    }
 
-   @Override
    public void unbind(String name)
    {
       servletContext.removeAttribute(name);
    }
 
-   @Override
    public void close()
    {
    }
 
-   @Override
    public Object getContext()
    {
       return servletContext;
    }
 
-   @Override
    public void setContext(Object o)
    {
       servletContext = (ServletContext)o;

Modified: branches/hornetq-416/hornetq-rest/hornetq-rest/src/main/java/org/hornetq/rest/queue/ConsumersResource.java
===================================================================
--- branches/hornetq-416/hornetq-rest/hornetq-rest/src/main/java/org/hornetq/rest/queue/ConsumersResource.java	2010-10-13 00:11:20 UTC (rev 9781)
+++ branches/hornetq-416/hornetq-rest/hornetq-rest/src/main/java/org/hornetq/rest/queue/ConsumersResource.java	2010-10-13 07:38:20 UTC (rev 9782)
@@ -78,7 +78,6 @@
 
    private Object timeoutLock = new Object();
 
-   @Override
    public void testTimeout(String target)
    {
       synchronized (timeoutLock)

Modified: branches/hornetq-416/hornetq-rest/hornetq-rest/src/main/java/org/hornetq/rest/queue/push/FilePushStore.java
===================================================================
--- branches/hornetq-416/hornetq-rest/hornetq-rest/src/main/java/org/hornetq/rest/queue/push/FilePushStore.java	2010-10-13 00:11:20 UTC (rev 9781)
+++ branches/hornetq-416/hornetq-rest/hornetq-rest/src/main/java/org/hornetq/rest/queue/push/FilePushStore.java	2010-10-13 07:38:20 UTC (rev 9782)
@@ -57,7 +57,6 @@
       return list;
    }
 
-   @Override
    public synchronized List<PushRegistration> getByDestination(String destination)
    {
       List<PushRegistration> list = new ArrayList<PushRegistration>();
@@ -71,7 +70,6 @@
       return list;
    }
 
-   @Override
    public synchronized void update(PushRegistration reg) throws Exception
    {
       if (reg.getLoadedFrom() == null) return;
@@ -86,7 +84,6 @@
       marshaller.marshal(reg, (File) reg.getLoadedFrom());
    }
 
-   @Override
    public synchronized void add(PushRegistration reg) throws Exception
    {
       map.put(reg.getId(), reg);
@@ -97,7 +94,6 @@
       save(reg);
    }
 
-   @Override
    public synchronized void remove(PushRegistration reg) throws Exception
    {
       map.remove(reg.getId());
@@ -106,7 +102,6 @@
       fp.delete();
    }
 
-   @Override
    public synchronized void removeAll() throws Exception
    {
       ArrayList<PushRegistration> copy = new ArrayList<PushRegistration>();

Modified: branches/hornetq-416/hornetq-rest/hornetq-rest/src/main/java/org/hornetq/rest/queue/push/PushConsumer.java
===================================================================
--- branches/hornetq-416/hornetq-rest/hornetq-rest/src/main/java/org/hornetq/rest/queue/push/PushConsumer.java	2010-10-13 00:11:20 UTC (rev 9781)
+++ branches/hornetq-416/hornetq-rest/hornetq-rest/src/main/java/org/hornetq/rest/queue/push/PushConsumer.java	2010-10-13 07:38:20 UTC (rev 9782)
@@ -100,7 +100,6 @@
       }
    }
 
-   @Override
    public void onMessage(ClientMessage clientMessage)
    {
       if (strategy.push(clientMessage) == false)

Modified: branches/hornetq-416/hornetq-rest/hornetq-rest/src/main/java/org/hornetq/rest/queue/push/UriStrategy.java
===================================================================
--- branches/hornetq-416/hornetq-rest/hornetq-rest/src/main/java/org/hornetq/rest/queue/push/UriStrategy.java	2010-10-13 00:11:20 UTC (rev 9781)
+++ branches/hornetq-416/hornetq-rest/hornetq-rest/src/main/java/org/hornetq/rest/queue/push/UriStrategy.java	2010-10-13 07:38:20 UTC (rev 9782)
@@ -30,7 +30,6 @@
    protected String method;
    protected String contentType;
 
-   @Override
    public void setRegistration(PushRegistration reg)
    {
       this.registration = reg;
@@ -63,12 +62,10 @@
       }
    }
 
-   @Override
    public void stop()
    {
    }
 
-   @Override
    public boolean push(ClientMessage message)
    {
       String uri = createUri(message);

Modified: branches/hornetq-416/hornetq-rest/hornetq-rest/src/main/java/org/hornetq/rest/topic/FileTopicPushStore.java
===================================================================
--- branches/hornetq-416/hornetq-rest/hornetq-rest/src/main/java/org/hornetq/rest/topic/FileTopicPushStore.java	2010-10-13 00:11:20 UTC (rev 9781)
+++ branches/hornetq-416/hornetq-rest/hornetq-rest/src/main/java/org/hornetq/rest/topic/FileTopicPushStore.java	2010-10-13 07:38:20 UTC (rev 9782)
@@ -18,7 +18,6 @@
       super(dirname);
    }
 
-   @Override
    public synchronized List<PushTopicRegistration> getByTopic(String topic)
    {
       List<PushTopicRegistration> list = new ArrayList<PushTopicRegistration>();

Modified: branches/hornetq-416/hornetq-rest/hornetq-rest/src/main/java/org/hornetq/rest/topic/SubscriptionsResource.java
===================================================================
--- branches/hornetq-416/hornetq-rest/hornetq-rest/src/main/java/org/hornetq/rest/topic/SubscriptionsResource.java	2010-10-13 00:11:20 UTC (rev 9781)
+++ branches/hornetq-416/hornetq-rest/hornetq-rest/src/main/java/org/hornetq/rest/topic/SubscriptionsResource.java	2010-10-13 07:38:20 UTC (rev 9782)
@@ -84,7 +84,6 @@
 
    private Object timeoutLock = new Object();
 
-   @Override
    public void testTimeout(String target)
    {
       synchronized (timeoutLock)

Modified: branches/hornetq-416/hornetq-rest/hornetq-rest/src/main/java/org/hornetq/rest/util/CustomHeaderLinkStrategy.java
===================================================================
--- branches/hornetq-416/hornetq-rest/hornetq-rest/src/main/java/org/hornetq/rest/util/CustomHeaderLinkStrategy.java	2010-10-13 00:11:20 UTC (rev 9781)
+++ branches/hornetq-416/hornetq-rest/hornetq-rest/src/main/java/org/hornetq/rest/util/CustomHeaderLinkStrategy.java	2010-10-13 07:38:20 UTC (rev 9782)
@@ -8,7 +8,6 @@
  */
 public class CustomHeaderLinkStrategy implements LinkStrategy
 {
-   @Override
    public void setLinkHeader(Response.ResponseBuilder builder, String title, String rel, String href, String type)
    {
       String headerName = null;

Modified: branches/hornetq-416/hornetq-rest/hornetq-rest/src/main/java/org/hornetq/rest/util/TimeoutTask.java
===================================================================
--- branches/hornetq-416/hornetq-rest/hornetq-rest/src/main/java/org/hornetq/rest/util/TimeoutTask.java	2010-10-13 00:11:20 UTC (rev 9781)
+++ branches/hornetq-416/hornetq-rest/hornetq-rest/src/main/java/org/hornetq/rest/util/TimeoutTask.java	2010-10-13 07:38:20 UTC (rev 9782)
@@ -58,7 +58,6 @@
       thread.start();
    }
 
-   @Override
    public void run()
    {
       while (running)

Modified: branches/hornetq-416/hornetq-rest/hornetq-rest/src/test/java/org/hornetq/rest/test/JMSTest.java
===================================================================
--- branches/hornetq-416/hornetq-rest/hornetq-rest/src/test/java/org/hornetq/rest/test/JMSTest.java	2010-10-13 00:11:20 UTC (rev 9781)
+++ branches/hornetq-416/hornetq-rest/hornetq-rest/src/test/java/org/hornetq/rest/test/JMSTest.java	2010-10-13 07:38:20 UTC (rev 9782)
@@ -2,6 +2,7 @@
 
 import org.hornetq.jms.client.HornetQConnectionFactory;
 import org.hornetq.jms.client.HornetQDestination;
+import org.hornetq.jms.client.HornetQJMSConnectionFactory;
 import org.hornetq.rest.HttpHeaderProperty;
 import org.hornetq.rest.Jms;
 import org.hornetq.rest.queue.QueueDeployment;
@@ -39,7 +40,7 @@
    @BeforeClass
    public static void setup() throws Exception
    {
-      connectionFactory = new HornetQConnectionFactory(manager.getQueueManager().getSessionFactory());
+      connectionFactory = new HornetQJMSConnectionFactory(manager.getQueueManager().getSessionFactory());
    }
 
    @XmlRootElement
@@ -128,7 +129,6 @@
       public static Order order;
       public static CountDownLatch latch = new CountDownLatch(1);
 
-      @Override
       public void onMessage(Message message)
       {
          try

Modified: branches/hornetq-416/hornetq-rest/hornetq-rest/src/test/java/org/hornetq/rest/test/RawRestartTest.java
===================================================================
--- branches/hornetq-416/hornetq-rest/hornetq-rest/src/test/java/org/hornetq/rest/test/RawRestartTest.java	2010-10-13 00:11:20 UTC (rev 9781)
+++ branches/hornetq-416/hornetq-rest/hornetq-rest/src/test/java/org/hornetq/rest/test/RawRestartTest.java	2010-10-13 07:38:20 UTC (rev 9782)
@@ -80,7 +80,6 @@
 
    private static class MyListener implements MessageHandler
    {
-      @Override
       public void onMessage(ClientMessage message)
       {
          int size = message.getBodyBuffer().readInt();

Modified: branches/hornetq-416/hornetq-rest/hornetq-rest/src/test/java/org/hornetq/rest/test/TransformTest.java
===================================================================
--- branches/hornetq-416/hornetq-rest/hornetq-rest/src/test/java/org/hornetq/rest/test/TransformTest.java	2010-10-13 00:11:20 UTC (rev 9781)
+++ branches/hornetq-416/hornetq-rest/hornetq-rest/src/test/java/org/hornetq/rest/test/TransformTest.java	2010-10-13 07:38:20 UTC (rev 9782)
@@ -180,7 +180,6 @@
       public static Order order;
       public static CountDownLatch latch = new CountDownLatch(1);
 
-      @Override
       public void onMessage(ClientMessage clientMessage)
       {
          System.out.println("onMessage!");

Modified: branches/hornetq-416/src/config/common/schema/hornetq-jms.xsd
===================================================================
--- branches/hornetq-416/src/config/common/schema/hornetq-jms.xsd	2010-10-13 00:11:20 UTC (rev 9781)
+++ branches/hornetq-416/src/config/common/schema/hornetq-jms.xsd	2010-10-13 07:38:20 UTC (rev 9782)
@@ -26,6 +26,7 @@
    <xsd:element name="connection-factory">
    	<xsd:complexType>
    		<xsd:all>
+           	<xsd:element name="xa" type="xsd:boolean" maxOccurs="1" minOccurs="0"></xsd:element>
            	<xsd:element name="discovery-group-ref" type="discovery-group-refType" maxOccurs="1" minOccurs="0"></xsd:element>
            	<xsd:element name="discovery-initial-wait-timeout" type="xsd:long" maxOccurs="1" minOccurs="0"></xsd:element>
 	
@@ -135,6 +136,7 @@
             </xsd:element>
    		</xsd:all>
    		<xsd:attribute name="name" type="xsd:string"></xsd:attribute>
+   		<xsd:attribute name="signature" type="xsd:string"></xsd:attribute>
    	</xsd:complexType>
    </xsd:element>
 

Modified: branches/hornetq-416/src/config/jboss-as-4/clustered/jms-ds.xml
===================================================================
--- branches/hornetq-416/src/config/jboss-as-4/clustered/jms-ds.xml	2010-10-13 00:11:20 UTC (rev 9781)
+++ branches/hornetq-416/src/config/jboss-as-4/clustered/jms-ds.xml	2010-10-13 07:38:20 UTC (rev 9782)
@@ -22,10 +22,6 @@
       <attribute name="FactoryRef">java:/XAConnectionFactory</attribute>
       <attribute name="QueueFactoryRef">java:/XAConnectionFactory</attribute>
       <attribute name="TopicFactoryRef">java:/XAConnectionFactory</attribute>
-      <attribute name="Properties">
-       java.naming.factory.initial=org.jnp.interfaces.NamingContextFactory
-       java.naming.factory.url.pkgs=org.jnp.interfaces
-       java.naming.provider.url=localhost:1199
     </attribute>
 
    </mbean>

Copied: branches/hornetq-416/src/config/jboss-as-4/clustered/login-config.xml (from rev 9781, trunk/src/config/jboss-as-4/clustered/login-config.xml)
===================================================================
--- branches/hornetq-416/src/config/jboss-as-4/clustered/login-config.xml	                        (rev 0)
+++ branches/hornetq-416/src/config/jboss-as-4/clustered/login-config.xml	2010-10-13 07:38:20 UTC (rev 9782)
@@ -0,0 +1,159 @@
+<?xml version='1.0'?>
+
+<!--
+  ~ 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.
+  -->
+
+<!-- The XML based JAAS login configuration read by the
+org.jboss.security.auth.login.XMLLoginConfig mbean. Add
+an application-policy element for each security domain.
+
+The outline of the application-policy is:
+<application-policy name="security-domain-name">
+  <authentication>
+    <login-module code="login.module1.class.name" flag="control_flag">
+      <module-option name = "option1-name">option1-value</module-option>
+      <module-option name = "option2-name">option2-value</module-option>
+      ...
+    </login-module>
+
+    <login-module code="login.module2.class.name" flag="control_flag">
+      ...
+    </login-module>
+    ...
+  </authentication>
+</application-policy>
+
+$Id: login-config.xml 76444 2008-07-29 23:50:53Z sguilhen at redhat.com $
+$Revision: 76444 $
+-->
+
+<policy>
+  <!-- Used by clients within the application server VM such as
+  mbeans and servlets that access EJBs.
+  -->
+  <application-policy name="client-login">
+    <authentication>
+      <login-module code="org.jboss.security.ClientLoginModule"
+        flag="required">
+         <!-- Any existing security context will be restored on logout -->
+         <module-option name="restore-login-identity">true</module-option>
+      </login-module>
+    </authentication>
+  </application-policy>
+
+  <!-- Security domains for testing new jca framework -->
+  <application-policy name="HsqlDbRealm">
+    <authentication>
+      <login-module code="org.jboss.resource.security.ConfiguredIdentityLoginModule"
+        flag="required">
+        <module-option name="principal">sa</module-option>
+        <module-option name="userName">sa</module-option>
+        <module-option name="password"></module-option>
+        <module-option name="managedConnectionFactoryName">jboss.jca:service=LocalTxCM,name=DefaultDS</module-option>
+      </login-module>
+    </authentication>
+  </application-policy>
+
+  <application-policy name="JmsXARealm">
+    <authentication>
+      <login-module code="org.jboss.resource.security.ConfiguredIdentityLoginModule"
+        flag="required">
+        <module-option name="principal">guest</module-option>
+        <module-option name="userName">guest</module-option>
+        <module-option name="password">guest</module-option>
+        <module-option name="managedConnectionFactoryName">jboss.jca:service=TxCM,name=JmsXA</module-option>
+      </login-module>
+    </authentication>
+  </application-policy>
+
+  <!-- A template configuration for hornetq. This
+    defaults to the UsersRolesLoginModule the same as other and should be
+    changed to a stronger authentication mechanism as required.
+  -->
+<application-policy name="hornetq">
+    <authentication>
+      <login-module code="org.jboss.security.auth.spi.UsersRolesLoginModule"
+        flag="required">
+	<module-option name = "unauthenticatedIdentity">guest</module-option>
+        <module-option name="usersProperties">props/hornetq-users.properties</module-option>
+        <module-option name="rolesProperties">props/hornetq-roles.properties</module-option>
+      </login-module>
+    </authentication>
+  </application-policy>
+
+  <!-- A template configuration for the jmx-console web application. This
+    defaults to the UsersRolesLoginModule the same as other and should be
+    changed to a stronger authentication mechanism as required.
+  -->
+  <application-policy name="jmx-console">
+    <authentication>
+      <login-module code="org.jboss.security.auth.spi.UsersRolesLoginModule"
+        flag="required">
+        <module-option name="usersProperties">props/jmx-console-users.properties</module-option>
+        <module-option name="rolesProperties">props/jmx-console-roles.properties</module-option>
+      </login-module>
+    </authentication>
+  </application-policy>
+
+  <!-- A template configuration for the web-console web application. This
+    defaults to the UsersRolesLoginModule the same as other and should be
+    changed to a stronger authentication mechanism as required.
+  -->
+  <application-policy name="web-console">
+    <authentication>
+      <login-module code="org.jboss.security.auth.spi.UsersRolesLoginModule"
+        flag="required">
+        <module-option name="usersProperties">web-console-users.properties</module-option>
+        <module-option name="rolesProperties">web-console-roles.properties</module-option>
+      </login-module>
+    </authentication>
+  </application-policy>
+
+  <!--
+    A template configuration for the JBossWS security domain.
+    This defaults to the UsersRolesLoginModule the same as other and should be
+    changed to a stronger authentication mechanism as required.
+  -->
+  <application-policy name="JBossWS">
+    <authentication>
+      <login-module code="org.jboss.security.auth.spi.UsersRolesLoginModule"
+        flag="required">
+        <module-option name="usersProperties">props/jbossws-users.properties</module-option>
+        <module-option name="rolesProperties">props/jbossws-roles.properties</module-option>
+        <module-option name="unauthenticatedIdentity">anonymous</module-option>
+      </login-module>
+    </authentication>
+  </application-policy>
+
+  <!-- The default login configuration used by any security domain that
+  does not have a application-policy entry with a matching name
+  -->
+  <application-policy name="other">
+    <!-- A simple server login module, which can be used when the number
+    of users is relatively small. It uses two properties files:
+    users.properties, which holds users (key) and their password (value).
+    roles.properties, which holds users (key) and a comma-separated list of
+    their roles (value).
+    The unauthenticatedIdentity property defines the name of the principal
+    that will be used when a null username and password are presented as is
+    the case for an unuathenticated web client or MDB. If you want to
+    allow such users to be authenticated add the property, e.g.,
+    unauthenticatedIdentity="nobody"
+    -->
+    <authentication>
+      <login-module code="org.jboss.security.auth.spi.UsersRolesLoginModule"
+        flag="required"/>
+    </authentication>
+  </application-policy>
+
+</policy>

Modified: branches/hornetq-416/src/main/org/hornetq/api/core/client/HornetQClient.java
===================================================================
--- branches/hornetq-416/src/main/org/hornetq/api/core/client/HornetQClient.java	2010-10-13 00:11:20 UTC (rev 9781)
+++ branches/hornetq-416/src/main/org/hornetq/api/core/client/HornetQClient.java	2010-10-13 07:38:20 UTC (rev 9782)
@@ -91,6 +91,8 @@
    public static final boolean DEFAULT_CACHE_LARGE_MESSAGE_CLIENT = false;
 
    public static final int DEFAULT_INITIAL_MESSAGE_PACKET_SIZE = 1500;
+
+   public static final boolean DEFAULT_XA = false;
    
    /**
     * Creates a ClientSessionFactory using all the defaults.

Modified: branches/hornetq-416/src/main/org/hornetq/api/jms/HornetQJMSClient.java
===================================================================
--- branches/hornetq-416/src/main/org/hornetq/api/jms/HornetQJMSClient.java	2010-10-13 00:11:20 UTC (rev 9781)
+++ branches/hornetq-416/src/main/org/hornetq/api/jms/HornetQJMSClient.java	2010-10-13 07:38:20 UTC (rev 9782)
@@ -23,6 +23,13 @@
 import org.hornetq.core.logging.Logger;
 import org.hornetq.jms.client.HornetQConnectionFactory;
 import org.hornetq.jms.client.HornetQDestination;
+import org.hornetq.jms.client.HornetQJMSConnectionFactory;
+import org.hornetq.jms.client.HornetQQueueConnectionFactory;
+import org.hornetq.jms.client.HornetQTopicConnectionFactory;
+import org.hornetq.jms.client.HornetQXAConnectionFactory;
+import org.hornetq.jms.client.HornetQXAQueueConnectionFactory;
+import org.hornetq.jms.client.HornetQXATopicConnectionFactory;
+import org.hornetq.jms.server.impl.JMSFactoryType;
 
 /**
  * A utility class for creating HornetQ client-side JMS managed resources.
@@ -49,9 +56,9 @@
     * @param sessionFactory The underlying ClientSessionFactory to use.
     * @return The HornetQConnectionFactory.
     */
-   public static HornetQConnectionFactory createConnectionFactory(final ClientSessionFactory sessionFactory)
+   public static HornetQJMSConnectionFactory createConnectionFactory(final ClientSessionFactory sessionFactory)
    {
-      return new HornetQConnectionFactory(sessionFactory);
+      return new HornetQJMSConnectionFactory(sessionFactory);
    }
 
    /**
@@ -59,11 +66,38 @@
     *
     * @param discoveryAddress The address to use for discovery.
     * @param discoveryPort The port to use for discovery.
+    * @param jmsFactoryType 
     * @return The HornetQConnectionFactory.
     */
-   public static HornetQConnectionFactory createConnectionFactory(final String discoveryAddress, final int discoveryPort)
+   public static HornetQConnectionFactory createConnectionFactory(final String discoveryAddress, final int discoveryPort, JMSFactoryType jmsFactoryType)
    {
-      return new HornetQConnectionFactory(discoveryAddress, discoveryPort);
+      HornetQConnectionFactory factory = null;
+      if (jmsFactoryType.equals(JMSFactoryType.CF))
+      {
+         factory = new HornetQJMSConnectionFactory(discoveryAddress, discoveryPort);
+      }
+      else if (jmsFactoryType.equals(JMSFactoryType.QUEUE_CF))
+      {
+         factory = new HornetQQueueConnectionFactory(discoveryAddress, discoveryPort);
+      }
+      else if (jmsFactoryType.equals(JMSFactoryType.TOPIC_CF))
+      {
+         factory = new HornetQTopicConnectionFactory(discoveryAddress, discoveryPort);
+      }
+      else if (jmsFactoryType.equals(JMSFactoryType.XA_CF))
+      {
+         factory = new HornetQXAConnectionFactory(discoveryAddress, discoveryPort);
+      }
+      else if (jmsFactoryType.equals(JMSFactoryType.QUEUE_XA_CF))
+      {
+         factory = new HornetQXAQueueConnectionFactory(discoveryAddress, discoveryPort);
+      }
+      else if (jmsFactoryType.equals(JMSFactoryType.TOPIC_XA_CF))
+      {
+         factory = new HornetQXATopicConnectionFactory(discoveryAddress, discoveryPort);
+      }
+      
+      return factory;
    }
 
    /**
@@ -72,22 +106,75 @@
     * @param staticConnectors The list of TransportConfiguration to use.
     * @return The HornetQConnectionFactory.
     */
-   public static HornetQConnectionFactory createConnectionFactory(final List<Pair<TransportConfiguration, TransportConfiguration>> staticConnectors)
+   public static HornetQConnectionFactory createConnectionFactory(final List<Pair<TransportConfiguration, TransportConfiguration>> staticConnectors, 
+                                                                  final JMSFactoryType jmsFactoryType)
    {
-      return new HornetQConnectionFactory(staticConnectors);
+      HornetQConnectionFactory factory = null;
+      if (jmsFactoryType.equals(JMSFactoryType.CF))
+      {
+         factory = new HornetQJMSConnectionFactory(staticConnectors);
+      }
+      else if (jmsFactoryType.equals(JMSFactoryType.QUEUE_CF))
+      {
+         factory = new HornetQQueueConnectionFactory(staticConnectors);
+      }
+      else if (jmsFactoryType.equals(JMSFactoryType.TOPIC_CF))
+      {
+         factory = new HornetQTopicConnectionFactory(staticConnectors);
+      }
+      else if (jmsFactoryType.equals(JMSFactoryType.XA_CF))
+      {
+         factory = new HornetQXAConnectionFactory(staticConnectors);
+      }
+      else if (jmsFactoryType.equals(JMSFactoryType.QUEUE_XA_CF))
+      {
+         factory = new HornetQXAQueueConnectionFactory(staticConnectors);
+      }
+      else if (jmsFactoryType.equals(JMSFactoryType.TOPIC_XA_CF))
+      {
+         factory = new HornetQXATopicConnectionFactory(staticConnectors);
+      }
+      
+      return factory;
    }
 
    /**
     * Creates a HornetQConnectionFactory using a single pair of live-backup TransportConfiguration.
     *
-    * @param connectorConfig The TransportConfiguration of the server to connect to.
-    * @param backupConnectorConfig The TransportConfiguration of the backup server to connect to. can be null.
+    * @param connectorConfigs The TransportConfiguration of the server to connect to.
     * @return The HornetQConnectionFactory.
     */
    public static HornetQConnectionFactory createConnectionFactory(final TransportConfiguration connectorConfig,
-                                   final TransportConfiguration backupConnectorConfig)
+                                                                  final TransportConfiguration backupConnectorConfig,
+                                                                  final JMSFactoryType jmsFactoryType)
    {
-      return new HornetQConnectionFactory(connectorConfig, backupConnectorConfig);
+      HornetQConnectionFactory factory = null;
+      if (jmsFactoryType.equals(JMSFactoryType.CF))
+      {
+         factory = new HornetQJMSConnectionFactory(connectorConfig, backupConnectorConfig);
+      }
+      else if (jmsFactoryType.equals(JMSFactoryType.QUEUE_CF))
+      {
+         factory = new HornetQQueueConnectionFactory(connectorConfig, backupConnectorConfig);
+      }
+      else if (jmsFactoryType.equals(JMSFactoryType.TOPIC_CF))
+      {
+         factory = new HornetQTopicConnectionFactory(connectorConfig, backupConnectorConfig);
+      }
+      else if (jmsFactoryType.equals(JMSFactoryType.XA_CF))
+      {
+         factory = new HornetQXAConnectionFactory(connectorConfig, backupConnectorConfig);
+      }
+      else if (jmsFactoryType.equals(JMSFactoryType.QUEUE_XA_CF))
+      {
+         factory = new HornetQXAQueueConnectionFactory(connectorConfig, backupConnectorConfig);
+      }
+      else if (jmsFactoryType.equals(JMSFactoryType.TOPIC_XA_CF))
+      {
+         factory = new HornetQXATopicConnectionFactory(connectorConfig, backupConnectorConfig);
+      }
+      
+      return factory;
    }
 
    /**
@@ -96,11 +183,16 @@
     * @param connectorConfig The TransportConfiguration of the server.
     * @return The HornetQConnectionFactory.
     */
-   public static HornetQConnectionFactory createConnectionFactory(final TransportConfiguration connectorConfig)
+   public static HornetQJMSConnectionFactory createConnectionFactory(final TransportConfiguration connectorConfig)
    {
-      return new HornetQConnectionFactory(connectorConfig);
+      return new HornetQJMSConnectionFactory(connectorConfig);
    }
 
+   public static HornetQXAConnectionFactory createXAConnectionFactory(final TransportConfiguration connectorConfig)
+   {
+      return new HornetQXAConnectionFactory(connectorConfig);
+   }
+
    /**
     * Creates a client-side representation of a JMS Topic.
     *

Modified: branches/hornetq-416/src/main/org/hornetq/core/client/impl/ClientConsumerImpl.java
===================================================================
--- branches/hornetq-416/src/main/org/hornetq/core/client/impl/ClientConsumerImpl.java	2010-10-13 00:11:20 UTC (rev 9781)
+++ branches/hornetq-416/src/main/org/hornetq/core/client/impl/ClientConsumerImpl.java	2010-10-13 07:38:20 UTC (rev 9782)
@@ -16,7 +16,6 @@
 import java.io.File;
 import java.util.Iterator;
 import java.util.concurrent.Executor;
-import java.util.concurrent.atomic.AtomicLong;
 
 import org.hornetq.api.core.HornetQBuffers;
 import org.hornetq.api.core.HornetQException;
@@ -113,7 +112,7 @@
 
    private boolean stopped = false;
 
-   private final AtomicLong forceDeliveryCount = new AtomicLong(0);
+   private long forceDeliveryCount;
 
    private final SessionQueueQueryResponseMessage queueInfo;
 
@@ -226,7 +225,7 @@
                      // we only force delivery once per call to receive
                      if (!deliveryForced)
                      {
-                        session.forceDelivery(id, forceDeliveryCount.incrementAndGet());
+                        session.forceDelivery(id, forceDeliveryCount++);
 
                         deliveryForced = true;
                      }
@@ -260,18 +259,17 @@
                if (m.containsProperty(ClientConsumerImpl.FORCED_DELIVERY_MESSAGE))
                {
                   long seq = m.getLongProperty(ClientConsumerImpl.FORCED_DELIVERY_MESSAGE);
-                  if (seq >= forceDeliveryCount.longValue())
+
+                  if (forcingDelivery && seq == forceDeliveryCount - 1)
                   {
                      // forced delivery messages are discarded, nothing has been delivered by the queue
-                     if (forcingDelivery)
-                     {
-                        resetIfSlowConsumer();
-                        return null;
-                     }
+                     resetIfSlowConsumer();
+
+                     return null;
                   }
                   else
                   {
-                     // ignore any previous forced delivery message
+                     // Ignore the message
                      continue;
                   }
                }
@@ -425,7 +423,7 @@
       lastAckedMessage = null;
 
       creditsToSend = 0;
-      
+
       ackIndividually = false;
    }
 
@@ -468,7 +466,7 @@
    {
       return browseOnly;
    }
-   
+
    public synchronized void handleMessage(final ClientMessageInternal message) throws Exception
    {
       if (closing)
@@ -571,7 +569,7 @@
          while (iter.hasNext())
          {
             ClientMessageInternal message = iter.next();
-            
+
             flowControlBeforeConsumption(message);
          }
 
@@ -603,7 +601,7 @@
          {
             flushAcks();
          }
-         
+
          session.individualAcknowledge(id, message.getMessageID());
       }
       else
@@ -708,7 +706,7 @@
 
    private void resetIfSlowConsumer()
    {
-      if(clientWindowSize == 0)
+      if (clientWindowSize == 0)
       {
          slowConsumerInitialCreditSent = false;
          sendCredits(0);
@@ -729,6 +727,7 @@
       {
          ClientConsumerImpl.log.trace("Adding Runner on Executor for delivery");
       }
+      
       sessionExecutor.execute(runner);
    }
 
@@ -806,6 +805,12 @@
 
          if (message != null)
          {
+            if (message.containsProperty(ClientConsumerImpl.FORCED_DELIVERY_MESSAGE))
+            {
+               //Ignore, this could be a relic from a previous receiveImmediate();
+               return;
+            }
+            
             boolean expired = message.isExpired();
 
             flowControlBeforeConsumption(message);
@@ -933,7 +938,6 @@
    {
       public void run()
       {
-
          try
          {
             callOnMessage();

Modified: branches/hornetq-416/src/main/org/hornetq/core/client/impl/ClientSessionImpl.java
===================================================================
--- branches/hornetq-416/src/main/org/hornetq/core/client/impl/ClientSessionImpl.java	2010-10-13 00:11:20 UTC (rev 9781)
+++ branches/hornetq-416/src/main/org/hornetq/core/client/impl/ClientSessionImpl.java	2010-10-13 07:38:20 UTC (rev 9782)
@@ -974,6 +974,13 @@
 
                      sendPacketWithoutLock(packet);
                   }
+                  else
+                  {
+                     //https://jira.jboss.org/browse/HORNETQ-522
+                     SessionConsumerFlowCreditMessage packet = new SessionConsumerFlowCreditMessage(entry.getKey(),
+                                                                                                    1);
+                     sendPacketWithoutLock(packet);
+                  }
                }
 
                if ((!autoCommitAcks || !autoCommitSends) && workDone)

Modified: branches/hornetq-416/src/main/org/hornetq/core/client/impl/FailoverManagerImpl.java
===================================================================
--- branches/hornetq-416/src/main/org/hornetq/core/client/impl/FailoverManagerImpl.java	2010-10-13 00:11:20 UTC (rev 9781)
+++ branches/hornetq-416/src/main/org/hornetq/core/client/impl/FailoverManagerImpl.java	2010-10-13 07:38:20 UTC (rev 9782)
@@ -296,9 +296,15 @@
    {
       handleConnectionFailure(connectionID, me);
    }
+   
+   public void connectionReadyForWrites(final Object connectionID, final boolean ready)
+   {
+   }
 
    // ConnectionManager implementation ------------------------------------------------------------------
 
+   
+
    public ClientSession createSession(final String username,
                                       final String password,
                                       final boolean xa,

Modified: branches/hornetq-416/src/main/org/hornetq/core/deployers/impl/FileConfigurationParser.java
===================================================================
--- branches/hornetq-416/src/main/org/hornetq/core/deployers/impl/FileConfigurationParser.java	2010-10-13 00:11:20 UTC (rev 9781)
+++ branches/hornetq-416/src/main/org/hornetq/core/deployers/impl/FileConfigurationParser.java	2010-10-13 07:38:20 UTC (rev 9782)
@@ -686,31 +686,31 @@
                }
                else if (FileConfigurationParser.CREATEDURABLEQUEUE_NAME.equals(type))
                {
-                  createDurableQueue.add(role);
+                  createDurableQueue.add(role.trim());
                }
                else if (FileConfigurationParser.DELETEDURABLEQUEUE_NAME.equals(type))
                {
-                  deleteDurableQueue.add(role);
+                  deleteDurableQueue.add(role.trim());
                }
                else if (FileConfigurationParser.CREATE_NON_DURABLE_QUEUE_NAME.equals(type))
                {
-                  createNonDurableQueue.add(role);
+                  createNonDurableQueue.add(role.trim());
                }
                else if (FileConfigurationParser.DELETE_NON_DURABLE_QUEUE_NAME.equals(type))
                {
-                  deleteNonDurableQueue.add(role);
+                  deleteNonDurableQueue.add(role.trim());
                }
                else if (FileConfigurationParser.CREATETEMPQUEUE_NAME.equals(type))
                {
-                  createNonDurableQueue.add(role);
+                  createNonDurableQueue.add(role.trim());
                }
                else if (FileConfigurationParser.DELETETEMPQUEUE_NAME.equals(type))
                {
-                  deleteNonDurableQueue.add(role);
+                  deleteNonDurableQueue.add(role.trim());
                }
                else if (FileConfigurationParser.MANAGE_NAME.equals(type))
                {
-                  manageRoles.add(role);
+                  manageRoles.add(role.trim());
                }
                if (!allRoles.contains(role.trim()))
                {

Modified: branches/hornetq-416/src/main/org/hornetq/core/paging/PagingStore.java
===================================================================
--- branches/hornetq-416/src/main/org/hornetq/core/paging/PagingStore.java	2010-10-13 00:11:20 UTC (rev 9781)
+++ branches/hornetq-416/src/main/org/hornetq/core/paging/PagingStore.java	2010-10-13 07:38:20 UTC (rev 9782)
@@ -13,6 +13,8 @@
 
 package org.hornetq.core.paging;
 
+import java.util.List;
+
 import org.hornetq.api.core.SimpleString;
 import org.hornetq.core.server.HornetQComponent;
 import org.hornetq.core.server.ServerMessage;
@@ -49,7 +51,7 @@
 
    void sync() throws Exception;
 
-   boolean page(ServerMessage message, long transactionId) throws Exception;
+   boolean page(List<ServerMessage> messages, long transactionId) throws Exception;
 
    boolean page(ServerMessage message) throws Exception;
 

Modified: branches/hornetq-416/src/main/org/hornetq/core/paging/impl/PageImpl.java
===================================================================
--- branches/hornetq-416/src/main/org/hornetq/core/paging/impl/PageImpl.java	2010-10-13 00:11:20 UTC (rev 9781)
+++ branches/hornetq-416/src/main/org/hornetq/core/paging/impl/PageImpl.java	2010-10-13 07:38:20 UTC (rev 9782)
@@ -236,6 +236,11 @@
    {
       return size.intValue();
    }
+   
+   public String toString()
+   {
+      return "PageImpl::pageID="  + this.pageId + ", file=" + this.file;
+   }
 
    // Package protected ---------------------------------------------
 

Modified: branches/hornetq-416/src/main/org/hornetq/core/paging/impl/PagingManagerImpl.java
===================================================================
--- branches/hornetq-416/src/main/org/hornetq/core/paging/impl/PagingManagerImpl.java	2010-10-13 00:11:20 UTC (rev 9781)
+++ branches/hornetq-416/src/main/org/hornetq/core/paging/impl/PagingManagerImpl.java	2010-10-13 07:38:20 UTC (rev 9782)
@@ -235,11 +235,16 @@
 
    // Private -------------------------------------------------------
 
-   private PagingStore newStore(final SimpleString address) throws Exception
+   protected PagingStore newStore(final SimpleString address) throws Exception
    {
       return pagingStoreFactory.newStore(address,
                                          addressSettingsRepository.getMatch(address.toString()));
    }
+   
+   protected PagingStoreFactory getStoreFactory()
+   {
+      return pagingStoreFactory;
+   }
 
    // Inner classes -------------------------------------------------
 

Modified: branches/hornetq-416/src/main/org/hornetq/core/paging/impl/PagingStoreFactoryNIO.java
===================================================================
--- branches/hornetq-416/src/main/org/hornetq/core/paging/impl/PagingStoreFactoryNIO.java	2010-10-13 00:11:20 UTC (rev 9781)
+++ branches/hornetq-416/src/main/org/hornetq/core/paging/impl/PagingStoreFactoryNIO.java	2010-10-13 07:38:20 UTC (rev 9782)
@@ -220,6 +220,26 @@
    {
       return new NIOSequentialFileFactory(directory + File.separatorChar + directoryName, false);
    }
+   
+   protected PagingManager getPagingManager()
+   {
+      return pagingManager;
+   }
+   
+   protected StorageManager getStorageManager()
+   {
+      return storageManager;
+   }
+   
+   protected PostOffice getPostOffice()
+   {
+      return postOffice;
+   }
+   
+   protected ExecutorFactory getExecutorFactory()
+   {
+      return executorFactory;
+   }
 
    // Private -------------------------------------------------------
 

Modified: branches/hornetq-416/src/main/org/hornetq/core/paging/impl/PagingStoreImpl.java
===================================================================
--- branches/hornetq-416/src/main/org/hornetq/core/paging/impl/PagingStoreImpl.java	2010-10-13 00:11:20 UTC (rev 9781)
+++ branches/hornetq-416/src/main/org/hornetq/core/paging/impl/PagingStoreImpl.java	2010-10-13 07:38:20 UTC (rev 9782)
@@ -14,6 +14,7 @@
 package org.hornetq.core.paging.impl;
 
 import java.text.DecimalFormat;
+import java.util.Arrays;
 import java.util.HashMap;
 import java.util.List;
 import java.util.Map;
@@ -110,7 +111,7 @@
    private volatile Page currentPage;
 
    private final ReentrantLock writeLock = new ReentrantLock();
-   
+
    /** duplicate cache used at this address */
    private final DuplicateIDCache duplicateCache;
 
@@ -186,7 +187,7 @@
       this.storeFactory = storeFactory;
 
       this.syncNonTransactional = syncNonTransactional;
-      
+
       // Post office could be null on the backup node
       if (postOffice == null)
       {
@@ -196,7 +197,7 @@
       {
          this.duplicateCache = postOffice.getDuplicateIDCache(storeName);
       }
-      
+
    }
 
    // Public --------------------------------------------------------
@@ -263,7 +264,7 @@
       return storeName;
    }
 
-   public boolean page(final ServerMessage message, final long transactionID) throws Exception
+   public boolean page(final List<ServerMessage> message, final long transactionID) throws Exception
    {
       // The sync on transactions is done on commit only
       return page(message, transactionID, false);
@@ -273,7 +274,7 @@
    {
       // If non Durable, there is no need to sync as there is no requirement for persistence for those messages in case
       // of crash
-      return page(message, -1, syncNonTransactional && message.isDurable());
+      return page(Arrays.asList(message), -1, syncNonTransactional && message.isDurable());
    }
 
    public void sync() throws Exception
@@ -541,7 +542,6 @@
       writeLock.lock();
 
       currentPageLock.writeLock().lock(); // Make sure no checks are done on currentPage while we are depaging
-
       try
       {
          if (!running)
@@ -597,6 +597,7 @@
             {
                returnPage = createPage(firstPageId++);
             }
+
             return returnPage;
          }
       }
@@ -619,10 +620,14 @@
     * @return
     * @throws Exception
     */
-   private boolean readPage() throws Exception
+   protected boolean readPage() throws Exception
    {
       Page page = depage();
 
+      // It's important that only depage should happen while locked
+      // or we would be holding a lock for a long time
+      // The reading (IO part) should happen outside of any locks
+
       if (page == null)
       {
          return false;
@@ -630,8 +635,8 @@
 
       page.open();
 
-      List<PagedMessage> messages =  null;
-      
+      List<PagedMessage> messages = null;
+
       try
       {
          messages = page.read();
@@ -688,25 +693,25 @@
    class OurRunnable implements Runnable
    {
       boolean ran;
-      
+
       final Runnable runnable;
-      
+
       OurRunnable(final Runnable runnable)
       {
          this.runnable = runnable;
       }
-      
+
       public synchronized void run()
       {
          if (!ran)
          {
             runnable.run();
-            
+
             ran = true;
          }
       }
    }
-   
+
    public void executeRunnableWhenMemoryAvailable(final Runnable runnable)
    {
       if (addressFullMessagePolicy == AddressFullMessagePolicy.BLOCK && maxSize != -1)
@@ -714,23 +719,23 @@
          if (sizeInBytes.get() > maxSize)
          {
             OurRunnable ourRunnable = new OurRunnable(runnable);
-            
+
             onMemoryFreedRunnables.add(ourRunnable);
-            
-            //We check again to avoid a race condition where the size can come down just after the element
-            //has been added, but the check to execute was done before the element was added
-            //NOTE! We do not fix this race by locking the whole thing, doing this check provides
-            //MUCH better performance in a highly concurrent environment
+
+            // We check again to avoid a race condition where the size can come down just after the element
+            // has been added, but the check to execute was done before the element was added
+            // NOTE! We do not fix this race by locking the whole thing, doing this check provides
+            // MUCH better performance in a highly concurrent environment
             if (sizeInBytes.get() <= maxSize)
             {
-               //run it now
+               // run it now
                ourRunnable.run();
             }
 
             return;
          }
       }
-      
+
       runnable.run();
    }
 
@@ -797,9 +802,7 @@
 
    }
 
-   private boolean page(final ServerMessage message,
-                        final long transactionID,
-                        final boolean sync) throws Exception
+   protected boolean page(final List<ServerMessage> messages, final long transactionID, final boolean sync) throws Exception
    {
       if (!running)
       {
@@ -857,60 +860,63 @@
             return false;
          }
 
-         PagedMessage pagedMessage;
-         
-         if (!message.isDurable())
+         for (ServerMessage message : messages)
          {
-            // The address should never be transient when paging (even for non-persistent messages when paging)
-            // This will force everything to be persisted
-            message.bodyChanged();
-         }
+            PagedMessage pagedMessage;
 
-         if (transactionID != -1)
-         {
-            pagedMessage = new PagedMessageImpl(message, transactionID);
-         }
-         else
-         {
-            pagedMessage = new PagedMessageImpl(message);
-         }
+            if (!message.isDurable())
+            {
+               // The address should never be transient when paging (even for non-persistent messages when paging)
+               // This will force everything to be persisted
+               message.bodyChanged();
+            }
 
-         int bytesToWrite = pagedMessage.getEncodeSize() + PageImpl.SIZE_RECORD;
-
-         if (currentPageSize.addAndGet(bytesToWrite) > pageSize && currentPage.getNumberOfMessages() > 0)
-         {
-            // Make sure nothing is currently validating or using currentPage
-            currentPageLock.writeLock().lock();
-            try
+            if (transactionID != -1)
             {
-               openNewPage();
-
-               // openNewPage will set currentPageSize to zero, we need to set it again
-               currentPageSize.addAndGet(bytesToWrite);
+               pagedMessage = new PagedMessageImpl(message, transactionID);
             }
-            finally
+            else
             {
-               currentPageLock.writeLock().unlock();
+               pagedMessage = new PagedMessageImpl(message);
             }
-         }
 
-         currentPageLock.readLock().lock();
+            int bytesToWrite = pagedMessage.getEncodeSize() + PageImpl.SIZE_RECORD;
 
-         try
-         {
-            currentPage.write(pagedMessage);
+            if (currentPageSize.addAndGet(bytesToWrite) > pageSize && currentPage.getNumberOfMessages() > 0)
+            {
+               // Make sure nothing is currently validating or using currentPage
+               currentPageLock.writeLock().lock();
+               try
+               {
+                  openNewPage();
 
-            if (sync)
+                  // openNewPage will set currentPageSize to zero, we need to set it again
+                  currentPageSize.addAndGet(bytesToWrite);
+               }
+               finally
+               {
+                  currentPageLock.writeLock().unlock();
+               }
+            }
+
+            currentPageLock.readLock().lock();
+
+            try
             {
-               currentPage.sync();
+               currentPage.write(pagedMessage);
+ 
+               if (sync)
+               {
+                  currentPage.sync();
+               }
             }
+            finally
+            {
+               currentPageLock.readLock().unlock();
+            }
+         }
 
-            return true;
-         }
-         finally
-         {
-            currentPageLock.readLock().unlock();
-         }
+         return true;
       }
       finally
       {
@@ -940,9 +946,9 @@
 
       // Depage has to be done atomically, in case of failure it should be
       // back to where it was
-      
+
       byte[] duplicateIdForPage = generateDuplicateID(pageId);
-      
+
       Transaction depageTransaction = new TransactionImpl(storageManager);
 
       // DuplicateCache could be null during replication
@@ -950,7 +956,8 @@
       {
          if (duplicateCache.contains(duplicateIdForPage))
          {
-            log.warn("Page " + pageId + " had been processed already but the file wasn't removed as a crash happened. Ignoring this page");
+            log.warn("Page " + pageId +
+                     " had been processed already but the file wasn't removed as a crash happened. Ignoring this page");
             return true;
          }
 
@@ -1058,7 +1065,7 @@
       {
          // This will set the journal transaction to commit;
          depageTransaction.setContainsPersistent();
-         
+
          entry.getKey().storeUpdate(storageManager, this.pagingManager, depageTransaction, entry.getValue().intValue());
       }
 

Modified: branches/hornetq-416/src/main/org/hornetq/core/persistence/impl/journal/JournalStorageManager.java
===================================================================
--- branches/hornetq-416/src/main/org/hornetq/core/persistence/impl/journal/JournalStorageManager.java	2010-10-13 00:11:20 UTC (rev 9781)
+++ branches/hornetq-416/src/main/org/hornetq/core/persistence/impl/journal/JournalStorageManager.java	2010-10-13 07:38:20 UTC (rev 9782)
@@ -168,11 +168,10 @@
    private final String journalDir;
 
    private final String largeMessagesDirectory;
-   
-   
+
    // Persisted core configuration
    private final Map<SimpleString, PersistedRoles> mapPersistedRoles = new ConcurrentHashMap<SimpleString, PersistedRoles>();
-   
+
    private final Map<SimpleString, PersistedAddressSetting> mapPersistedAddressSettings = new ConcurrentHashMap<SimpleString, PersistedAddressSetting>();
 
    public JournalStorageManager(final Configuration config, final ExecutorFactory executorFactory)
@@ -585,7 +584,11 @@
 
    public void updatePageTransaction(final long txID, final PageTransactionInfo pageTransaction, final int depages) throws Exception
    {
-      messageJournal.appendUpdateRecordTransactional(txID, pageTransaction.getRecordID(), JournalStorageManager.PAGE_TRANSACTION, new PageUpdateTXEncoding(pageTransaction.getTransactionID(), depages));
+      messageJournal.appendUpdateRecordTransactional(txID,
+                                                     pageTransaction.getRecordID(),
+                                                     JournalStorageManager.PAGE_TRANSACTION,
+                                                     new PageUpdateTXEncoding(pageTransaction.getTransactionID(),
+                                                                              depages));
    }
 
    public void storeReferenceTransactional(final long txID, final long queueID, final long messageID) throws Exception
@@ -697,8 +700,7 @@
                                         getContext(syncNonTransactional));
 
    }
-   
-   
+
    public void storeAddressSetting(PersistedAddressSetting addressSetting) throws Exception
    {
       deleteAddressSetting(addressSetting.getAddressMatch());
@@ -707,14 +709,13 @@
       bindingsJournal.appendAddRecord(id, ADDRESS_SETTING_RECORD, addressSetting, true);
       mapPersistedAddressSettings.put(addressSetting.getAddressMatch(), addressSetting);
    }
-   
+
    public List<PersistedAddressSetting> recoverAddressSettings() throws Exception
    {
       ArrayList<PersistedAddressSetting> list = new ArrayList<PersistedAddressSetting>(mapPersistedAddressSettings.size());
       list.addAll(mapPersistedAddressSettings.values());
       return list;
    }
-   
 
    /* (non-Javadoc)
     * @see org.hornetq.core.persistence.StorageManager#recoverPersistedRoles()
@@ -746,9 +747,9 @@
       {
          bindingsJournal.appendDeleteRecord(oldSetting.getStoreId(), false);
       }
-      
+
    }
-   
+
    public void deleteSecurityRoles(SimpleString addressMatch) throws Exception
    {
       PersistedRoles oldRoles = mapPersistedRoles.remove(addressMatch);
@@ -758,8 +759,6 @@
       }
    }
 
-
-
    public JournalLoadInformation loadMessageJournal(final PostOffice postOffice,
                                                     final PagingManager pagingManager,
                                                     final ResourceManager resourceManager,
@@ -771,7 +770,7 @@
       List<PreparedTransactionInfo> preparedTransactions = new ArrayList<PreparedTransactionInfo>();
 
       Map<Long, ServerMessage> messages = new HashMap<Long, ServerMessage>();
-      
+
       JournalLoadInformation info = messageJournal.load(records,
                                                         preparedTransactions,
                                                         new LargeMessageTXFailureCallback(messages));
@@ -781,17 +780,17 @@
       Map<Long, Map<Long, AddMessageRecord>> queueMap = new HashMap<Long, Map<Long, AddMessageRecord>>();
 
       final int totalSize = records.size();
-      
-      for (int reccount = 0 ; reccount < totalSize; reccount++)
+
+      for (int reccount = 0; reccount < totalSize; reccount++)
       {
          // It will show log.info only with large journals (more than 1 million records)
-         if (reccount> 0 && reccount % 1000000 == 0)
+         if (reccount > 0 && reccount % 1000000 == 0)
          {
             long percent = (long)((((double)reccount) / ((double)totalSize)) * 100f);
-            
+
             log.info(percent + "% loaded");
          }
-         
+
          RecordInfo record = records.get(reccount);
          byte[] data = record.data;
 
@@ -885,15 +884,15 @@
 
                if (queueMessages == null)
                {
-                  log.warn("Cannot find queue "  + encoding.queueID + " to update delivery count");
+                  log.warn("Cannot find queue " + encoding.queueID + " to update delivery count");
                }
                else
                {
                   AddMessageRecord rec = queueMessages.get(messageID);
-   
+
                   if (rec == null)
                   {
-                     log.warn("Cannot find message "  + messageID + " to update delivery count");
+                     log.warn("Cannot find message " + messageID + " to update delivery count");
                   }
                   else
                   {
@@ -908,21 +907,21 @@
                if (record.isUpdate)
                {
                   PageUpdateTXEncoding pageUpdate = new PageUpdateTXEncoding();
-                  
+
                   pageUpdate.decode(buff);
-                  
+
                   PageTransactionInfo pageTX = pagingManager.getTransaction(pageUpdate.pageTX);
-                  
+
                   pageTX.update(pageUpdate.recods, null, null);
                }
                else
                {
                   PageTransactionInfoImpl pageTransactionInfo = new PageTransactionInfoImpl();
-   
+
                   pageTransactionInfo.decode(buff);
-   
+
                   pageTransactionInfo.setRecordID(record.id);
-   
+
                   pagingManager.addTransaction(pageTransactionInfo);
                }
 
@@ -985,13 +984,13 @@
                throw new IllegalStateException("Invalid record type " + recordType);
             }
          }
-         
+
          // This will free up memory sooner. The record is not needed any more
          // and its byte array would consume memory during the load process even though it's not necessary any longer
          // what would delay processing time during load
          records.set(reccount, null);
       }
-      
+
       // Release the memory as soon as not needed any longer
       records.clear();
       records = null;
@@ -1003,7 +1002,14 @@
          Map<Long, AddMessageRecord> queueRecords = entry.getValue();
 
          Queue queue = queues.get(queueID);
-         
+
+         if (queue == null)
+         {
+            log.warn("Message for queue " + queueID + " which does not exist. This message will be ignored.");
+
+            continue;
+         }
+
          Collection<AddMessageRecord> valueRecords = queueRecords.values();
 
          for (AddMessageRecord record : valueRecords)
@@ -1037,7 +1043,7 @@
             msg.decrementDelayDeletionCount();
          }
       }
-      
+
       for (ServerMessage msg : messages.values())
       {
          if (msg.getRefCount() == 0)
@@ -1053,7 +1059,7 @@
             }
          }
       }
-      
+
       if (perfBlastPages != -1)
       {
          messageJournal.perfBlast(perfBlastPages);
@@ -1418,18 +1424,22 @@
 
                   if (queue == null)
                   {
-                     throw new IllegalStateException("Cannot find queue with id " + encoding.queueID);
+                     log.warn("Message in prepared tx for queue " + encoding.queueID +
+                              " which does not exist. This message will be ignored.");
+
                   }
+                  else
+                  {
+                     ServerMessage message = messages.get(messageID);
 
-                  ServerMessage message = messages.get(messageID);
+                     if (message == null)
+                     {
+                        throw new IllegalStateException("Cannot find message with id " + messageID);
+                     }
 
-                  if (message == null)
-                  {
-                     throw new IllegalStateException("Cannot find message with id " + messageID);
+                     postOffice.reroute(message, queue, tx);
                   }
 
-                  postOffice.reroute(message, queue, tx);
-
                   break;
                }
                case ACKNOWLEDGE_REF:
@@ -1446,7 +1456,7 @@
                   {
                      throw new IllegalStateException("Cannot find queue with id " + encoding.queueID);
                   }
-                  
+
                   // TODO - this involves a scan - we should find a quicker way of doing it
                   MessageReference removed = queue.removeReferenceWithID(messageID);
 
@@ -2017,24 +2027,24 @@
          super(queueID);
       }
    }
-   
+
    private static class PageUpdateTXEncoding implements EncodingSupport
    {
-      
+
       public long pageTX;
-      
+
       public int recods;
-      
+
       public PageUpdateTXEncoding()
       {
       }
-      
+
       public PageUpdateTXEncoding(final long pageTX, final int records)
       {
          this.pageTX = pageTX;
          this.recods = records;
       }
-      
+
       public void decode(HornetQBuffer buffer)
       {
          this.pageTX = buffer.readLong();
@@ -2057,7 +2067,7 @@
       {
          return DataConstants.SIZE_LONG + DataConstants.SIZE_INT;
       }
-      
+
    }
 
    private static class ScheduledDeliveryEncoding extends QueueEncoding
@@ -2182,6 +2192,7 @@
       }
 
    }
+
    private static final class AddMessageRecord
    {
       public AddMessageRecord(final ServerMessage message)
@@ -2194,7 +2205,7 @@
       long scheduledDeliveryTime;
 
       int deliveryCount;
-      
+
       boolean referenced = false;
    }
 

Modified: branches/hornetq-416/src/main/org/hornetq/core/postoffice/impl/PostOfficeImpl.java
===================================================================
--- branches/hornetq-416/src/main/org/hornetq/core/postoffice/impl/PostOfficeImpl.java	2010-10-13 00:11:20 UTC (rev 9781)
+++ branches/hornetq-416/src/main/org/hornetq/core/postoffice/impl/PostOfficeImpl.java	2010-10-13 07:38:20 UTC (rev 9782)
@@ -15,16 +15,15 @@
 
 import java.util.ArrayList;
 import java.util.HashMap;
-import java.util.HashSet;
 import java.util.Iterator;
 import java.util.List;
 import java.util.Map;
-import java.util.Set;
 import java.util.concurrent.ConcurrentHashMap;
 import java.util.concurrent.ConcurrentMap;
 
 import org.hornetq.api.core.HornetQException;
 import org.hornetq.api.core.Message;
+import org.hornetq.api.core.Pair;
 import org.hornetq.api.core.SimpleString;
 import org.hornetq.api.core.management.ManagementHelper;
 import org.hornetq.api.core.management.NotificationType;
@@ -476,10 +475,10 @@
       if (addressManager.getBindingsForRoutingAddress(binding.getAddress()) == null)
       {
          pagingManager.deletePageStore(binding.getAddress());
-         
+
          managementService.unregisterAddress(binding.getAddress());
       }
-      
+
       if (binding.getType() == BindingType.LOCAL_QUEUE)
       {
          managementService.unregisterQueue(uniqueName, binding.getAddress());
@@ -488,21 +487,24 @@
       {
          managementService.unregisterDivert(uniqueName);
       }
+      
+      if (binding.getType() != BindingType.DIVERT)
+      {
+         TypedProperties props = new TypedProperties();
 
-      TypedProperties props = new TypedProperties();
+         props.putSimpleStringProperty(ManagementHelper.HDR_ADDRESS, binding.getAddress());
 
-      props.putSimpleStringProperty(ManagementHelper.HDR_ADDRESS, binding.getAddress());
+         props.putSimpleStringProperty(ManagementHelper.HDR_CLUSTER_NAME, binding.getClusterName());
 
-      props.putSimpleStringProperty(ManagementHelper.HDR_CLUSTER_NAME, binding.getClusterName());
+         props.putSimpleStringProperty(ManagementHelper.HDR_ROUTING_NAME, binding.getRoutingName());
 
-      props.putSimpleStringProperty(ManagementHelper.HDR_ROUTING_NAME, binding.getRoutingName());
+         props.putIntProperty(ManagementHelper.HDR_DISTANCE, binding.getDistance());
 
-      props.putIntProperty(ManagementHelper.HDR_DISTANCE, binding.getDistance());
+         managementService.sendNotification(new Notification(null, NotificationType.BINDING_REMOVED, props));
+      }
 
-      managementService.sendNotification(new Notification(null, NotificationType.BINDING_REMOVED, props));
+      binding.close();
 
-      binding.close();
-      
       return binding;
    }
 
@@ -537,7 +539,7 @@
    {
       route(message, new RoutingContextImpl(tx), direct);
    }
-   
+
    public void route(final ServerMessage message, final RoutingContext context, final boolean direct) throws Exception
    {
       // Sanity check
@@ -547,7 +549,7 @@
       }
 
       SimpleString address = message.getAddress();
-      
+
       setPagingStore(message);
 
       Object duplicateID = message.getObjectProperty(Message.HDR_DUPLICATE_DETECTION_ID);
@@ -614,17 +616,18 @@
       else
       {
          Transaction tx = context.getTransaction();
-         
+
          boolean depage = tx.getProperty(TransactionPropertyIndexes.IS_DEPAGE) != null;
-         
-         // if the TX paged at least one message on a give address, all the other addresses should also go towards paging cache now 
+
+         // if the TX paged at least one message on a give address, all the other addresses should also go towards
+         // paging cache now
          boolean alreadyPaging = false;
-         
+
          if (tx.isPaging())
          {
-            alreadyPaging = getPageOperation(tx).isPaging(message.getAddress()); 
+            alreadyPaging = getPageOperation(tx).isPaging(message.getAddress());
          }
-         
+
          if (!depage && message.storeIsPaging() || alreadyPaging)
          {
             tx.setPaging(true);
@@ -633,7 +636,7 @@
             {
                tx.commit();
             }
-            
+
             return;
          }
       }
@@ -849,7 +852,7 @@
    private void setPagingStore(final ServerMessage message) throws Exception
    {
       PagingStore store = pagingManager.getPageStore(message.getAddress());
-      
+
       message.setPagingStore(store);
    }
 
@@ -1113,21 +1116,26 @@
 
    private class PageMessageOperation implements TransactionOperation
    {
-      private final List<ServerMessage> messagesToPage = new ArrayList<ServerMessage>();
-      
-      private final HashSet<SimpleString> addressesPaging = new HashSet<SimpleString>();
-      
+      private final HashMap<SimpleString, Pair<PagingStore, List<ServerMessage>>> pagingData = new HashMap<SimpleString, Pair<PagingStore, List<ServerMessage>>>();
+
       private Transaction subTX = null;
-      
+
       void addMessageToPage(final ServerMessage message)
       {
-         messagesToPage.add(message);
-         addressesPaging.add(message.getAddress());
+         Pair<PagingStore, List<ServerMessage>> pagePair = pagingData.get(message.getAddress());
+         if (pagePair == null)
+         {
+            pagePair = new Pair<PagingStore, List<ServerMessage>>(message.getPagingStore(),
+                                                                  new ArrayList<ServerMessage>());
+            pagingData.put(message.getAddress(), pagePair);
+         }
+
+         pagePair.b.add(message);
       }
-      
+
       boolean isPaging(final SimpleString address)
       {
-         return addressesPaging.contains(address);
+         return pagingData.get(address) != null;
       }
 
       public void afterCommit(final Transaction tx)
@@ -1142,7 +1150,7 @@
          {
             pageTransaction.commit();
          }
-         
+
          if (subTX != null)
          {
             subTX.afterCommit();
@@ -1178,18 +1186,18 @@
          {
             pageMessages(tx);
          }
-         
+
          if (subTX != null)
          {
             subTX.beforeCommit();
          }
-         
+
       }
 
       public void beforePrepare(final Transaction tx) throws Exception
       {
          pageMessages(tx);
-         
+
          if (subTX != null)
          {
             subTX.beforePrepare();
@@ -1206,7 +1214,7 @@
 
       private void pageMessages(final Transaction tx) throws Exception
       {
-         if (!messagesToPage.isEmpty())
+         if (!pagingData.isEmpty())
          {
             PageTransactionInfo pageTransaction = (PageTransactionInfo)tx.getProperty(TransactionPropertyIndexes.PAGE_TRANSACTION);
 
@@ -1223,21 +1231,33 @@
 
             boolean pagingPersistent = false;
 
-            Set<PagingStore> pagingStoresToSync = new HashSet<PagingStore>();
+            ArrayList<ServerMessage> nonPagedMessages = null;
 
-            for (ServerMessage message : messagesToPage)
+            for (Pair<PagingStore, List<ServerMessage>> pair : pagingData.values())
             {
-               if (message.page(tx.getID()))
+               
+               if (!pair.a.page(pair.b, tx.getID()))
                {
-                  if (message.isDurable())
+                  if (nonPagedMessages == null)
                   {
-                     // We only create pageTransactions if using persistent messages
+                     nonPagedMessages = new ArrayList<ServerMessage>();
+                  }
+                  nonPagedMessages.addAll(pair.b);
+               }
+               
+               for (ServerMessage msg : pair.b)
+               {
+                  if (msg.isDurable())
+                  {
                      pageTransaction.increment();
                      pagingPersistent = true;
-                     pagingStoresToSync.add(message.getPagingStore());
                   }
                }
-               else
+            }
+
+            if (nonPagedMessages != null)
+            {
+               for (ServerMessage message : nonPagedMessages)
                {
                   // This could happen when the PageStore left the pageState
                   // we create a copy of the transaction so that messages are routed with the same tx ID.
@@ -1246,9 +1266,9 @@
                   {
                      subTX = tx.copy();
                   }
-                  
+
                   route(message, subTX, false);
-                  
+
                   if (subTX.isContainsPersistent())
                   {
                      // The route wouldn't be able to update the persistent flag on the main TX
@@ -1261,16 +1281,12 @@
             if (pagingPersistent)
             {
                tx.setContainsPersistent();
-
-               if (!pagingStoresToSync.isEmpty())
+               for (Pair<PagingStore, List<ServerMessage>> pair : pagingData.values())
                {
-                  for (PagingStore store : pagingStoresToSync)
-                  {
-                     store.sync();
-                  }
+                  pair.a.sync();
+               }
 
-                  pageTransaction.store(storageManager, pagingManager, tx);
-               }
+               pageTransaction.store(storageManager, pagingManager, tx);
             }
          }
       }

Modified: branches/hornetq-416/src/main/org/hornetq/core/protocol/core/ServerSessionPacketHandler.java
===================================================================
--- branches/hornetq-416/src/main/org/hornetq/core/protocol/core/ServerSessionPacketHandler.java	2010-10-13 00:11:20 UTC (rev 9781)
+++ branches/hornetq-416/src/main/org/hornetq/core/protocol/core/ServerSessionPacketHandler.java	2010-10-13 07:38:20 UTC (rev 9782)
@@ -107,7 +107,7 @@
  * @author <a href="mailto:andy.taylor at jboss.org>Andy Taylor</a>
  * @author <a href="mailto:clebert.suconic at jboss.org>Clebert Suconic</a>
  */
-public class ServerSessionPacketHandler implements ChannelHandler, CloseListener, FailureListener
+public class ServerSessionPacketHandler implements ChannelHandler
 {
    private static final Logger log = Logger.getLogger(ServerSessionPacketHandler.class);
 
@@ -150,8 +150,6 @@
       {
          direct = false;
       }
-      
-      addConnectionListeners();
    }
 
    public long getID()
@@ -159,22 +157,6 @@
       return channel.getID();
    }
 
-   public void connectionFailed(final HornetQException exception)
-   {
-      log.warn("Client connection failed, clearing up resources for session " + session.getName());
-
-      try
-      {
-         session.close(true);
-      }
-      catch (Exception e)
-      {
-         log.error("Failed to close session", e);
-      }
-
-      log.warn("Cleared up resources for session " + session.getName());
-   }
-
    public void close()
    {
       channel.flushConfirmations();
@@ -189,22 +171,6 @@
       }
    }
 
-   public void connectionClosed()
-   {
-   }
-
-   private void addConnectionListeners()
-   {
-      remotingConnection.addFailureListener(this);
-      remotingConnection.addCloseListener(this);
-   }
-
-   private void removeConnectionListeners()
-   {
-      remotingConnection.removeFailureListener(this);
-      remotingConnection.removeCloseListener(this);
-   }
-
    public Channel getChannel()
    {
       return channel;
@@ -423,7 +389,7 @@
                {
                   requiresResponse = true;
                   session.close(false);
-                  removeConnectionListeners();
+                 // removeConnectionListeners();
                   response = new NullResponseMessage();
                   flush = true;
                   closeChannel = true;
@@ -601,10 +567,10 @@
       // might be executed
       // before we have transferred the connection, leaving it in a started state
       session.setTransferring(true);
-
-      remotingConnection.removeFailureListener(this);
-      remotingConnection.removeCloseListener(this);
-
+            
+      List<CloseListener> closeListeners = remotingConnection.removeCloseListeners();
+      List<FailureListener> failureListeners = remotingConnection.removeFailureListeners();
+      
       // Note. We do not destroy the replicating connection here. In the case the live server has really crashed
       // then the connection will get cleaned up anyway when the server ping timeout kicks in.
       // In the case the live server is really still up, i.e. a split brain situation (or in tests), then closing
@@ -618,8 +584,8 @@
 
       remotingConnection = newConnection;
 
-      remotingConnection.addFailureListener(this);
-      remotingConnection.addCloseListener(this);
+      remotingConnection.setCloseListeners(closeListeners);
+      remotingConnection.setFailureListeners(failureListeners);
 
       int serverLastReceivedCommandID = channel.getLastConfirmedCommandID();
 

Modified: branches/hornetq-416/src/main/org/hornetq/core/protocol/core/impl/CoreSessionCallback.java
===================================================================
--- branches/hornetq-416/src/main/org/hornetq/core/protocol/core/impl/CoreSessionCallback.java	2010-10-13 00:11:20 UTC (rev 9781)
+++ branches/hornetq-416/src/main/org/hornetq/core/protocol/core/impl/CoreSessionCallback.java	2010-10-13 07:38:20 UTC (rev 9782)
@@ -23,11 +23,12 @@
 import org.hornetq.core.server.ServerMessage;
 import org.hornetq.spi.core.protocol.ProtocolManager;
 import org.hornetq.spi.core.protocol.SessionCallback;
+import org.hornetq.spi.core.remoting.ReadyListener;
 
 /**
  * A CoreSessionCallback
  *
- * @author <a href="mailto:jmesnil at redhat.com">Jeff Mesnil</a>
+ * @author Tim Fox
  *
  *
  */
@@ -54,8 +55,8 @@
 
       channel.send(packet);
 
-      int size =  packet.getPacketSize();
-      
+      int size = packet.getPacketSize();
+
       return size;
    }
 
@@ -67,15 +68,15 @@
 
       return packet.getPacketSize();
    }
-     
+
    public int sendMessage(ServerMessage message, long consumerID, int deliveryCount)
    {
       Packet packet = new SessionReceiveMessage(consumerID, message, deliveryCount);
 
       channel.sendBatched(packet);
-      
-      int size =  packet.getPacketSize();
 
+      int size = packet.getPacketSize();
+
       return size;
    }
 
@@ -90,4 +91,15 @@
    {
       protocolManager.removeHandler(name);
    }
+   
+   public void addReadyListener(final ReadyListener listener)
+   {
+      channel.getConnection().getTransportConnection().addReadyListener(listener);      
+   }
+
+   public void removeReadyListener(final ReadyListener listener)
+   {
+      channel.getConnection().getTransportConnection().removeReadyListener(listener);
+   }
+
 }
\ No newline at end of file

Modified: branches/hornetq-416/src/main/org/hornetq/core/protocol/core/impl/RemotingConnectionImpl.java
===================================================================
--- branches/hornetq-416/src/main/org/hornetq/core/protocol/core/impl/RemotingConnectionImpl.java	2010-10-13 00:11:20 UTC (rev 9781)
+++ branches/hornetq-416/src/main/org/hornetq/core/protocol/core/impl/RemotingConnectionImpl.java	2010-10-13 07:38:20 UTC (rev 9782)
@@ -234,6 +234,31 @@
       return closeListeners.remove(listener);
    }
 
+   public List<CloseListener> removeCloseListeners()
+   {
+      List<CloseListener> ret = new ArrayList<CloseListener>(closeListeners);
+      
+      closeListeners.clear();
+      
+      return ret;
+   }
+
+   public List<FailureListener> removeFailureListeners()
+   {
+      List<FailureListener> ret = new ArrayList<FailureListener>(failureListeners);
+      
+      failureListeners.clear();
+      
+      return ret; 
+   }
+
+   public void setCloseListeners(List<CloseListener> listeners)
+   {
+      closeListeners.clear();
+      
+      closeListeners.addAll(listeners);      
+   }
+
    public HornetQBuffer createBuffer(final int size)
    {
       return transportConnection.createBuffer(size);
@@ -480,6 +505,7 @@
          channels.clear();
       }
    }  
+   
    private void callFailureListeners(final HornetQException me)
    {
       final List<FailureListener> listenersClone = new ArrayList<FailureListener>(failureListeners);

Modified: branches/hornetq-416/src/main/org/hornetq/core/protocol/stomp/StompConnection.java
===================================================================
--- branches/hornetq-416/src/main/org/hornetq/core/protocol/stomp/StompConnection.java	2010-10-13 00:11:20 UTC (rev 9781)
+++ branches/hornetq-416/src/main/org/hornetq/core/protocol/stomp/StompConnection.java	2010-10-13 07:38:20 UTC (rev 9782)
@@ -13,8 +13,10 @@
 
 package org.hornetq.core.protocol.stomp;
 
+import java.util.ArrayList;
 import java.util.Collections;
 import java.util.List;
+import java.util.concurrent.CopyOnWriteArrayList;
 
 import org.hornetq.api.core.HornetQBuffer;
 import org.hornetq.api.core.HornetQBuffers;
@@ -32,8 +34,9 @@
  *
  *
  */
-class StompConnection implements RemotingConnection
+public class StompConnection implements RemotingConnection
 {
+
    private static final Logger log = Logger.getLogger(StompConnection.class);
 
    private final StompProtocolManager manager;
@@ -52,6 +55,21 @@
    
    private final long creationTime;
 
+   private StompDecoder decoder = new StompDecoder();
+
+   private final List<FailureListener> failureListeners = new CopyOnWriteArrayList<FailureListener>();
+
+   private final List<CloseListener> closeListeners = new CopyOnWriteArrayList<CloseListener>();
+
+   private final Object failLock = new Object();
+   
+   private volatile boolean dataReceived;
+
+   public StompDecoder getDecoder()
+   {
+      return decoder;
+   }
+
    StompConnection(final Connection transportConnection, final StompProtocolManager manager)
    {
       this.transportConnection = transportConnection;
@@ -61,17 +79,90 @@
       this.creationTime = System.currentTimeMillis();
    }
 
-   public void addCloseListener(CloseListener listener)
+   public void addFailureListener(final FailureListener listener)
    {
+      if (listener == null)
+      {
+         throw new IllegalStateException("FailureListener cannot be null");
+      }
+
+      failureListeners.add(listener);
    }
 
-   public void addFailureListener(FailureListener listener)
+   public boolean removeFailureListener(final FailureListener listener)
    {
+      if (listener == null)
+      {
+         throw new IllegalStateException("FailureListener cannot be null");
+      }
+
+      return failureListeners.remove(listener);
    }
 
+   public void addCloseListener(final CloseListener listener)
+   {
+      if (listener == null)
+      {
+         throw new IllegalStateException("CloseListener cannot be null");
+      }
+
+      closeListeners.add(listener);
+   }
+
+   public boolean removeCloseListener(final CloseListener listener)
+   {
+      if (listener == null)
+      {
+         throw new IllegalStateException("CloseListener cannot be null");
+      }
+
+      return closeListeners.remove(listener);
+   }
+
+   public List<CloseListener> removeCloseListeners()
+   {
+      List<CloseListener> ret = new ArrayList<CloseListener>(closeListeners);
+
+      closeListeners.clear();
+
+      return ret;
+   }
+
+   public List<FailureListener> removeFailureListeners()
+   {
+      List<FailureListener> ret = new ArrayList<FailureListener>(failureListeners);
+
+      failureListeners.clear();
+
+      return ret;
+   }
+
+   public void setCloseListeners(List<CloseListener> listeners)
+   {
+      closeListeners.clear();
+
+      closeListeners.addAll(listeners);
+   }
+
+   public void setFailureListeners(final List<FailureListener> listeners)
+   {
+      failureListeners.clear();
+
+      failureListeners.addAll(listeners);
+   }
+   
+   public void setDataReceived()
+   {
+      dataReceived = true;
+   }
+
    public boolean checkDataReceived()
    {
-      return true;
+      boolean res = dataReceived;
+
+      dataReceived = false;
+
+      return res;
    }
 
    public HornetQBuffer createBuffer(int size)
@@ -81,13 +172,23 @@
 
    public void destroy()
    {
-      if (destroyed)
+      synchronized (failLock)
       {
-         return;
+         if (destroyed)
+         {
+            return;
+         }
       }
 
       destroyed = true;
 
+      internalClose();
+
+      callClosingListeners();
+   }
+
+   private void internalClose()
+   {
       transportConnection.close();
 
       manager.cleanup(this);
@@ -97,8 +198,29 @@
    {
    }
 
-   public void fail(HornetQException me)
+   public void fail(final HornetQException me)
    {
+      synchronized (failLock)
+      {
+         if (destroyed)
+         {
+            return;
+         }
+
+         destroyed = true;
+      }
+
+      log.warn("Connection failure has been detected: " + me.getMessage() +
+                                      " [code=" +
+                                      me.getCode() +
+                                      "]");
+
+      // Then call the listeners
+      callFailureListeners(me);
+
+      callClosingListeners();
+      
+      internalClose();
    }
 
    public void flush()
@@ -142,20 +264,6 @@
       return destroyed;
    }
 
-   public boolean removeCloseListener(CloseListener listener)
-   {
-      return false;
-   }
-
-   public boolean removeFailureListener(FailureListener listener)
-   {
-      return false;
-   }
-
-   public void setFailureListeners(List<FailureListener> listeners)
-   {
-   }
-
    public void bufferReceived(Object connectionID, HornetQBuffer buffer)
    {
       manager.handleBuffer(this, buffer);
@@ -190,7 +298,7 @@
    {
       return clientID;
    }
-   
+
    public boolean isValid()
    {
       return valid;
@@ -200,4 +308,45 @@
    {
       this.valid = valid;
    }
+
+   private void callFailureListeners(final HornetQException me)
+   {
+      final List<FailureListener> listenersClone = new ArrayList<FailureListener>(failureListeners);
+
+      for (final FailureListener listener : listenersClone)
+      {
+         try
+         {
+            listener.connectionFailed(me);
+         }
+         catch (final Throwable t)
+         {
+            // Failure of one listener to execute shouldn't prevent others
+            // from
+            // executing
+            log.error("Failed to execute failure listener", t);
+         }
+      }
+   }
+
+   private void callClosingListeners()
+   {
+      final List<CloseListener> listenersClone = new ArrayList<CloseListener>(closeListeners);
+
+      for (final CloseListener listener : listenersClone)
+      {
+         try
+         {
+            listener.connectionClosed();
+         }
+         catch (final Throwable t)
+         {
+            // Failure of one listener to execute shouldn't prevent others
+            // from
+            // executing
+            log.error("Failed to execute failure listener", t);
+         }
+      }
+   }
+
 }

Copied: branches/hornetq-416/src/main/org/hornetq/core/protocol/stomp/StompDecoder.java (from rev 9781, trunk/src/main/org/hornetq/core/protocol/stomp/StompDecoder.java)
===================================================================
--- branches/hornetq-416/src/main/org/hornetq/core/protocol/stomp/StompDecoder.java	                        (rev 0)
+++ branches/hornetq-416/src/main/org/hornetq/core/protocol/stomp/StompDecoder.java	2010-10-13 07:38:20 UTC (rev 9782)
@@ -0,0 +1,574 @@
+/*
+ * Copyright 2010 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.hornetq.core.protocol.stomp;
+
+import java.util.HashMap;
+import java.util.Map;
+
+import org.hornetq.api.core.HornetQBuffer;
+import org.hornetq.core.logging.Logger;
+
+/**
+ * A StompDecoder
+ *
+ * @author Tim Fox
+ *
+ *
+ */
+public class StompDecoder
+{
+   private static final Logger log = Logger.getLogger(StompDecoder.class);
+
+   private static final boolean TRIM_LEADING_HEADER_VALUE_WHITESPACE = true;
+
+   private static final String COMMAND_ABORT = "ABORT";
+
+   private static final int COMMAND_ABORT_LENGTH = COMMAND_ABORT.length();
+
+   private static final String COMMAND_ACK = "ACK";
+
+   private static final int COMMAND_ACK_LENGTH = COMMAND_ACK.length();
+
+   private static final String COMMAND_BEGIN = "BEGIN";
+
+   private static final int COMMAND_BEGIN_LENGTH = COMMAND_BEGIN.length();
+
+   private static final String COMMAND_COMMIT = "COMMIT";
+
+   private static final int COMMAND_COMMIT_LENGTH = COMMAND_COMMIT.length();
+
+   private static final String COMMAND_CONNECT = "CONNECT";
+
+   private static final int COMMAND_CONNECT_LENGTH = COMMAND_CONNECT.length();
+
+   private static final String COMMAND_DISCONNECT = "DISCONNECT";
+
+   private static final int COMMAND_DISCONNECT_LENGTH = COMMAND_DISCONNECT.length();
+
+   private static final String COMMAND_SEND = "SEND";
+
+   private static final int COMMAND_SEND_LENGTH = COMMAND_SEND.length();
+
+   private static final String COMMAND_SUBSCRIBE = "SUBSCRIBE";
+
+   private static final int COMMAND_SUBSCRIBE_LENGTH = COMMAND_SUBSCRIBE.length();
+
+   private static final String COMMAND_UNSUBSCRIBE = "UNSUBSCRIBE";
+
+   private static final int COMMAND_UNSUBSCRIBE_LENGTH = COMMAND_UNSUBSCRIBE.length();
+
+   private static final byte A = (byte)'A';
+
+   private static final byte B = (byte)'B';
+
+   private static final byte C = (byte)'C';
+
+   private static final byte D = (byte)'D';
+
+   private static final byte E = (byte)'E';
+
+   private static final byte M = (byte)'M';
+
+   private static final byte S = (byte)'S';
+
+   private static final byte U = (byte)'U';
+
+   private static final byte HEADER_SEPARATOR = (byte)':';
+
+   private static final byte NEW_LINE = (byte)'\n';
+
+   private static final byte SPACE = (byte)' ';
+
+   private static final byte TAB = (byte)'\t';
+
+   private static String CONTENT_LENGTH_HEADER_NAME = "content-length";
+
+   private byte[] workingBuffer = new byte[1024];
+
+   private int pos;
+
+   private int data;
+
+   private String command;
+
+   private Map<String, Object> headers;
+
+   private int headerBytesCopyStart;
+
+   private boolean readingHeaders;
+
+   private boolean headerValueWhitespace;
+
+   private boolean inHeaderName;
+
+   private String headerName;
+
+   private boolean whiteSpaceOnly;
+
+   private int contentLength;
+
+   private int bodyStart;
+
+   public StompDecoder()
+   {
+      init();
+   }
+
+   public boolean hasBytes()
+   {
+      return data > pos;
+   }
+
+   /*
+    * Stomp format is a command on the first line
+    * followed by a set of headers NAME:VALUE
+    * followed by an empty line
+    * followed by an optional message body
+    * terminated with a null character
+    */
+   public synchronized StompFrame decode(final HornetQBuffer buffer) throws Exception
+   {
+      //log.info("got buff " + buffer.readableBytes());
+      
+      long start = System.nanoTime();
+      
+      int readable = buffer.readableBytes();
+
+      if (data + readable >= workingBuffer.length)
+      {
+         resizeWorking(data + readable);
+      }
+
+      buffer.readBytes(workingBuffer, data, readable);
+
+      data += readable;
+
+      if (command == null)
+      {
+         if (data < 4)
+         {
+            // Need at least four bytes to identify the command
+            // - up to 3 bytes for the command name + potentially another byte for a leading \n
+
+            return null;
+         }
+
+         int offset;
+
+         if (workingBuffer[0] == NEW_LINE)
+         {
+            // Yuck, some badly behaved STOMP clients add a \n *after* the terminating NUL char at the end of the
+            // STOMP
+            // frame this can manifest as an extra \n at the beginning when the next STOMP frame is read - we need to
+            // deal
+            // with this
+            offset = 1;
+         }
+         else
+         {
+            offset = 0;
+         }
+
+         byte b = workingBuffer[offset];
+
+         switch (b)
+         {
+            case A:
+            {
+               if (workingBuffer[offset + 1] == B)
+               {
+                  if (!tryIncrement(offset + COMMAND_ABORT_LENGTH + 1))
+                  {
+                     return null;
+                  }
+
+                  // ABORT
+                  command = COMMAND_ABORT;
+               }
+               else
+               {
+                  if (!tryIncrement(offset + COMMAND_ACK_LENGTH + 1))
+                  {
+                     return null;
+                  }
+
+                  // ACK
+                  command = COMMAND_ACK;
+               }
+               break;
+            }
+            case B:
+            {
+               if (!tryIncrement(offset + COMMAND_BEGIN_LENGTH + 1))
+               {
+                  return null;
+               }
+
+               // BEGIN
+               command = COMMAND_BEGIN;
+
+               break;
+            }
+            case C:
+            {
+               if (workingBuffer[offset + 2] == M)
+               {
+                  if (!tryIncrement(offset + COMMAND_COMMIT_LENGTH + 1))
+                  {
+                     return null;
+                  }
+
+                  // COMMIT
+                  command = COMMAND_COMMIT;
+               }
+               else
+               {
+                  if (!tryIncrement(offset + COMMAND_CONNECT_LENGTH + 1))
+                  {
+                     return null;
+                  }
+
+                  // CONNECT
+                  command = COMMAND_CONNECT;
+               }
+               break;
+            }
+            case D:
+            {
+               if (!tryIncrement(offset + COMMAND_DISCONNECT_LENGTH + 1))
+               {
+                  return null;
+               }
+
+               // DISCONNECT
+               command = COMMAND_DISCONNECT;
+
+               break;
+            }
+            case S:
+            {
+               if (workingBuffer[offset + 1] == E)
+               {
+                  if (!tryIncrement(offset + COMMAND_SEND_LENGTH + 1))
+                  {
+                     return null;
+                  }
+
+                  // SEND
+                  command = COMMAND_SEND;
+               }
+               else
+               {
+                  if (!tryIncrement(offset + COMMAND_SUBSCRIBE_LENGTH + 1))
+                  {
+                     return null;
+                  }
+
+                  // SUBSCRIBE
+                  command = COMMAND_SUBSCRIBE;
+               }
+               break;
+            }
+            case U:
+            {
+               if (!tryIncrement(offset + COMMAND_UNSUBSCRIBE_LENGTH + 1))
+               {
+                  return null;
+               }
+
+               // UNSUBSCRIBE
+               command = COMMAND_UNSUBSCRIBE;
+
+               break;
+            }
+            default:
+            {
+               throwInvalid();
+            }
+         }
+
+         // Sanity check
+
+         if (workingBuffer[pos - 1] != NEW_LINE)
+         {
+            throwInvalid();
+         }
+      }
+      
+      long commandTime = System.nanoTime() - start;
+
+      if (readingHeaders)
+      {
+         if (headerBytesCopyStart == -1)
+         {
+            headerBytesCopyStart = pos;
+         }
+
+         // Now the headers
+
+         outer: while (true)
+         {
+            byte b = workingBuffer[pos++];
+
+            switch (b)
+            {
+               case HEADER_SEPARATOR:
+               {
+                  if (inHeaderName)
+                  {
+                     byte[] data = new byte[pos - headerBytesCopyStart - 1];
+
+                     System.arraycopy(workingBuffer, headerBytesCopyStart, data, 0, data.length);
+
+                     headerName = new String(data);
+
+                     inHeaderName = false;
+
+                     headerBytesCopyStart = pos;
+
+                     headerValueWhitespace = true;
+                  }
+
+                  whiteSpaceOnly = false;
+
+                  break;
+               }
+               case NEW_LINE:
+               {
+                  if (whiteSpaceOnly)
+                  {
+                     // Headers are terminated by a blank line
+                     readingHeaders = false;
+
+                     break outer;
+                  }
+
+                  byte[] data = new byte[pos - headerBytesCopyStart - 1];
+
+                  System.arraycopy(workingBuffer, headerBytesCopyStart, data, 0, data.length);
+
+                  String headerValue = new String(data);
+
+                  headers.put(headerName, headerValue);
+
+                  if (headerName.equals(CONTENT_LENGTH_HEADER_NAME))
+                  {
+                     contentLength = Integer.parseInt(headerValue.toString());
+                  }
+
+                  whiteSpaceOnly = true;
+
+                  headerBytesCopyStart = pos;
+
+                  inHeaderName = true;
+
+                  headerValueWhitespace = false;
+
+                  break;
+               }
+               case SPACE:
+               {
+               }
+               case TAB:
+               {
+                  if (TRIM_LEADING_HEADER_VALUE_WHITESPACE && headerValueWhitespace)
+                  {
+                     // trim off leading whitespace from header values.
+                     // The STOMP spec examples seem to imply that whitespace should be trimmed although it is not
+                     // explicit in the spec
+                     // ActiveMQ + StompConnect also seem to trim whitespace from header values.
+                     // Trimming is problematic though if the user has set a header with a value which deliberately
+                     // has
+                     // leading whitespace since
+                     // this will be removed
+                     headerBytesCopyStart++;
+                  }
+
+                  break;
+               }
+               default:
+               {
+                  whiteSpaceOnly = false;
+
+                  headerValueWhitespace = false;
+               }
+            }
+            if (pos == data)
+            {
+               // Run out of data
+
+               return null;
+            }
+         }
+      }
+      
+      long headersTime = System.nanoTime() - start - commandTime;
+
+      // Now the body
+
+      byte[] content = null;
+
+      if (contentLength != -1)
+      {
+         if (pos + contentLength > data)
+         {
+            // Need more bytes
+         }
+         else
+         {
+            content = new byte[contentLength];
+
+            System.arraycopy(workingBuffer, pos, content, 0, contentLength);
+
+            pos += contentLength + 1;
+         }
+      }
+      else
+      {
+         // Need to scan for terminating NUL
+
+         if (bodyStart == -1)
+         {
+            bodyStart = pos;
+         }
+
+         while (pos < data)
+         {
+            if (workingBuffer[pos++] == 0)
+            {
+               content = new byte[pos - bodyStart - 1];
+
+               System.arraycopy(workingBuffer, bodyStart, content, 0, content.length);
+
+               break;
+            }
+         }
+      }
+      
+      
+
+      if (content != null)
+      {
+         if (data > pos)
+         {
+            // More data still in the buffer from the next packet
+
+            System.arraycopy(workingBuffer, pos, workingBuffer, 0, data - pos);
+         }
+
+         data = data - pos;
+
+         // reset
+
+         StompFrame ret = new StompFrame(command, headers, content);
+
+         init();
+         
+        // log.info("decoded");
+         
+         long bodyTime = System.nanoTime() - start - headersTime - commandTime;
+         
+        // log.info("command: "+ commandTime + " headers: " + headersTime + " body: " + bodyTime);
+
+         return ret;
+      }
+      else
+      {
+         return null;
+      }
+   }
+
+   private void throwInvalid() throws StompException
+   {
+      throw new StompException("Invalid STOMP frame: " + this.dumpByteArray(workingBuffer));
+   }
+
+   private void init()
+   {
+      pos = 0;
+
+      command = null;
+
+      headers = new HashMap<String, Object>();
+
+      this.headerBytesCopyStart = -1;
+
+      readingHeaders = true;
+
+      inHeaderName = true;
+
+      headerValueWhitespace = false;
+
+      headerName = null;
+
+      whiteSpaceOnly = true;
+
+      contentLength = -1;
+
+      bodyStart = -1;
+   }
+
+   private void resizeWorking(final int newSize)
+   {
+      byte[] oldBuffer = workingBuffer;
+
+      workingBuffer = new byte[newSize];
+
+      System.arraycopy(oldBuffer, 0, workingBuffer, 0, oldBuffer.length);
+   }
+
+   private boolean tryIncrement(final int length)
+   {
+      if (pos + length >= data)
+      {
+         return false;
+      }
+      else
+      {
+         pos += length;
+
+         return true;
+      }
+   }
+
+   private String dumpByteArray(final byte[] bytes)
+   {
+      StringBuilder str = new StringBuilder();
+
+      for (int i = 0; i < data; i++)
+      {
+         char b = (char)bytes[i];
+
+         if (b == '\n')
+         {
+            str.append("\\n");
+         }
+         else if (b == 0)
+         {
+            str.append("NUL");
+         }
+         else
+         {
+            str.append(b);
+         }
+
+         if (i != bytes.length - 1)
+         {
+            str.append(",");
+         }
+      }
+
+      return str.toString();
+   }
+}

Modified: branches/hornetq-416/src/main/org/hornetq/core/protocol/stomp/StompFrame.java
===================================================================
--- branches/hornetq-416/src/main/org/hornetq/core/protocol/stomp/StompFrame.java	2010-10-13 00:11:20 UTC (rev 9781)
+++ branches/hornetq-416/src/main/org/hornetq/core/protocol/stomp/StompFrame.java	2010-10-13 07:38:20 UTC (rev 9782)
@@ -22,31 +22,40 @@
 
 import org.hornetq.api.core.HornetQBuffer;
 import org.hornetq.api.core.HornetQBuffers;
+import org.hornetq.core.logging.Logger;
 
 /**
  * Represents all the data in a STOMP frame.
  *
  * @author <a href="http://hiramchirino.com">chirino</a>
+ * @author Tim Fox
+ * 
  */
 class StompFrame
 {
+   private static final Logger log = Logger.getLogger(StompFrame.class);
+
    public static final byte[] NO_DATA = new byte[] {};
+
    private static final byte[] END_OF_FRAME = new byte[] { 0, '\n' };
 
    private final String command;
+
    private final Map<String, Object> headers;
+
    private final byte[] content;
-   
+
    private HornetQBuffer buffer = null;
+
    private int size;
-
+   
    public StompFrame(String command, Map<String, Object> headers, byte[] data)
    {
       this.command = command;
       this.headers = headers;
       this.content = data;
    }
-   
+
    public StompFrame(String command, Map<String, Object> headers)
    {
       this.command = command;
@@ -63,7 +72,7 @@
    {
       return content;
    }
-
+   
    public Map<String, Object> getHeaders()
    {
       return headers;
@@ -95,7 +104,8 @@
       out += new String(content);
       return out;
    }
-   
+
+ 
    public HornetQBuffer toHornetQBuffer() throws Exception
    {
       if (buffer == null)

Deleted: branches/hornetq-416/src/main/org/hornetq/core/protocol/stomp/StompFrameDecoder.java
===================================================================
--- branches/hornetq-416/src/main/org/hornetq/core/protocol/stomp/StompFrameDecoder.java	2010-10-13 00:11:20 UTC (rev 9781)
+++ branches/hornetq-416/src/main/org/hornetq/core/protocol/stomp/StompFrameDecoder.java	2010-10-13 07:38:20 UTC (rev 9782)
@@ -1,209 +0,0 @@
-/**
- *
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements.  See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.hornetq.core.protocol.stomp;
-
-import java.io.IOException;
-import java.util.HashMap;
-
-import org.hornetq.api.core.HornetQBuffer;
-import org.hornetq.core.logging.Logger;
-
-/**
- * Implements marshalling and unmarsalling the <a href="http://stomp.codehaus.org/">Stomp</a> protocol.
- */
-class StompFrameDecoder
-{
-   private static final Logger log = Logger.getLogger(StompFrameDecoder.class);
-
-   private static final int MAX_COMMAND_LENGTH = 1024;
-
-   private static final int MAX_HEADER_LENGTH = 1024 * 10;
-
-   private static final int MAX_HEADERS = 1000;
-
-   private static final int MAX_DATA_LENGTH = 1024 * 1024 * 10;
-
-   public StompFrame decode(HornetQBuffer buffer)
-   {
-      try
-      {
-         String command = null;
-
-         // skip white space to next real action line
-         while (true) {
-            command = StompFrameDecoder.readLine(buffer, StompFrameDecoder.MAX_COMMAND_LENGTH, "The maximum command length was exceeded");
-             if (command == null) {
-                return null;
-             }
-             else {
-                command = command.trim();
-                 if (command.length() > 0) {
-                     break;
-                 }
-             }
-         }
-         
-         // Parse the headers
-         HashMap<String, Object> headers = new HashMap<String, Object>(25);
-         while (true)
-         {
-            String line = StompFrameDecoder.readLine(buffer, StompFrameDecoder.MAX_HEADER_LENGTH, "The maximum header length was exceeded");
-            if (line == null)
-            {
-               return null;
-            }
-
-            if (headers.size() > StompFrameDecoder.MAX_HEADERS)
-            {
-               throw new StompException("The maximum number of headers was exceeded", true);
-            }
-
-            if (line.trim().length() == 0)
-            {
-               break;
-            }
-
-            try
-            {
-               int seperator_index = line.indexOf(Stomp.Headers.SEPARATOR);
-               if (seperator_index == -1)
-               {
-                  return null;
-               }
-               String name = line.substring(0, seperator_index).trim();
-               String value = line.substring(seperator_index + 1, line.length()).trim();
-               headers.put(name, value);
-            }
-            catch (Exception e)
-            {
-               throw new StompException("Unable to parse header line [" + line + "]", true);
-            }
-         }
-         // Read in the data part.
-         byte[] data = StompFrame.NO_DATA;
-         String contentLength = (String)headers.get(Stomp.Headers.CONTENT_LENGTH);
-         if (contentLength != null)
-         {
-
-            // Bless the client, he's telling us how much data to read in.
-            int length;
-            try
-            {
-               length = Integer.parseInt(contentLength.trim());
-            }
-            catch (NumberFormatException e)
-            {
-               throw new StompException("Specified content-length is not a valid integer", true);
-            }
-
-            if (length > StompFrameDecoder.MAX_DATA_LENGTH)
-            {
-               throw new StompException("The maximum data length was exceeded", true);
-            }
-
-            if (buffer.readableBytes() < length)
-            {
-               return null;
-            }
-            
-            data = new byte[length];
-            buffer.readBytes(data);
-
-            if (!buffer.readable())
-            {
-               return null;
-            }
-            if (buffer.readByte() != 0)
-            {
-               throw new StompException(Stomp.Headers.CONTENT_LENGTH + " bytes were read and " +
-                                        "there was no trailing null byte", true);
-            }
-         }
-         else
-         {
-            byte[] body = new byte[StompFrameDecoder.MAX_DATA_LENGTH];
-            boolean bodyCorrectlyEnded = false;
-            int count = 0;
-            while (buffer.readable())
-            {
-               byte b = buffer.readByte();
-
-               if (b == (byte)'\0')
-               {
-                  bodyCorrectlyEnded = true;
-                  break;
-               }
-               else
-               {
-                  body[count++] = b;
-               }
-            }
-
-            if (!bodyCorrectlyEnded)
-            {
-               return null;
-            }
-
-            data = new byte[count];
-            System.arraycopy(body, 0, data, 0, count);
-         }
-
-         return new StompFrame(command, headers, data);
-      }
-      catch (IOException e)
-      {
-         log.error("Unable to decode stomp frame", e);
-         return null;
-      }
-   }
-   
-   private static String readLine(HornetQBuffer in, int maxLength, String errorMessage) throws IOException
-   {
-      char[] chars = new char[MAX_HEADER_LENGTH];
-
-      if (!in.readable())
-      {
-         return null;
-      }
-      
-      boolean properString = false;
-      int count = 0;
-      while (in.readable())
-      {
-         byte b = in.readByte();
-
-         if (b == (byte)'\n')
-         {
-            properString = true;
-            break;
-         }
-         else
-         {
-            chars[count++] = (char)b;
-         }
-      }
-      if (properString)
-      {
-         return new String(chars, 0, count);
-      }
-      else
-      {
-         return null;
-      }
-   }
-}

Modified: branches/hornetq-416/src/main/org/hornetq/core/protocol/stomp/StompProtocolManager.java
===================================================================
--- branches/hornetq-416/src/main/org/hornetq/core/protocol/stomp/StompProtocolManager.java	2010-10-13 00:11:20 UTC (rev 9781)
+++ branches/hornetq-416/src/main/org/hornetq/core/protocol/stomp/StompProtocolManager.java	2010-10-13 07:38:20 UTC (rev 9782)
@@ -59,8 +59,6 @@
 
    private final HornetQServer server;
 
-   private final StompFrameDecoder frameDecoder;
-
    private final Executor executor;
 
    private final Map<String, StompSession> transactedSessions = new HashMap<String, StompSession>();
@@ -105,7 +103,6 @@
    public StompProtocolManager(final HornetQServer server, final List<Interceptor> interceptors)
    {
       this.server = server;
-      this.frameDecoder = new StompFrameDecoder();
       this.executor = server.getExecutorFactory().getExecutor();
    }
 
@@ -115,7 +112,21 @@
    {
       StompConnection conn = new StompConnection(connection, this);
 
-      return new ConnectionEntry(conn, 0, 0);
+      // Note that STOMP has no heartbeat, so if connection ttl is non zero, data must continue to be sent or connection
+      // will be timed out and closed!
+
+      long ttl = server.getConfiguration().getConnectionTTLOverride();
+
+      if (ttl != -1)
+      {
+         return new ConnectionEntry(conn, System.currentTimeMillis(), ttl);
+      }
+      else
+      {
+         // Default to 1 minute - which is same as core protocol
+
+         return new ConnectionEntry(conn, System.currentTimeMillis(), 1 * 60 * 1000);
+      }
    }
 
    public void removeHandler(String name)
@@ -124,121 +135,131 @@
 
    public int isReadyToHandle(HornetQBuffer buffer)
    {
-      int start = buffer.readerIndex();
+      // This never gets called
 
-      StompFrame frame = frameDecoder.decode(buffer);
-
-      if (frame == null)
-      {
-         return -1;
-      }
-      else
-      {
-         return buffer.readerIndex() - start;
-      }
+      return -1;
    }
 
    public void handleBuffer(final RemotingConnection connection, final HornetQBuffer buffer)
    {
-      try
-      {
-         doHandleBuffer(connection, buffer);
-      }
-      finally
-      {
-         server.getStorageManager().clearContext();
-      }
-   }
+      long start = System.nanoTime();
+      StompConnection conn = (StompConnection)connection;
+      
+      conn.setDataReceived();
+      
+      StompDecoder decoder = conn.getDecoder();
+      
+     // log.info("in handle");
 
-   private void doHandleBuffer(final RemotingConnection connection, final HornetQBuffer buffer)
-   {
-      StompConnection conn = (StompConnection)connection;
-      StompFrame request = null;
-      try
+      do
       {
-         request = frameDecoder.decode(buffer);
-         if (log.isTraceEnabled())
+         StompFrame request;
+         
+         try
          {
-            log.trace("received " + request);
+            request = decoder.decode(buffer);
          }
+         catch (Exception e)
+         {
+            log.error("Failed to decode", e);
 
-         String command = request.getCommand();
-         StompFrame response = null;
-
-         if (Stomp.Commands.CONNECT.equals(command))
-         {
-            response = onConnect(request, conn);
+            return;
          }
-         else if (Stomp.Commands.DISCONNECT.equals(command))
+         
+         if (request == null)
          {
-            response = onDisconnect(request, conn);
+            break;
          }
-         else if (Stomp.Commands.SEND.equals(command))
+
+         try
          {
-            response = onSend(request, conn);
-         }
-         else if (Stomp.Commands.SUBSCRIBE.equals(command))
-         {
-            response = onSubscribe(request, conn);
-         }
-         else if (Stomp.Commands.UNSUBSCRIBE.equals(command))
-         {
-            response = onUnsubscribe(request, conn);
-         }
-         else if (Stomp.Commands.ACK.equals(command))
-         {
-            response = onAck(request, conn);
-         }
-         else if (Stomp.Commands.BEGIN.equals(command))
-         {
-            response = onBegin(request, server, conn);
-         }
-         else if (Stomp.Commands.COMMIT.equals(command))
-         {
-            response = onCommit(request, conn);
-         }
-         else if (Stomp.Commands.ABORT.equals(command))
-         {
-            response = onAbort(request, conn);
-         }
-         else
-         {
-            log.error("Unsupported Stomp frame: " + request);
-            response = new StompFrame(Stomp.Responses.ERROR,
-                                      new HashMap<String, Object>(),
-                                      ("Unsupported frame: " + command).getBytes());
-         }
+            String command = request.getCommand();
 
-         if (request.getHeaders().containsKey(Stomp.Headers.RECEIPT_REQUESTED))
-         {
-            if (response == null)
+            StompFrame response = null;
+
+            if (Stomp.Commands.CONNECT.equals(command))
             {
-               Map<String, Object> h = new HashMap<String, Object>();
-               response = new StompFrame(Stomp.Responses.RECEIPT, h);
+               response = onConnect(request, conn);
             }
-            response.getHeaders().put(Stomp.Headers.Response.RECEIPT_ID,
-                                      request.getHeaders().get(Stomp.Headers.RECEIPT_REQUESTED));
-         }
+            else if (Stomp.Commands.DISCONNECT.equals(command))
+            {
+               response = onDisconnect(request, conn);
+            }
+            else if (Stomp.Commands.SEND.equals(command))
+            {
+               response = onSend(request, conn);
+            }
+            else if (Stomp.Commands.SUBSCRIBE.equals(command))
+            {
+               response = onSubscribe(request, conn);
+            }
+            else if (Stomp.Commands.UNSUBSCRIBE.equals(command))
+            {
+               response = onUnsubscribe(request, conn);
+            }
+            else if (Stomp.Commands.ACK.equals(command))
+            {
+               response = onAck(request, conn);
+            }
+            else if (Stomp.Commands.BEGIN.equals(command))
+            {
+               response = onBegin(request, server, conn);
+            }
+            else if (Stomp.Commands.COMMIT.equals(command))
+            {
+               response = onCommit(request, conn);
+            }
+            else if (Stomp.Commands.ABORT.equals(command))
+            {
+               response = onAbort(request, conn);
+            }
+            else
+            {
+               log.error("Unsupported Stomp frame: " + request);
+               response = new StompFrame(Stomp.Responses.ERROR,
+                                         new HashMap<String, Object>(),
+                                         ("Unsupported frame: " + command).getBytes());
+            }
 
-         if (response != null)
-         {
-            sendReply(conn, response);
+            if (request.getHeaders().containsKey(Stomp.Headers.RECEIPT_REQUESTED))
+            {
+               if (response == null)
+               {
+                  Map<String, Object> h = new HashMap<String, Object>();
+                  response = new StompFrame(Stomp.Responses.RECEIPT, h);
+               }
+               response.getHeaders().put(Stomp.Headers.Response.RECEIPT_ID,
+                                         request.getHeaders().get(Stomp.Headers.RECEIPT_REQUESTED));
+            }
+
+            if (response != null)
+            {
+               sendReply(conn, response);
+            }
+
+            if (Stomp.Commands.DISCONNECT.equals(command))
+            {
+               conn.destroy();
+            }
          }
-
-         if (Stomp.Commands.DISCONNECT.equals(command))
+         catch (Exception e)
          {
-            conn.destroy();
+            e.printStackTrace();
+            StompFrame error = createError(e, request);
+            if (error != null)
+            {
+               sendReply(conn, error);
+            }
          }
-      }
-      catch (Exception e)
-      {
-         e.printStackTrace();
-         StompFrame error = createError(e, request);
-         if (error != null)
+         finally
          {
-            sendReply(conn, error);
+            server.getStorageManager().clearContext();
          }
-      }
+      } while (decoder.hasBytes());
+      
+      long end = System.nanoTime();
+      
+     // log.info("handle took " + (end-start));
    }
 
    // Public --------------------------------------------------------
@@ -454,7 +475,8 @@
       StompSession stompSession = sessions.get(connection.getID());
       if (stompSession == null)
       {
-         stompSession = new StompSession(connection, this, server.getStorageManager().newContext(server.getExecutorFactory().getExecutor()));
+         stompSession = new StompSession(connection, this, server.getStorageManager()
+                                                                 .newContext(server.getExecutorFactory().getExecutor()));
          String name = UUIDGenerator.getInstance().generateStringUUID();
          ServerSession session = server.createSession(name,
                                                       connection.getLogin(),
@@ -504,7 +526,7 @@
       cleanup(connection);
       return null;
    }
-
+   
    private StompFrame onSend(StompFrame frame, StompConnection connection) throws Exception
    {
       checkConnected(connection);
@@ -542,7 +564,8 @@
       {
          message.putStringProperty(CONNECTION_ID_PROP, connection.getID().toString());
       }
-      stompSession.getSession().send(message, true);
+      stompSession.getSession().send(message, true);           
+      
       return null;
    }
 

Modified: branches/hornetq-416/src/main/org/hornetq/core/protocol/stomp/StompSession.java
===================================================================
--- branches/hornetq-416/src/main/org/hornetq/core/protocol/stomp/StompSession.java	2010-10-13 00:11:20 UTC (rev 9781)
+++ branches/hornetq-416/src/main/org/hornetq/core/protocol/stomp/StompSession.java	2010-10-13 07:38:20 UTC (rev 9782)
@@ -30,6 +30,7 @@
 import org.hornetq.core.server.ServerSession;
 import org.hornetq.spi.core.protocol.RemotingConnection;
 import org.hornetq.spi.core.protocol.SessionCallback;
+import org.hornetq.spi.core.remoting.ReadyListener;
 import org.hornetq.utils.DataConstants;
 import org.hornetq.utils.UUIDGenerator;
 
@@ -93,7 +94,7 @@
          HornetQBuffer buffer = serverMessage.getBodyBuffer();
 
          int bodyPos = serverMessage.getEndOfBodyPosition() == -1 ? buffer.writerIndex()
-                                                                  : serverMessage.getEndOfBodyPosition();
+                                                                 : serverMessage.getEndOfBodyPosition();
          int size = bodyPos - buffer.readerIndex();
          buffer.readerIndex(MessageImpl.BUFFER_HEADER_SPACE + DataConstants.SIZE_INT);
          byte[] data = new byte[size];
@@ -108,7 +109,8 @@
             if (text != null)
             {
                data = text.toString().getBytes("UTF-8");
-            } else
+            }
+            else
             {
                data = new byte[0];
             }
@@ -155,7 +157,17 @@
    public void closed()
    {
    }
+   
+   public void addReadyListener(final ReadyListener listener)
+   {
+      connection.getTransportConnection().addReadyListener(listener);      
+   }
 
+   public void removeReadyListener(final ReadyListener listener)
+   {
+      connection.getTransportConnection().removeReadyListener(listener);
+   }
+
    public void acknowledge(String messageID) throws Exception
    {
       long id = Long.parseLong(messageID);

Modified: branches/hornetq-416/src/main/org/hornetq/core/protocol/stomp/StompUtils.java
===================================================================
--- branches/hornetq-416/src/main/org/hornetq/core/protocol/stomp/StompUtils.java	2010-10-13 00:11:20 UTC (rev 9781)
+++ branches/hornetq-416/src/main/org/hornetq/core/protocol/stomp/StompUtils.java	2010-10-13 07:38:20 UTC (rev 9782)
@@ -21,6 +21,7 @@
 import org.hornetq.api.core.Message;
 import org.hornetq.api.core.SimpleString;
 import org.hornetq.core.client.impl.ClientMessageImpl;
+import org.hornetq.core.logging.Logger;
 import org.hornetq.core.message.impl.MessageInternal;
 import org.hornetq.core.server.impl.ServerMessageImpl;
 
@@ -34,7 +35,10 @@
 class StompUtils
 {
    // Constants -----------------------------------------------------
+   
+   private static final Logger log = Logger.getLogger(StompUtils.class);
 
+
    // Attributes ----------------------------------------------------
 
    // Static --------------------------------------------------------
@@ -53,6 +57,7 @@
       {
          msg.setDurable(Boolean.parseBoolean(persistent));
       }
+      
       // FIXME should use a proper constant
       msg.putObjectProperty("JMSCorrelationID", headers.remove(Stomp.Headers.Send.CORRELATION_ID));
       msg.putObjectProperty("JMSType", headers.remove(Stomp.Headers.Send.TYPE));

Modified: branches/hornetq-416/src/main/org/hornetq/core/protocol/stomp/WebSocketStompFrameEncoder.java
===================================================================
--- branches/hornetq-416/src/main/org/hornetq/core/protocol/stomp/WebSocketStompFrameEncoder.java	2010-10-13 00:11:20 UTC (rev 9781)
+++ branches/hornetq-416/src/main/org/hornetq/core/protocol/stomp/WebSocketStompFrameEncoder.java	2010-10-13 07:38:20 UTC (rev 9782)
@@ -38,20 +38,25 @@
  */
 public class WebSocketStompFrameEncoder extends OneToOneEncoder
 {
-
-   private final StompFrameDecoder decoder = new StompFrameDecoder();
-   
    @Override
    protected Object encode(ChannelHandlerContext ctx, Channel channel, Object msg) throws Exception
    {
       
       if (msg instanceof ChannelBuffer)
       {
+         // FIXME - this is a silly way to do this - a better way to do this would be to create a new protocol, with protocol manager etc
+         // and re-use some of the STOMP codec stuff - Tim
+         
+         
          // this is ugly and slow!
          // we have to go ChannelBuffer -> HornetQBuffer -> StompFrame -> String -> WebSocketFrame
          // since HornetQ protocol SPI requires to return HornetQBuffer to the transport
          HornetQBuffer buffer = new ChannelBufferWrapper((ChannelBuffer)msg);
+         
+         StompDecoder decoder = new StompDecoder();
+         
          StompFrame frame = decoder.decode(buffer);
+         
          if (frame != null)
          {
             WebSocketFrame wsFrame = new DefaultWebSocketFrame(frame.asString());

Modified: branches/hornetq-416/src/main/org/hornetq/core/remoting/impl/invm/InVMAcceptor.java
===================================================================
--- branches/hornetq-416/src/main/org/hornetq/core/remoting/impl/invm/InVMAcceptor.java	2010-10-13 00:11:20 UTC (rev 9781)
+++ branches/hornetq-416/src/main/org/hornetq/core/remoting/impl/invm/InVMAcceptor.java	2010-10-13 07:38:20 UTC (rev 9782)
@@ -250,6 +250,9 @@
          listener.connectionException(connectionID, me);
       }
 
+      public void connectionReadyForWrites(Object connectionID, boolean ready)
+      {
+      }
    }
 
 }

Modified: branches/hornetq-416/src/main/org/hornetq/core/remoting/impl/invm/InVMConnection.java
===================================================================
--- branches/hornetq-416/src/main/org/hornetq/core/remoting/impl/invm/InVMConnection.java	2010-10-13 00:11:20 UTC (rev 9781)
+++ branches/hornetq-416/src/main/org/hornetq/core/remoting/impl/invm/InVMConnection.java	2010-10-13 07:38:20 UTC (rev 9782)
@@ -22,6 +22,7 @@
 import org.hornetq.spi.core.remoting.BufferHandler;
 import org.hornetq.spi.core.remoting.Connection;
 import org.hornetq.spi.core.remoting.ConnectionLifeCycleListener;
+import org.hornetq.spi.core.remoting.ReadyListener;
 import org.hornetq.utils.UUIDGenerator;
 
 /**
@@ -32,6 +33,7 @@
  */
 public class InVMConnection implements Connection
 {
+
    private static final Logger log = Logger.getLogger(InVMConnection.class);
 
    private final BufferHandler handler;
@@ -159,5 +161,12 @@
    {
       return -1;
    }
+   
+   public void addReadyListener(ReadyListener listener)
+   {
+   }
 
+   public void removeReadyListener(ReadyListener listener)
+   {
+   }
 }

Modified: branches/hornetq-416/src/main/org/hornetq/core/remoting/impl/invm/InVMConnector.java
===================================================================
--- branches/hornetq-416/src/main/org/hornetq/core/remoting/impl/invm/InVMConnector.java	2010-10-13 00:11:20 UTC (rev 9781)
+++ branches/hornetq-416/src/main/org/hornetq/core/remoting/impl/invm/InVMConnector.java	2010-10-13 07:38:20 UTC (rev 9782)
@@ -215,6 +215,12 @@
          });
       }
 
+      public void connectionReadyForWrites(Object connectionID, boolean ready)
+      {
+      }
+      
+      
+
    }
 
 }

Modified: branches/hornetq-416/src/main/org/hornetq/core/remoting/impl/netty/HornetQChannelHandler.java
===================================================================
--- branches/hornetq-416/src/main/org/hornetq/core/remoting/impl/netty/HornetQChannelHandler.java	2010-10-13 00:11:20 UTC (rev 9781)
+++ branches/hornetq-416/src/main/org/hornetq/core/remoting/impl/netty/HornetQChannelHandler.java	2010-10-13 07:38:20 UTC (rev 9782)
@@ -58,8 +58,14 @@
       group.add(e.getChannel());
       ctx.sendUpstream(e);
    }
-   
+         
    @Override
+   public void channelInterestChanged(ChannelHandlerContext ctx, ChannelStateEvent e) throws Exception
+   {
+      listener.connectionReadyForWrites(e.getChannel().getId(), e.getChannel().isWritable());      
+   }
+
+   @Override
    public void messageReceived(final ChannelHandlerContext ctx, final MessageEvent e) throws Exception
    {
       ChannelBuffer buffer = (ChannelBuffer)e.getMessage();

Modified: branches/hornetq-416/src/main/org/hornetq/core/remoting/impl/netty/NettyAcceptor.java
===================================================================
--- branches/hornetq-416/src/main/org/hornetq/core/remoting/impl/netty/NettyAcceptor.java	2010-10-13 00:11:20 UTC (rev 9781)
+++ branches/hornetq-416/src/main/org/hornetq/core/remoting/impl/netty/NettyAcceptor.java	2010-10-13 07:38:20 UTC (rev 9782)
@@ -137,7 +137,7 @@
 
    private final HttpKeepAliveRunnable httpKeepAliveRunnable;
 
-   private final ConcurrentMap<Object, Connection> connections = new ConcurrentHashMap<Object, Connection>();
+   private final ConcurrentMap<Object, NettyConnection> connections = new ConcurrentHashMap<Object, NettyConnection>();
 
    private final Executor threadPool;
 
@@ -356,8 +356,8 @@
             if (protocol == ProtocolType.CORE)
             {
                // Core protocol uses its own optimised decoder
-               
-               handlers.put("hornetq-decode", new HornetQFrameDecoder2());
+
+               handlers.put("hornetq-decoder", new HornetQFrameDecoder2());
             }
             else if (protocol == ProtocolType.STOMP_WS)
             {
@@ -367,13 +367,17 @@
                handlers.put("hornetq-decoder", new HornetQFrameDecoder(decoder));
                handlers.put("websocket-handler", new WebSocketServerHandler());
             }
+            else if (protocol == ProtocolType.STOMP)
+            {
+               //With STOMP the decoding is handled in the StompFrame class
+            }
             else
             {
-                handlers.put("hornetq-decoder", new HornetQFrameDecoder(decoder));
+               handlers.put("hornetq-decoder", new HornetQFrameDecoder(decoder));
             }
 
             handlers.put("handler", new HornetQServerChannelHandler(channelGroup, handler, new Listener()));
-            
+
             /**
              * STOMP_WS protocol mandates use of named handlers to be able to replace http codecs
              * by websocket codecs after handshake.
@@ -650,7 +654,7 @@
    {
       public void connectionCreated(final Connection connection, final ProtocolType protocol)
       {
-         if (connections.putIfAbsent(connection.getID(), connection) != null)
+         if (connections.putIfAbsent(connection.getID(), (NettyConnection)connection) != null)
          {
             throw new IllegalArgumentException("Connection already exists with id " + connection.getID());
          }
@@ -679,6 +683,16 @@
          }.start();
 
       }
+
+      public void connectionReadyForWrites(final Object connectionID, boolean ready)
+      {
+         NettyConnection conn = connections.get(connectionID);
+         
+         if (conn != null)
+         {
+            conn.fireReady(ready);
+         }         
+      }            
    }
 
    private class BatchFlusher implements Runnable

Modified: branches/hornetq-416/src/main/org/hornetq/core/remoting/impl/netty/NettyConnection.java
===================================================================
--- branches/hornetq-416/src/main/org/hornetq/core/remoting/impl/netty/NettyConnection.java	2010-10-13 00:11:20 UTC (rev 9781)
+++ branches/hornetq-416/src/main/org/hornetq/core/remoting/impl/netty/NettyConnection.java	2010-10-13 07:38:20 UTC (rev 9782)
@@ -13,6 +13,7 @@
 
 package org.hornetq.core.remoting.impl.netty;
 
+import java.util.Set;
 import java.util.concurrent.atomic.AtomicBoolean;
 
 import org.hornetq.api.core.HornetQBuffer;
@@ -22,6 +23,8 @@
 import org.hornetq.spi.core.protocol.ProtocolType;
 import org.hornetq.spi.core.remoting.Connection;
 import org.hornetq.spi.core.remoting.ConnectionLifeCycleListener;
+import org.hornetq.spi.core.remoting.ReadyListener;
+import org.hornetq.utils.ConcurrentHashSet;
 import org.jboss.netty.buffer.ChannelBuffers;
 import org.jboss.netty.channel.Channel;
 import org.jboss.netty.channel.ChannelFuture;
@@ -57,6 +60,8 @@
    private volatile HornetQBuffer batchBuffer;
 
    private final AtomicBoolean writeLock = new AtomicBoolean(false);
+   
+   private Set<ReadyListener> readyListeners = new ConcurrentHashSet<ReadyListener>();
 
    // Static --------------------------------------------------------
 
@@ -241,6 +246,24 @@
    {
       return directDeliver;
    }
+   
+   public void addReadyListener(final ReadyListener listener)
+   {
+      readyListeners.add(listener);
+   }
+   
+   public void removeReadyListener(final ReadyListener listener)
+   {
+      readyListeners.remove(listener);
+   }
+   
+   public void fireReady(final boolean ready)
+   {
+      for (ReadyListener listener: readyListeners)
+      {
+         listener.readyForWriting(ready);
+      }
+   }
 
    // Public --------------------------------------------------------
 

Modified: branches/hornetq-416/src/main/org/hornetq/core/remoting/impl/netty/NettyConnector.java
===================================================================
--- branches/hornetq-416/src/main/org/hornetq/core/remoting/impl/netty/NettyConnector.java	2010-10-13 00:11:20 UTC (rev 9781)
+++ branches/hornetq-416/src/main/org/hornetq/core/remoting/impl/netty/NettyConnector.java	2010-10-13 07:38:20 UTC (rev 9782)
@@ -693,6 +693,12 @@
             }
          });
       }
+
+      public void connectionReadyForWrites(Object connectionID, boolean ready)
+      {
+      }
+      
+      
    }
    
    private class BatchFlusher implements Runnable

Modified: branches/hornetq-416/src/main/org/hornetq/core/remoting/server/impl/RemotingServiceImpl.java
===================================================================
--- branches/hornetq-416/src/main/org/hornetq/core/remoting/server/impl/RemotingServiceImpl.java	2010-10-13 00:11:20 UTC (rev 9781)
+++ branches/hornetq-416/src/main/org/hornetq/core/remoting/server/impl/RemotingServiceImpl.java	2010-10-13 07:38:20 UTC (rev 9782)
@@ -33,13 +33,13 @@
 import org.hornetq.api.core.TransportConfiguration;
 import org.hornetq.core.config.Configuration;
 import org.hornetq.core.logging.Logger;
-import org.hornetq.core.protocol.core.ServerSessionPacketHandler;
 import org.hornetq.core.protocol.core.impl.CoreProtocolManagerFactory;
 import org.hornetq.core.protocol.stomp.StompProtocolManagerFactory;
 import org.hornetq.core.remoting.FailureListener;
 import org.hornetq.core.remoting.impl.netty.TransportConstants;
 import org.hornetq.core.remoting.server.RemotingService;
 import org.hornetq.core.server.HornetQServer;
+import org.hornetq.core.server.impl.ServerSessionImpl;
 import org.hornetq.core.server.management.ManagementService;
 import org.hornetq.spi.core.protocol.ConnectionEntry;
 import org.hornetq.spi.core.protocol.ProtocolManager;
@@ -133,7 +133,8 @@
       // difference between Stomp and Stomp over Web Sockets is handled in NettyAcceptor.getPipeline()
       this.protocolMap.put(ProtocolType.STOMP, new StompProtocolManagerFactory().createProtocolManager(server,
                                                                                                        interceptors));
-      this.protocolMap.put(ProtocolType.STOMP_WS, new StompProtocolManagerFactory().createProtocolManager(server, interceptors));
+      this.protocolMap.put(ProtocolType.STOMP_WS, new StompProtocolManagerFactory().createProtocolManager(server,
+                                                                                                          interceptors));
    }
 
    // RemotingService implementation -------------------------------
@@ -144,15 +145,14 @@
       {
          return;
       }
-      
-      ClassLoader tccl =
-         AccessController.doPrivileged(new PrivilegedAction<ClassLoader>()
+
+      ClassLoader tccl = AccessController.doPrivileged(new PrivilegedAction<ClassLoader>()
+      {
+         public ClassLoader run()
          {
-            public ClassLoader run()
-            {
-               return Thread.currentThread().getContextClassLoader();
-            }
-         });
+            return Thread.currentThread().getContextClassLoader();
+         }
+      });
 
       // The remoting service maintains it's own thread pool for handling remoting traffic
       // If OIO each connection will have it's own thread
@@ -161,7 +161,8 @@
       // to support many hundreds of connections, but the main thread pool must be kept small for better performance
 
       ThreadFactory tFactory = new HornetQThreadFactory("HornetQ-remoting-threads" + System.identityHashCode(this),
-                                                        false, tccl);
+                                                        false,
+                                                        tccl);
 
       threadPool = Executors.newCachedThreadPool(tFactory);
 
@@ -200,7 +201,7 @@
             ProtocolManager manager = protocolMap.get(protocol);
 
             Acceptor acceptor = factory.createAcceptor(info.getParams(),
-                                                       new DelegatingBufferHandler(manager),
+                                                       new DelegatingBufferHandler(),
                                                        manager,
                                                        this,
                                                        threadPool,
@@ -322,6 +323,8 @@
       }
       else
       {
+         log.info("failed to remove connection");
+
          return null;
       }
    }
@@ -388,7 +391,7 @@
 
          for (FailureListener listener : failureListeners)
          {
-            if (listener instanceof ServerSessionPacketHandler)
+            if (listener instanceof ServerSessionImpl)
             {
                empty = false;
 
@@ -420,6 +423,10 @@
 
       // Connections should only fail when TTL is exceeded
    }
+   
+   public void connectionReadyForWrites(final Object connectionID, final boolean ready)
+   {
+   }
 
    public void addInterceptor(final Interceptor interceptor)
    {
@@ -443,13 +450,6 @@
 
    private final class DelegatingBufferHandler implements BufferHandler
    {
-      private ProtocolManager manager;
-
-      DelegatingBufferHandler(final ProtocolManager manager)
-      {
-         this.manager = manager;
-      }
-
       public void bufferReceived(final Object connectionID, final HornetQBuffer buffer)
       {
          ConnectionEntry conn = connections.get(connectionID);
@@ -535,9 +535,12 @@
                RemotingConnection conn = removeConnection(id);
 
                HornetQException me = new HornetQException(HornetQException.CONNECTION_TIMEDOUT,
-                                                          "Did not receive ping from " + conn.getRemoteAddress() +
+                                                          "Did not receive data from " + conn.getRemoteAddress() +
                                                                    ". It is likely the client has exited or crashed without " +
-                                                                   "closing its connection, or the network between the server and client has failed. The connection will now be closed.");
+                                                                   "closing its connection, or the network between the server and client has failed. " +
+                                                                   "You also might have configured connection-ttl and client-failure-check-period incorrectly. " +
+                                                                   "Please check user manual for more information." +
+                                                                   " The connection will now be closed.");
                conn.fail(me);
             }
 

Modified: branches/hornetq-416/src/main/org/hornetq/core/server/HornetQServer.java
===================================================================
--- branches/hornetq-416/src/main/org/hornetq/core/server/HornetQServer.java	2010-10-13 00:11:20 UTC (rev 9781)
+++ branches/hornetq-416/src/main/org/hornetq/core/server/HornetQServer.java	2010-10-13 07:38:20 UTC (rev 9782)
@@ -23,6 +23,7 @@
 import org.hornetq.core.config.Configuration;
 import org.hornetq.core.config.DivertConfiguration;
 import org.hornetq.core.management.impl.HornetQServerControlImpl;
+import org.hornetq.core.paging.PagingManager;
 import org.hornetq.core.persistence.StorageManager;
 import org.hornetq.core.postoffice.PostOffice;
 import org.hornetq.core.protocol.core.Channel;
@@ -58,6 +59,8 @@
    RemotingService getRemotingService();
 
    StorageManager getStorageManager();
+   
+   PagingManager getPagingManager();
 
    ManagementService getManagementService();
 

Modified: branches/hornetq-416/src/main/org/hornetq/core/server/impl/HornetQServerImpl.java
===================================================================
--- branches/hornetq-416/src/main/org/hornetq/core/server/impl/HornetQServerImpl.java	2010-10-13 00:11:20 UTC (rev 9781)
+++ branches/hornetq-416/src/main/org/hornetq/core/server/impl/HornetQServerImpl.java	2010-10-13 07:38:20 UTC (rev 9782)
@@ -502,6 +502,11 @@
    {
       return mbeanServer;
    }
+   
+   public PagingManager getPagingManager()
+   {
+      return pagingManager;
+   }
 
    public RemotingService getRemotingService()
    {

Modified: branches/hornetq-416/src/main/org/hornetq/core/server/impl/ServerConsumerImpl.java
===================================================================
--- branches/hornetq-416/src/main/org/hornetq/core/server/impl/ServerConsumerImpl.java	2010-10-13 00:11:20 UTC (rev 9781)
+++ branches/hornetq-416/src/main/org/hornetq/core/server/impl/ServerConsumerImpl.java	2010-10-13 07:38:20 UTC (rev 9782)
@@ -17,6 +17,7 @@
 import java.util.LinkedList;
 import java.util.concurrent.ConcurrentLinkedQueue;
 import java.util.concurrent.Executor;
+import java.util.concurrent.atomic.AtomicBoolean;
 import java.util.concurrent.atomic.AtomicInteger;
 
 import org.hornetq.api.core.HornetQBuffer;
@@ -42,6 +43,7 @@
 import org.hornetq.core.transaction.Transaction;
 import org.hornetq.core.transaction.impl.TransactionImpl;
 import org.hornetq.spi.core.protocol.SessionCallback;
+import org.hornetq.spi.core.remoting.ReadyListener;
 import org.hornetq.utils.Future;
 import org.hornetq.utils.TypedProperties;
 
@@ -54,7 +56,7 @@
  * 
  * @version <tt>$Revision: 3783 $</tt> $Id: ServerConsumerImpl.java 3783 2008-02-25 12:15:14Z timfox $
  */
-public class ServerConsumerImpl implements ServerConsumer
+public class ServerConsumerImpl implements ServerConsumer, ReadyListener
 {
    // Constants ------------------------------------------------------------------------------------
 
@@ -117,6 +119,12 @@
    private final Binding binding;
 
    private boolean transferring = false;
+   
+   /* As well as consumer credit based flow control, we also tap into TCP flow control (assuming transport is using TCP)
+    * This is useful in the case where consumer-window-size = -1, but we don't want to OOM by sending messages ad infinitum to the Netty
+    * write queue when the TCP buffer is full, e.g. the client is slow or has died.    
+    */
+   private AtomicBoolean writeReady = new AtomicBoolean(true);
 
    private final long creationTime;
 
@@ -161,6 +169,8 @@
       minLargeMessageSize = session.getMinLargeMessageSize();
 
       this.strictUpdateDeliveryCount = strictUpdateDeliveryCount;
+      
+      this.callback.addReadyListener(this);
 
       this.creationTime = System.currentTimeMillis();
       
@@ -199,6 +209,12 @@
          return HandleStatus.BUSY;
       }
       
+// TODO - https://jira.jboss.org/browse/HORNETQ-533      
+//      if (!writeReady.get())
+//      {
+//         return HandleStatus.BUSY;
+//      }
+      
       synchronized (lock)
       {
          // If the consumer is stopped then we don't accept the message, it
@@ -278,6 +294,8 @@
 
    public void close(final boolean failed) throws Exception
    {
+      callback.removeReadyListener(this);
+      
       setStarted(false);
 
       if (largeMessageDeliverer != null)
@@ -598,9 +616,21 @@
 
       return ref;
    }
+      
+   public void readyForWriting(final boolean ready)
+   {
+      if (ready)
+      {
+         writeReady.set(true);
+         
+         promptDelivery();
+      }
+      else
+      {
+         writeReady.set(false);
+      }
+   }
 
-   // Public ---------------------------------------------------------------------------------------
-
    /** To be used on tests only */
    public AtomicInteger getAvailableCredits()
    {

Modified: branches/hornetq-416/src/main/org/hornetq/core/server/impl/ServerMessageImpl.java
===================================================================
--- branches/hornetq-416/src/main/org/hornetq/core/server/impl/ServerMessageImpl.java	2010-10-13 00:11:20 UTC (rev 9781)
+++ branches/hornetq-416/src/main/org/hornetq/core/server/impl/ServerMessageImpl.java	2010-10-13 07:38:20 UTC (rev 9782)
@@ -14,6 +14,7 @@
 package org.hornetq.core.server.impl;
 
 import java.io.InputStream;
+import java.util.Arrays;
 
 import org.hornetq.api.core.Message;
 import org.hornetq.api.core.SimpleString;
@@ -72,7 +73,7 @@
    }
 
    /*
-    * Construct a MessageImpl from storage, or notification
+    * Construct a MessageImpl from storage, or notification, or before routing
     */
    public ServerMessageImpl(final long messageID, final int initialMessageBufferSize)
    {
@@ -81,11 +82,6 @@
       this.messageID = messageID;
    }
 
-   protected ServerMessageImpl(final int initialMessageBufferSize)
-   {
-      super(initialMessageBufferSize);
-   }
-
    /*
     * Copy constructor
     */
@@ -269,7 +265,7 @@
    {
       if (pagingStore != null)
       {
-         return pagingStore.page(this, transactionID);
+         return pagingStore.page(Arrays.asList((ServerMessage)this), transactionID);
       }
       else
       {

Modified: branches/hornetq-416/src/main/org/hornetq/core/server/impl/ServerSessionImpl.java
===================================================================
--- branches/hornetq-416/src/main/org/hornetq/core/server/impl/ServerSessionImpl.java	2010-10-13 00:11:20 UTC (rev 9781)
+++ branches/hornetq-416/src/main/org/hornetq/core/server/impl/ServerSessionImpl.java	2010-10-13 07:38:20 UTC (rev 9782)
@@ -74,7 +74,7 @@
  * @author <a href="mailto:jmesnil at redhat.com">Jeff Mesnil</a>
  * @author <a href="mailto:andy.taylor at jboss.org>Andy Taylor</a>
  */
-public class ServerSessionImpl implements ServerSession, FailureListener
+public class ServerSessionImpl implements ServerSession , FailureListener
 {
    // Constants -----------------------------------------------------------------------------
 

Modified: branches/hornetq-416/src/main/org/hornetq/jms/bridge/ConnectionFactoryFactory.java
===================================================================
--- branches/hornetq-416/src/main/org/hornetq/jms/bridge/ConnectionFactoryFactory.java	2010-10-13 00:11:20 UTC (rev 9781)
+++ branches/hornetq-416/src/main/org/hornetq/jms/bridge/ConnectionFactoryFactory.java	2010-10-13 07:38:20 UTC (rev 9782)
@@ -13,8 +13,6 @@
 
 package org.hornetq.jms.bridge;
 
-import javax.jms.ConnectionFactory;
-
 /**
  * A ConnectionFactoryFactory
  *
@@ -26,5 +24,5 @@
  */
 public interface ConnectionFactoryFactory
 {
-   ConnectionFactory createConnectionFactory() throws Exception;
+   Object createConnectionFactory() throws Exception;
 }

Modified: branches/hornetq-416/src/main/org/hornetq/jms/bridge/impl/JMSBridgeImpl.java
===================================================================
--- branches/hornetq-416/src/main/org/hornetq/jms/bridge/impl/JMSBridgeImpl.java	2010-10-13 00:11:20 UTC (rev 9781)
+++ branches/hornetq-416/src/main/org/hornetq/jms/bridge/impl/JMSBridgeImpl.java	2010-10-13 07:38:20 UTC (rev 9782)
@@ -969,7 +969,7 @@
    {
       Connection conn;
 
-      ConnectionFactory cf = cff.createConnectionFactory();
+      Object cf = cff.createConnectionFactory();
 
       if (qualityOfServiceMode == QualityOfServiceMode.ONCE_AND_ONLY_ONCE && !(cf instanceof XAConnectionFactory))
       {
@@ -992,7 +992,7 @@
             {
                JMSBridgeImpl.log.trace("Creating a non XA connection");
             }
-            conn = cf.createConnection();
+            conn = ((ConnectionFactory)cf).createConnection();
          }
       }
       else
@@ -1011,7 +1011,7 @@
             {
                JMSBridgeImpl.log.trace("Creating a non XA connection");
             }
-            conn = cf.createConnection(username, password);
+            conn = ((ConnectionFactory)cf).createConnection(username, password);
          }
       }
 
@@ -1232,10 +1232,8 @@
 
          // If this fails we should attempt to cleanup or we might end up in some weird state
 
-         if (log.isTraceEnabled())
-         {
-            log.trace("Failed to connect bridge", e);
-         }
+         // Adding a log.warn, so the use may see the cause of the failure and take actions
+         log.warn("Failed to connect bridge", e);
 
          cleanup();
 

Modified: branches/hornetq-416/src/main/org/hornetq/jms/bridge/impl/JNDIConnectionFactoryFactory.java
===================================================================
--- branches/hornetq-416/src/main/org/hornetq/jms/bridge/impl/JNDIConnectionFactoryFactory.java	2010-10-13 00:11:20 UTC (rev 9781)
+++ branches/hornetq-416/src/main/org/hornetq/jms/bridge/impl/JNDIConnectionFactoryFactory.java	2010-10-13 07:38:20 UTC (rev 9782)
@@ -15,8 +15,6 @@
 
 import java.util.Hashtable;
 
-import javax.jms.ConnectionFactory;
-
 import org.hornetq.jms.bridge.ConnectionFactoryFactory;
 
 
@@ -36,9 +34,9 @@
       super(jndiProperties, lookup);
    }
 
-   public ConnectionFactory createConnectionFactory() throws Exception
+   public Object createConnectionFactory() throws Exception
    {
-      return (ConnectionFactory)createObject();
+      return createObject();
    }
 
 }

Modified: branches/hornetq-416/src/main/org/hornetq/jms/client/HornetQConnection.java
===================================================================
--- branches/hornetq-416/src/main/org/hornetq/jms/client/HornetQConnection.java	2010-10-13 00:11:20 UTC (rev 9781)
+++ branches/hornetq-416/src/main/org/hornetq/jms/client/HornetQConnection.java	2010-10-13 07:38:20 UTC (rev 9782)
@@ -216,7 +216,7 @@
       justCreated = false;
    }
 
-   public void start() throws JMSException
+   public synchronized void start() throws JMSException
    {
       checkClosed();
 
@@ -229,7 +229,7 @@
       started = true;
    }
 
-   public void stop() throws JMSException
+   public synchronized void stop() throws JMSException
    {
       checkClosed();
 

Modified: branches/hornetq-416/src/main/org/hornetq/jms/client/HornetQConnectionFactory.java
===================================================================
--- branches/hornetq-416/src/main/org/hornetq/jms/client/HornetQConnectionFactory.java	2010-10-13 00:11:20 UTC (rev 9781)
+++ branches/hornetq-416/src/main/org/hornetq/jms/client/HornetQConnectionFactory.java	2010-10-13 07:38:20 UTC (rev 9782)
@@ -17,18 +17,12 @@
 import java.util.List;
 
 import javax.jms.Connection;
-import javax.jms.ConnectionFactory;
 import javax.jms.JMSException;
 import javax.jms.QueueConnection;
-import javax.jms.QueueConnectionFactory;
 import javax.jms.TopicConnection;
-import javax.jms.TopicConnectionFactory;
 import javax.jms.XAConnection;
-import javax.jms.XAConnectionFactory;
 import javax.jms.XAQueueConnection;
-import javax.jms.XAQueueConnectionFactory;
 import javax.jms.XATopicConnection;
-import javax.jms.XATopicConnectionFactory;
 import javax.naming.NamingException;
 import javax.naming.Reference;
 import javax.naming.Referenceable;
@@ -48,8 +42,7 @@
  * @author <a href="mailto:tim.fox at jboss.com">Tim Fox</a>
  * @version <tt>$Revision$</tt> $Id$
  */
-public class HornetQConnectionFactory implements ConnectionFactory, QueueConnectionFactory, TopicConnectionFactory,
-         XAConnectionFactory, XAQueueConnectionFactory, XATopicConnectionFactory, Serializable, Referenceable
+public class HornetQConnectionFactory implements Serializable, Referenceable
 {
    // Constants ------------------------------------------------------------------------------------
 

Copied: branches/hornetq-416/src/main/org/hornetq/jms/client/HornetQJMSConnectionFactory.java (from rev 9781, trunk/src/main/org/hornetq/jms/client/HornetQJMSConnectionFactory.java)
===================================================================
--- branches/hornetq-416/src/main/org/hornetq/jms/client/HornetQJMSConnectionFactory.java	                        (rev 0)
+++ branches/hornetq-416/src/main/org/hornetq/jms/client/HornetQJMSConnectionFactory.java	2010-10-13 07:38:20 UTC (rev 9782)
@@ -0,0 +1,60 @@
+/*
+ * 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.hornetq.jms.client;
+
+import java.util.List;
+
+import javax.jms.ConnectionFactory;
+
+import org.hornetq.api.core.Pair;
+import org.hornetq.api.core.TransportConfiguration;
+import org.hornetq.api.core.client.ClientSessionFactory;
+
+
+/**
+ * A class that represents a ConnectionFactory.
+ * 
+ * @author <a href="mailto:hgao at redhat.com">Howard Gao</a>
+ */
+public class HornetQJMSConnectionFactory extends HornetQConnectionFactory implements ConnectionFactory
+{
+
+   private final static long serialVersionUID = -2810634789345348326L;
+
+   public HornetQJMSConnectionFactory(TransportConfiguration transportConfiguration)
+   {
+      super(transportConfiguration);
+   }
+
+   public HornetQJMSConnectionFactory(ClientSessionFactory sessionFactory)
+   {
+      super(sessionFactory);
+   }
+
+   public HornetQJMSConnectionFactory(String discoveryAddress, int discoveryPort)
+   {
+      super(discoveryAddress, discoveryPort);
+   }
+
+   public HornetQJMSConnectionFactory(List<Pair<TransportConfiguration, TransportConfiguration>> connectorConfigs)
+   {
+      super(connectorConfigs);
+   }
+
+   public HornetQJMSConnectionFactory(TransportConfiguration connectorConfig,
+                                      TransportConfiguration backupConnectorConfig)
+   {
+      super(connectorConfig, backupConnectorConfig);
+   }
+}

Copied: branches/hornetq-416/src/main/org/hornetq/jms/client/HornetQQueueConnectionFactory.java (from rev 9781, trunk/src/main/org/hornetq/jms/client/HornetQQueueConnectionFactory.java)
===================================================================
--- branches/hornetq-416/src/main/org/hornetq/jms/client/HornetQQueueConnectionFactory.java	                        (rev 0)
+++ branches/hornetq-416/src/main/org/hornetq/jms/client/HornetQQueueConnectionFactory.java	2010-10-13 07:38:20 UTC (rev 9782)
@@ -0,0 +1,49 @@
+/*
+ * Copyright 2010 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.hornetq.jms.client;
+
+import java.util.List;
+
+import javax.jms.QueueConnectionFactory;
+
+import org.hornetq.api.core.Pair;
+import org.hornetq.api.core.TransportConfiguration;
+
+
+/**
+ * A class that represents a QueueConnectionFactory.
+ * 
+ * @author <a href="mailto:hgao at redhat.com">Howard Gao</a>
+ *
+ */
+public class HornetQQueueConnectionFactory extends HornetQConnectionFactory implements QueueConnectionFactory
+{
+   private static final long serialVersionUID = 5312455021322463546L;
+
+   public HornetQQueueConnectionFactory(String discoveryAddress, int discoveryPort)
+   {
+      super(discoveryAddress, discoveryPort);
+   }
+
+   public HornetQQueueConnectionFactory(List<Pair<TransportConfiguration, TransportConfiguration>> connectorConfigs)
+   {
+      super(connectorConfigs);
+   }
+
+   public HornetQQueueConnectionFactory(TransportConfiguration connectorConfig,
+                                        TransportConfiguration backupConnectorConfig)
+   {
+      super(connectorConfig, backupConnectorConfig);
+   }
+}

Modified: branches/hornetq-416/src/main/org/hornetq/jms/client/HornetQSession.java
===================================================================
--- branches/hornetq-416/src/main/org/hornetq/jms/client/HornetQSession.java	2010-10-13 00:11:20 UTC (rev 9781)
+++ branches/hornetq-416/src/main/org/hornetq/jms/client/HornetQSession.java	2010-10-13 07:38:20 UTC (rev 9782)
@@ -111,11 +111,11 @@
    // Constructors --------------------------------------------------
 
    protected HornetQSession(final HornetQConnection connection,
-                         final boolean transacted,
-                         final boolean xa,
-                         final int ackMode,
-                         final ClientSession session,
-                         final int sessionType)
+                            final boolean transacted,
+                            final boolean xa,
+                            final int ackMode,
+                            final ClientSession session,
+                            final int sessionType)
    {
       this.connection = connection;
 
@@ -213,7 +213,7 @@
 
       return ackMode;
    }
-   
+
    public boolean isXA()
    {
       return xa;
@@ -262,21 +262,24 @@
 
    public void close() throws JMSException
    {
-      try
+      synchronized (connection)
       {
-         for (HornetQMessageConsumer cons : new HashSet<HornetQMessageConsumer>(consumers))
+         try
          {
-            cons.close();
-         }
+            for (HornetQMessageConsumer cons : new HashSet<HornetQMessageConsumer>(consumers))
+            {
+               cons.close();
+            }
 
-         session.close();
+            session.close();
 
-         connection.removeSession(this);
+            connection.removeSession(this);
+         }
+         catch (HornetQException e)
+         {
+            throw JMSExceptionHelper.convertFromHornetQException(e);
+         }
       }
-      catch (HornetQException e)
-      {
-         throw JMSExceptionHelper.convertFromHornetQException(e);
-      }
    }
 
    public void recover() throws JMSException
@@ -393,7 +396,7 @@
       try
       {
          HornetQQueue queue = lookupQueue(queueName, false);
-         
+
          if (queue == null)
          {
             queue = lookupQueue(queueName, true);
@@ -413,7 +416,6 @@
          throw JMSExceptionHelper.convertFromHornetQException(e);
       }
    }
-   
 
    public Topic createTopic(final String topicName) throws JMSException
    {
@@ -423,7 +425,6 @@
          throw new IllegalStateException("Cannot create a topic on a QueueSession");
       }
 
-      
       try
       {
          HornetQTopic topic = lookupTopic(topicName, false);
@@ -477,7 +478,7 @@
       }
 
       HornetQDestination jbdest = (HornetQDestination)topic;
-      
+
       if (jbdest.isQueue())
       {
          throw new InvalidDestinationException("Cannot create a subscriber on a queue");
@@ -490,7 +491,7 @@
                                                  final String subscriptionName,
                                                  String selectorString,
                                                  final boolean noLocal) throws JMSException
-   {     
+   {
       try
       {
          selectorString = "".equals(selectorString) ? null : selectorString;
@@ -525,7 +526,7 @@
          SimpleString autoDeleteQueueName = null;
 
          if (dest.isQueue())
-         {            
+         {
             BindingQuery response = session.bindingQuery(dest.getSimpleAddress());
 
             if (!response.isExists())
@@ -573,7 +574,7 @@
                }
 
                queueName = new SimpleString(HornetQDestination.createQueueNameForDurableSubscription(connection.getClientID(),
-                                                                                               subscriptionName));
+                                                                                                     subscriptionName));
 
                QueueQuery subResponse = session.queueQuery(queueName);
 
@@ -678,10 +679,10 @@
       }
 
       HornetQDestination jbq = (HornetQDestination)queue;
-      
+
       if (!jbq.isQueue())
       {
-         throw new InvalidDestinationException("Cannot create a browser on a topic");  
+         throw new InvalidDestinationException("Cannot create a browser on a topic");
       }
 
       try
@@ -767,7 +768,7 @@
       }
 
       SimpleString queueName = new SimpleString(HornetQDestination.createQueueNameForDurableSubscription(connection.getClientID(),
-                                                                                                   name));
+                                                                                                         name));
 
       try
       {
@@ -887,7 +888,7 @@
       {
          throw new InvalidDestinationException("Not a temporary topic " + tempTopic);
       }
-      
+
       try
       {
          BindingQuery response = session.bindingQuery(tempTopic.getSimpleAddress());
@@ -949,7 +950,7 @@
          throw JMSExceptionHelper.convertFromHornetQException(e);
       }
    }
-   
+
    public void start() throws JMSException
    {
       try
@@ -991,11 +992,11 @@
          }
          catch (HornetQException ignore)
          {
-            //Exception on deleting queue shouldn't prevent close from completing
+            // Exception on deleting queue shouldn't prevent close from completing
          }
       }
    }
-   
+
    // Protected -----------------------------------------------------
 
    // Private -------------------------------------------------------
@@ -1007,11 +1008,11 @@
          throw new IllegalStateException("Session is closed");
       }
    }
-   
+
    private HornetQQueue lookupQueue(final String queueName, boolean isTemporary) throws HornetQException
    {
       HornetQQueue queue;
-      
+
       if (isTemporary)
       {
          queue = HornetQDestination.createTemporaryQueue(queueName);
@@ -1020,7 +1021,7 @@
       {
          queue = HornetQDestination.createQueue(queueName);
       }
-      
+
       QueueQuery response = session.queueQuery(queue.getSimpleAddress());
 
       if (response.isExists())
@@ -1032,12 +1033,12 @@
          return null;
       }
    }
-   
+
    private HornetQTopic lookupTopic(final String topicName, final boolean isTemporary) throws HornetQException
    {
 
       HornetQTopic topic;
-      
+
       if (isTemporary)
       {
          topic = HornetQDestination.createTemporaryTopic(topicName);
@@ -1046,7 +1047,7 @@
       {
          topic = HornetQDestination.createTopic(topicName);
       }
-      
+
       BindingQuery query = session.bindingQuery(topic.getSimpleAddress());
 
       if (!query.isExists())
@@ -1059,7 +1060,6 @@
       }
    }
 
-
    // Inner classes -------------------------------------------------
 
 }

Copied: branches/hornetq-416/src/main/org/hornetq/jms/client/HornetQTopicConnectionFactory.java (from rev 9781, trunk/src/main/org/hornetq/jms/client/HornetQTopicConnectionFactory.java)
===================================================================
--- branches/hornetq-416/src/main/org/hornetq/jms/client/HornetQTopicConnectionFactory.java	                        (rev 0)
+++ branches/hornetq-416/src/main/org/hornetq/jms/client/HornetQTopicConnectionFactory.java	2010-10-13 07:38:20 UTC (rev 9782)
@@ -0,0 +1,49 @@
+/*
+ * Copyright 2010 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.hornetq.jms.client;
+
+import java.util.List;
+
+import javax.jms.TopicConnectionFactory;
+
+import org.hornetq.api.core.Pair;
+import org.hornetq.api.core.TransportConfiguration;
+
+
+/**
+ * A class that represents a TopicConnectionFactory.
+ * 
+ * @author <a href="mailto:hgao at redhat.com">Howard Gao</a>
+ *
+ */
+public class HornetQTopicConnectionFactory extends HornetQConnectionFactory implements TopicConnectionFactory
+{
+   private static final long serialVersionUID = 7317051989866548455L;
+
+   public HornetQTopicConnectionFactory(String discoveryAddress, int discoveryPort)
+   {
+      super(discoveryAddress, discoveryPort);
+   }
+
+   public HornetQTopicConnectionFactory(List<Pair<TransportConfiguration, TransportConfiguration>> connectorConfigs)
+   {
+      super(connectorConfigs);
+   }
+
+   public HornetQTopicConnectionFactory(TransportConfiguration connectorConfig,
+                                        TransportConfiguration backupConnectorConfig)
+   {
+      super(connectorConfig, backupConnectorConfig);
+   }
+}

Copied: branches/hornetq-416/src/main/org/hornetq/jms/client/HornetQXAConnectionFactory.java (from rev 9781, trunk/src/main/org/hornetq/jms/client/HornetQXAConnectionFactory.java)
===================================================================
--- branches/hornetq-416/src/main/org/hornetq/jms/client/HornetQXAConnectionFactory.java	                        (rev 0)
+++ branches/hornetq-416/src/main/org/hornetq/jms/client/HornetQXAConnectionFactory.java	2010-10-13 07:38:20 UTC (rev 9782)
@@ -0,0 +1,53 @@
+/*
+ * Copyright 2010 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.hornetq.jms.client;
+
+import java.util.List;
+
+import javax.jms.XAConnectionFactory;
+
+import org.hornetq.api.core.Pair;
+import org.hornetq.api.core.TransportConfiguration;
+
+
+/**
+ * A class that represents a XAConnectionFactory.
+ * 
+ * @author <a href="mailto:hgao at redhat.com">Howard Gao</a>
+ */
+public class HornetQXAConnectionFactory extends HornetQConnectionFactory implements XAConnectionFactory
+{
+   private static final long serialVersionUID = 743611571839154115L;
+
+   public HornetQXAConnectionFactory(String discoveryAddress, int discoveryPort)
+   {
+      super(discoveryAddress, discoveryPort);
+   }
+
+   public HornetQXAConnectionFactory(List<Pair<TransportConfiguration, TransportConfiguration>> connectorConfigs)
+   {
+      super(connectorConfigs);
+   }
+
+   public HornetQXAConnectionFactory(TransportConfiguration connectorConfig,
+                                     TransportConfiguration backupConnectorConfig)
+   {
+      super(connectorConfig, backupConnectorConfig);
+   }
+
+   public HornetQXAConnectionFactory(TransportConfiguration connectorConfig)
+   {
+      super(connectorConfig);
+   }
+}

Copied: branches/hornetq-416/src/main/org/hornetq/jms/client/HornetQXAQueueConnectionFactory.java (from rev 9781, trunk/src/main/org/hornetq/jms/client/HornetQXAQueueConnectionFactory.java)
===================================================================
--- branches/hornetq-416/src/main/org/hornetq/jms/client/HornetQXAQueueConnectionFactory.java	                        (rev 0)
+++ branches/hornetq-416/src/main/org/hornetq/jms/client/HornetQXAQueueConnectionFactory.java	2010-10-13 07:38:20 UTC (rev 9782)
@@ -0,0 +1,49 @@
+/*
+ * Copyright 2010 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.hornetq.jms.client;
+
+import java.util.List;
+
+import javax.jms.XAQueueConnectionFactory;
+
+import org.hornetq.api.core.Pair;
+import org.hornetq.api.core.TransportConfiguration;
+
+
+/**
+ * A class that represents a XAQueueConnectionFactory.
+ * 
+ * @author <a href="mailto:hgao at redhat.com">Howard Gao</a>
+ *
+ */
+public class HornetQXAQueueConnectionFactory extends HornetQConnectionFactory implements XAQueueConnectionFactory
+{
+   private static final long serialVersionUID = 8612457847251087454L;
+
+   public HornetQXAQueueConnectionFactory(String discoveryAddress, int discoveryPort)
+   {
+      super(discoveryAddress, discoveryPort);
+   }
+
+   public HornetQXAQueueConnectionFactory(List<Pair<TransportConfiguration, TransportConfiguration>> connectorConfigs)
+   {
+      super(connectorConfigs);
+   }
+
+   public HornetQXAQueueConnectionFactory(TransportConfiguration connectorConfig,
+                                          TransportConfiguration backupConnectorConfig)
+   {
+      super(connectorConfig, backupConnectorConfig);
+   }
+}

Copied: branches/hornetq-416/src/main/org/hornetq/jms/client/HornetQXATopicConnectionFactory.java (from rev 9781, trunk/src/main/org/hornetq/jms/client/HornetQXATopicConnectionFactory.java)
===================================================================
--- branches/hornetq-416/src/main/org/hornetq/jms/client/HornetQXATopicConnectionFactory.java	                        (rev 0)
+++ branches/hornetq-416/src/main/org/hornetq/jms/client/HornetQXATopicConnectionFactory.java	2010-10-13 07:38:20 UTC (rev 9782)
@@ -0,0 +1,49 @@
+/*
+ * Copyright 2010 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.hornetq.jms.client;
+
+import java.util.List;
+
+import javax.jms.XATopicConnectionFactory;
+
+import org.hornetq.api.core.Pair;
+import org.hornetq.api.core.TransportConfiguration;
+
+
+/**
+ * A class that represents a XATopicConnectionFactory.
+ * 
+ * @author <a href="mailto:hgao at redhat.com">Howard Gao</a>
+ *
+ */
+public class HornetQXATopicConnectionFactory extends HornetQConnectionFactory implements XATopicConnectionFactory
+{
+   private static final long serialVersionUID = -7018290426884419693L;
+
+   public HornetQXATopicConnectionFactory(String discoveryAddress, int discoveryPort)
+   {
+      super(discoveryAddress, discoveryPort);
+   }
+
+   public HornetQXATopicConnectionFactory(List<Pair<TransportConfiguration, TransportConfiguration>> connectorConfigs)
+   {
+      super(connectorConfigs);
+   }
+
+   public HornetQXATopicConnectionFactory(TransportConfiguration connectorConfig,
+                                          TransportConfiguration backupConnectorConfig)
+   {
+      super(connectorConfig, backupConnectorConfig);
+   }
+}

Modified: branches/hornetq-416/src/main/org/hornetq/jms/client/SelectorTranslator.java
===================================================================
--- branches/hornetq-416/src/main/org/hornetq/jms/client/SelectorTranslator.java	2010-10-13 00:11:20 UTC (rev 9781)
+++ branches/hornetq-416/src/main/org/hornetq/jms/client/SelectorTranslator.java	2010-10-13 07:38:20 UTC (rev 9782)
@@ -50,6 +50,7 @@
       filterString = SelectorTranslator.parse(filterString, "JMSPriority", "HQPriority");
       filterString = SelectorTranslator.parse(filterString, "JMSTimestamp", "HQTimestamp");
       filterString = SelectorTranslator.parse(filterString, "JMSMessageID", "HQUserID");
+      filterString = SelectorTranslator.parse(filterString, "JMSExpiration", "HQExpiration");
 
       return filterString;
 

Modified: branches/hornetq-416/src/main/org/hornetq/jms/management/impl/JMSServerControlImpl.java
===================================================================
--- branches/hornetq-416/src/main/org/hornetq/jms/management/impl/JMSServerControlImpl.java	2010-10-13 00:11:20 UTC (rev 9781)
+++ branches/hornetq-416/src/main/org/hornetq/jms/management/impl/JMSServerControlImpl.java	2010-10-13 07:38:20 UTC (rev 9782)
@@ -47,6 +47,7 @@
 import org.hornetq.spi.core.protocol.RemotingConnection;
 import org.hornetq.utils.json.JSONArray;
 import org.hornetq.utils.json.JSONObject;
+import org.hornetq.jms.server.impl.JMSFactoryType;
 
 /**
  * @author <a href="mailto:jmesnil at redhat.com">Jeff Mesnil</a>
@@ -204,7 +205,7 @@
       {
          TransportConfiguration liveTC = new TransportConfiguration(liveTransportClassName, liveTransportParams);
 
-         server.createConnectionFactory(name, liveTC, JMSServerControlImpl.convert(jndiBindings));
+         server.createConnectionFactory(name, liveTC, JMSFactoryType.CF, JMSServerControlImpl.convert(jndiBindings));
 
          sendNotification(NotificationType.CONNECTION_FACTORY_CREATED, name);
       }
@@ -214,6 +215,121 @@
       }
                                        }
 
+   public void createXAConnectionFactory(final String name,
+                                       final String liveTransportClassName,
+                                       final Map<String, Object> liveTransportParams,
+                                       final Object[] jndiBindings) throws Exception
+   {
+      checkStarted();
+
+      clearIO();
+
+      try
+      {
+         TransportConfiguration liveTC = new TransportConfiguration(liveTransportClassName, liveTransportParams);
+
+         server.createConnectionFactory(name, liveTC, JMSFactoryType.XA_CF, JMSServerControlImpl.convert(jndiBindings));
+
+         sendNotification(NotificationType.CONNECTION_FACTORY_CREATED, name);
+      }
+      finally
+      {
+         blockOnIO();
+      }
+   }
+
+   public void createQueueConnectionFactory(final String name,
+                                       final String liveTransportClassName,
+                                       final Map<String, Object> liveTransportParams,
+                                       final Object[] jndiBindings) throws Exception
+   {
+      checkStarted();
+
+      clearIO();
+
+      try
+      {
+         TransportConfiguration liveTC = new TransportConfiguration(liveTransportClassName, liveTransportParams);
+
+         server.createConnectionFactory(name, liveTC, JMSFactoryType.QUEUE_CF, JMSServerControlImpl.convert(jndiBindings));
+
+         sendNotification(NotificationType.CONNECTION_FACTORY_CREATED, name);
+      }
+      finally
+      {
+         blockOnIO();
+      }
+   }
+
+   public void createTopicConnectionFactory(final String name,
+                                       final String liveTransportClassName,
+                                       final Map<String, Object> liveTransportParams,
+                                       final Object[] jndiBindings) throws Exception
+   {
+      checkStarted();
+
+      clearIO();
+
+      try
+      {
+         TransportConfiguration liveTC = new TransportConfiguration(liveTransportClassName, liveTransportParams);
+
+         server.createConnectionFactory(name, liveTC, JMSFactoryType.TOPIC_CF, JMSServerControlImpl.convert(jndiBindings));
+
+         sendNotification(NotificationType.CONNECTION_FACTORY_CREATED, name);
+      }
+      finally
+      {
+         blockOnIO();
+      }
+   }
+
+   public void createXAQueueConnectionFactory(final String name,
+                                       final String liveTransportClassName,
+                                       final Map<String, Object> liveTransportParams,
+                                       final Object[] jndiBindings) throws Exception
+   {
+      checkStarted();
+
+      clearIO();
+
+      try
+      {
+         TransportConfiguration liveTC = new TransportConfiguration(liveTransportClassName, liveTransportParams);
+
+         server.createConnectionFactory(name, liveTC, JMSFactoryType.QUEUE_XA_CF, JMSServerControlImpl.convert(jndiBindings));
+
+         sendNotification(NotificationType.CONNECTION_FACTORY_CREATED, name);
+      }
+      finally
+      {
+         blockOnIO();
+      }
+   }
+
+   public void createXATopicConnectionFactory(final String name,
+                                       final String liveTransportClassName,
+                                       final Map<String, Object> liveTransportParams,
+                                       final Object[] jndiBindings) throws Exception
+   {
+      checkStarted();
+
+      clearIO();
+
+      try
+      {
+         TransportConfiguration liveTC = new TransportConfiguration(liveTransportClassName, liveTransportParams);
+
+         server.createConnectionFactory(name, liveTC, JMSFactoryType.TOPIC_XA_CF, JMSServerControlImpl.convert(jndiBindings));
+
+         sendNotification(NotificationType.CONNECTION_FACTORY_CREATED, name);
+      }
+      finally
+      {
+         blockOnIO();
+      }
+   }
+
    public void createConnectionFactory(final String name,
                                        final Object[] liveConnectorsTransportClassNames,
                                        final Object[] liveConnectorTransportParams,

Modified: branches/hornetq-416/src/main/org/hornetq/jms/server/JMSServerManager.java
===================================================================
--- branches/hornetq-416/src/main/org/hornetq/jms/server/JMSServerManager.java	2010-10-13 00:11:20 UTC (rev 9781)
+++ branches/hornetq-416/src/main/org/hornetq/jms/server/JMSServerManager.java	2010-10-13 07:38:20 UTC (rev 9782)
@@ -25,6 +25,7 @@
 import org.hornetq.core.server.HornetQServer;
 import org.hornetq.core.settings.impl.AddressSettings;
 import org.hornetq.jms.server.config.ConnectionFactoryConfiguration;
+import org.hornetq.jms.server.impl.JMSFactoryType;
 import org.hornetq.spi.core.naming.BindingRegistry;
 
 /**
@@ -170,7 +171,7 @@
                                 TransportConfiguration backupTC,
                                 String ... bindings) throws Exception;
 
-   void createConnectionFactory(String name, TransportConfiguration liveTC, String ... bindings) throws Exception;
+   void createConnectionFactory(String name, TransportConfiguration liveTC, JMSFactoryType cfType, String ... bindings) throws Exception;
 
    void createConnectionFactory(String name,
                                 String clientID,
@@ -222,6 +223,7 @@
                                 boolean failoverOnInitialConnection,
                                 boolean failoverOnServerShutdown,
                                 String groupId,
+                                JMSFactoryType factoryType,
                                 String ... bindings) throws Exception;
 
    void createConnectionFactory(String name,

Modified: branches/hornetq-416/src/main/org/hornetq/jms/server/config/ConnectionFactoryConfiguration.java
===================================================================
--- branches/hornetq-416/src/main/org/hornetq/jms/server/config/ConnectionFactoryConfiguration.java	2010-10-13 00:11:20 UTC (rev 9781)
+++ branches/hornetq-416/src/main/org/hornetq/jms/server/config/ConnectionFactoryConfiguration.java	2010-10-13 07:38:20 UTC (rev 9782)
@@ -19,6 +19,7 @@
 import org.hornetq.api.core.TransportConfiguration;
 import org.hornetq.core.journal.EncodingSupport;
 import org.hornetq.jms.server.JMSServerManager;
+import org.hornetq.jms.server.impl.JMSFactoryType;
 
 /**
  * A ConnectionFactoryConfiguration
@@ -202,4 +203,8 @@
    String getGroupID();
 
    void setGroupID(String groupID);
+
+   void setFactoryType(JMSFactoryType factType);
+   
+   JMSFactoryType getFactoryType();
 }

Modified: branches/hornetq-416/src/main/org/hornetq/jms/server/config/impl/ConnectionFactoryConfigurationImpl.java
===================================================================
--- branches/hornetq-416/src/main/org/hornetq/jms/server/config/impl/ConnectionFactoryConfigurationImpl.java	2010-10-13 00:11:20 UTC (rev 9781)
+++ branches/hornetq-416/src/main/org/hornetq/jms/server/config/impl/ConnectionFactoryConfigurationImpl.java	2010-10-13 07:38:20 UTC (rev 9782)
@@ -21,6 +21,7 @@
 import org.hornetq.api.core.TransportConfiguration;
 import org.hornetq.api.core.client.HornetQClient;
 import org.hornetq.jms.server.config.ConnectionFactoryConfiguration;
+import org.hornetq.jms.server.impl.JMSFactoryType;
 import org.hornetq.utils.BufferHelper;
 import org.hornetq.utils.DataConstants;
 
@@ -115,6 +116,8 @@
    
    private String groupID = null;
    
+   private JMSFactoryType factoryType = JMSFactoryType.CF;
+   
    // Static --------------------------------------------------------
 
    // Constructors --------------------------------------------------
@@ -671,6 +674,8 @@
       failoverOnServerShutdown = buffer.readBoolean();
 
       groupID = BufferHelper.readNullableSimpleStringAsString(buffer);
+      
+      factoryType = JMSFactoryType.valueOf(buffer.readInt());
    }
 
    /* (non-Javadoc)
@@ -762,6 +767,8 @@
       buffer.writeBoolean(failoverOnServerShutdown);
 
       BufferHelper.writeAsNullableSimpleString(buffer, groupID);
+      
+      buffer.writeInt(factoryType.intValue());
    }
 
 
@@ -860,8 +867,20 @@
 
              DataConstants.SIZE_BOOLEAN + // failoverOnServerShutdown
              
-             BufferHelper.sizeOfNullableSimpleString(groupID);
+             BufferHelper.sizeOfNullableSimpleString(groupID) + 
+             
+             DataConstants.SIZE_INT; //factoryType
    }
+
+   public void setFactoryType(JMSFactoryType factoryType)
+   {
+      this.factoryType = factoryType;
+   }
+
+   public JMSFactoryType getFactoryType()
+   {
+      return factoryType;
+   }
    
    // Public --------------------------------------------------------
 

Copied: branches/hornetq-416/src/main/org/hornetq/jms/server/impl/JMSFactoryType.java (from rev 9781, trunk/src/main/org/hornetq/jms/server/impl/JMSFactoryType.java)
===================================================================
--- branches/hornetq-416/src/main/org/hornetq/jms/server/impl/JMSFactoryType.java	                        (rev 0)
+++ branches/hornetq-416/src/main/org/hornetq/jms/server/impl/JMSFactoryType.java	2010-10-13 07:38:20 UTC (rev 9782)
@@ -0,0 +1,83 @@
+/*
+ * Copyright 2010 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.hornetq.jms.server.impl;
+
+/**
+ * A JMSFactoryType
+ *
+ * @author howard
+ *
+ *
+ */
+public enum JMSFactoryType
+{
+   CF, QUEUE_CF, TOPIC_CF, XA_CF, QUEUE_XA_CF, TOPIC_XA_CF;
+
+   public int intValue()
+   {
+      int val = 0;
+      switch (this)
+      {
+         case CF:
+            val = 0;
+            break;
+         case QUEUE_CF:
+            val = 1;
+            break;
+         case TOPIC_CF:
+            val = 2;
+            break;
+         case XA_CF:
+            val = 3;
+            break;
+         case QUEUE_XA_CF:
+            val = 4;
+            break;
+         case TOPIC_XA_CF:
+            val = 5;
+            break;
+      }
+      return val;
+   }
+
+   public static JMSFactoryType valueOf(int val)
+   {
+      JMSFactoryType type;
+      switch (val)
+      {
+         case 0:
+            type = CF;
+            break;
+         case 1:
+            type = QUEUE_CF;
+            break;
+         case 2:
+            type = TOPIC_CF;
+            break;
+         case 3:
+            type = XA_CF;
+            break;
+         case 4:
+            type = QUEUE_XA_CF;
+            break;
+         case 5:
+            type = TOPIC_XA_CF;
+            break;
+         default:
+            type = XA_CF;
+            break;
+      }
+      return type;
+   }
+}

Modified: branches/hornetq-416/src/main/org/hornetq/jms/server/impl/JMSServerConfigParserImpl.java
===================================================================
--- branches/hornetq-416/src/main/org/hornetq/jms/server/impl/JMSServerConfigParserImpl.java	2010-10-13 00:11:20 UTC (rev 9781)
+++ branches/hornetq-416/src/main/org/hornetq/jms/server/impl/JMSServerConfigParserImpl.java	2010-10-13 07:38:20 UTC (rev 9782)
@@ -205,7 +205,14 @@
       Element e = (Element)node;
 
       String name = node.getAttributes().getNamedItem(JMSServerConfigParserImpl.NAME_ATTR).getNodeValue();
+      
+      String fact = e.getAttribute("signature");
+      boolean isXA = XMLConfigurationUtil.getBoolean(e,
+                                                     "xa",
+                                                     HornetQClient.DEFAULT_XA);
 
+      JMSFactoryType factType = resolveFactoryType(fact, isXA);
+
       long clientFailureCheckPeriod = XMLConfigurationUtil.getLong(e,
                                                                    "client-failure-check-period",
                                                                    HornetQClient.DEFAULT_CLIENT_FAILURE_CHECK_PERIOD,
@@ -381,6 +388,7 @@
          cfConfig.setConnectorNames(connectorNames);
       }
 
+      cfConfig.setFactoryType(factType);
       cfConfig.setClientID(clientID);
       cfConfig.setClientFailureCheckPeriod(clientFailureCheckPeriod);
       cfConfig.setConnectionTTL(connectionTTL);
@@ -413,6 +421,46 @@
       return cfConfig;
    }
 
+   private JMSFactoryType resolveFactoryType(String fact, boolean isXA) throws HornetQException
+   {
+      if ("".equals(fact))
+      {
+         fact = "generic";
+      }
+      if (isXA)
+      {
+         if ("generic".equals(fact))
+         {
+            return JMSFactoryType.XA_CF;
+         }
+         if ("queue".equals(fact))
+         {
+            return JMSFactoryType.QUEUE_XA_CF;
+         }
+         if ("topic".equals(fact))
+         {
+            return JMSFactoryType.TOPIC_XA_CF;
+         }
+      }
+      else
+      {
+         if ("generic".equals(fact))
+         {
+            return JMSFactoryType.CF;
+         }
+         if ("queue".equals(fact))
+         {
+            return JMSFactoryType.QUEUE_CF;
+         }
+         if ("topic".equals(fact))
+         {
+            return JMSFactoryType.TOPIC_CF;
+         }
+      }
+      throw new HornetQException(HornetQException.INTERNAL_ERROR, "Invalid signature " + fact +
+      " at parseConnectionFactory");
+   }
+
    /**
     * hook for integration layers 
     * @param topicName

Modified: branches/hornetq-416/src/main/org/hornetq/jms/server/impl/JMSServerManagerImpl.java
===================================================================
--- branches/hornetq-416/src/main/org/hornetq/jms/server/impl/JMSServerManagerImpl.java	2010-10-13 00:11:20 UTC (rev 9781)
+++ branches/hornetq-416/src/main/org/hornetq/jms/server/impl/JMSServerManagerImpl.java	2010-10-13 07:38:20 UTC (rev 9782)
@@ -23,7 +23,6 @@
 
 import javax.naming.Context;
 import javax.naming.InitialContext;
-import javax.naming.NameNotFoundException;
 import javax.naming.NamingException;
 
 import org.hornetq.api.core.HornetQException;
@@ -754,6 +753,7 @@
                                                     final boolean failoverOnInitialConnection,
                                                     final boolean failoverOnServerShutdown,
                                                     final String groupId,
+                                                    final JMSFactoryType factoryType,
                                                     String... jndiBindings) throws Exception
    {
       checkInitialised();
@@ -790,6 +790,7 @@
          configuration.setFailoverOnInitialConnection(failoverOnInitialConnection);
          configuration.setFailoverOnServerShutdown(failoverOnServerShutdown);
          configuration.setGroupID(groupId);
+         configuration.setFactoryType(factoryType);
          createConnectionFactory(true, configuration, jndiBindings);
       }
    }
@@ -869,6 +870,7 @@
          configuration.setReconnectAttempts(reconnectAttempts);
          configuration.setFailoverOnInitialConnection(failoverOnInitialConnection);
          configuration.setFailoverOnServerShutdown(failoverOnServerShutdown);
+         configuration.setGroupID(groupId);
          createConnectionFactory(true, configuration, jndiBindings);
       }
    }
@@ -968,13 +970,14 @@
                                                                     final int reconnectAttempts,
                                                                     final boolean failoverOnInitialConnection,
                                                                     final boolean failoverOnServerShutdown,
-                                                                    final String groupId) throws Exception
+                                                                    final String groupId, 
+                                                                    final JMSFactoryType jmsFactoryType) throws Exception
    {
       checkInitialised();
       HornetQConnectionFactory cf = connectionFactories.get(name);
       if (cf == null)
       {
-         cf = (HornetQConnectionFactory)HornetQJMSClient.createConnectionFactory(discoveryAddress, discoveryPort);
+         cf = (HornetQConnectionFactory)HornetQJMSClient.createConnectionFactory(discoveryAddress, discoveryPort, jmsFactoryType);
          cf.setClientID(clientID);
          cf.setLocalBindAddress(localBindAddress);
          cf.setDiscoveryRefreshTimeout(discoveryRefreshTimeout);
@@ -1006,6 +1009,7 @@
          cf.setReconnectAttempts(reconnectAttempts);
          cf.setFailoverOnInitialConnection(failoverOnInitialConnection);
          cf.setFailoverOnServerShutdown(failoverOnServerShutdown);
+         cf.setGroupID(groupId);
       }
 
       return cf;
@@ -1041,13 +1045,14 @@
                                                                     final int reconnectAttempts,
                                                                     final boolean failoverOnInitialConnection,
                                                                     final boolean failoverOnServerShutdown,
-                                                                    final String groupId) throws Exception
+                                                                    final String groupId, 
+                                                                    final JMSFactoryType jmsFactoryType) throws Exception
    {
       checkInitialised();
       HornetQConnectionFactory cf = connectionFactories.get(name);
       if (cf == null)
       {
-         cf = (HornetQConnectionFactory)HornetQJMSClient.createConnectionFactory(connectorConfigs);
+         cf = (HornetQConnectionFactory)HornetQJMSClient.createConnectionFactory(connectorConfigs, jmsFactoryType);
          cf.setClientID(clientID);
          cf.setClientFailureCheckPeriod(clientFailureCheckPeriod);
          cf.setConnectionTTL(connectionTTL);
@@ -1211,7 +1216,8 @@
                                               cfConfig.getReconnectAttempts(),
                                               cfConfig.isFailoverOnInitialConnection(),
                                               cfConfig.isFailoverOnServerShutdown(),
-                                              cfConfig.getGroupID());
+                                              cfConfig.getGroupID(),
+                                              cfConfig.getFactoryType());
       }
       else
       {
@@ -1245,7 +1251,8 @@
                                               cfConfig.getReconnectAttempts(),
                                               cfConfig.isFailoverOnInitialConnection(),
                                               cfConfig.isFailoverOnServerShutdown(),
-                                              cfConfig.getGroupID());
+                                              cfConfig.getGroupID(),
+                                              cfConfig.getFactoryType());
       }
       connectionFactories.put(cfConfig.getName(), cf);
 
@@ -1256,6 +1263,7 @@
 
    public synchronized void createConnectionFactory(final String name,
                                                     final TransportConfiguration liveTC,
+                                                    final JMSFactoryType cfType,
                                                     final String... jndiBindings) throws Exception
    {
       checkInitialised();
@@ -1263,6 +1271,7 @@
       if (cf == null)
       {
          ConnectionFactoryConfiguration configuration = new ConnectionFactoryConfigurationImpl(name, liveTC);
+         configuration.setFactoryType(cfType);
          createConnectionFactory(true, configuration, jndiBindings);
       }
    }

Modified: branches/hornetq-416/src/main/org/hornetq/ra/HornetQResourceAdapter.java
===================================================================
--- branches/hornetq-416/src/main/org/hornetq/ra/HornetQResourceAdapter.java	2010-10-13 00:11:20 UTC (rev 9781)
+++ branches/hornetq-416/src/main/org/hornetq/ra/HornetQResourceAdapter.java	2010-10-13 07:38:20 UTC (rev 9782)
@@ -35,6 +35,7 @@
 import org.hornetq.api.core.client.ClientSessionFactory;
 import org.hornetq.api.core.client.HornetQClient;
 import org.hornetq.jms.client.HornetQConnectionFactory;
+import org.hornetq.jms.server.impl.JMSFactoryType;
 import org.hornetq.api.jms.HornetQJMSClient;
 import org.hornetq.core.logging.Logger;
 import org.hornetq.ra.inflow.HornetQActivation;
@@ -1389,13 +1390,13 @@
                                                                          : new TransportConfiguration(backUpCOnnectorClassname,
                                                                                                       backupConnectionParams);
 
-         cf = HornetQJMSClient.createConnectionFactory(transportConf, backup);
+         cf = HornetQJMSClient.createConnectionFactory(transportConf, backup, JMSFactoryType.XA_CF);
       }
       else if (discoveryAddress != null)
       {
          Integer discoveryPort = overrideProperties.getDiscoveryPort() != null ? overrideProperties.getDiscoveryPort()
                                                                               : getDiscoveryPort();
-         cf = HornetQJMSClient.createConnectionFactory(discoveryAddress, discoveryPort);
+         cf = HornetQJMSClient.createConnectionFactory(discoveryAddress, discoveryPort, JMSFactoryType.XA_CF);
       }
       else
       {

Modified: branches/hornetq-416/src/main/org/hornetq/spi/core/protocol/RemotingConnection.java
===================================================================
--- branches/hornetq-416/src/main/org/hornetq/spi/core/protocol/RemotingConnection.java	2010-10-13 00:11:20 UTC (rev 9781)
+++ branches/hornetq-416/src/main/org/hornetq/spi/core/protocol/RemotingConnection.java	2010-10-13 07:38:20 UTC (rev 9782)
@@ -82,14 +82,22 @@
     * @return true if removed
     */
    boolean removeCloseListener(CloseListener listener);
-
+   
+   List<CloseListener> removeCloseListeners();
+   
+   void setCloseListeners(List<CloseListener> listeners);
+   
+   
    /**
     * return all the failure listeners
     *
     * @return the listeners
     */
    List<FailureListener> getFailureListeners();
+   
+   List<FailureListener> removeFailureListeners();
 
+
    /**
     * set the failure listeners.
     * <p/>

Modified: branches/hornetq-416/src/main/org/hornetq/spi/core/protocol/SessionCallback.java
===================================================================
--- branches/hornetq-416/src/main/org/hornetq/spi/core/protocol/SessionCallback.java	2010-10-13 00:11:20 UTC (rev 9781)
+++ branches/hornetq-416/src/main/org/hornetq/spi/core/protocol/SessionCallback.java	2010-10-13 07:38:20 UTC (rev 9782)
@@ -15,6 +15,7 @@
 
 import org.hornetq.api.core.SimpleString;
 import org.hornetq.core.server.ServerMessage;
+import org.hornetq.spi.core.remoting.ReadyListener;
 
 /**
  * A SessionCallback
@@ -34,4 +35,8 @@
    int sendLargeMessageContinuation(long consumerID, byte[] body, boolean continues, boolean requiresResponse);
    
    void closed();
+   
+   void addReadyListener(ReadyListener listener);
+   
+   void removeReadyListener(ReadyListener listener);
 }

Modified: branches/hornetq-416/src/main/org/hornetq/spi/core/remoting/Connection.java
===================================================================
--- branches/hornetq-416/src/main/org/hornetq/spi/core/remoting/Connection.java	2010-10-13 00:11:20 UTC (rev 9781)
+++ branches/hornetq-416/src/main/org/hornetq/spi/core/remoting/Connection.java	2010-10-13 07:38:20 UTC (rev 9782)
@@ -70,4 +70,8 @@
     * Called periodically to flush any data in the batch buffer
     */
    void checkFlushBatchBuffer();
+   
+   void addReadyListener(ReadyListener listener);
+   
+   void removeReadyListener(ReadyListener listener);
 }
\ No newline at end of file

Modified: branches/hornetq-416/src/main/org/hornetq/spi/core/remoting/ConnectionLifeCycleListener.java
===================================================================
--- branches/hornetq-416/src/main/org/hornetq/spi/core/remoting/ConnectionLifeCycleListener.java	2010-10-13 00:11:20 UTC (rev 9781)
+++ branches/hornetq-416/src/main/org/hornetq/spi/core/remoting/ConnectionLifeCycleListener.java	2010-10-13 07:38:20 UTC (rev 9782)
@@ -44,4 +44,6 @@
     * @param me           the exception.
     */
    void connectionException(Object connectionID, HornetQException me);
+   
+   void connectionReadyForWrites(Object connectionID, boolean ready);
 }

Copied: branches/hornetq-416/src/main/org/hornetq/spi/core/remoting/ReadyListener.java (from rev 9781, trunk/src/main/org/hornetq/spi/core/remoting/ReadyListener.java)
===================================================================
--- branches/hornetq-416/src/main/org/hornetq/spi/core/remoting/ReadyListener.java	                        (rev 0)
+++ branches/hornetq-416/src/main/org/hornetq/spi/core/remoting/ReadyListener.java	2010-10-13 07:38:20 UTC (rev 9782)
@@ -0,0 +1,27 @@
+/*
+ * Copyright 2010 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.hornetq.spi.core.remoting;
+
+/**
+ * A ReadyListener
+ *
+ * @author Tim Fox
+ *
+ *
+ */
+public interface ReadyListener
+{
+   void readyForWriting(boolean ready);
+
+}

Modified: branches/hornetq-416/tests/jms-tests/config/hornetq-jms.xml
===================================================================
--- branches/hornetq-416/tests/jms-tests/config/hornetq-jms.xml	2010-10-13 00:11:20 UTC (rev 9781)
+++ branches/hornetq-416/tests/jms-tests/config/hornetq-jms.xml	2010-10-13 07:38:20 UTC (rev 9782)
@@ -15,4 +15,112 @@
       </entries>
    </connection-factory>
 
-</configuration>
\ No newline at end of file
+   <connection-factory name="JMSConnectionFactory1">
+      <xa>true</xa>
+      <connectors>
+         <connector-ref connector-name="netty"/>
+      </connectors>
+      <entries>
+         <entry name="/CF_XA_TRUE"/>
+      </entries>
+   </connection-factory>
+
+   <connection-factory name="JMSConnectionFactory2">
+      <xa>false</xa>
+      <connectors>
+         <connector-ref connector-name="netty"/>
+      </connectors>
+      <entries>
+         <entry name="/CF_XA_FALSE"/>
+      </entries>
+   </connection-factory>
+
+   <connection-factory name="JMSConnectionFactory3" signature="generic">
+      <connectors>
+         <connector-ref connector-name="netty"/>
+      </connectors>
+      <entries>
+         <entry name="/CF_GENERIC"/>
+      </entries>
+   </connection-factory>
+
+   <connection-factory name="JMSConnectionFactory4" signature="generic">
+      <xa>true</xa>
+      <connectors>
+         <connector-ref connector-name="netty"/>
+      </connectors>
+      <entries>
+         <entry name="/CF_GENERIC_XA_TRUE"/>
+      </entries>
+   </connection-factory>
+
+   <connection-factory name="JMSConnectionFactory5" signature="generic">
+      <xa>false</xa>
+      <connectors>
+         <connector-ref connector-name="netty"/>
+      </connectors>
+      <entries>
+         <entry name="/CF_GENERIC_XA_FALSE"/>
+      </entries>
+   </connection-factory>
+
+   <connection-factory name="JMSConnectionFactory6" signature="queue">
+      <connectors>
+         <connector-ref connector-name="netty"/>
+      </connectors>
+      <entries>
+         <entry name="/CF_QUEUE"/>
+      </entries>
+   </connection-factory>
+
+   <connection-factory name="JMSConnectionFactory7" signature="queue">
+      <xa>true</xa>
+      <connectors>
+         <connector-ref connector-name="netty"/>
+      </connectors>
+      <entries>
+         <entry name="/CF_QUEUE_XA_TRUE"/>
+      </entries>
+   </connection-factory>
+
+   <connection-factory name="JMSConnectionFactory8" signature="queue">
+      <xa>false</xa>
+      <connectors>
+         <connector-ref connector-name="netty"/>
+      </connectors>
+      <entries>
+         <entry name="/CF_QUEUE_XA_FALSE"/>
+      </entries>
+   </connection-factory>
+
+   <connection-factory name="JMSConnectionFactory9" signature="topic">
+      <connectors>
+         <connector-ref connector-name="netty"/>
+      </connectors>
+      <entries>
+         <entry name="/CF_TOPIC"/>
+      </entries>
+   </connection-factory>
+
+   <connection-factory name="JMSConnectionFactory10" signature="topic">
+      <xa>true</xa>
+      <connectors>
+         <connector-ref connector-name="netty"/>
+      </connectors>
+      <entries>
+         <entry name="/CF_TOPIC_XA_TRUE"/>
+      </entries>
+   </connection-factory>
+
+   <connection-factory name="JMSConnectionFactory11" signature="topic">
+      <xa>false</xa>
+      <connectors>
+         <connector-ref connector-name="netty"/>
+      </connectors>
+      <entries>
+         <entry name="/CF_TOPIC_XA_FALSE"/>
+      </entries>
+   </connection-factory>
+
+</configuration>
+

Modified: branches/hornetq-416/tests/jms-tests/src/org/hornetq/jms/tests/CTSMiscellaneousTest.java
===================================================================
--- branches/hornetq-416/tests/jms-tests/src/org/hornetq/jms/tests/CTSMiscellaneousTest.java	2010-10-13 00:11:20 UTC (rev 9781)
+++ branches/hornetq-416/tests/jms-tests/src/org/hornetq/jms/tests/CTSMiscellaneousTest.java	2010-10-13 07:38:20 UTC (rev 9782)
@@ -25,6 +25,7 @@
 import org.hornetq.api.core.TransportConfiguration;
 import org.hornetq.api.core.client.HornetQClient;
 import org.hornetq.jms.client.HornetQConnectionFactory;
+import org.hornetq.jms.server.impl.JMSFactoryType;
 
 /**
  * Safeguards for previously detected TCK failures.
@@ -95,6 +96,7 @@
                                                        HornetQClient.DEFAULT_FAILOVER_ON_INITIAL_CONNECTION,
                                                        HornetQClient.DEFAULT_FAILOVER_ON_SERVER_SHUTDOWN,
                                                        null,
+                                                       JMSFactoryType.CF,
                                                        "/StrictTCKConnectionFactory");
 
          CTSMiscellaneousTest.cf = (HornetQConnectionFactory)getInitialContext().lookup("/StrictTCKConnectionFactory");

Modified: branches/hornetq-416/tests/jms-tests/src/org/hornetq/jms/tests/ConnectionClosedTest.java
===================================================================
--- branches/hornetq-416/tests/jms-tests/src/org/hornetq/jms/tests/ConnectionClosedTest.java	2010-10-13 00:11:20 UTC (rev 9781)
+++ branches/hornetq-416/tests/jms-tests/src/org/hornetq/jms/tests/ConnectionClosedTest.java	2010-10-13 07:38:20 UTC (rev 9782)
@@ -66,8 +66,8 @@
    /** See TCK test: topicconntests.connNotStartedTopicTest */
    public void testCannotReceiveMessageOnStoppedConnection() throws Exception
    {
-      TopicConnection conn1 = ((TopicConnectionFactory)JMSTestCase.cf).createTopicConnection();
-      TopicConnection conn2 = ((TopicConnectionFactory)JMSTestCase.cf).createTopicConnection();
+      TopicConnection conn1 = ((TopicConnectionFactory)JMSTestCase.topicCf).createTopicConnection();
+      TopicConnection conn2 = ((TopicConnectionFactory)JMSTestCase.topicCf).createTopicConnection();
 
       TopicSession sess1 = conn1.createTopicSession(false, Session.AUTO_ACKNOWLEDGE);
       TopicSession sess2 = conn2.createTopicSession(false, Session.AUTO_ACKNOWLEDGE);

Modified: branches/hornetq-416/tests/jms-tests/src/org/hornetq/jms/tests/ConnectionFactoryTest.java
===================================================================
--- branches/hornetq-416/tests/jms-tests/src/org/hornetq/jms/tests/ConnectionFactoryTest.java	2010-10-13 00:11:20 UTC (rev 9781)
+++ branches/hornetq-416/tests/jms-tests/src/org/hornetq/jms/tests/ConnectionFactoryTest.java	2010-10-13 07:38:20 UTC (rev 9782)
@@ -28,7 +28,11 @@
 import javax.jms.Topic;
 import javax.jms.TopicConnection;
 import javax.jms.TopicConnectionFactory;
+import javax.jms.XAConnectionFactory;
+import javax.jms.XAQueueConnectionFactory;
+import javax.jms.XATopicConnectionFactory;
 
+import org.hornetq.jms.client.HornetQConnectionFactory;
 import org.hornetq.jms.tests.util.ProxyAssertSupport;
 
 /**
@@ -62,7 +66,7 @@
     */
    public void testQueueConnectionFactory() throws Exception
    {
-      QueueConnectionFactory qcf = (QueueConnectionFactory)JMSTestCase.ic.lookup("/ConnectionFactory");
+      QueueConnectionFactory qcf = (QueueConnectionFactory)JMSTestCase.ic.lookup("/CF_QUEUE_XA_FALSE");
       QueueConnection qc = qcf.createQueueConnection();
       qc.close();
    }
@@ -73,7 +77,7 @@
     */
    public void testTopicConnectionFactory() throws Exception
    {
-      TopicConnectionFactory qcf = (TopicConnectionFactory)JMSTestCase.ic.lookup("/ConnectionFactory");
+      TopicConnectionFactory qcf = (TopicConnectionFactory)JMSTestCase.ic.lookup("/CF_TOPIC_XA_FALSE");
       TopicConnection tc = qcf.createTopicConnection();
       tc.close();
    }
@@ -107,7 +111,7 @@
       // the ConnectionFactories that ship with HornetQ do not have their clientID
       // administratively configured.
 
-      ConnectionFactory cf = (ConnectionFactory)JMSTestCase.ic.lookup("/ConnectionFactory");
+      ConnectionFactory cf = (ConnectionFactory)JMSTestCase.ic.lookup("/CF_XA_FALSE");
       Connection c = cf.createConnection();
 
       ProxyAssertSupport.assertNull(c.getClientID());
@@ -120,7 +124,7 @@
       // the ConnectionFactories that ship with HornetQ do not have their clientID
       // administratively configured.
 
-      ConnectionFactory cf = (ConnectionFactory)JMSTestCase.ic.lookup("/ConnectionFactory");
+      ConnectionFactory cf = (ConnectionFactory)JMSTestCase.ic.lookup("/CF_XA_FALSE");
       Connection c = cf.createConnection();
 
       // set the client id immediately after the connection is created
@@ -320,7 +324,102 @@
       }
 
    }
+   
+   public void testFactoryTypes() throws Exception
+   {
+      HornetQConnectionFactory factory = null;
+      
+      factory = (HornetQConnectionFactory)JMSTestCase.ic.lookup("/ConnectionFactory");
+      
+      assertTrue(factory instanceof ConnectionFactory);
+      assertEquals(1, getTypes(factory));
+      
+      factory = (HornetQConnectionFactory)JMSTestCase.ic.lookup("/CF_XA_TRUE");
+      
+      assertTrue(factory instanceof XAConnectionFactory);
+      assertEquals(1, getTypes(factory));
+      
+      factory = (HornetQConnectionFactory)JMSTestCase.ic.lookup("/CF_XA_FALSE");
+      
+      assertTrue(factory instanceof ConnectionFactory);
+      assertEquals(1, getTypes(factory));
+      
+      factory = (HornetQConnectionFactory)JMSTestCase.ic.lookup("/CF_GENERIC");
+      
+      assertTrue(factory instanceof ConnectionFactory);
+      assertEquals(1, getTypes(factory));
+      
+      factory = (HornetQConnectionFactory)JMSTestCase.ic.lookup("/CF_GENERIC_XA_TRUE");
+      
+      assertTrue(factory instanceof XAConnectionFactory);
+      assertEquals(1, getTypes(factory));
+      
+      factory = (HornetQConnectionFactory)JMSTestCase.ic.lookup("/CF_GENERIC_XA_FALSE");
+      
+      assertTrue(factory instanceof ConnectionFactory);
+      assertEquals(1, getTypes(factory));
+      
+      factory = (HornetQConnectionFactory)JMSTestCase.ic.lookup("/CF_QUEUE");
+      
+      assertTrue(factory instanceof QueueConnectionFactory);
+      assertEquals(2, getTypes(factory));
+      
+      factory = (HornetQConnectionFactory)JMSTestCase.ic.lookup("/CF_QUEUE_XA_TRUE");
+      
+      assertTrue(factory instanceof XAQueueConnectionFactory);
+      assertEquals(4, getTypes(factory));
+      
+      factory = (HornetQConnectionFactory)JMSTestCase.ic.lookup("/CF_QUEUE_XA_FALSE");
+      
+      assertTrue(factory instanceof QueueConnectionFactory);
+      assertEquals(2, getTypes(factory));
+      
+      factory = (HornetQConnectionFactory)JMSTestCase.ic.lookup("/CF_TOPIC");
+      
+      assertTrue(factory instanceof TopicConnectionFactory);
+      assertEquals(2, getTypes(factory));
+      
+      factory = (HornetQConnectionFactory)JMSTestCase.ic.lookup("/CF_TOPIC_XA_TRUE");
+      
+      assertTrue(factory instanceof XATopicConnectionFactory);
+      assertEquals(4, getTypes(factory));
+      
+      factory = (HornetQConnectionFactory)JMSTestCase.ic.lookup("/CF_TOPIC_XA_FALSE");
+      
+      assertTrue(factory instanceof TopicConnectionFactory);
+      assertEquals(2, getTypes(factory));
+   }
 
+   private int getTypes(HornetQConnectionFactory factory)
+   {
+      int num = 0;
+      if (factory instanceof ConnectionFactory)
+      {
+         num++;
+      }
+      if (factory instanceof XAConnectionFactory)
+      {
+         num++;
+      }
+      if (factory instanceof QueueConnectionFactory)
+      {
+         num++;
+      }
+      if (factory instanceof TopicConnectionFactory)
+      {
+         num++;
+      }
+      if (factory instanceof XAQueueConnectionFactory)
+      {
+         num++;
+      }
+      if (factory instanceof XATopicConnectionFactory)
+      {
+         num++;
+      }
+      return num;
+   }
+
    // Package protected ---------------------------------------------
 
    // Protected -----------------------------------------------------

Modified: branches/hornetq-416/tests/jms-tests/src/org/hornetq/jms/tests/ConnectionTest.java
===================================================================
--- branches/hornetq-416/tests/jms-tests/src/org/hornetq/jms/tests/ConnectionTest.java	2010-10-13 00:11:20 UTC (rev 9781)
+++ branches/hornetq-416/tests/jms-tests/src/org/hornetq/jms/tests/ConnectionTest.java	2010-10-13 07:38:20 UTC (rev 9782)
@@ -148,17 +148,19 @@
 
       connection.close();
 
-      connection = JMSTestCase.cf.createConnection();
-      connection.getClientID();
-      try
-      {
-         connection.setClientID(clientID);
-         ProxyAssertSupport.fail();
-      }
-      catch (javax.jms.IllegalStateException e)
-      {
-      }
-      connection.close();
+      // TODO: This will probably go away, remove it enterily after we 
+      //       make sure this rule can go away
+//      connection = JMSTestCase.cf.createConnection();
+//      connection.getClientID();
+//      try
+//      {
+//         connection.setClientID(clientID);
+//         ProxyAssertSupport.fail();
+//      }
+//      catch (javax.jms.IllegalStateException e)
+//      {
+//      }
+//      connection.close();
 
       connection = JMSTestCase.cf.createConnection();
       ExceptionListener listener = connection.getExceptionListener();
@@ -209,7 +211,7 @@
     */
    public void testQueueConnection1() throws Exception
    {
-      QueueConnectionFactory qcf = JMSTestCase.cf;
+      QueueConnectionFactory qcf = JMSTestCase.queueCf;
 
       QueueConnection qc = qcf.createQueueConnection();
 
@@ -223,7 +225,7 @@
     */
    public void testQueueConnection2() throws Exception
    {
-      TopicConnectionFactory tcf = JMSTestCase.cf;
+      TopicConnectionFactory tcf = JMSTestCase.topicCf;
 
       TopicConnection tc = tcf.createTopicConnection();
 
@@ -278,7 +280,7 @@
     */
    public void testDurableSubscriberOnQueueConnection() throws Exception
    {
-      QueueConnection queueConnection = ((QueueConnectionFactory)JMSTestCase.cf).createQueueConnection();
+      QueueConnection queueConnection = ((QueueConnectionFactory)JMSTestCase.queueCf).createQueueConnection();
 
       try
       {

Modified: branches/hornetq-416/tests/jms-tests/src/org/hornetq/jms/tests/HornetQServerTestCase.java
===================================================================
--- branches/hornetq-416/tests/jms-tests/src/org/hornetq/jms/tests/HornetQServerTestCase.java	2010-10-13 00:11:20 UTC (rev 9781)
+++ branches/hornetq-416/tests/jms-tests/src/org/hornetq/jms/tests/HornetQServerTestCase.java	2010-10-13 07:38:20 UTC (rev 9782)
@@ -318,12 +318,12 @@
 
    public TopicConnectionFactory getTopicConnectionFactory() throws Exception
    {
-      return (TopicConnectionFactory)getInitialContext().lookup("/ConnectionFactory");
+      return (TopicConnectionFactory)getInitialContext().lookup("/CF_TOPIC");
    }
 
    public XAConnectionFactory getXAConnectionFactory() throws Exception
    {
-      return (XAConnectionFactory)getInitialContext().lookup("/ConnectionFactory");
+      return (XAConnectionFactory)getInitialContext().lookup("/CF_XA_TRUE");
    }
 
    public InitialContext getInitialContext(final int serverid) throws Exception

Modified: branches/hornetq-416/tests/jms-tests/src/org/hornetq/jms/tests/JMSTestCase.java
===================================================================
--- branches/hornetq-416/tests/jms-tests/src/org/hornetq/jms/tests/JMSTestCase.java	2010-10-13 00:11:20 UTC (rev 9781)
+++ branches/hornetq-416/tests/jms-tests/src/org/hornetq/jms/tests/JMSTestCase.java	2010-10-13 07:38:20 UTC (rev 9782)
@@ -22,6 +22,10 @@
 import org.hornetq.api.core.TransportConfiguration;
 import org.hornetq.api.core.client.HornetQClient;
 import org.hornetq.jms.client.HornetQConnectionFactory;
+import org.hornetq.jms.client.HornetQJMSConnectionFactory;
+import org.hornetq.jms.client.HornetQQueueConnectionFactory;
+import org.hornetq.jms.client.HornetQTopicConnectionFactory;
+import org.hornetq.jms.server.impl.JMSFactoryType;
 
 /**
  * @author <a href="mailto:tim.fox at jboss.com">Tim Fox</a>
@@ -32,8 +36,12 @@
 public class JMSTestCase extends HornetQServerTestCase
 {
 
-   protected static HornetQConnectionFactory cf;
+   protected static HornetQJMSConnectionFactory cf;
 
+   protected static HornetQQueueConnectionFactory queueCf;
+
+   protected static HornetQTopicConnectionFactory topicCf;
+
    protected static InitialContext ic;
 
    protected static final String defaultConf = "all";
@@ -91,10 +99,81 @@
                                                     HornetQClient.DEFAULT_FAILOVER_ON_INITIAL_CONNECTION,
                                                     HornetQClient.DEFAULT_FAILOVER_ON_SERVER_SHUTDOWN,
                                                     null,
+                                                    JMSFactoryType.CF,
                                                     "/testsuitecf");
 
-      JMSTestCase.cf = (HornetQConnectionFactory)getInitialContext().lookup("/testsuitecf");
+      getJmsServerManager().createConnectionFactory("testsuitecf_queue",
+                                                    connectorConfigs,
+                                                    null,
+                                                    HornetQClient.DEFAULT_CLIENT_FAILURE_CHECK_PERIOD,
+                                                    HornetQClient.DEFAULT_CONNECTION_TTL,
+                                                    HornetQClient.DEFAULT_CALL_TIMEOUT,
+                                                    HornetQClient.DEFAULT_CACHE_LARGE_MESSAGE_CLIENT,
+                                                    HornetQClient.DEFAULT_MIN_LARGE_MESSAGE_SIZE,
+                                                    HornetQClient.DEFAULT_CONSUMER_WINDOW_SIZE,
+                                                    HornetQClient.DEFAULT_CONSUMER_MAX_RATE,
+                                                    HornetQClient.DEFAULT_CONFIRMATION_WINDOW_SIZE,
+                                                    HornetQClient.DEFAULT_PRODUCER_WINDOW_SIZE,
+                                                    HornetQClient.DEFAULT_PRODUCER_MAX_RATE,
+                                                    true,
+                                                    true,
+                                                    true,
+                                                    HornetQClient.DEFAULT_AUTO_GROUP,
+                                                    HornetQClient.DEFAULT_PRE_ACKNOWLEDGE,
+                                                    HornetQClient.DEFAULT_CONNECTION_LOAD_BALANCING_POLICY_CLASS_NAME,
+                                                    HornetQClient.DEFAULT_ACK_BATCH_SIZE,
+                                                    HornetQClient.DEFAULT_ACK_BATCH_SIZE,
+                                                    HornetQClient.DEFAULT_USE_GLOBAL_POOLS,
+                                                    HornetQClient.DEFAULT_SCHEDULED_THREAD_POOL_MAX_SIZE,
+                                                    HornetQClient.DEFAULT_THREAD_POOL_MAX_SIZE,
+                                                    HornetQClient.DEFAULT_RETRY_INTERVAL,
+                                                    HornetQClient.DEFAULT_RETRY_INTERVAL_MULTIPLIER,
+                                                    HornetQClient.DEFAULT_MAX_RETRY_INTERVAL,
+                                                    HornetQClient.DEFAULT_RECONNECT_ATTEMPTS,
+                                                    HornetQClient.DEFAULT_FAILOVER_ON_INITIAL_CONNECTION,
+                                                    HornetQClient.DEFAULT_FAILOVER_ON_SERVER_SHUTDOWN,
+                                                    null,
+                                                    JMSFactoryType.QUEUE_CF,
+                                                    "/testsuitecf_queue");
 
+      getJmsServerManager().createConnectionFactory("testsuitecf_topic",
+                                                    connectorConfigs,
+                                                    null,
+                                                    HornetQClient.DEFAULT_CLIENT_FAILURE_CHECK_PERIOD,
+                                                    HornetQClient.DEFAULT_CONNECTION_TTL,
+                                                    HornetQClient.DEFAULT_CALL_TIMEOUT,
+                                                    HornetQClient.DEFAULT_CACHE_LARGE_MESSAGE_CLIENT,
+                                                    HornetQClient.DEFAULT_MIN_LARGE_MESSAGE_SIZE,
+                                                    HornetQClient.DEFAULT_CONSUMER_WINDOW_SIZE,
+                                                    HornetQClient.DEFAULT_CONSUMER_MAX_RATE,
+                                                    HornetQClient.DEFAULT_CONFIRMATION_WINDOW_SIZE,
+                                                    HornetQClient.DEFAULT_PRODUCER_WINDOW_SIZE,
+                                                    HornetQClient.DEFAULT_PRODUCER_MAX_RATE,
+                                                    true,
+                                                    true,
+                                                    true,
+                                                    HornetQClient.DEFAULT_AUTO_GROUP,
+                                                    HornetQClient.DEFAULT_PRE_ACKNOWLEDGE,
+                                                    HornetQClient.DEFAULT_CONNECTION_LOAD_BALANCING_POLICY_CLASS_NAME,
+                                                    HornetQClient.DEFAULT_ACK_BATCH_SIZE,
+                                                    HornetQClient.DEFAULT_ACK_BATCH_SIZE,
+                                                    HornetQClient.DEFAULT_USE_GLOBAL_POOLS,
+                                                    HornetQClient.DEFAULT_SCHEDULED_THREAD_POOL_MAX_SIZE,
+                                                    HornetQClient.DEFAULT_THREAD_POOL_MAX_SIZE,
+                                                    HornetQClient.DEFAULT_RETRY_INTERVAL,
+                                                    HornetQClient.DEFAULT_RETRY_INTERVAL_MULTIPLIER,
+                                                    HornetQClient.DEFAULT_MAX_RETRY_INTERVAL,
+                                                    HornetQClient.DEFAULT_RECONNECT_ATTEMPTS,
+                                                    HornetQClient.DEFAULT_FAILOVER_ON_INITIAL_CONNECTION,
+                                                    HornetQClient.DEFAULT_FAILOVER_ON_SERVER_SHUTDOWN,
+                                                    null,
+                                                    JMSFactoryType.TOPIC_CF,
+                                                    "/testsuitecf_topic");
+
+      JMSTestCase.cf = (HornetQJMSConnectionFactory)getInitialContext().lookup("/testsuitecf");
+      JMSTestCase.queueCf = (HornetQQueueConnectionFactory)getInitialContext().lookup("/testsuitecf_queue");
+      JMSTestCase.topicCf = (HornetQTopicConnectionFactory)getInitialContext().lookup("/testsuitecf_topic");
+
       assertRemainingMessages(0);
    }
 

Modified: branches/hornetq-416/tests/jms-tests/src/org/hornetq/jms/tests/ReferenceableTest.java
===================================================================
--- branches/hornetq-416/tests/jms-tests/src/org/hornetq/jms/tests/ReferenceableTest.java	2010-10-13 00:11:20 UTC (rev 9781)
+++ branches/hornetq-416/tests/jms-tests/src/org/hornetq/jms/tests/ReferenceableTest.java	2010-10-13 07:38:20 UTC (rev 9782)
@@ -27,6 +27,7 @@
 
 import org.hornetq.jms.client.HornetQConnectionFactory;
 import org.hornetq.jms.client.HornetQDestination;
+import org.hornetq.jms.client.HornetQJMSConnectionFactory;
 import org.hornetq.jms.client.HornetQQueue;
 import org.hornetq.jms.client.HornetQTopic;
 import org.hornetq.jms.referenceable.ConnectionFactoryObjectFactory;
@@ -88,7 +89,7 @@
 
       ProxyAssertSupport.assertTrue(instance instanceof HornetQConnectionFactory);
 
-      HornetQConnectionFactory cf2 = (HornetQConnectionFactory)instance;
+      HornetQJMSConnectionFactory cf2 = (HornetQJMSConnectionFactory)instance;
 
       simpleSendReceive(cf2, HornetQServerTestCase.queue1);
    }

Modified: branches/hornetq-416/tests/jms-tests/src/org/hornetq/jms/tests/message/JMSXDeliveryCountTest.java
===================================================================
--- branches/hornetq-416/tests/jms-tests/src/org/hornetq/jms/tests/message/JMSXDeliveryCountTest.java	2010-10-13 00:11:20 UTC (rev 9781)
+++ branches/hornetq-416/tests/jms-tests/src/org/hornetq/jms/tests/message/JMSXDeliveryCountTest.java	2010-10-13 07:38:20 UTC (rev 9782)
@@ -499,7 +499,7 @@
 
          producer.send(tm);
 
-         xaConn = ((XAConnectionFactory)getConnectionFactory()).createXAConnection();
+         xaConn = ((XAConnectionFactory)getXAConnectionFactory()).createXAConnection();
 
          XASession consumerSess = xaConn.createXASession();
          MessageConsumer consumer = consumerSess.createConsumer(HornetQServerTestCase.queue1);

Modified: branches/hornetq-416/tests/jms-tests/src/org/hornetq/jms/tests/selector/SelectorTest.java
===================================================================
--- branches/hornetq-416/tests/jms-tests/src/org/hornetq/jms/tests/selector/SelectorTest.java	2010-10-13 00:11:20 UTC (rev 9781)
+++ branches/hornetq-416/tests/jms-tests/src/org/hornetq/jms/tests/selector/SelectorTest.java	2010-10-13 07:38:20 UTC (rev 9782)
@@ -846,6 +846,54 @@
       }
    }
    
+   public void testJMSExpirationOnSelector() throws Exception
+   {
+      Connection conn = null;
+
+      try
+      {
+         conn = getConnectionFactory().createConnection();
+         conn.start();
+
+         Session session = conn.createSession(false, Session.AUTO_ACKNOWLEDGE);
+         
+         MessageProducer prod = session.createProducer(HornetQServerTestCase.queue1);
+         
+         TextMessage msg1 = session.createTextMessage("msg1");
+         prod.send(msg1);
+         
+         prod.setTimeToLive(100000);
+         
+         TextMessage msg2 = session.createTextMessage("msg2");
+                           
+         prod.send(msg2);
+         
+         long expire = msg2.getJMSExpiration();
+         
+         String selector = "JMSExpiration = " + expire;
+         
+         MessageConsumer cons = session.createConsumer(HornetQServerTestCase.queue1, selector);
+         
+         conn.start();
+
+         TextMessage rec = (TextMessage)cons.receive(10000);
+         
+         assertNotNull(rec);
+         
+         assertEquals("msg2", rec.getText());
+         
+         assertNull(cons.receiveNoWait());
+         
+      }
+      finally
+      {
+         if (conn != null)
+         {
+            conn.close();
+         }
+      }
+   }
+   
    public void testJMSTypeOnSelector() throws Exception
    {
       Connection conn = null;

Modified: branches/hornetq-416/tests/jms-tests/src/org/hornetq/jms/tests/tools/container/LocalTestServer.java
===================================================================
--- branches/hornetq-416/tests/jms-tests/src/org/hornetq/jms/tests/tools/container/LocalTestServer.java	2010-10-13 00:11:20 UTC (rev 9781)
+++ branches/hornetq-416/tests/jms-tests/src/org/hornetq/jms/tests/tools/container/LocalTestServer.java	2010-10-13 07:38:20 UTC (rev 9782)
@@ -38,6 +38,7 @@
 import org.hornetq.core.server.HornetQServer;
 import org.hornetq.integration.bootstrap.HornetQBootstrapServer;
 import org.hornetq.jms.server.JMSServerManager;
+import org.hornetq.jms.server.impl.JMSFactoryType;
 import org.jboss.kernel.plugins.config.property.PropertyKernelConfig;
 
 /**
@@ -321,6 +322,7 @@
                                                     HornetQClient.DEFAULT_FAILOVER_ON_INITIAL_CONNECTION,
                                                     HornetQClient.DEFAULT_FAILOVER_ON_SERVER_SHUTDOWN,
                                                     null,
+                                                    JMSFactoryType.CF,
                                                     jndiBindings);
    }
 

Modified: branches/hornetq-416/tests/joram-tests/src/org/hornetq/jms/HornetQAdmin.java
===================================================================
--- branches/hornetq-416/tests/joram-tests/src/org/hornetq/jms/HornetQAdmin.java	2010-10-13 00:11:20 UTC (rev 9781)
+++ branches/hornetq-416/tests/joram-tests/src/org/hornetq/jms/HornetQAdmin.java	2010-10-13 07:38:20 UTC (rev 9782)
@@ -129,7 +129,19 @@
 
    public void createQueueConnectionFactory(final String name)
    {
-      createConnectionFactory(name);
+      try
+      {
+         invokeSyncOperation(ResourceNames.JMS_SERVER,
+                             "createQueueConnectionFactory",
+                             name,
+                             NettyConnectorFactory.class.getName(),
+                             new HashMap<String, Object>(),
+                             new String[] { name });
+      }
+      catch (Exception e)
+      {
+         throw new IllegalStateException(e);
+      }
    }
 
    public void createTopic(final String name)
@@ -148,7 +160,19 @@
 
    public void createTopicConnectionFactory(final String name)
    {
-      createConnectionFactory(name);
+      try
+      {
+         invokeSyncOperation(ResourceNames.JMS_SERVER,
+                             "createTopicConnectionFactory",
+                             name,
+                             NettyConnectorFactory.class.getName(),
+                             new HashMap<String, Object>(),
+                             new String[] { name });
+      }
+      catch (Exception e)
+      {
+         throw new IllegalStateException(e);
+      }
    }
 
    public void deleteConnectionFactory(final String name)

Modified: branches/hornetq-416/tests/src/org/hornetq/tests/integration/client/PagingTest.java
===================================================================
--- branches/hornetq-416/tests/src/org/hornetq/tests/integration/client/PagingTest.java	2010-10-13 00:11:20 UTC (rev 9781)
+++ branches/hornetq-416/tests/src/org/hornetq/tests/integration/client/PagingTest.java	2010-10-13 07:38:20 UTC (rev 9782)
@@ -13,10 +13,17 @@
 
 package org.hornetq.tests.integration.client;
 
+import java.lang.management.ManagementFactory;
 import java.nio.ByteBuffer;
 import java.util.ArrayList;
 import java.util.HashMap;
+import java.util.List;
 import java.util.Map;
+import java.util.concurrent.CountDownLatch;
+import java.util.concurrent.Executor;
+import java.util.concurrent.Executors;
+import java.util.concurrent.Semaphore;
+import java.util.concurrent.TimeUnit;
 import java.util.concurrent.atomic.AtomicInteger;
 
 import junit.framework.Assert;
@@ -33,14 +40,30 @@
 import org.hornetq.api.core.client.MessageHandler;
 import org.hornetq.core.config.Configuration;
 import org.hornetq.core.config.DivertConfiguration;
+import org.hornetq.core.journal.SequentialFileFactory;
 import org.hornetq.core.logging.Logger;
+import org.hornetq.core.paging.Page;
+import org.hornetq.core.paging.PagingManager;
+import org.hornetq.core.paging.PagingStore;
+import org.hornetq.core.paging.PagingStoreFactory;
+import org.hornetq.core.paging.impl.PageImpl;
+import org.hornetq.core.paging.impl.PagingManagerImpl;
+import org.hornetq.core.paging.impl.PagingStoreFactoryNIO;
+import org.hornetq.core.paging.impl.PagingStoreImpl;
 import org.hornetq.core.paging.impl.TestSupportPageStore;
+import org.hornetq.core.persistence.StorageManager;
+import org.hornetq.core.postoffice.PostOffice;
 import org.hornetq.core.server.HornetQServer;
 import org.hornetq.core.server.Queue;
+import org.hornetq.core.server.ServerMessage;
+import org.hornetq.core.server.impl.HornetQServerImpl;
 import org.hornetq.core.settings.impl.AddressFullMessagePolicy;
 import org.hornetq.core.settings.impl.AddressSettings;
+import org.hornetq.spi.core.security.HornetQSecurityManager;
+import org.hornetq.spi.core.security.HornetQSecurityManagerImpl;
 import org.hornetq.tests.util.ServiceTestBase;
 import org.hornetq.tests.util.UnitTestCase;
+import org.hornetq.utils.ExecutorFactory;
 
 /**
  * A PagingTest
@@ -129,17 +152,17 @@
 
       server.start();
 
-      final int numberOfIntegers = 256;
+      final int messageSize = 1024;
 
       final int numberOfMessages = 30000;
 
-      final byte[] body = new byte[numberOfIntegers * 4];
+      final byte[] body = new byte[messageSize];
 
       ByteBuffer bb = ByteBuffer.wrap(body);
 
-      for (int j = 1; j <= numberOfIntegers; j++)
+      for (int j = 1; j <= messageSize; j++)
       {
-         bb.putInt(j);
+         bb.put(getSamplebyte(j));
       }
 
       try
@@ -244,7 +267,7 @@
                      }
 
                      consumer.close();
-                     
+
                      session.close();
                   }
                   catch (Throwable e)
@@ -266,11 +289,20 @@
          {
             threads[i].join();
          }
-         
+
          assertEquals(0, errors.get());
          
+         for (int i = 0 ; i < 20 && server.getPostOffice().getPagingManager().getTransactions().size() != 0; i++)
+         {
+            if (server.getPostOffice().getPagingManager().getTransactions().size() != 0)
+            {
+               // The delete may be asynchronous, giving some time case it eventually happen asynchronously
+               Thread.sleep(500);
+            }
+         }
+
          assertEquals(0, server.getPostOffice().getPagingManager().getTransactions().size());
-         
+
       }
       finally
       {
@@ -740,11 +772,11 @@
             message.putIntProperty(new SimpleString("id"), i);
 
             producerTransacted.send(message);
-            
+
             if (i % 2 == 0)
             {
                System.out.println("Sending 20 msgs to make it page");
-               for (int j = 0 ; j < 20; j++)
+               for (int j = 0; j < 20; j++)
                {
                   ClientMessage msgSend = sessionNonTX.createMessage(true);
                   msgSend.getBodyBuffer().writeBytes(new byte[10 * 1024]);
@@ -756,7 +788,7 @@
             {
                System.out.println("Consuming 20 msgs to make it page");
                ClientConsumer consumer = sessionNonTX.createConsumer(PagingTest.ADDRESS);
-               for (int j = 0 ; j < 20; j++)
+               for (int j = 0; j < 20; j++)
                {
                   ClientMessage msgReceived = consumer.receive(10000);
                   assertNotNull(msgReceived);
@@ -765,7 +797,7 @@
                consumer.close();
             }
          }
-         
+
          ClientConsumer consumerNonTX = sessionNonTX.createConsumer(PagingTest.ADDRESS);
          while (true)
          {
@@ -777,7 +809,6 @@
             msgReceived.acknowledge();
          }
          consumerNonTX.close();
-         
 
          ClientConsumer consumer = sessionNonTX.createConsumer(PagingTest.ADDRESS);
 
@@ -798,7 +829,7 @@
             // System.out.println(messageID);
             Assert.assertNotNull(messageID);
             Assert.assertEquals("message received out of order", i, messageID.intValue());
-            
+
             System.out.println("MessageID = " + messageID);
 
             message.acknowledge();
@@ -823,7 +854,6 @@
 
    }
 
-
    public void testDepageDuringTransaction4() throws Exception
    {
       clearData();
@@ -835,93 +865,88 @@
                                           PagingTest.PAGE_SIZE,
                                           PagingTest.PAGE_MAX,
                                           new HashMap<String, AddressSettings>());
-      
+
       server.getConfiguration().setJournalSyncNonTransactional(false);
       server.getConfiguration().setJournalSyncTransactional(false);
 
       server.start();
 
       final AtomicInteger errors = new AtomicInteger(0);
-      
+
       final int messageSize = 1024; // 1k
       final int numberOfMessages = 10000;
 
       try
       {
          final ClientSessionFactory sf = createInVMFactory();
-         
 
          sf.setBlockOnNonDurableSend(true);
          sf.setBlockOnDurableSend(true);
          sf.setBlockOnAcknowledge(false);
 
          final byte[] body = new byte[messageSize];
-         
-         
+
          Thread producerThread = new Thread()
          {
-           public void run()
-           {
-              ClientSession sessionProducer = null;
-              try
-              {
-                 sessionProducer = sf.createSession(false, false);
-                 ClientProducer producer = sessionProducer.createProducer(ADDRESS);
-                 
-                 for (int i = 0 ; i < numberOfMessages; i++)
-                 {
-                    ClientMessage msg = sessionProducer.createMessage(true);
-                    msg.getBodyBuffer().writeBytes(body);
-                    msg.putIntProperty("count", i);
-                    producer.send(msg);
-                    
-                    if (i % 50 == 0 && i != 0)
-                    {
-                       sessionProducer.commit();
-                       //Thread.sleep(500);
-                    }
-                 }
-                 
-                 sessionProducer.commit();
-                 
-                 System.out.println("Producer gone");
-                 
-                 
-                 
-              }
-              catch (Throwable e)
-              {
-                 e.printStackTrace(); // >> junit report
-                 errors.incrementAndGet();
-              }
-              finally
-              {
-                 try
-                 {
-                    if (sessionProducer != null)
-                    {
-                       sessionProducer.close();
-                    }
-                 }
-                 catch (Throwable e)
-                 {
-                    e.printStackTrace();
-                    errors.incrementAndGet();
-                 }
-              }
-           }
+            public void run()
+            {
+               ClientSession sessionProducer = null;
+               try
+               {
+                  sessionProducer = sf.createSession(false, false);
+                  ClientProducer producer = sessionProducer.createProducer(ADDRESS);
+
+                  for (int i = 0; i < numberOfMessages; i++)
+                  {
+                     ClientMessage msg = sessionProducer.createMessage(true);
+                     msg.getBodyBuffer().writeBytes(body);
+                     msg.putIntProperty("count", i);
+                     producer.send(msg);
+
+                     if (i % 50 == 0 && i != 0)
+                     {
+                        sessionProducer.commit();
+                        // Thread.sleep(500);
+                     }
+                  }
+
+                  sessionProducer.commit();
+
+                  System.out.println("Producer gone");
+
+               }
+               catch (Throwable e)
+               {
+                  e.printStackTrace(); // >> junit report
+                  errors.incrementAndGet();
+               }
+               finally
+               {
+                  try
+                  {
+                     if (sessionProducer != null)
+                     {
+                        sessionProducer.close();
+                     }
+                  }
+                  catch (Throwable e)
+                  {
+                     e.printStackTrace();
+                     errors.incrementAndGet();
+                  }
+               }
+            }
          };
-         
+
          ClientSession session = sf.createSession(true, true, 0);
          session.start();
          session.createQueue(PagingTest.ADDRESS, PagingTest.ADDRESS, null, true);
-         
+
          producerThread.start();
- 
+
          ClientConsumer consumer = session.createConsumer(PagingTest.ADDRESS);
-         
-         
-         for (int i = 0 ; i < numberOfMessages; i++)
+
+         for (int i = 0; i < numberOfMessages; i++)
          {
             ClientMessage msg = consumer.receive(500000);
             assertNotNull(msg);
@@ -929,15 +954,15 @@
             msg.acknowledge();
             if (i > 0 && i % 10 == 0)
             {
-               //session.commit();
+               // session.commit();
             }
          }
-         //session.commit();
-         
+         // session.commit();
+
          session.close();
-         
+
          producerThread.join();
-         
+
          assertEquals(0, errors.get());
       }
       finally
@@ -953,6 +978,361 @@
 
    }
 
+   // This test will force a depage thread as soon as the first message hits the page
+   public void testDepageOnTX5() throws Exception
+   {
+      clearData();
+
+      final Configuration config = createDefaultConfig();
+      HornetQSecurityManager securityManager = new HornetQSecurityManagerImpl();
+
+      final Executor executor = Executors.newSingleThreadExecutor();
+
+      final AtomicInteger countDepage = new AtomicInteger(0);
+      class HackPagingStore extends PagingStoreImpl
+      {
+         HackPagingStore(final SimpleString address,
+                         final PagingManager pagingManager,
+                         final StorageManager storageManager,
+                         final PostOffice postOffice,
+                         final SequentialFileFactory fileFactory,
+                         final PagingStoreFactory storeFactory,
+                         final SimpleString storeName,
+                         final AddressSettings addressSettings,
+                         final Executor executor,
+                         final boolean syncNonTransactional)
+         {
+            super(address,
+                  pagingManager,
+                  storageManager,
+                  postOffice,
+                  fileFactory,
+                  storeFactory,
+                  storeName,
+                  addressSettings,
+                  executor,
+                  syncNonTransactional);
+         }
+
+         protected boolean page(final List<ServerMessage> messages, final long transactionID, final boolean sync) throws Exception
+         {
+            boolean paged = super.page(messages, transactionID, sync);
+
+            if (paged)
+            {
+
+               if (countDepage.incrementAndGet() == 1)
+               {
+                  countDepage.set(0);
+
+                  executor.execute(new Runnable()
+                  {
+                     public void run()
+                     {
+                        try
+                        {
+                           while (isStarted() && readPage());
+                        }
+                        catch (Exception e)
+                        {
+                           e.printStackTrace();
+                        }
+                     }
+                  });
+               }
+            }
+
+            return paged;
+         }
+
+         public boolean startDepaging()
+         {
+            // do nothing, we are hacking depage right in between paging
+            return false;
+         }
+
+      };
+
+      class HackStoreFactory extends PagingStoreFactoryNIO
+      {
+         HackStoreFactory(final String directory,
+                          final ExecutorFactory executorFactory,
+                          final boolean syncNonTransactional)
+         {
+            super(directory, executorFactory, syncNonTransactional);
+         }
+
+         public synchronized PagingStore newStore(final SimpleString address, final AddressSettings settings) throws Exception
+         {
+
+            return new HackPagingStore(address,
+                                       getPagingManager(),
+                                       getStorageManager(),
+                                       getPostOffice(),
+                                       null,
+                                       this,
+                                       address,
+                                       settings,
+                                       getExecutorFactory().getExecutor(),
+                                       syncNonTransactional);
+         }
+
+      };
+
+      HornetQServer server = new HornetQServerImpl(config, ManagementFactory.getPlatformMBeanServer(), securityManager)
+
+      {
+         protected PagingManager createPagingManager()
+         {
+            return new PagingManagerImpl(new HackStoreFactory(config.getPagingDirectory(),
+                                                              getExecutorFactory(),
+                                                              config.isJournalSyncNonTransactional()),
+                                         getStorageManager(),
+                                         getAddressSettingsRepository());
+         }
+      };
+
+      AddressSettings defaultSetting = new AddressSettings();
+      defaultSetting.setPageSizeBytes(PAGE_SIZE);
+      defaultSetting.setMaxSizeBytes(PAGE_MAX);
+      server.getAddressSettingsRepository().addMatch("#", defaultSetting);
+
+      server.start();
+
+      final AtomicInteger errors = new AtomicInteger(0);
+
+      final int messageSize = 1024; // 1k
+      final int numberOfMessages = 2000;
+
+      try
+      {
+         final ClientSessionFactory sf = createInVMFactory();
+
+         sf.setBlockOnNonDurableSend(true);
+         sf.setBlockOnDurableSend(true);
+         sf.setBlockOnAcknowledge(false);
+
+         final byte[] body = new byte[messageSize];
+
+         Thread producerThread = new Thread()
+         {
+            public void run()
+            {
+               ClientSession sessionProducer = null;
+               try
+               {
+                  sessionProducer = sf.createSession(false, false);
+                  ClientProducer producer = sessionProducer.createProducer(ADDRESS);
+
+                  for (int i = 0; i < numberOfMessages; i++)
+                  {
+                     ClientMessage msg = sessionProducer.createMessage(true);
+                     msg.getBodyBuffer().writeBytes(body);
+                     msg.putIntProperty("count", i);
+                     producer.send(msg);
+
+                     if (i % 500 == 0 && i != 0)
+                     {
+                        sessionProducer.commit();
+                        // Thread.sleep(500);
+                     }
+                  }
+
+                  sessionProducer.commit();
+
+                  System.out.println("Producer gone");
+
+               }
+               catch (Throwable e)
+               {
+                  e.printStackTrace(); // >> junit report
+                  errors.incrementAndGet();
+               }
+               finally
+               {
+                  try
+                  {
+                     if (sessionProducer != null)
+                     {
+                        sessionProducer.close();
+                     }
+                  }
+                  catch (Throwable e)
+                  {
+                     e.printStackTrace();
+                     errors.incrementAndGet();
+                  }
+               }
+            }
+         };
+
+         ClientSession session = sf.createSession(true, true, 0);
+         session.start();
+         session.createQueue(PagingTest.ADDRESS, PagingTest.ADDRESS, null, true);
+
+         producerThread.start();
+
+         ClientConsumer consumer = session.createConsumer(PagingTest.ADDRESS);
+
+         for (int i = 0; i < numberOfMessages; i++)
+         {
+            ClientMessage msg = consumer.receive(500000);
+            assertNotNull(msg);
+            assertEquals(i, msg.getIntProperty("count").intValue());
+            msg.acknowledge();
+            if (i > 0 && i % 10 == 0)
+            {
+               // session.commit();
+            }
+         }
+         // session.commit();
+
+         session.close();
+
+         producerThread.join();
+
+         assertEquals(0, errors.get());
+      }
+      finally
+      {
+         try
+         {
+            server.stop();
+         }
+         catch (Throwable ignored)
+         {
+         }
+      }
+
+   }
+
+   public void testOrderingNonTX() throws Exception
+   {
+      clearData();
+
+      Configuration config = createDefaultConfig();
+
+      final HornetQServer server = createServer(true,
+                                                config,
+                                                PagingTest.PAGE_SIZE,
+                                                PagingTest.PAGE_SIZE * 2,
+                                                new HashMap<String, AddressSettings>());
+
+      server.getConfiguration().setJournalSyncNonTransactional(false);
+      server.getConfiguration().setJournalSyncTransactional(false);
+
+      server.start();
+
+      final AtomicInteger errors = new AtomicInteger(0);
+
+      final int messageSize = 1024; // 1k
+      final int numberOfMessages = 2000;
+
+      try
+      {
+         final ClientSessionFactory sf = createInVMFactory();
+
+         sf.setBlockOnNonDurableSend(false);
+         sf.setBlockOnDurableSend(true);
+         sf.setBlockOnAcknowledge(false);
+
+         final CountDownLatch ready = new CountDownLatch(1);
+
+         final byte[] body = new byte[messageSize];
+
+         Thread producerThread = new Thread()
+         {
+            public void run()
+            {
+               ClientSession sessionProducer = null;
+               try
+               {
+                  sessionProducer = sf.createSession(true, true);
+                  ClientProducer producer = sessionProducer.createProducer(ADDRESS);
+
+                  for (int i = 0; i < numberOfMessages; i++)
+                  {
+                     ClientMessage msg = sessionProducer.createMessage(true);
+                     msg.getBodyBuffer().writeBytes(body);
+                     msg.putIntProperty("count", i);
+                     producer.send(msg);
+
+                     if (i == 1000)
+                     {
+                        // The session is not TX, but we do this just to perform a round trip to the server
+                        // and make sure there are no pending messages
+                        sessionProducer.commit();
+
+                        assertTrue(server.getPagingManager().getPageStore(ADDRESS).isPaging());
+                        ready.countDown();
+                     }
+                  }
+
+                  sessionProducer.commit();
+
+                  System.out.println("Producer gone");
+
+               }
+               catch (Throwable e)
+               {
+                  e.printStackTrace(); // >> junit report
+                  errors.incrementAndGet();
+               }
+               finally
+               {
+                  try
+                  {
+                     if (sessionProducer != null)
+                     {
+                        sessionProducer.close();
+                     }
+                  }
+                  catch (Throwable e)
+                  {
+                     e.printStackTrace();
+                     errors.incrementAndGet();
+                  }
+               }
+            }
+         };
+
+         ClientSession session = sf.createSession(true, true, 0);
+         session.start();
+         session.createQueue(PagingTest.ADDRESS, PagingTest.ADDRESS, null, true);
+
+         producerThread.start();
+
+         assertTrue(ready.await(10, TimeUnit.SECONDS));
+
+         ClientConsumer consumer = session.createConsumer(PagingTest.ADDRESS);
+
+         for (int i = 0; i < numberOfMessages; i++)
+         {
+            ClientMessage msg = consumer.receive(500000);
+            assertNotNull(msg);
+            assertEquals(i, msg.getIntProperty("count").intValue());
+            msg.acknowledge();
+         }
+
+         session.close();
+
+         producerThread.join();
+
+         assertEquals(0, errors.get());
+      }
+      finally
+      {
+         try
+         {
+            server.stop();
+         }
+         catch (Throwable ignored)
+         {
+         }
+      }
+
+   }
+
    public void testPageOnSchedulingNoRestart() throws Exception
    {
       internalTestPageOnScheduling(false);
@@ -1678,13 +2058,13 @@
 
          Assert.assertNull(consumerNonPaged.receiveImmediate());
 
-         consumerNonPaged.close();
-
          for (ClientMessage ack : ackList)
          {
             ack.acknowledge();
          }
 
+         consumerNonPaged.close();
+         
          session.commit();
 
          ackList = null;

Modified: branches/hornetq-416/tests/src/org/hornetq/tests/integration/client/ReceiveImmediateTest.java
===================================================================
--- branches/hornetq-416/tests/src/org/hornetq/tests/integration/client/ReceiveImmediateTest.java	2010-10-13 00:11:20 UTC (rev 9781)
+++ branches/hornetq-416/tests/src/org/hornetq/tests/integration/client/ReceiveImmediateTest.java	2010-10-13 07:38:20 UTC (rev 9782)
@@ -12,11 +12,19 @@
  */
 package org.hornetq.tests.integration.client;
 
+import java.util.concurrent.atomic.AtomicBoolean;
+
 import junit.framework.Assert;
 
 import org.hornetq.api.core.SimpleString;
 import org.hornetq.api.core.TransportConfiguration;
-import org.hornetq.api.core.client.*;
+import org.hornetq.api.core.client.ClientConsumer;
+import org.hornetq.api.core.client.ClientMessage;
+import org.hornetq.api.core.client.ClientProducer;
+import org.hornetq.api.core.client.ClientSession;
+import org.hornetq.api.core.client.ClientSessionFactory;
+import org.hornetq.api.core.client.HornetQClient;
+import org.hornetq.api.core.client.MessageHandler;
 import org.hornetq.core.config.Configuration;
 import org.hornetq.core.logging.Logger;
 import org.hornetq.core.server.HornetQServer;
@@ -113,7 +121,87 @@
       sf.close();
 
    }
+   
+   // https://jira.jboss.org/browse/HORNETQ-450
+   public void testReceivedImmediateFollowedByReceive() throws Exception
+   {
+      sf = HornetQClient.createClientSessionFactory(new TransportConfiguration("org.hornetq.core.remoting.impl.invm.InVMConnectorFactory"));
+      sf.setBlockOnNonDurableSend(true);
 
+      ClientSession session = sf.createSession(false, true, true);
+
+      session.createQueue(ADDRESS, QUEUE, null, false);
+      
+      ClientProducer producer = session.createProducer(ADDRESS);
+
+      ClientMessage message = session.createMessage(false);
+      
+      producer.send(message);
+
+      ClientConsumer consumer = session.createConsumer(QUEUE, null, false);
+      
+      session.start();
+      
+      ClientMessage received = consumer.receiveImmediate();
+
+      assertNotNull(received);
+      
+      received.acknowledge();
+      
+      received = consumer.receive(1);
+      
+      assertNull(received);      
+
+      session.close();
+
+      sf.close();
+   }
+   
+   // https://jira.jboss.org/browse/HORNETQ-450
+   public void testReceivedImmediateFollowedByAsyncConsume() throws Exception
+   {
+      sf = HornetQClient.createClientSessionFactory(new TransportConfiguration("org.hornetq.core.remoting.impl.invm.InVMConnectorFactory"));
+      sf.setBlockOnNonDurableSend(true);
+
+      ClientSession session = sf.createSession(false, true, true);
+
+      session.createQueue(ADDRESS, QUEUE, null, false);
+      
+      ClientProducer producer = session.createProducer(ADDRESS);
+
+      ClientMessage message = session.createMessage(false);
+      
+      producer.send(message);
+
+      ClientConsumer consumer = session.createConsumer(QUEUE, null, false);
+      
+      session.start();
+      
+      ClientMessage received = consumer.receiveImmediate();
+
+      assertNotNull(received);
+      
+      received.acknowledge();
+      
+      final AtomicBoolean receivedAsync = new AtomicBoolean(false);
+      
+      consumer.setMessageHandler(new MessageHandler()
+      {
+         public void onMessage(ClientMessage message)
+         {
+            receivedAsync.set(true);
+         }
+      });
+      
+      Thread.sleep(1000);
+                  
+      assertFalse(receivedAsync.get());      
+
+      session.close();
+
+      sf.close();
+   }
+
    private void doConsumerReceiveImmediateWithNoMessages(final boolean browser) throws Exception
    {
       sf = HornetQClient.createClientSessionFactory(new TransportConfiguration("org.hornetq.core.remoting.impl.invm.InVMConnectorFactory"));

Modified: branches/hornetq-416/tests/src/org/hornetq/tests/integration/cluster/failover/FailoverTest.java
===================================================================
--- branches/hornetq-416/tests/src/org/hornetq/tests/integration/cluster/failover/FailoverTest.java	2010-10-13 00:11:20 UTC (rev 9781)
+++ branches/hornetq-416/tests/src/org/hornetq/tests/integration/cluster/failover/FailoverTest.java	2010-10-13 07:38:20 UTC (rev 9782)
@@ -37,6 +37,7 @@
 import org.hornetq.api.core.client.ClientSession;
 import org.hornetq.api.core.client.ClientSessionFactory;
 import org.hornetq.api.core.client.HornetQClient;
+import org.hornetq.api.core.client.MessageHandler;
 import org.hornetq.api.core.client.SessionFailureListener;
 import org.hornetq.core.client.impl.ClientSessionFactoryInternal;
 import org.hornetq.core.client.impl.ClientSessionInternal;
@@ -87,6 +88,92 @@
       }
    }
 
+   //https://jira.jboss.org/browse/HORNETQ-522
+   public void testNonTransactedWithZeroConsumerWindowSize() throws Exception
+   {
+      ClientSessionFactoryInternal sf = getSessionFactory();
+
+      sf.setBlockOnNonDurableSend(true);
+      sf.setBlockOnDurableSend(true);
+
+      ClientSession session = sf.createSession(true, true);
+
+      session.createQueue(FailoverTestBase.ADDRESS, FailoverTestBase.ADDRESS, null, true);
+
+      final CountDownLatch latch = new CountDownLatch(1);
+
+      class MyListener extends BaseListener
+      {
+         public void connectionFailed(final HornetQException me)
+         {
+            latch.countDown();
+         }
+      }
+
+      session.addFailureListener(new MyListener());
+
+      ClientProducer producer = session.createProducer(FailoverTestBase.ADDRESS);
+
+      final int numMessages = 100;
+
+      for (int i = 0; i < numMessages; i++)
+      {
+         ClientMessage message = session.createMessage(true);
+
+         setBody(i, message);
+
+         message.putIntProperty("counter", i);
+
+         producer.send(message);
+      }
+
+      int winSize = 0;
+      ClientConsumer consumer = session.createConsumer(FailoverTestBase.ADDRESS, null, winSize, 100, false);
+      
+      final List<ClientMessage> received = new ArrayList<ClientMessage>();
+      
+      consumer.setMessageHandler(new MessageHandler() {
+
+         public void onMessage(ClientMessage message)
+         {
+            received.add(message);
+            try
+            {
+               Thread.sleep(20);
+            }
+            catch (InterruptedException e)
+            {
+               // TODO Auto-generated catch block
+               e.printStackTrace();
+            }
+         }
+         
+      });
+
+      session.start();
+      
+      fail(session, latch);
+      
+      int retry = 0;
+      while (received.size() != numMessages)
+      {
+         Thread.sleep(1000);
+         retry++;
+         if (retry > 5)
+         {
+            break;
+         }
+      }
+
+      session.close();
+      
+      Assert.assertTrue(retry <= 5);
+
+      Assert.assertEquals(0, sf.numSessions());
+
+      Assert.assertEquals(0, sf.numConnections());
+   }
+
    public void testNonTransacted() throws Exception
    {
       ClientSessionFactoryInternal sf = getSessionFactory();

Modified: branches/hornetq-416/tests/src/org/hornetq/tests/integration/http/NettyHttpTest.java
===================================================================
--- branches/hornetq-416/tests/src/org/hornetq/tests/integration/http/NettyHttpTest.java	2010-10-13 00:11:20 UTC (rev 9781)
+++ branches/hornetq-416/tests/src/org/hornetq/tests/integration/http/NettyHttpTest.java	2010-10-13 07:38:20 UTC (rev 9782)
@@ -561,5 +561,11 @@
       {
          me.printStackTrace();
       }
+
+      public void connectionReadyForWrites(Object connectionID, boolean ready)
+      {
+      }
+      
+      
    }
 }

Modified: branches/hornetq-416/tests/src/org/hornetq/tests/integration/jms/FloodServerTest.java
===================================================================
--- branches/hornetq-416/tests/src/org/hornetq/tests/integration/jms/FloodServerTest.java	2010-10-13 00:11:20 UTC (rev 9781)
+++ branches/hornetq-416/tests/src/org/hornetq/tests/integration/jms/FloodServerTest.java	2010-10-13 07:38:20 UTC (rev 9782)
@@ -35,6 +35,7 @@
 import org.hornetq.core.remoting.impl.netty.NettyConnectorFactory;
 import org.hornetq.core.server.HornetQServer;
 import org.hornetq.core.server.HornetQServers;
+import org.hornetq.jms.server.impl.JMSFactoryType;
 import org.hornetq.jms.server.impl.JMSServerManagerImpl;
 import org.hornetq.tests.unit.util.InVMContext;
 import org.hornetq.tests.util.UnitTestCase;
@@ -159,6 +160,7 @@
                                             HornetQClient.DEFAULT_FAILOVER_ON_INITIAL_CONNECTION,
                                             failoverOnServerShutdown,
                                             null,
+                                            JMSFactoryType.CF,
                                             "/cf");
    }
 

Modified: branches/hornetq-416/tests/src/org/hornetq/tests/integration/jms/HornetQConnectionFactoryTest.java
===================================================================
--- branches/hornetq-416/tests/src/org/hornetq/tests/integration/jms/HornetQConnectionFactoryTest.java	2010-10-13 00:11:20 UTC (rev 9781)
+++ branches/hornetq-416/tests/src/org/hornetq/tests/integration/jms/HornetQConnectionFactoryTest.java	2010-10-13 07:38:20 UTC (rev 9782)
@@ -28,6 +28,7 @@
 import org.hornetq.api.core.client.ClientSessionFactory;
 import org.hornetq.api.core.client.HornetQClient;
 import org.hornetq.jms.client.HornetQConnectionFactory;
+import org.hornetq.jms.server.impl.JMSFactoryType;
 import org.hornetq.api.jms.HornetQJMSClient;
 import org.hornetq.core.config.BroadcastGroupConfiguration;
 import org.hornetq.core.config.Configuration;
@@ -172,7 +173,7 @@
 
    public void testDiscoveryConstructor() throws Exception
    {
-      HornetQConnectionFactory cf = (HornetQConnectionFactory) HornetQJMSClient.createConnectionFactory(groupAddress, groupPort);
+      HornetQConnectionFactory cf = (HornetQConnectionFactory) HornetQJMSClient.createConnectionFactory(groupAddress, groupPort, JMSFactoryType.CF);
       assertFactoryParams(cf,
                           null,
                           groupAddress,
@@ -219,7 +220,7 @@
                                                                                                                             backupTC);
       staticConnectors.add(pair0);
 
-      HornetQConnectionFactory cf = (HornetQConnectionFactory) HornetQJMSClient.createConnectionFactory(staticConnectors);
+      HornetQConnectionFactory cf = (HornetQConnectionFactory) HornetQJMSClient.createConnectionFactory(staticConnectors, JMSFactoryType.CF);
       assertFactoryParams(cf,
                           staticConnectors,
                           null,
@@ -267,7 +268,7 @@
                                                                                                                             backupTC);
       staticConnectors.add(pair0);
 
-      HornetQConnectionFactory cf = (HornetQConnectionFactory) HornetQJMSClient.createConnectionFactory(liveTC, backupTC);
+      HornetQConnectionFactory cf = (HornetQConnectionFactory) HornetQJMSClient.createConnectionFactory(liveTC, backupTC, JMSFactoryType.CF);
       assertFactoryParams(cf,
                           staticConnectors,
                           null,

Modified: branches/hornetq-416/tests/src/org/hornetq/tests/integration/jms/bridge/BridgeTestBase.java
===================================================================
--- branches/hornetq-416/tests/src/org/hornetq/tests/integration/jms/bridge/BridgeTestBase.java	2010-10-13 00:11:20 UTC (rev 9781)
+++ branches/hornetq-416/tests/src/org/hornetq/tests/integration/jms/bridge/BridgeTestBase.java	2010-10-13 07:38:20 UTC (rev 9782)
@@ -28,6 +28,7 @@
 import javax.jms.Session;
 import javax.jms.TextMessage;
 import javax.jms.Topic;
+import javax.jms.XAConnectionFactory;
 import javax.transaction.TransactionManager;
 
 import junit.framework.Assert;
@@ -50,8 +51,9 @@
 import org.hornetq.jms.bridge.ConnectionFactoryFactory;
 import org.hornetq.jms.bridge.DestinationFactory;
 import org.hornetq.jms.bridge.QualityOfServiceMode;
-import org.hornetq.jms.client.HornetQConnectionFactory;
+import org.hornetq.jms.client.HornetQJMSConnectionFactory;
 import org.hornetq.jms.client.HornetQMessage;
+import org.hornetq.jms.client.HornetQXAConnectionFactory;
 import org.hornetq.jms.server.JMSServerManager;
 import org.hornetq.jms.server.impl.JMSServerManagerImpl;
 import org.hornetq.tests.unit.util.InVMContext;
@@ -73,8 +75,12 @@
 
    protected ConnectionFactoryFactory cff0, cff1;
 
+   protected ConnectionFactoryFactory cff0xa, cff1xa;
+
    protected ConnectionFactory cf0, cf1;
 
+   protected XAConnectionFactory cf0xa, cf1xa;
+
    protected DestinationFactory sourceQueueFactory, targetQueueFactory, localTargetQueueFactory, sourceTopicFactory;
 
    protected Queue sourceQueue, targetQueue, localTargetQueue;
@@ -173,8 +179,12 @@
       server0.stop();
 
       cff0 = cff1 = null;
+      
+      cff0xa = cff1xa = null;
 
       cf0 = cf1 = null;
+      
+      cf0xa = cf1xa = null;
 
       sourceQueueFactory = targetQueueFactory = localTargetQueueFactory = sourceTopicFactory = null;
 
@@ -203,7 +213,7 @@
       {
          public ConnectionFactory createConnectionFactory() throws Exception
          {
-            HornetQConnectionFactory cf = (HornetQConnectionFactory) HornetQJMSClient.createConnectionFactory(new TransportConfiguration(InVMConnectorFactory.class.getName()));
+            HornetQJMSConnectionFactory cf = (HornetQJMSConnectionFactory) HornetQJMSClient.createConnectionFactory(new TransportConfiguration(InVMConnectorFactory.class.getName()));
 
             // Note! We disable automatic reconnection on the session factory. The bridge needs to do the reconnection
             cf.setReconnectAttempts(0);
@@ -216,14 +226,32 @@
 
       };
 
-      cf0 = cff0.createConnectionFactory();
+      cff0xa = new ConnectionFactoryFactory()
+      {
+         public Object createConnectionFactory() throws Exception
+         {
+            HornetQXAConnectionFactory cf = HornetQJMSClient.createXAConnectionFactory(new TransportConfiguration(InVMConnectorFactory.class.getName()));
 
+            // Note! We disable automatic reconnection on the session factory. The bridge needs to do the reconnection
+            cf.setReconnectAttempts(0);
+            cf.setBlockOnNonDurableSend(true);
+            cf.setBlockOnDurableSend(true);
+            cf.setCacheLargeMessagesClient(true);
+
+            return cf;
+         }
+
+      };
+
+      cf0 = (ConnectionFactory)cff0.createConnectionFactory();
+      cf0xa = (XAConnectionFactory)cff0xa.createConnectionFactory();
+
       cff1 = new ConnectionFactoryFactory()
       {
 
          public ConnectionFactory createConnectionFactory() throws Exception
          {
-            HornetQConnectionFactory cf = (HornetQConnectionFactory) HornetQJMSClient.createConnectionFactory(new TransportConfiguration(InVMConnectorFactory.class.getName(),
+            HornetQJMSConnectionFactory cf = (HornetQJMSConnectionFactory) HornetQJMSClient.createConnectionFactory(new TransportConfiguration(InVMConnectorFactory.class.getName(),
                                                                                                   params1));
 
             // Note! We disable automatic reconnection on the session factory. The bridge needs to do the reconnection
@@ -236,8 +264,27 @@
          }
       };
 
-      cf1 = cff1.createConnectionFactory();
+      cff1xa = new ConnectionFactoryFactory()
+      {
 
+         public XAConnectionFactory createConnectionFactory() throws Exception
+         {
+            HornetQXAConnectionFactory cf = (HornetQXAConnectionFactory) HornetQJMSClient.createXAConnectionFactory(new TransportConfiguration(InVMConnectorFactory.class.getName(),
+                                                                                                  params1));
+
+            // Note! We disable automatic reconnection on the session factory. The bridge needs to do the reconnection
+            cf.setReconnectAttempts(0);
+            cf.setBlockOnNonDurableSend(true);
+            cf.setBlockOnDurableSend(true);
+            cf.setCacheLargeMessagesClient(true);
+
+            return cf;
+         }
+      };
+
+      cf1 = (ConnectionFactory)cff1.createConnectionFactory();
+      cf1xa = (XAConnectionFactory)cff1xa.createConnectionFactory();
+
       sourceQueueFactory = new DestinationFactory()
       {
          public Destination createDestination() throws Exception

Modified: branches/hornetq-416/tests/src/org/hornetq/tests/integration/jms/bridge/JMSBridgeReconnectionTest.java
===================================================================
--- branches/hornetq-416/tests/src/org/hornetq/tests/integration/jms/bridge/JMSBridgeReconnectionTest.java	2010-10-13 00:11:20 UTC (rev 9781)
+++ branches/hornetq-416/tests/src/org/hornetq/tests/integration/jms/bridge/JMSBridgeReconnectionTest.java	2010-10-13 07:38:20 UTC (rev 9782)
@@ -18,6 +18,7 @@
 import junit.framework.Assert;
 
 import org.hornetq.core.logging.Logger;
+import org.hornetq.jms.bridge.ConnectionFactoryFactory;
 import org.hornetq.jms.bridge.QualityOfServiceMode;
 import org.hornetq.jms.bridge.impl.JMSBridgeImpl;
 
@@ -196,10 +197,18 @@
    {
       JMSBridgeImpl bridge = null;
 
+      ConnectionFactoryFactory factInUse0 = cff0;
+      ConnectionFactoryFactory factInUse1 = cff1;
+      if (qosMode.equals(QualityOfServiceMode.ONCE_AND_ONLY_ONCE))
+      {
+         factInUse0 = cff0xa;
+         factInUse1 = cff1xa;
+      }
+
       try
       {
-         bridge = new JMSBridgeImpl(cff0,
-                                    cff1,
+         bridge = new JMSBridgeImpl(factInUse0,
+                                    factInUse1,
                                     sourceQueueFactory,
                                     targetQueueFactory,
                                     null,
@@ -290,8 +299,8 @@
 
       try
       {
-         bridge = new JMSBridgeImpl(cff0,
-                                    cff1,
+         bridge = new JMSBridgeImpl(cff0xa,
+                                    cff1xa,
                                     sourceQueueFactory,
                                     targetQueueFactory,
                                     null,

Modified: branches/hornetq-416/tests/src/org/hornetq/tests/integration/jms/bridge/JMSBridgeTest.java
===================================================================
--- branches/hornetq-416/tests/src/org/hornetq/tests/integration/jms/bridge/JMSBridgeTest.java	2010-10-13 00:11:20 UTC (rev 9781)
+++ branches/hornetq-416/tests/src/org/hornetq/tests/integration/jms/bridge/JMSBridgeTest.java	2010-10-13 07:38:20 UTC (rev 9782)
@@ -33,6 +33,7 @@
 
 import org.hornetq.api.jms.HornetQJMSConstants;
 import org.hornetq.core.logging.Logger;
+import org.hornetq.jms.bridge.ConnectionFactoryFactory;
 import org.hornetq.jms.bridge.QualityOfServiceMode;
 import org.hornetq.jms.bridge.impl.JMSBridgeImpl;
 import org.hornetq.jms.client.HornetQMessage;
@@ -1444,10 +1445,18 @@
 
       Thread t = null;
 
+      ConnectionFactoryFactory factInUse0 = cff0;
+      ConnectionFactoryFactory factInUse1 = cff1;
+      if (qosMode.equals(QualityOfServiceMode.ONCE_AND_ONLY_ONCE))
+      {
+         factInUse0 = cff0xa;
+         factInUse1 = cff1xa;
+      }
+
       try
       {
-         bridge = new JMSBridgeImpl(cff0,
-                                    cff1,
+         bridge = new JMSBridgeImpl(factInUse0,
+                                    factInUse1,
                                     sourceQueueFactory,
                                     targetQueueFactory,
                                     null,
@@ -1530,10 +1539,18 @@
 
       Thread t = null;
 
+      ConnectionFactoryFactory factInUse0 = cff0;
+      ConnectionFactoryFactory factInUse1 = cff1;
+      if (qosMode.equals(QualityOfServiceMode.ONCE_AND_ONLY_ONCE))
+      {
+         factInUse0 = cff0xa;
+         factInUse1 = cff1xa;
+      }
+
       try
       {
-         bridge = new JMSBridgeImpl(cff0,
-                                    cff1,
+         bridge = new JMSBridgeImpl(factInUse0,
+                                    factInUse1,
                                     sourceQueueFactory,
                                     targetQueueFactory,
                                     null,
@@ -1617,10 +1634,16 @@
 
       Thread t = null;
 
+      ConnectionFactoryFactory factInUse0 = cff0;
+      if (qosMode.equals(QualityOfServiceMode.ONCE_AND_ONLY_ONCE))
+      {
+         factInUse0 = cff0xa;
+      }
+
       try
       {
-         bridge = new JMSBridgeImpl(cff0,
-                                    cff0,
+         bridge = new JMSBridgeImpl(factInUse0,
+                                    factInUse0,
                                     sourceQueueFactory,
                                     localTargetQueueFactory,
                                     null,
@@ -1699,12 +1722,19 @@
    {
       JMSBridgeImpl bridge = null;
 
+      ConnectionFactoryFactory factInUse0 = cff0;
+      ConnectionFactoryFactory factInUse1 = cff1;
+      if (qosMode.equals(QualityOfServiceMode.ONCE_AND_ONLY_ONCE))
+      {
+         factInUse0 = cff0xa;
+         factInUse1 = cff1xa;
+      }
       try
       {
          final int NUM_MESSAGES = 10;
 
-         bridge = new JMSBridgeImpl(cff0,
-                                    cff1,
+         bridge = new JMSBridgeImpl(factInUse0,
+                                    factInUse1,
                                     sourceQueueFactory,
                                     targetQueueFactory,
                                     null,
@@ -1770,12 +1800,18 @@
    {
       JMSBridgeImpl bridge = null;
 
+      ConnectionFactoryFactory factInUse0 = cff0;
+      if (qosMode.equals(QualityOfServiceMode.ONCE_AND_ONLY_ONCE))
+      {
+         factInUse0 = cff0xa;
+      }
+
       try
       {
          final int NUM_MESSAGES = 10;
 
-         bridge = new JMSBridgeImpl(cff0,
-                                    cff0,
+         bridge = new JMSBridgeImpl(factInUse0,
+                                    factInUse0,
                                     sourceQueueFactory,
                                     localTargetQueueFactory,
                                     null,
@@ -1840,14 +1876,22 @@
    {
       JMSBridgeImpl bridge = null;
 
+      ConnectionFactoryFactory factInUse0 = cff0;
+      ConnectionFactoryFactory factInUse1 = cff1;
+      if (qosMode.equals(QualityOfServiceMode.ONCE_AND_ONLY_ONCE))
+      {
+         factInUse0 = cff0xa;
+         factInUse1 = cff1xa;
+      }
+
       try
       {
          final long MAX_BATCH_TIME = 3000;
 
          final int MAX_BATCH_SIZE = 100000; // something big so it won't reach it
 
-         bridge = new JMSBridgeImpl(cff0,
-                                    cff1,
+         bridge = new JMSBridgeImpl(factInUse0,
+                                    factInUse1,
                                     sourceQueueFactory,
                                     targetQueueFactory,
                                     null,
@@ -1894,14 +1938,20 @@
    {
       JMSBridgeImpl bridge = null;
 
+      ConnectionFactoryFactory factInUse0 = cff0;
+      if (qosMode.equals(QualityOfServiceMode.ONCE_AND_ONLY_ONCE))
+      {
+         factInUse0 = cff0xa;
+      }
+
       try
       {
          final long MAX_BATCH_TIME = 3000;
 
          final int MAX_BATCH_SIZE = 100000; // something big so it won't reach it
 
-         bridge = new JMSBridgeImpl(cff0,
-                                    cff0,
+         bridge = new JMSBridgeImpl(factInUse0,
+                                    factInUse0,
                                     sourceQueueFactory,
                                     localTargetQueueFactory,
                                     null,

Copied: branches/hornetq-416/tests/src/org/hornetq/tests/integration/jms/client/AutoGroupingTest.java (from rev 9781, trunk/tests/src/org/hornetq/tests/integration/jms/client/AutoGroupingTest.java)
===================================================================
--- branches/hornetq-416/tests/src/org/hornetq/tests/integration/jms/client/AutoGroupingTest.java	                        (rev 0)
+++ branches/hornetq-416/tests/src/org/hornetq/tests/integration/jms/client/AutoGroupingTest.java	2010-10-13 07:38:20 UTC (rev 9782)
@@ -0,0 +1,50 @@
+/*
+ * Copyright 2010 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.hornetq.tests.integration.jms.client;
+
+import javax.jms.ConnectionFactory;
+import javax.jms.Message;
+
+import org.hornetq.api.core.TransportConfiguration;
+import org.hornetq.api.jms.HornetQJMSClient;
+import org.hornetq.core.remoting.impl.netty.NettyConnectorFactory;
+import org.hornetq.jms.client.HornetQJMSConnectionFactory;
+
+/**
+ * A AutoGroupingTest
+ *
+ * @author Tim Fox
+ *
+ *
+ */
+public class AutoGroupingTest extends GroupingTest
+{
+
+   @Override
+   protected ConnectionFactory getCF() throws Exception
+   {
+      HornetQJMSConnectionFactory cf = HornetQJMSClient.createConnectionFactory(new TransportConfiguration(NettyConnectorFactory.class.getName()));
+      
+      cf.setAutoGroup(true);
+      
+      return cf;
+   }
+   
+
+   @Override
+   protected void setProperty(Message message)
+   {
+   }
+
+}

Copied: branches/hornetq-416/tests/src/org/hornetq/tests/integration/jms/client/GroupIDTest.java (from rev 9781, trunk/tests/src/org/hornetq/tests/integration/jms/client/GroupIDTest.java)
===================================================================
--- branches/hornetq-416/tests/src/org/hornetq/tests/integration/jms/client/GroupIDTest.java	                        (rev 0)
+++ branches/hornetq-416/tests/src/org/hornetq/tests/integration/jms/client/GroupIDTest.java	2010-10-13 07:38:20 UTC (rev 9782)
@@ -0,0 +1,49 @@
+/*
+ * Copyright 2010 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.hornetq.tests.integration.jms.client;
+
+import javax.jms.ConnectionFactory;
+import javax.jms.Message;
+
+import org.hornetq.api.core.TransportConfiguration;
+import org.hornetq.api.jms.HornetQJMSClient;
+import org.hornetq.core.remoting.impl.netty.NettyConnectorFactory;
+import org.hornetq.jms.client.HornetQJMSConnectionFactory;
+
+/**
+ * A GroupIDTest
+ *
+ * @author Tim Fox
+ *
+ *
+ */
+public class GroupIDTest extends GroupingTest
+{
+
+   @Override
+   protected ConnectionFactory getCF() throws Exception
+   {
+      HornetQJMSConnectionFactory cf = HornetQJMSClient.createConnectionFactory(new TransportConfiguration(NettyConnectorFactory.class.getName()));
+      
+      cf.setGroupID("wibble");
+      
+      return cf;
+   }
+   
+
+   @Override
+   protected void setProperty(Message message)
+   {
+   }
+}

Copied: branches/hornetq-416/tests/src/org/hornetq/tests/integration/jms/client/GroupingTest.java (from rev 9781, trunk/tests/src/org/hornetq/tests/integration/jms/client/GroupingTest.java)
===================================================================
--- branches/hornetq-416/tests/src/org/hornetq/tests/integration/jms/client/GroupingTest.java	                        (rev 0)
+++ branches/hornetq-416/tests/src/org/hornetq/tests/integration/jms/client/GroupingTest.java	2010-10-13 07:38:20 UTC (rev 9782)
@@ -0,0 +1,126 @@
+/*
+ * Copyright 2010 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.hornetq.tests.integration.jms.client;
+
+import javax.jms.Connection;
+import javax.jms.ConnectionFactory;
+import javax.jms.Message;
+import javax.jms.MessageConsumer;
+import javax.jms.MessageProducer;
+import javax.jms.Queue;
+import javax.jms.Session;
+import javax.jms.TextMessage;
+
+import org.hornetq.api.core.SimpleString;
+import org.hornetq.core.logging.Logger;
+import org.hornetq.core.message.impl.MessageImpl;
+import org.hornetq.jms.client.HornetQMessage;
+import org.hornetq.tests.util.JMSTestBase;
+
+/**
+ * GroupingTest
+ *
+ * @author Tim Fox
+ *
+ */
+public class GroupingTest extends JMSTestBase
+{
+   private static final Logger log = Logger.getLogger(GroupingTest.class);
+
+   private Queue queue;
+
+   protected void setUp() throws Exception
+   {
+      super.setUp();
+      
+      queue = createQueue("TestQueue");
+   }
+   
+   protected void tearDown() throws Exception
+   {
+      jmsServer.destroyQueue("TestQueue");
+      
+      super.tearDown();
+   }
+   
+   protected void setProperty(Message message)
+   {
+      ((HornetQMessage)message).getCoreMessage().putStringProperty(MessageImpl.HDR_GROUP_ID, new SimpleString("foo"));
+   }
+   
+   protected ConnectionFactory getCF() throws Exception
+   {
+      return cf;
+   }
+   
+   public void testGrouping() throws Exception
+   {
+      ConnectionFactory fact = getCF();
+      
+      Connection connection = fact.createConnection();
+      
+      Session session = connection.createSession(false, Session.CLIENT_ACKNOWLEDGE);
+
+      MessageProducer producer = session.createProducer(queue);
+      
+      MessageConsumer consumer1 = session.createConsumer(queue);
+      MessageConsumer consumer2 = session.createConsumer(queue);
+      MessageConsumer consumer3 = session.createConsumer(queue);
+      
+      connection.start();
+      
+      String jmsxgroupID = null;
+
+      for (int j = 0; j < 100; j++)
+      {
+         TextMessage message = session.createTextMessage();
+                  
+         message.setText("Message" + j);
+         
+         setProperty(message);
+         
+         producer.send(message);
+         
+         String prop = message.getStringProperty("JMSXGroupID");
+         
+         assertNotNull(prop);
+         
+         if (jmsxgroupID != null)
+         {
+            assertEquals(jmsxgroupID, prop);
+         }
+         else
+         {
+            jmsxgroupID = prop;
+         }
+      }
+
+      //All msgs should go to the first consumer
+      for (int j = 0; j < 100; j++)
+      {        
+         TextMessage tm = (TextMessage)consumer1.receive(10000);
+         
+         assertNotNull(tm);
+         
+         assertEquals("Message" + j, tm.getText());
+         
+         assertEquals(tm.getStringProperty("JMSXGroupID"), jmsxgroupID);
+      }
+      
+      connection.close();
+      
+      
+   }
+
+}

Modified: branches/hornetq-416/tests/src/org/hornetq/tests/integration/jms/client/PreACKJMSTest.java
===================================================================
--- branches/hornetq-416/tests/src/org/hornetq/tests/integration/jms/client/PreACKJMSTest.java	2010-10-13 00:11:20 UTC (rev 9781)
+++ branches/hornetq-416/tests/src/org/hornetq/tests/integration/jms/client/PreACKJMSTest.java	2010-10-13 07:38:20 UTC (rev 9782)
@@ -27,6 +27,7 @@
 import org.hornetq.api.core.Pair;
 import org.hornetq.api.core.TransportConfiguration;
 import org.hornetq.api.core.client.HornetQClient;
+import org.hornetq.jms.server.impl.JMSFactoryType;
 import org.hornetq.tests.util.JMSTestBase;
 
 /**
@@ -229,6 +230,7 @@
                                         HornetQClient.DEFAULT_FAILOVER_ON_INITIAL_CONNECTION,
                                         failoverOnServerShutdown,
                                         null,
+                                        JMSFactoryType.CF,
                                         jndiBindings);
    }
 

Modified: branches/hornetq-416/tests/src/org/hornetq/tests/integration/jms/client/ReSendMessageTest.java
===================================================================
--- branches/hornetq-416/tests/src/org/hornetq/tests/integration/jms/client/ReSendMessageTest.java	2010-10-13 00:11:20 UTC (rev 9781)
+++ branches/hornetq-416/tests/src/org/hornetq/tests/integration/jms/client/ReSendMessageTest.java	2010-10-13 07:38:20 UTC (rev 9782)
@@ -34,6 +34,7 @@
 import org.hornetq.api.core.TransportConfiguration;
 import org.hornetq.api.core.client.HornetQClient;
 import org.hornetq.api.jms.HornetQJMSConstants;
+import org.hornetq.jms.server.impl.JMSFactoryType;
 import org.hornetq.tests.util.JMSTestBase;
 import org.hornetq.tests.util.UnitTestCase;
 
@@ -328,6 +329,7 @@
                                         HornetQClient.DEFAULT_FAILOVER_ON_INITIAL_CONNECTION,
                                         failoverOnServerShutdown,
                                         null,
+                                        JMSFactoryType.CF,
                                         jndiBindings);
    }
 

Modified: branches/hornetq-416/tests/src/org/hornetq/tests/integration/jms/client/ReceiveNoWaitTest.java
===================================================================
--- branches/hornetq-416/tests/src/org/hornetq/tests/integration/jms/client/ReceiveNoWaitTest.java	2010-10-13 00:11:20 UTC (rev 9781)
+++ branches/hornetq-416/tests/src/org/hornetq/tests/integration/jms/client/ReceiveNoWaitTest.java	2010-10-13 07:38:20 UTC (rev 9782)
@@ -15,7 +15,6 @@
 
 import javax.jms.Connection;
 import javax.jms.DeliveryMode;
-import javax.jms.Message;
 import javax.jms.MessageConsumer;
 import javax.jms.MessageProducer;
 import javax.jms.Queue;
@@ -29,7 +28,7 @@
  * 
  * A ReceiveNoWaitTest
  *
- * @author tim
+ * @author Tim Fox
  *
  *
  */
@@ -65,8 +64,6 @@
 
       for (int i = 0; i < 10; i++)
       {
-         log.info("Iteration " + i);
-         
          Connection connection = cf.createConnection();
                           
          Session session = connection.createSession(false, Session.CLIENT_ACKNOWLEDGE);

Modified: branches/hornetq-416/tests/src/org/hornetq/tests/integration/jms/client/SessionClosedOnRemotingConnectionFailureTest.java
===================================================================
--- branches/hornetq-416/tests/src/org/hornetq/tests/integration/jms/client/SessionClosedOnRemotingConnectionFailureTest.java	2010-10-13 00:11:20 UTC (rev 9781)
+++ branches/hornetq-416/tests/src/org/hornetq/tests/integration/jms/client/SessionClosedOnRemotingConnectionFailureTest.java	2010-10-13 07:38:20 UTC (rev 9782)
@@ -34,6 +34,7 @@
 import org.hornetq.core.logging.Logger;
 import org.hornetq.core.remoting.impl.netty.NettyConnectorFactory;
 import org.hornetq.jms.client.HornetQSession;
+import org.hornetq.jms.server.impl.JMSFactoryType;
 import org.hornetq.spi.core.protocol.RemotingConnection;
 import org.hornetq.tests.util.JMSTestBase;
 
@@ -97,6 +98,7 @@
                                         HornetQClient.DEFAULT_FAILOVER_ON_INITIAL_CONNECTION,
                                         false,
                                         null,
+                                        JMSFactoryType.CF,
                                         "/cffoo");
 
       cf = (ConnectionFactory)context.lookup("/cffoo");

Modified: branches/hornetq-416/tests/src/org/hornetq/tests/integration/jms/client/TextMessageTest.java
===================================================================
--- branches/hornetq-416/tests/src/org/hornetq/tests/integration/jms/client/TextMessageTest.java	2010-10-13 00:11:20 UTC (rev 9781)
+++ branches/hornetq-416/tests/src/org/hornetq/tests/integration/jms/client/TextMessageTest.java	2010-10-13 07:38:20 UTC (rev 9782)
@@ -27,6 +27,7 @@
 import org.hornetq.api.core.Pair;
 import org.hornetq.api.core.TransportConfiguration;
 import org.hornetq.api.core.client.HornetQClient;
+import org.hornetq.jms.server.impl.JMSFactoryType;
 import org.hornetq.tests.util.JMSTestBase;
 import org.hornetq.tests.util.RandomUtil;
 
@@ -264,6 +265,7 @@
                                         HornetQClient.DEFAULT_FAILOVER_ON_INITIAL_CONNECTION,
                                         failoverOnServerShutdown,
                                         null,
+                                        JMSFactoryType.CF,
                                         jndiBindings);
    }
 

Modified: branches/hornetq-416/tests/src/org/hornetq/tests/integration/jms/cluster/JMSFailoverTest.java
===================================================================
--- branches/hornetq-416/tests/src/org/hornetq/tests/integration/jms/cluster/JMSFailoverTest.java	2010-10-13 00:11:20 UTC (rev 9781)
+++ branches/hornetq-416/tests/src/org/hornetq/tests/integration/jms/cluster/JMSFailoverTest.java	2010-10-13 07:38:20 UTC (rev 9782)
@@ -47,6 +47,7 @@
 import org.hornetq.jms.client.HornetQDestination;
 import org.hornetq.jms.client.HornetQSession;
 import org.hornetq.jms.server.JMSServerManager;
+import org.hornetq.jms.server.impl.JMSFactoryType;
 import org.hornetq.jms.server.impl.JMSServerManagerImpl;
 import org.hornetq.spi.core.protocol.RemotingConnection;
 import org.hornetq.tests.unit.util.InVMContext;
@@ -159,7 +160,7 @@
    {
       HornetQConnectionFactory jbcf = (HornetQConnectionFactory) HornetQJMSClient.createConnectionFactory(new TransportConfiguration("org.hornetq.core.remoting.impl.invm.InVMConnectorFactory"),
                                                                    new TransportConfiguration("org.hornetq.core.remoting.impl.invm.InVMConnectorFactory",
-                                                                                              backupParams));
+                                                                                              backupParams), JMSFactoryType.CF);
 
       jbcf.setBlockOnDurableSend(true);
       jbcf.setBlockOnNonDurableSend(true);

Copied: branches/hornetq-416/tests/src/org/hornetq/tests/integration/jms/connection/ConcurrentSessionCloseTest.java (from rev 9781, trunk/tests/src/org/hornetq/tests/integration/jms/connection/ConcurrentSessionCloseTest.java)
===================================================================
--- branches/hornetq-416/tests/src/org/hornetq/tests/integration/jms/connection/ConcurrentSessionCloseTest.java	                        (rev 0)
+++ branches/hornetq-416/tests/src/org/hornetq/tests/integration/jms/connection/ConcurrentSessionCloseTest.java	2010-10-13 07:38:20 UTC (rev 9782)
@@ -0,0 +1,110 @@
+/*
+ * 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.hornetq.tests.integration.jms.connection;
+
+import java.util.Random;
+import java.util.concurrent.atomic.AtomicBoolean;
+
+import javax.jms.Connection;
+import javax.jms.Session;
+
+import org.hornetq.api.core.TransportConfiguration;
+import org.hornetq.api.jms.HornetQJMSClient;
+import org.hornetq.core.logging.Logger;
+import org.hornetq.jms.client.HornetQConnectionFactory;
+import org.hornetq.tests.util.JMSTestBase;
+
+/**
+ * 
+ * A ConcurrentSessionCloseTest
+ *
+ * @author <a href="mailto:tim.fox at jboss.com">Tim Fox</a>
+ *
+ *
+ */
+public class ConcurrentSessionCloseTest extends JMSTestBase
+{
+   private static final Logger log = Logger.getLogger(ConcurrentSessionCloseTest.class);
+
+   private HornetQConnectionFactory cf;
+
+   @Override
+   protected void setUp() throws Exception
+   {
+      super.setUp();
+
+      cf = HornetQJMSClient.createConnectionFactory(new TransportConfiguration("org.hornetq.core.remoting.impl.invm.InVMConnectorFactory"));
+
+   }
+
+   @Override
+   protected void tearDown() throws Exception
+   {
+      cf = null;
+
+      super.tearDown();
+   }
+
+   // https://jira.jboss.org/browse/HORNETQ-525
+   public void testConcurrentClose() throws Exception
+   {
+      final Connection con = cf.createConnection();
+
+      for (int j = 0; j < 100; j++)
+      {
+         final AtomicBoolean failed = new AtomicBoolean(false);
+
+         int threadCount = 10;
+
+         ThreadGroup group = new ThreadGroup("Test");
+
+         Thread[] threads = new Thread[threadCount];
+
+         for (int i = 0; i < threadCount; i++)
+         {
+            threads[i] = new Thread(group, "thread " + i)
+            {
+               public void run()
+               {
+                  try
+                  {
+                     con.start();
+                     
+                     Session session = con.createSession(false, Session.AUTO_ACKNOWLEDGE);
+
+                     session.close();
+                  }
+                  catch (Exception e)
+                  {
+                     e.printStackTrace();
+
+                     failed.set(true);
+                  }
+
+               };
+            };
+            threads[i].start();
+         }
+
+         for (int i = 0; i < threadCount; i++)
+         {
+            threads[i].join();
+         }
+
+         assertFalse(failed.get());
+      }
+
+      jmsServer.stop();
+   }
+
+}

Modified: branches/hornetq-416/tests/src/org/hornetq/tests/integration/jms/divert/DivertAndACKClientTest.java
===================================================================
--- branches/hornetq-416/tests/src/org/hornetq/tests/integration/jms/divert/DivertAndACKClientTest.java	2010-10-13 00:11:20 UTC (rev 9781)
+++ branches/hornetq-416/tests/src/org/hornetq/tests/integration/jms/divert/DivertAndACKClientTest.java	2010-10-13 07:38:20 UTC (rev 9782)
@@ -30,6 +30,7 @@
 import org.hornetq.api.core.client.HornetQClient;
 import org.hornetq.core.config.Configuration;
 import org.hornetq.core.config.DivertConfiguration;
+import org.hornetq.jms.server.impl.JMSFactoryType;
 import org.hornetq.tests.util.JMSTestBase;
 
 /**
@@ -175,6 +176,7 @@
                                         HornetQClient.DEFAULT_FAILOVER_ON_INITIAL_CONNECTION,
                                         failoverOnServerShutdown,
                                         null,
+                                        JMSFactoryType.CF,
                                         jndiBindings);
    }
 

Modified: branches/hornetq-416/tests/src/org/hornetq/tests/integration/jms/server/management/JMSUtil.java
===================================================================
--- branches/hornetq-416/tests/src/org/hornetq/tests/integration/jms/server/management/JMSUtil.java	2010-10-13 00:11:20 UTC (rev 9781)
+++ branches/hornetq-416/tests/src/org/hornetq/tests/integration/jms/server/management/JMSUtil.java	2010-10-13 07:38:20 UTC (rev 9782)
@@ -28,6 +28,7 @@
 
 import org.hornetq.api.core.TransportConfiguration;
 import org.hornetq.jms.client.HornetQConnectionFactory;
+import org.hornetq.jms.client.HornetQJMSConnectionFactory;
 import org.hornetq.api.jms.HornetQJMSClient;
 import org.hornetq.core.remoting.impl.invm.InVMConnectorFactory;
 import org.hornetq.tests.util.RandomUtil;
@@ -65,7 +66,7 @@
                                                  final long connectionTTL,
                                                  final long clientFailureCheckPeriod) throws JMSException
    {
-      HornetQConnectionFactory cf = (HornetQConnectionFactory) HornetQJMSClient.createConnectionFactory(new TransportConfiguration(connectorFactory));
+      HornetQJMSConnectionFactory cf = (HornetQJMSConnectionFactory) HornetQJMSClient.createConnectionFactory(new TransportConfiguration(connectorFactory));
 
       cf.setBlockOnNonDurableSend(true);
       cf.setBlockOnDurableSend(true);
@@ -113,7 +114,7 @@
 
    public static String[] sendMessages(final Destination destination, final int messagesToSend) throws Exception
    {
-      HornetQConnectionFactory cf = (HornetQConnectionFactory) HornetQJMSClient.createConnectionFactory(new TransportConfiguration(InVMConnectorFactory.class.getName()));
+      HornetQJMSConnectionFactory cf = (HornetQJMSConnectionFactory) HornetQJMSClient.createConnectionFactory(new TransportConfiguration(InVMConnectorFactory.class.getName()));
       return JMSUtil.sendMessages(cf, destination, messagesToSend);
    }
 

Modified: branches/hornetq-416/tests/src/org/hornetq/tests/integration/persistence/DeleteMessagesOnStartupTest.java
===================================================================
--- branches/hornetq-416/tests/src/org/hornetq/tests/integration/persistence/DeleteMessagesOnStartupTest.java	2010-10-13 00:11:20 UTC (rev 9781)
+++ branches/hornetq-416/tests/src/org/hornetq/tests/integration/persistence/DeleteMessagesOnStartupTest.java	2010-10-13 07:38:20 UTC (rev 9782)
@@ -15,10 +15,8 @@
 
 import java.util.ArrayList;
 import java.util.HashMap;
-import java.util.Map;
 
-import com.arjuna.ats.internal.arjuna.template.HashList;
-
+import org.hornetq.api.core.SimpleString;
 import org.hornetq.core.config.Configuration;
 import org.hornetq.core.persistence.GroupingInfo;
 import org.hornetq.core.persistence.QueueBindingInfo;
@@ -26,8 +24,8 @@
 import org.hornetq.core.server.Queue;
 import org.hornetq.core.server.ServerMessage;
 import org.hornetq.core.server.impl.ServerMessageImpl;
+import org.hornetq.tests.unit.core.postoffice.impl.FakeQueue;
 import org.hornetq.tests.unit.core.server.impl.fakes.FakePostOffice;
-import org.hornetq.tests.util.ServiceTestBase;
 
 /**
  * A DeleteMessagesOnStartupTest
@@ -56,9 +54,13 @@
    public void testDeleteMessagesOnStartup() throws Exception
    {
       createStorage();
-
+      
+      Queue theQueue = new FakeQueue(new SimpleString(""));
+      HashMap<Long, Queue> queues = new HashMap<Long, Queue>();
+      queues.put(100l, theQueue);
+      
       ServerMessage msg = new ServerMessageImpl(1, 100);
-
+      
       journal.storeMessage(msg);
 
       for (int i = 2; i < 100; i++)
@@ -66,18 +68,16 @@
          journal.storeMessage(new ServerMessageImpl(i, 100));
       }
       
-      journal.storeReference(1, 1, true);
+      journal.storeReference(100, 1, true);
 
       journal.stop();
 
       journal.start();
 
-      Map<Long, Queue> queues = new HashMap<Long, Queue>();
-
+      journal.loadBindingJournal(new ArrayList<QueueBindingInfo>(), new ArrayList<GroupingInfo>());
+      
       journal.loadMessageJournal(new FakePostOffice(), null, null, queues, null);
 
-      journal.loadBindingJournal(new ArrayList<QueueBindingInfo>(), new ArrayList<GroupingInfo>());
-      
       assertEquals(98, deletedMessage.size());
       
       for (Long messageID : deletedMessage)
@@ -107,5 +107,6 @@
    // Private -------------------------------------------------------
 
    // Inner classes -------------------------------------------------
+   
 
 }

Modified: branches/hornetq-416/tests/src/org/hornetq/tests/integration/spring/SpringIntegrationTest.java
===================================================================
--- branches/hornetq-416/tests/src/org/hornetq/tests/integration/spring/SpringIntegrationTest.java	2010-10-13 00:11:20 UTC (rev 9781)
+++ branches/hornetq-416/tests/src/org/hornetq/tests/integration/spring/SpringIntegrationTest.java	2010-10-13 07:38:20 UTC (rev 9782)
@@ -1,7 +1,9 @@
 package org.hornetq.tests.integration.spring;
 
 import junit.framework.Assert;
-import junit.framework.TestCase;
+
+import org.hornetq.jms.server.embedded.EmbeddedJMS;
+import org.hornetq.tests.util.UnitTestCase;
 import org.springframework.context.ApplicationContext;
 import org.springframework.context.support.ClassPathXmlApplicationContext;
 
@@ -9,7 +11,7 @@
  * @author <a href="mailto:bill at burkecentral.com">Bill Burke</a>
  * @version $Revision: 1 $
  */
-public class SpringIntegrationTest extends TestCase
+public class SpringIntegrationTest extends UnitTestCase
 {
    public void testSpring() throws Exception
    {
@@ -20,5 +22,9 @@
       sender.send("Hello world");
       Thread.sleep(100);
       Assert.assertEquals(ExampleListener.lastMessage, "Hello world");
+      
+      EmbeddedJMS jms = (EmbeddedJMS) context.getBean("EmbeddedJms");
+      jms.stop();
+      
    }
 }

Copied: branches/hornetq-416/tests/src/org/hornetq/tests/integration/stomp/StompConnectionCleanupTest.java (from rev 9781, trunk/tests/src/org/hornetq/tests/integration/stomp/StompConnectionCleanupTest.java)
===================================================================
--- branches/hornetq-416/tests/src/org/hornetq/tests/integration/stomp/StompConnectionCleanupTest.java	                        (rev 0)
+++ branches/hornetq-416/tests/src/org/hornetq/tests/integration/stomp/StompConnectionCleanupTest.java	2010-10-13 07:38:20 UTC (rev 9782)
@@ -0,0 +1,128 @@
+/*
+ * Copyright 2010 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.hornetq.tests.integration.stomp;
+
+import javax.jms.Message;
+import javax.jms.MessageConsumer;
+
+import junit.framework.Assert;
+
+import org.hornetq.core.protocol.stomp.Stomp;
+import org.hornetq.jms.server.JMSServerManager;
+
+/**
+ * A StompConnectionCleanupTest
+ *
+ * @author Tim Fox
+ *
+ *
+ */
+public class StompConnectionCleanupTest extends StompTestBase
+{
+   private static final long CONNECTION_TTL = 2000;
+
+   public void testConnectionCleanup() throws Exception
+   {
+      String frame = "CONNECT\n" + "login: brianm\n" + "passcode: wombats\n\n" + Stomp.NULL;
+      sendFrame(frame);
+      frame = receiveFrame(10000);
+      
+      //We send and consumer a message to ensure a STOMP connection and server session is created
+
+      Assert.assertTrue(frame.startsWith("CONNECTED"));
+
+      frame = "SUBSCRIBE\n" + "destination:" + getQueuePrefix() + getQueueName() + "\n" + "ack:auto\n\n" + Stomp.NULL;
+      sendFrame(frame);
+
+      frame = "SEND\n" + "destination:" + getQueuePrefix() + getQueueName() + "\n\n" + "Hello World" + Stomp.NULL;
+      sendFrame(frame);
+
+      frame = receiveFrame(10000);
+      Assert.assertTrue(frame.startsWith("MESSAGE"));
+      Assert.assertTrue(frame.indexOf("destination:") > 0);
+    
+      // Now we wait until the connection is cleared on the server, which will happen some time after ttl, since no data
+      // is being sent
+
+      long start = System.currentTimeMillis();
+
+      while (true)
+      {
+         int connCount = server.getHornetQServer().getRemotingService().getConnections().size();
+
+         int sessionCount = server.getHornetQServer().getSessions().size();
+         
+         // All connections and sessions should be timed out including STOMP + JMS connection
+
+         if (connCount == 0 && sessionCount == 0)
+         {
+            break;
+         }
+         
+         Thread.sleep(10);
+
+         if (System.currentTimeMillis() - start > 10000)
+         {
+            fail("Timed out waiting for connection to be cleared up");
+         }
+      }      
+   }
+   
+   public void testConnectionNotCleanedUp() throws Exception
+   {
+      String frame = "CONNECT\n" + "login: brianm\n" + "passcode: wombats\n\n" + Stomp.NULL;
+      sendFrame(frame);
+      frame = receiveFrame(10000);
+      
+      //We send and consumer a message to ensure a STOMP connection and server session is created
+
+      Assert.assertTrue(frame.startsWith("CONNECTED"));
+
+      MessageConsumer consumer = session.createConsumer(queue);
+      
+      long time = CONNECTION_TTL * 3;
+      
+      long start = System.currentTimeMillis();
+      
+      //Send msgs for an amount of time > connection_ttl make sure connection is not closed
+      while (true)
+      {
+         //Send and receive a msg
+         
+         frame = "SEND\n" + "destination:" + getQueuePrefix() + getQueueName() + "\n\n" + "Hello World" + Stomp.NULL;
+         sendFrame(frame);
+
+         Message msg = consumer.receive(1000);
+         assertNotNull(msg);
+                
+         Thread.sleep(100);
+         
+         if (System.currentTimeMillis() - start > time)
+         {
+            break;
+         }
+      }
+    
+   }
+   
+   @Override
+   protected JMSServerManager createServer() throws Exception
+   {
+      JMSServerManager s = super.createServer();
+      
+      s.getHornetQServer().getConfiguration().setConnectionTTLOverride(CONNECTION_TTL);
+      
+      return s;
+   }
+}

Modified: branches/hornetq-416/tests/src/org/hornetq/tests/integration/stomp/StompTest.java
===================================================================
--- branches/hornetq-416/tests/src/org/hornetq/tests/integration/stomp/StompTest.java	2010-10-13 00:11:20 UTC (rev 9781)
+++ branches/hornetq-416/tests/src/org/hornetq/tests/integration/stomp/StompTest.java	2010-10-13 07:38:20 UTC (rev 9782)
@@ -19,78 +19,30 @@
 
 import java.io.ByteArrayOutputStream;
 import java.io.IOException;
-import java.io.InputStream;
-import java.io.OutputStream;
-import java.net.Socket;
 import java.net.SocketTimeoutException;
-import java.util.HashMap;
-import java.util.Map;
 import java.util.concurrent.CountDownLatch;
 import java.util.concurrent.TimeUnit;
 import java.util.regex.Matcher;
 import java.util.regex.Pattern;
 
 import javax.jms.BytesMessage;
-import javax.jms.Connection;
-import javax.jms.ConnectionFactory;
 import javax.jms.DeliveryMode;
-import javax.jms.Destination;
 import javax.jms.Message;
 import javax.jms.MessageConsumer;
 import javax.jms.MessageListener;
 import javax.jms.MessageProducer;
-import javax.jms.Queue;
-import javax.jms.Session;
 import javax.jms.TextMessage;
-import javax.jms.Topic;
 
 import junit.framework.Assert;
 
-import org.hornetq.api.core.TransportConfiguration;
-import org.hornetq.core.config.Configuration;
-import org.hornetq.core.config.impl.ConfigurationImpl;
 import org.hornetq.core.logging.Logger;
 import org.hornetq.core.protocol.stomp.Stomp;
-import org.hornetq.core.remoting.impl.invm.InVMAcceptorFactory;
-import org.hornetq.core.remoting.impl.invm.InVMConnectorFactory;
-import org.hornetq.core.remoting.impl.netty.NettyAcceptorFactory;
-import org.hornetq.core.remoting.impl.netty.TransportConstants;
-import org.hornetq.core.server.HornetQServer;
-import org.hornetq.core.server.HornetQServers;
-import org.hornetq.jms.client.HornetQConnectionFactory;
-import org.hornetq.jms.server.JMSServerManager;
-import org.hornetq.jms.server.config.JMSConfiguration;
-import org.hornetq.jms.server.config.impl.JMSConfigurationImpl;
-import org.hornetq.jms.server.config.impl.JMSQueueConfigurationImpl;
-import org.hornetq.jms.server.config.impl.TopicConfigurationImpl;
-import org.hornetq.jms.server.impl.JMSServerManagerImpl;
-import org.hornetq.spi.core.protocol.ProtocolType;
-import org.hornetq.tests.unit.util.InVMContext;
-import org.hornetq.tests.util.UnitTestCase;
 
-public class StompTest extends UnitTestCase
+public class StompTest extends StompTestBase
 {
    private static final transient Logger log = Logger.getLogger(StompTest.class);
 
-   private int port = 61613;
-
-   private Socket stompSocket;
-
-   private ByteArrayOutputStream inputBuffer;
-
-   private ConnectionFactory connectionFactory;
-
-   private Connection connection;
-
-   private Session session;
-
-   private Queue queue;
-
-   private Topic topic;
-
-   private JMSServerManager server;
-   
-   public void _testSendManyMessages() throws Exception
+   public void testSendManyMessages() throws Exception
    {
       MessageConsumer consumer = session.createConsumer(queue);
 
@@ -106,7 +58,7 @@
 
          public void onMessage(Message arg0)
          {
-            System.out.println("<<< " + (1000 - latch.getCount()));
+            // System.out.println("<<< " + (1000 - latch.getCount()));
             latch.countDown();
          }
       });
@@ -115,12 +67,11 @@
       for (int i = 1; i <= count; i++)
       {
          // Thread.sleep(1);
-         System.out.println(">>> " + i);
+         // System.out.println(">>> " + i);
          sendFrame(frame);
       }
 
       assertTrue(latch.await(60, TimeUnit.SECONDS));
-
    }
 
    public void testConnect() throws Exception
@@ -185,14 +136,14 @@
       frame = receiveFrame(10000);
       Assert.assertTrue(frame.startsWith("CONNECTED"));
 
-      frame = "\nSEND\n" + "destination:" + getQueuePrefix() + getQueueName() + "\n\n" + "Hello World" + Stomp.NULL;
+      frame = "SEND\n" + "destination:" + getQueuePrefix() + getQueueName() + "\n\n" + "Hello World" + Stomp.NULL;
 
       sendFrame(frame);
 
       TextMessage message = (TextMessage)consumer.receive(1000);
       Assert.assertNotNull(message);
       Assert.assertEquals("Hello World", message.getText());
-      
+
       // Make sure that the timestamp is valid - should
       // be very close to the current time.
       long tnow = System.currentTimeMillis();
@@ -200,6 +151,43 @@
       Assert.assertTrue(Math.abs(tnow - tmsg) < 1000);
    }
 
+   /*
+    * Some STOMP clients erroneously put a new line \n *after* the terminating NUL char at the end of the frame
+    * This means next frame read might have a \n a the beginning.
+    * This is contrary to STOMP spec but we deal with it so we can work nicely with crappy STOMP clients
+    */
+   public void testSendMessageWithLeadingNewLine() throws Exception
+   {
+
+      MessageConsumer consumer = session.createConsumer(queue);
+
+      String frame = "CONNECT\n" + "login: brianm\n" + "passcode: wombats\n\n" + Stomp.NULL + "\n";
+      sendFrame(frame);
+
+      frame = receiveFrame(10000);
+      Assert.assertTrue(frame.startsWith("CONNECTED"));
+
+      frame = "SEND\n" + "destination:" +
+              getQueuePrefix() +
+              getQueueName() +
+              "\n\n" +
+              "Hello World" +
+              Stomp.NULL +
+              "\n";
+
+      sendFrame(frame);
+
+      TextMessage message = (TextMessage)consumer.receive(1000);
+      Assert.assertNotNull(message);
+      Assert.assertEquals("Hello World", message.getText());
+
+      // Make sure that the timestamp is valid - should
+      // be very close to the current time.
+      long tnow = System.currentTimeMillis();
+      long tmsg = message.getJMSTimestamp();
+      Assert.assertTrue(Math.abs(tnow - tmsg) < 1000);
+   }
+
    public void testSendMessageWithReceipt() throws Exception
    {
 
@@ -228,7 +216,7 @@
       TextMessage message = (TextMessage)consumer.receive(1000);
       Assert.assertNotNull(message);
       Assert.assertEquals("Hello World", message.getText());
-      
+
       // Make sure that the timestamp is valid - should
       // be very close to the current time.
       long tnow = System.currentTimeMillis();
@@ -1249,210 +1237,4 @@
       frame = "DISCONNECT\n" + "\n\n" + Stomp.NULL;
       sendFrame(frame);
    }
-
-   // Implementation methods
-   // -------------------------------------------------------------------------
-   protected void setUp() throws Exception
-   {
-      super.setUp();
-
-      server = createServer();
-      server.start();
-      connectionFactory = createConnectionFactory();
-
-      stompSocket = createSocket();
-      inputBuffer = new ByteArrayOutputStream();
-
-      connection = connectionFactory.createConnection();
-      session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE);
-      queue = session.createQueue(getQueueName());
-      topic = session.createTopic(getTopicName());
-      connection.start();
-   }
-
-   /**
-   * @return
-   * @throws Exception 
-   */
-   private JMSServerManager createServer() throws Exception
-   {
-      Configuration config = new ConfigurationImpl();
-      config.setSecurityEnabled(false);
-      config.setPersistenceEnabled(false);
-
-      Map<String, Object> params = new HashMap<String, Object>();
-      params.put(TransportConstants.PROTOCOL_PROP_NAME, ProtocolType.STOMP.toString());
-      params.put(TransportConstants.PORT_PROP_NAME, TransportConstants.DEFAULT_STOMP_PORT);
-      TransportConfiguration stompTransport = new TransportConfiguration(NettyAcceptorFactory.class.getName(), params);
-      config.getAcceptorConfigurations().add(stompTransport);
-      config.getAcceptorConfigurations().add(new TransportConfiguration(InVMAcceptorFactory.class.getName()));
-      HornetQServer hornetQServer = HornetQServers.newHornetQServer(config);
-
-      JMSConfiguration jmsConfig = new JMSConfigurationImpl();
-      jmsConfig.getQueueConfigurations()
-               .add(new JMSQueueConfigurationImpl(getQueueName(), null, false, getQueueName()));
-      jmsConfig.getTopicConfigurations().add(new TopicConfigurationImpl(getTopicName(), getTopicName()));
-      server = new JMSServerManagerImpl(hornetQServer, jmsConfig);
-      server.setContext(new InVMContext());
-      return server;
-   }
-
-   protected void tearDown() throws Exception
-   {
-      connection.close();
-      if (stompSocket != null)
-      {
-         stompSocket.close();
-      }
-      server.stop();
-
-      super.tearDown();
-   }
-
-   protected void reconnect() throws Exception
-   {
-      reconnect(0);
-   }
-
-   protected void reconnect(long sleep) throws Exception
-   {
-      stompSocket.close();
-
-      if (sleep > 0)
-      {
-         Thread.sleep(sleep);
-      }
-
-      stompSocket = createSocket();
-      inputBuffer = new ByteArrayOutputStream();
-   }
-
-   protected ConnectionFactory createConnectionFactory()
-   {
-      return new HornetQConnectionFactory(new TransportConfiguration(InVMConnectorFactory.class.getName()));
-   }
-
-   protected Socket createSocket() throws IOException
-   {
-      return new Socket("127.0.0.1", port);
-   }
-
-   protected String getQueueName()
-   {
-      return "test";
-   }
-
-   protected String getQueuePrefix()
-   {
-      return "jms.queue.";
-   }
-
-   protected String getTopicName()
-   {
-      return "testtopic";
-   }
-
-   protected String getTopicPrefix()
-   {
-      return "jms.topic.";
-   }
-
-   public void sendFrame(String data) throws Exception
-   {
-      byte[] bytes = data.getBytes("UTF-8");
-      OutputStream outputStream = stompSocket.getOutputStream();
-      for (int i = 0; i < bytes.length; i++)
-      {
-         outputStream.write(bytes[i]);
-      }
-      outputStream.flush();
-   }
-
-   public void sendFrame(byte[] data) throws Exception
-   {
-      OutputStream outputStream = stompSocket.getOutputStream();
-      for (int i = 0; i < data.length; i++)
-      {
-         outputStream.write(data[i]);
-      }
-      outputStream.flush();
-   }
-
-   public String receiveFrame(long timeOut) throws Exception
-   {
-      stompSocket.setSoTimeout((int)timeOut);
-      InputStream is = stompSocket.getInputStream();
-      int c = 0;
-      for (;;)
-      {
-         c = is.read();
-         if (c < 0)
-         {
-            throw new IOException("socket closed.");
-         }
-         else if (c == 0)
-         {
-            c = is.read();
-            if (c != '\n')
-            {
-               byte[] ba = inputBuffer.toByteArray();
-               System.out.println(new String(ba, "UTF-8"));
-            }
-            Assert.assertEquals("Expecting stomp frame to terminate with \0\n", c, '\n');
-            byte[] ba = inputBuffer.toByteArray();
-            inputBuffer.reset();
-            return new String(ba, "UTF-8");
-         }
-         else
-         {
-            inputBuffer.write(c);
-         }
-      }
-   }
-
-   public void sendMessage(String msg) throws Exception
-   {
-      sendMessage(msg, queue);
-   }
-
-   public void sendMessage(String msg, Destination destination) throws Exception
-   {
-      MessageProducer producer = session.createProducer(destination);
-      TextMessage message = session.createTextMessage(msg);
-      producer.send(message);
-   }
-
-   public void sendMessage(byte[] data, Destination destination) throws Exception
-   {
-      sendMessage(data, "foo", "xyz", destination);
-   }
-
-   public void sendMessage(String msg, String propertyName, String propertyValue) throws Exception
-   {
-      sendMessage(msg.getBytes("UTF-8"), propertyName, propertyValue, queue);
-   }
-
-   public void sendMessage(byte[] data, String propertyName, String propertyValue, Destination destination) throws Exception
-   {
-      MessageProducer producer = session.createProducer(destination);
-      BytesMessage message = session.createBytesMessage();
-      message.setStringProperty(propertyName, propertyValue);
-      message.writeBytes(data);
-      producer.send(message);
-   }
-
-   protected void waitForReceipt() throws Exception
-   {
-      String frame = receiveFrame(50000);
-      assertNotNull(frame);
-      assertTrue(frame.indexOf("RECEIPT") > -1);
-   }
-
-   protected void waitForFrameToTakeEffect() throws InterruptedException
-   {
-      // bit of a dirty hack :)
-      // another option would be to force some kind of receipt to be returned
-      // from the frame
-      Thread.sleep(2000);
-   }
 }

Copied: branches/hornetq-416/tests/src/org/hornetq/tests/integration/stomp/StompTestBase.java (from rev 9781, trunk/tests/src/org/hornetq/tests/integration/stomp/StompTestBase.java)
===================================================================
--- branches/hornetq-416/tests/src/org/hornetq/tests/integration/stomp/StompTestBase.java	                        (rev 0)
+++ branches/hornetq-416/tests/src/org/hornetq/tests/integration/stomp/StompTestBase.java	2010-10-13 07:38:20 UTC (rev 9782)
@@ -0,0 +1,290 @@
+/**
+ *
+ * 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.
+ */
+package org.hornetq.tests.integration.stomp;
+
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.net.Socket;
+import java.util.HashMap;
+import java.util.Map;
+
+import javax.jms.BytesMessage;
+import javax.jms.Connection;
+import javax.jms.ConnectionFactory;
+import javax.jms.Destination;
+import javax.jms.MessageProducer;
+import javax.jms.Queue;
+import javax.jms.Session;
+import javax.jms.TextMessage;
+import javax.jms.Topic;
+
+import junit.framework.Assert;
+
+import org.hornetq.api.core.TransportConfiguration;
+import org.hornetq.core.config.Configuration;
+import org.hornetq.core.config.impl.ConfigurationImpl;
+import org.hornetq.core.logging.Logger;
+import org.hornetq.core.remoting.impl.invm.InVMAcceptorFactory;
+import org.hornetq.core.remoting.impl.invm.InVMConnectorFactory;
+import org.hornetq.core.remoting.impl.netty.NettyAcceptorFactory;
+import org.hornetq.core.remoting.impl.netty.TransportConstants;
+import org.hornetq.core.server.HornetQServer;
+import org.hornetq.core.server.HornetQServers;
+import org.hornetq.jms.client.HornetQJMSConnectionFactory;
+import org.hornetq.jms.server.JMSServerManager;
+import org.hornetq.jms.server.config.JMSConfiguration;
+import org.hornetq.jms.server.config.impl.JMSConfigurationImpl;
+import org.hornetq.jms.server.config.impl.JMSQueueConfigurationImpl;
+import org.hornetq.jms.server.config.impl.TopicConfigurationImpl;
+import org.hornetq.jms.server.impl.JMSServerManagerImpl;
+import org.hornetq.spi.core.protocol.ProtocolType;
+import org.hornetq.tests.unit.util.InVMContext;
+import org.hornetq.tests.util.UnitTestCase;
+
+public abstract class StompTestBase extends UnitTestCase
+{
+   private static final transient Logger log = Logger.getLogger(StompTestBase.class);
+
+   private int port = 61613;
+
+   private Socket stompSocket;
+
+   private ByteArrayOutputStream inputBuffer;
+
+   private ConnectionFactory connectionFactory;
+
+   private Connection connection;
+
+   protected Session session;
+
+   protected Queue queue;
+
+   protected Topic topic;
+
+   protected JMSServerManager server;
+   
+   
+
+   // Implementation methods
+   // -------------------------------------------------------------------------
+   protected void setUp() throws Exception
+   {
+      super.setUp();
+
+      server = createServer();
+      server.start();
+      connectionFactory = createConnectionFactory();
+
+      stompSocket = createSocket();
+      inputBuffer = new ByteArrayOutputStream();
+
+      connection = connectionFactory.createConnection();
+      session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE);
+      queue = session.createQueue(getQueueName());
+      topic = session.createTopic(getTopicName());
+      connection.start();
+   }
+
+   /**
+   * @return
+   * @throws Exception 
+   */
+   protected JMSServerManager createServer() throws Exception
+   {
+      Configuration config = new ConfigurationImpl();
+      config.setSecurityEnabled(false);
+      config.setPersistenceEnabled(false);
+
+      Map<String, Object> params = new HashMap<String, Object>();
+      params.put(TransportConstants.PROTOCOL_PROP_NAME, ProtocolType.STOMP.toString());
+      params.put(TransportConstants.PORT_PROP_NAME, TransportConstants.DEFAULT_STOMP_PORT);
+      TransportConfiguration stompTransport = new TransportConfiguration(NettyAcceptorFactory.class.getName(), params);
+      config.getAcceptorConfigurations().add(stompTransport);
+      config.getAcceptorConfigurations().add(new TransportConfiguration(InVMAcceptorFactory.class.getName()));
+      HornetQServer hornetQServer = HornetQServers.newHornetQServer(config);
+
+      JMSConfiguration jmsConfig = new JMSConfigurationImpl();
+      jmsConfig.getQueueConfigurations()
+               .add(new JMSQueueConfigurationImpl(getQueueName(), null, false, getQueueName()));
+      jmsConfig.getTopicConfigurations().add(new TopicConfigurationImpl(getTopicName(), getTopicName()));
+      server = new JMSServerManagerImpl(hornetQServer, jmsConfig);
+      server.setContext(new InVMContext());
+      return server;
+   }
+
+   protected void tearDown() throws Exception
+   {
+      connection.close();
+      if (stompSocket != null)
+      {
+         stompSocket.close();
+      }
+      server.stop();
+
+      super.tearDown();
+   }
+
+   protected void reconnect() throws Exception
+   {
+      reconnect(0);
+   }
+
+   protected void reconnect(long sleep) throws Exception
+   {
+      stompSocket.close();
+
+      if (sleep > 0)
+      {
+         Thread.sleep(sleep);
+      }
+
+      stompSocket = createSocket();
+      inputBuffer = new ByteArrayOutputStream();
+   }
+
+   protected ConnectionFactory createConnectionFactory()
+   {
+      return new HornetQJMSConnectionFactory(new TransportConfiguration(InVMConnectorFactory.class.getName()));
+   }
+
+   protected Socket createSocket() throws IOException
+   {
+      return new Socket("127.0.0.1", port);
+   }
+
+   protected String getQueueName()
+   {
+      return "test";
+   }
+
+   protected String getQueuePrefix()
+   {
+      return "jms.queue.";
+   }
+
+   protected String getTopicName()
+   {
+      return "testtopic";
+   }
+
+   protected String getTopicPrefix()
+   {
+      return "jms.topic.";
+   }
+
+   public void sendFrame(String data) throws Exception
+   {
+      byte[] bytes = data.getBytes("UTF-8");
+      OutputStream outputStream = stompSocket.getOutputStream();
+      for (int i = 0; i < bytes.length; i++)
+      {
+         outputStream.write(bytes[i]);
+      }
+      outputStream.flush();
+   }
+
+   public void sendFrame(byte[] data) throws Exception
+   {
+      OutputStream outputStream = stompSocket.getOutputStream();
+      for (int i = 0; i < data.length; i++)
+      {
+         outputStream.write(data[i]);
+      }
+      outputStream.flush();
+   }
+
+   public String receiveFrame(long timeOut) throws Exception
+   {
+      stompSocket.setSoTimeout((int)timeOut);
+      InputStream is = stompSocket.getInputStream();
+      int c = 0;
+      for (;;)
+      {
+         c = is.read();
+         if (c < 0)
+         {
+            throw new IOException("socket closed.");
+         }
+         else if (c == 0)
+         {
+            c = is.read();
+            if (c != '\n')
+            {
+               byte[] ba = inputBuffer.toByteArray();
+               System.out.println(new String(ba, "UTF-8"));
+            }
+            Assert.assertEquals("Expecting stomp frame to terminate with \0\n", c, '\n');
+            byte[] ba = inputBuffer.toByteArray();
+            inputBuffer.reset();
+            return new String(ba, "UTF-8");
+         }
+         else
+         {
+            inputBuffer.write(c);
+         }
+      }
+   }
+
+   public void sendMessage(String msg) throws Exception
+   {
+      sendMessage(msg, queue);
+   }
+
+   public void sendMessage(String msg, Destination destination) throws Exception
+   {
+      MessageProducer producer = session.createProducer(destination);
+      TextMessage message = session.createTextMessage(msg);
+      producer.send(message);
+   }
+
+   public void sendMessage(byte[] data, Destination destination) throws Exception
+   {
+      sendMessage(data, "foo", "xyz", destination);
+   }
+
+   public void sendMessage(String msg, String propertyName, String propertyValue) throws Exception
+   {
+      sendMessage(msg.getBytes("UTF-8"), propertyName, propertyValue, queue);
+   }
+
+   public void sendMessage(byte[] data, String propertyName, String propertyValue, Destination destination) throws Exception
+   {
+      MessageProducer producer = session.createProducer(destination);
+      BytesMessage message = session.createBytesMessage();
+      message.setStringProperty(propertyName, propertyValue);
+      message.writeBytes(data);
+      producer.send(message);
+   }
+
+   protected void waitForReceipt() throws Exception
+   {
+      String frame = receiveFrame(50000);
+      assertNotNull(frame);
+      assertTrue(frame.indexOf("RECEIPT") > -1);
+   }
+
+   protected void waitForFrameToTakeEffect() throws InterruptedException
+   {
+      // bit of a dirty hack :)
+      // another option would be to force some kind of receipt to be returned
+      // from the frame
+      Thread.sleep(2000);
+   }
+}

Modified: branches/hornetq-416/tests/src/org/hornetq/tests/timing/jms/bridge/impl/JMSBridgeImplTest.java
===================================================================
--- branches/hornetq-416/tests/src/org/hornetq/tests/timing/jms/bridge/impl/JMSBridgeImplTest.java	2010-10-13 00:11:20 UTC (rev 9781)
+++ branches/hornetq-416/tests/src/org/hornetq/tests/timing/jms/bridge/impl/JMSBridgeImplTest.java	2010-10-13 07:38:20 UTC (rev 9782)
@@ -53,6 +53,7 @@
 import org.hornetq.jms.bridge.QualityOfServiceMode;
 import org.hornetq.jms.bridge.impl.JMSBridgeImpl;
 import org.hornetq.jms.client.HornetQConnectionFactory;
+import org.hornetq.jms.client.HornetQJMSConnectionFactory;
 import org.hornetq.jms.server.JMSServerManager;
 import org.hornetq.jms.server.impl.JMSServerManagerImpl;
 import org.hornetq.tests.unit.util.InVMContext;
@@ -157,7 +158,7 @@
 
    private static ConnectionFactory createConnectionFactory()
    {
-      HornetQConnectionFactory cf = (HornetQConnectionFactory) HornetQJMSClient.createConnectionFactory(new TransportConfiguration(InVMConnectorFactory.class.getName()));
+      HornetQJMSConnectionFactory cf = (HornetQJMSConnectionFactory) HornetQJMSClient.createConnectionFactory(new TransportConfiguration(InVMConnectorFactory.class.getName()));
       // Note! We disable automatic reconnection on the session factory. The bridge needs to do the reconnection
       cf.setReconnectAttempts(0);
       cf.setBlockOnNonDurableSend(true);
@@ -171,8 +172,10 @@
 
    public void testStartWithRepeatedFailure() throws Exception
    {
-      HornetQConnectionFactory failingSourceCF = new HornetQConnectionFactory(new TransportConfiguration(InVMConnectorFactory.class.getName()))
+      HornetQJMSConnectionFactory failingSourceCF = new HornetQJMSConnectionFactory(new TransportConfiguration(InVMConnectorFactory.class.getName()))
       {
+         private static final long serialVersionUID = -2142578705002528826L;
+
          @Override
          public Connection createConnection() throws JMSException
          {
@@ -212,8 +215,9 @@
 
    public void testStartWithFailureThenSuccess() throws Exception
    {
-      HornetQConnectionFactory failingSourceCF = new HornetQConnectionFactory(new TransportConfiguration(InVMConnectorFactory.class.getName()))
+      HornetQJMSConnectionFactory failingSourceCF = new HornetQJMSConnectionFactory(new TransportConfiguration(InVMConnectorFactory.class.getName()))
       {
+         private static final long serialVersionUID = 1274250681150776714L;
          boolean firstTime = true;
 
          @Override
@@ -410,8 +414,10 @@
    public void testExceptionOnSourceAndRetrySucceeds() throws Exception
    {
       final AtomicReference<Connection> sourceConn = new AtomicReference<Connection>();
-      HornetQConnectionFactory failingSourceCF = new HornetQConnectionFactory(new TransportConfiguration(InVMConnectorFactory.class.getName()))
+      HornetQJMSConnectionFactory failingSourceCF = new HornetQJMSConnectionFactory(new TransportConfiguration(InVMConnectorFactory.class.getName()))
       {
+         private static final long serialVersionUID = -6930787952179727779L;
+
          @Override
          public Connection createConnection() throws JMSException
          {
@@ -460,8 +466,9 @@
    public void testExceptionOnSourceAndRetryFails() throws Exception
    {
       final AtomicReference<Connection> sourceConn = new AtomicReference<Connection>();
-      HornetQConnectionFactory failingSourceCF = new HornetQConnectionFactory(new TransportConfiguration(InVMConnectorFactory.class.getName()))
+      HornetQJMSConnectionFactory failingSourceCF = new HornetQJMSConnectionFactory(new TransportConfiguration(InVMConnectorFactory.class.getName()))
       {
+         private static final long serialVersionUID = 4163579449500727852L;
          boolean firstTime = true;
 
          @Override

Modified: branches/hornetq-416/tests/src/org/hornetq/tests/unit/core/deployers/impl/SecurityDeployerTest.java
===================================================================
--- branches/hornetq-416/tests/src/org/hornetq/tests/unit/core/deployers/impl/SecurityDeployerTest.java	2010-10-13 00:11:20 UTC (rev 9781)
+++ branches/hornetq-416/tests/src/org/hornetq/tests/unit/core/deployers/impl/SecurityDeployerTest.java	2010-10-13 07:38:20 UTC (rev 9782)
@@ -41,7 +41,31 @@
                                + "      <permission type=\"manage\" roles=\"guest,publisher,durpublisher\"/>\n"
                                + "   </security-setting>";
 
-   private final String conf2 = "<security-setting match=\"jms.topic.testQueue\">\n" + "      <permission type=\"createNonDurableQueue\" roles=\"durpublisher\"/>\n"
+   private final String confWithWhiteSpace1 = "<security-setting match=\"jms.topic.testTopic\">\n" +
+   "      <permission type=\"createDurableQueue\" roles=\"guest, publisher, durpublisher\"/>\n" +
+   "<permission type=\"createNonDurableQueue\" roles=\"guest, publisher, durpublisher\"/>\n"
+   + "      <permission type=\"deleteNonDurableQueue\" roles=\"guest, publisher, durpublisher\"/>\n"
+                                              + "      <permission type=\"deleteDurableQueue\" roles=\"guest, publisher, durpublisher\"/>\n"
+                                              
+                                              + "      <permission type=\"consume\" roles=\"guest, publisher, durpublisher\"/>\n"
+                                              + "      <permission type=\"send\" roles=\"guest, publisher, durpublisher\"/>\n"
+                                              + "      <permission type=\"manage\" roles=\"guest, publisher, durpublisher\"/>\n"
+                                              + "      <permission type=\"manage\" roles=\"guest, publisher, durpublisher\"/>\n"
+                                              + "   </security-setting>";
+
+   private final String confWithWhiteSpace2 = "<security-setting match=\"jms.topic.testTopic\">\n" +
+   "      <permission type=\"createDurableQueue\" roles=\"guest , publisher , durpublisher\"/>\n" +
+   "<permission type=\"createNonDurableQueue\" roles=\"guest , publisher , durpublisher\"/>\n"
+   + "      <permission type=\"deleteNonDurableQueue\" roles=\"guest , publisher , durpublisher\"/>\n"
+                                              + "      <permission type=\"deleteDurableQueue\" roles=\"guest , publisher , durpublisher\"/>\n"
+                                              
+                                              + "      <permission type=\"consume\" roles=\"guest , publisher , durpublisher\"/>\n"
+                                              + "      <permission type=\"send\" roles=\"guest , publisher , durpublisher\"/>\n"
+                                              + "      <permission type=\"manage\" roles=\"guest , publisher , durpublisher\"/>\n"
+                                              + "   </security-setting>";
+
+   private final String conf2 = "<security-setting match=\"jms.topic.testQueue\">\n" + 
+   "      <permission type=\"createNonDurableQueue\" roles=\"durpublisher\"/>\n"
                                 + "      <permission type=\"deleteNonDurableQueue\" roles=\"durpublisher\"/>\n"
                                 + "      <permission type=\"consume\" roles=\"guest,publisher,durpublisher\"/>\n"
                                 + "      <permission type=\"send\" roles=\"guest,publisher,durpublisher\"/>\n"
@@ -106,7 +130,63 @@
          }
       }
    }
+   
+   public void testWithWhiteSpace1() throws Exception
+   {
+      testWithWhiteSpace(confWithWhiteSpace1);
+   }
+   
+   public void testWithWhiteSpace2() throws Exception
+   {
+      testWithWhiteSpace(confWithWhiteSpace2);
+   }
 
+   private void testWithWhiteSpace(String conf) throws Exception
+   {
+      Element e = org.hornetq.utils.XMLUtil.stringToElement(confWithWhiteSpace1);
+      deployer.deploy(e);
+      HashSet<Role> roles = (HashSet<Role>)repository.getMatch("jms.topic.testTopic");
+      Assert.assertNotNull(roles);
+      Assert.assertEquals(3, roles.size());
+      for (Role role : roles)
+      {
+         if (role.getName().equals("guest"))
+         {
+            Assert.assertTrue(role.isConsume());
+            Assert.assertTrue(role.isCreateDurableQueue());
+            Assert.assertTrue(role.isCreateNonDurableQueue());
+            Assert.assertTrue(role.isDeleteDurableQueue());
+            Assert.assertTrue(role.isDeleteNonDurableQueue());
+            Assert.assertTrue(role.isManage());
+            Assert.assertTrue(role.isSend());
+         }
+         else if (role.getName().equals("publisher"))
+         {
+            Assert.assertTrue(role.isConsume());
+            Assert.assertTrue(role.isCreateDurableQueue());
+            Assert.assertTrue(role.isCreateNonDurableQueue());
+            Assert.assertTrue(role.isDeleteDurableQueue());
+            Assert.assertTrue(role.isDeleteNonDurableQueue());
+            Assert.assertTrue(role.isManage());
+            Assert.assertTrue(role.isSend());
+         }
+         else if (role.getName().equals("durpublisher"))
+         {
+            Assert.assertTrue(role.isConsume());
+            Assert.assertTrue(role.isCreateDurableQueue());
+            Assert.assertTrue(role.isCreateNonDurableQueue());
+            Assert.assertTrue(role.isDeleteDurableQueue());
+            Assert.assertTrue(role.isDeleteNonDurableQueue());
+            Assert.assertTrue(role.isManage());
+            Assert.assertTrue(role.isSend());
+         }
+         else
+         {
+            Assert.fail("unexpected role");
+         }
+      }
+   }
+
    public void testMultiple() throws Exception
    {
       deployer.deploy(org.hornetq.utils.XMLUtil.stringToElement(conf));

Modified: branches/hornetq-416/tests/src/org/hornetq/tests/unit/core/remoting/impl/netty/NettyAcceptorFactoryTest.java
===================================================================
--- branches/hornetq-416/tests/src/org/hornetq/tests/unit/core/remoting/impl/netty/NettyAcceptorFactoryTest.java	2010-10-13 00:11:20 UTC (rev 9781)
+++ branches/hornetq-416/tests/src/org/hornetq/tests/unit/core/remoting/impl/netty/NettyAcceptorFactoryTest.java	2010-10-13 07:38:20 UTC (rev 9782)
@@ -66,6 +66,12 @@
          public void connectionCreated(final Connection connection, final ProtocolType protocol)
          {
          }
+
+         public void connectionReadyForWrites(Object connectionID, boolean ready)
+         {
+         }
+         
+         
       };
 
       Acceptor acceptor = factory.createAcceptor(params,

Modified: branches/hornetq-416/tests/src/org/hornetq/tests/unit/core/remoting/impl/netty/NettyAcceptorTest.java
===================================================================
--- branches/hornetq-416/tests/src/org/hornetq/tests/unit/core/remoting/impl/netty/NettyAcceptorTest.java	2010-10-13 00:11:20 UTC (rev 9781)
+++ branches/hornetq-416/tests/src/org/hornetq/tests/unit/core/remoting/impl/netty/NettyAcceptorTest.java	2010-10-13 07:38:20 UTC (rev 9782)
@@ -80,6 +80,10 @@
          public void connectionCreated(final Connection connection, final ProtocolType protocol)
          {
          }
+         
+         public void connectionReadyForWrites(Object connectionID, boolean ready)
+         {
+         }
       };
       NettyAcceptor acceptor = new NettyAcceptor(params,
                                                  handler,

Modified: branches/hornetq-416/tests/src/org/hornetq/tests/unit/core/remoting/impl/netty/NettyConnectionTest.java
===================================================================
--- branches/hornetq-416/tests/src/org/hornetq/tests/unit/core/remoting/impl/netty/NettyConnectionTest.java	2010-10-13 00:11:20 UTC (rev 9781)
+++ branches/hornetq-416/tests/src/org/hornetq/tests/unit/core/remoting/impl/netty/NettyConnectionTest.java	2010-10-13 07:38:20 UTC (rev 9782)
@@ -234,6 +234,10 @@
       {
 
       }
+      
+      public void connectionReadyForWrites(Object connectionID, boolean ready)
+      {
+      }
 
    }
 }

Modified: branches/hornetq-416/tests/src/org/hornetq/tests/unit/core/remoting/impl/netty/NettyConnectorTest.java
===================================================================
--- branches/hornetq-416/tests/src/org/hornetq/tests/unit/core/remoting/impl/netty/NettyConnectorTest.java	2010-10-13 00:11:20 UTC (rev 9781)
+++ branches/hornetq-416/tests/src/org/hornetq/tests/unit/core/remoting/impl/netty/NettyConnectorTest.java	2010-10-13 07:38:20 UTC (rev 9782)
@@ -69,6 +69,9 @@
          public void connectionCreated(final Connection connection, final ProtocolType protocol)
          {
          }
+         public void connectionReadyForWrites(Object connectionID, boolean ready)
+         {
+         }
       };
 
       NettyConnector connector = new NettyConnector(params,
@@ -106,6 +109,10 @@
          public void connectionCreated(final Connection connection, final ProtocolType protocol)
          {
          }
+         
+         public void connectionReadyForWrites(Object connectionID, boolean ready)
+         {
+         }
       };
 
       try

Modified: branches/hornetq-416/tests/src/org/hornetq/tests/unit/jms/client/SelectorTranslatorTest.java
===================================================================
--- branches/hornetq-416/tests/src/org/hornetq/tests/unit/jms/client/SelectorTranslatorTest.java	2010-10-13 00:11:20 UTC (rev 9781)
+++ branches/hornetq-416/tests/src/org/hornetq/tests/unit/jms/client/SelectorTranslatorTest.java	2010-10-13 07:38:20 UTC (rev 9782)
@@ -141,7 +141,31 @@
                           SelectorTranslator.convertToHornetQFilterString(selector));
 
    }
+   
+   public void testParseJMSExpiration()
+   {
+      String selector = "JMSExpiration=12345678";
 
+      Assert.assertEquals("HQExpiration=12345678", SelectorTranslator.convertToHornetQFilterString(selector));
+
+      selector = " JMSExpiration=12345678";
+
+      Assert.assertEquals(" HQExpiration=12345678", SelectorTranslator.convertToHornetQFilterString(selector));
+
+      selector = " JMSExpiration=12345678 OR 78766 = JMSExpiration AND (JMSExpiration= 1 + 4878787)";
+
+      Assert.assertEquals(" HQExpiration=12345678 OR 78766 = HQExpiration AND (HQExpiration= 1 + 4878787)",
+                          SelectorTranslator.convertToHornetQFilterString(selector));
+
+      checkNoSubstitute("JMSExpiration");
+
+      selector = "animal = 'lion' JMSExpiration = 321 OR animal_name = 'xyzJMSExpirationxyz'";
+
+      Assert.assertEquals("animal = 'lion' HQExpiration = 321 OR animal_name = 'xyzJMSExpirationxyz'",
+                          SelectorTranslator.convertToHornetQFilterString(selector));
+
+   }
+
    public void testParseJMSCorrelationID()
    {
       String selector = "JMSCorrelationID='ID:HQ-12435678";
@@ -191,6 +215,8 @@
 
       checkNoSubstitute("JMSType");
    }
+   
+   
 
    // Private -------------------------------------------------------------------------------------
 

Modified: branches/hornetq-416/tests/src/org/hornetq/tests/util/JMSTestBase.java
===================================================================
--- branches/hornetq-416/tests/src/org/hornetq/tests/util/JMSTestBase.java	2010-10-13 00:11:20 UTC (rev 9781)
+++ branches/hornetq-416/tests/src/org/hornetq/tests/util/JMSTestBase.java	2010-10-13 07:38:20 UTC (rev 9782)
@@ -29,6 +29,7 @@
 import org.hornetq.core.remoting.impl.netty.NettyConnectorFactory;
 import org.hornetq.core.server.HornetQServer;
 import org.hornetq.core.server.HornetQServers;
+import org.hornetq.jms.server.impl.JMSFactoryType;
 import org.hornetq.jms.server.impl.JMSServerManagerImpl;
 import org.hornetq.tests.unit.util.InVMContext;
 
@@ -213,6 +214,7 @@
                                         HornetQClient.DEFAULT_FAILOVER_ON_INITIAL_CONNECTION,
                                         failoverOnServerShutdown,
                                         null,
+                                        JMSFactoryType.CF,
                                         jndiBindings);
    }
 



More information about the hornetq-commits mailing list