[Jboss-cvs] JBoss Messaging SVN: r1255 - in trunk: src/etc/server/default/deploy src/etc/xmdesc src/main/org/jboss/jms/server src/main/org/jboss/jms/server/destination src/main/org/jboss/jms/server/endpoint src/main/org/jboss/jms/server/plugin src/main/org/jboss/messaging/core src/main/org/jboss/messaging/core/plugin src/main/org/jboss/messaging/core/plugin/contract src/main/org/jboss/messaging/core/plugin/exchange src/main/org/jboss/messaging/core/plugin/exchange/cluster src/main/org/jboss/messaging/core/tx tests tests/src/org/jboss/test/messaging/core tests/src/org/jboss/test/messaging/core/base tests/src/org/jboss/test/messaging/core/local tests/src/org/jboss/test/messaging/core/paging tests/src/org/jboss/test/messaging/core/plugin tests/src/org/jboss/test/messaging/core/plugin/base tests/src/org/jboss/test/messaging/jms tests/src/org/jboss/test/messaging/tools/jmx/rmi

jboss-cvs-commits at lists.jboss.org jboss-cvs-commits at lists.jboss.org
Tue Sep 5 12:08:45 EDT 2006


Author: timfox
Date: 2006-09-05 12:08:05 -0400 (Tue, 05 Sep 2006)
New Revision: 1255

Added:
   trunk/src/etc/xmdesc/JDBCShutdownLogger-xmbean.xml
   trunk/src/main/org/jboss/messaging/core/plugin/JDBCShutdownLogger.java
   trunk/src/main/org/jboss/messaging/core/plugin/contract/ShutdownLogger.java
   trunk/src/main/org/jboss/messaging/core/plugin/exchange/DefaultBinding.java
   trunk/src/main/org/jboss/messaging/core/plugin/exchange/cluster/
   trunk/src/main/org/jboss/messaging/core/plugin/exchange/cluster/BindRequest.java
   trunk/src/main/org/jboss/messaging/core/plugin/exchange/cluster/CastMessagesCallback.java
   trunk/src/main/org/jboss/messaging/core/plugin/exchange/cluster/CheckMessage.java
   trunk/src/main/org/jboss/messaging/core/plugin/exchange/cluster/ClusteredExchangeSupport.java
   trunk/src/main/org/jboss/messaging/core/plugin/exchange/cluster/ClusteredTopicExchange.java
   trunk/src/main/org/jboss/messaging/core/plugin/exchange/cluster/ExchangeInternal.java
   trunk/src/main/org/jboss/messaging/core/plugin/exchange/cluster/ExchangeRequest.java
   trunk/src/main/org/jboss/messaging/core/plugin/exchange/cluster/MessageHolder.java
   trunk/src/main/org/jboss/messaging/core/plugin/exchange/cluster/MessageRequest.java
   trunk/src/main/org/jboss/messaging/core/plugin/exchange/cluster/MessagesRequest.java
   trunk/src/main/org/jboss/messaging/core/plugin/exchange/cluster/SendNodeIdRequest.java
   trunk/src/main/org/jboss/messaging/core/plugin/exchange/cluster/SharedState.java
   trunk/src/main/org/jboss/messaging/core/plugin/exchange/cluster/TransactionId.java
   trunk/src/main/org/jboss/messaging/core/plugin/exchange/cluster/TransactionRequest.java
   trunk/src/main/org/jboss/messaging/core/plugin/exchange/cluster/UnbindRequest.java
   trunk/tests/src/org/jboss/test/messaging/jms/AcknowledgementTest.java
Removed:
   trunk/src/main/org/jboss/messaging/core/plugin/exchange/ClusteredExchangeSupport.java
   trunk/src/main/org/jboss/messaging/core/plugin/exchange/ClusteredTopicExchange.java
   trunk/src/main/org/jboss/messaging/core/plugin/exchange/SharedState.java
   trunk/src/main/org/jboss/messaging/core/plugin/exchange/SimpleBinding.java
   trunk/src/main/org/jboss/messaging/core/plugin/exchange/request/
   trunk/tests/src/org/jboss/test/messaging/jms/AcknowledgmentTest.java
Modified:
   trunk/src/etc/server/default/deploy/hsqldb-persistence-service.xml
   trunk/src/etc/server/default/deploy/messaging-service.xml
   trunk/src/etc/server/default/deploy/mysql-persistence-service.xml
   trunk/src/etc/xmdesc/Exchange-xmbean.xml
   trunk/src/main/org/jboss/jms/server/ServerPeer.java
   trunk/src/main/org/jboss/jms/server/destination/Queue.java
   trunk/src/main/org/jboss/jms/server/endpoint/ServerConsumerEndpoint.java
   trunk/src/main/org/jboss/jms/server/plugin/JDBCJMSUserManager.java
   trunk/src/main/org/jboss/messaging/core/ChannelSupport.java
   trunk/src/main/org/jboss/messaging/core/PagingChannel.java
   trunk/src/main/org/jboss/messaging/core/plugin/JDBCPersistenceManager.java
   trunk/src/main/org/jboss/messaging/core/plugin/contract/Exchange.java
   trunk/src/main/org/jboss/messaging/core/plugin/contract/PersistenceManager.java
   trunk/src/main/org/jboss/messaging/core/plugin/exchange/DirectExchange.java
   trunk/src/main/org/jboss/messaging/core/plugin/exchange/ExchangeSupport.java
   trunk/src/main/org/jboss/messaging/core/plugin/exchange/TopicExchange.java
   trunk/src/main/org/jboss/messaging/core/tx/Transaction.java
   trunk/tests/build.xml
   trunk/tests/src/org/jboss/test/messaging/core/SimpleReceiver.java
   trunk/tests/src/org/jboss/test/messaging/core/base/MessageQueueTestBase.java
   trunk/tests/src/org/jboss/test/messaging/core/local/RoundRobinPointToPointRouterTest.java
   trunk/tests/src/org/jboss/test/messaging/core/paging/ChannelShare_NP_2PCTest.java
   trunk/tests/src/org/jboss/test/messaging/core/paging/ChannelShare_NP_NTTest.java
   trunk/tests/src/org/jboss/test/messaging/core/paging/ChannelShare_NP_TTest.java
   trunk/tests/src/org/jboss/test/messaging/core/paging/ChannelShare_P_2PCTest.java
   trunk/tests/src/org/jboss/test/messaging/core/paging/ChannelShare_P_NTTest.java
   trunk/tests/src/org/jboss/test/messaging/core/paging/ChannelShare_P_TTest.java
   trunk/tests/src/org/jboss/test/messaging/core/paging/PagingStateTestBase.java
   trunk/tests/src/org/jboss/test/messaging/core/paging/SingleChannel_NP_2PCTest.java
   trunk/tests/src/org/jboss/test/messaging/core/paging/SingleChannel_NP_NTTest.java
   trunk/tests/src/org/jboss/test/messaging/core/paging/SingleChannel_NP_TTest.java
   trunk/tests/src/org/jboss/test/messaging/core/paging/SingleChannel_P_2PCTest.java
   trunk/tests/src/org/jboss/test/messaging/core/paging/SingleChannel_P_NTTest.java
   trunk/tests/src/org/jboss/test/messaging/core/paging/SingleChannel_P_TTest.java
   trunk/tests/src/org/jboss/test/messaging/core/paging/SingleChannel_ReloadTest.java
   trunk/tests/src/org/jboss/test/messaging/core/plugin/ClusteredTopicExchangeTest.java
   trunk/tests/src/org/jboss/test/messaging/core/plugin/DirectExchangeTest.java
   trunk/tests/src/org/jboss/test/messaging/core/plugin/TopicExchangeTest.java
   trunk/tests/src/org/jboss/test/messaging/core/plugin/base/MessageStoreTestBase.java
   trunk/tests/src/org/jboss/test/messaging/jms/PersistenceTest.java
   trunk/tests/src/org/jboss/test/messaging/tools/jmx/rmi/LocalTestServer.java
Log:
More clustering work



Modified: trunk/src/etc/server/default/deploy/hsqldb-persistence-service.xml
===================================================================
--- trunk/src/etc/server/default/deploy/hsqldb-persistence-service.xml	2006-09-03 17:56:48 UTC (rev 1254)
+++ trunk/src/etc/server/default/deploy/hsqldb-persistence-service.xml	2006-09-05 16:08:05 UTC (rev 1255)
@@ -21,7 +21,7 @@
       <attribute name="UsingBatchUpdates">true</attribute>
    </mbean>
 
-   <mbean code="org.jboss.messaging.core.plugin.DirectExchange"
+   <mbean code="org.jboss.messaging.core.plugin.exchange.DirectExchange"
       name="jboss.messaging:service=DirectExchange"
       xmbean-dd="xmdesc/Exchange-xmbean.xml">
       <!-- TODO this insures the fact that dependency exists. However I need to redundantly specifiy
@@ -33,7 +33,7 @@
       <attribute name="CreateTablesOnStartup">true</attribute>
    </mbean>
    
-	<mbean code="org.jboss.messaging.core.plugin.TopicExchange"
+	<mbean code="org.jboss.messaging.core.plugin.exchange.TopicExchange"
       name="jboss.messaging:service=TopicExchange"
       xmbean-dd="xmdesc/Exchange-xmbean.xml">
       <!-- TODO this insures the fact that dependency exists. However I need to redundantly specifiy

Modified: trunk/src/etc/server/default/deploy/messaging-service.xml
===================================================================
--- trunk/src/etc/server/default/deploy/messaging-service.xml	2006-09-03 17:56:48 UTC (rev 1254)
+++ trunk/src/etc/server/default/deploy/messaging-service.xml	2006-09-05 16:08:05 UTC (rev 1255)
@@ -25,6 +25,7 @@
       <depends optional-attribute-name="DirectExchange">jboss.messaging:service=DirectExchange</depends>
       <depends optional-attribute-name="TopicExchange">jboss.messaging:service=TopicExchange</depends>
       <depends optional-attribute-name="JMSUserManager">jboss.messaging:service=JMSUserManager</depends>
+	   <depends optional-attribute-name="ShutdownLogger">jboss.messaging:service=ShutdownLogger</depends>
 
       <!-- Set to -1 to completely disable client leasing -->
       <attribute name="SecurityDomain">java:/jaas/messaging</attribute>

Modified: trunk/src/etc/server/default/deploy/mysql-persistence-service.xml
===================================================================
--- trunk/src/etc/server/default/deploy/mysql-persistence-service.xml	2006-09-03 17:56:48 UTC (rev 1254)
+++ trunk/src/etc/server/default/deploy/mysql-persistence-service.xml	2006-09-05 16:08:05 UTC (rev 1255)
@@ -110,6 +110,18 @@
       <depends optional-attribute-name="TransactionManager">jboss:service=TransactionManager</depends>
       <attribute name="DataSource">java:/DefaultDS</attribute>
       <attribute name="CreateTablesOnStartup">true</attribute>
-   </mbean>    
+   </mbean> 
+   
+   <mbean code="org.jboss.jms.server.plugin.JDBCShutdownLogger"
+      name="jboss.messaging:service=ShutdownLogger"
+      xmbean-dd="xmdesc/JDBCShutdownLogger-xmbean.xml">
+      <!-- TODO this insures the fact that dependency exists. However I need to redundantly specifiy
+           the DataSource JNDI name in order to actually get a reference to it. Fix this.
+      -->   
+      <depends>jboss.jca:service=DataSourceBinding,name=DefaultDS</depends>
+      <depends optional-attribute-name="TransactionManager">jboss:service=TransactionManager</depends>
+      <attribute name="DataSource">java:/DefaultDS</attribute>
+      <attribute name="CreateTablesOnStartup">true</attribute>
+   </mbean>       
       
 </server>
\ No newline at end of file

Modified: trunk/src/etc/xmdesc/Exchange-xmbean.xml
===================================================================
--- trunk/src/etc/xmdesc/Exchange-xmbean.xml	2006-09-03 17:56:48 UTC (rev 1254)
+++ trunk/src/etc/xmdesc/Exchange-xmbean.xml	2006-09-05 16:08:05 UTC (rev 1255)
@@ -5,7 +5,7 @@
 
 <mbean>
    <description>An exchange</description>
-   <class>org.jboss.messaging.core.plugin.ExchangeSupport</class>
+   <class>org.jboss.messaging.core.plugin.exchange.ExchangeSupport</class>
 
    <!-- Managed constructors -->
 

Added: trunk/src/etc/xmdesc/JDBCShutdownLogger-xmbean.xml
===================================================================
--- trunk/src/etc/xmdesc/JDBCShutdownLogger-xmbean.xml	2006-09-03 17:56:48 UTC (rev 1254)
+++ trunk/src/etc/xmdesc/JDBCShutdownLogger-xmbean.xml	2006-09-05 16:08:05 UTC (rev 1255)
@@ -0,0 +1,66 @@
+<?xml version="1.0" encoding="UTF-8"?>
+   <!DOCTYPE mbean PUBLIC
+      "-//JBoss//DTD JBOSS XMBEAN 1.2//EN"
+      "http://www.jboss.org/j2ee/dtd/jboss_xmbean_1_2.dtd">
+
+<mbean>
+   <description>A JDBC Shutdown Logger</description>
+   <class>org.jboss.server.plugin.JDBCShutdownLogger</class>
+
+   <!-- Managed constructors -->
+
+   <!-- Managed attributes -->
+
+   <attribute access="read-only" getMethod="getInstance">
+      <description>The instance to plug into the server peer</description>
+      <name>Instance</name>
+      <type>java.lang.Object</type>
+   </attribute>
+
+   <attribute access="read-write" getMethod="getDataSource" setMethod="setDataSource">
+      <description>The JNDI name of the DataSource used by this ChannelMapper instance</description>
+      <name>DataSource</name>
+      <type>java.lang.String</type>
+   </attribute>
+
+   <attribute access="read-write" getMethod="getTransactionManager" setMethod="setTransactionManager">
+      <description>The ObjectName of the TransactionManager used by this ChannelMaper instance</description>
+      <name>TransactionManager</name>
+      <type>javax.management.ObjectName</type>
+   </attribute>
+   
+   <attribute access="read-write" getMethod="getSqlProperties" setMethod="setSqlProperties">
+      <description>DML and DDL overrides</description>
+      <name>SqlProperties</name>
+      <type>java.lang.String</type>
+   </attribute>
+
+   <attribute access="read-write" getMethod="isCreateTablesOnStartup" setMethod="setCreateTablesOnStartup">
+      <description>Should database tables be created on startup?</description>
+      <name>CreateTablesOnStartup</name>
+      <type>boolean</type>
+   </attribute>
+
+   <!-- Managed operations -->
+
+   <operation>
+      <description>JBoss Service lifecycle operation</description>
+      <name>create</name>
+   </operation>
+
+   <operation>
+      <description>JBoss Service lifecycle operation</description>
+      <name>start</name>
+   </operation>
+
+   <operation>
+      <description>JBoss Service lifecycle operation</description>
+      <name>stop</name>
+   </operation>
+
+   <operation>
+      <description>JBoss Service lifecycle operation</description>
+      <name>destroy</name>
+   </operation>   
+
+</mbean>
\ No newline at end of file

Modified: trunk/src/main/org/jboss/jms/server/ServerPeer.java
===================================================================
--- trunk/src/main/org/jboss/jms/server/ServerPeer.java	2006-09-03 17:56:48 UTC (rev 1254)
+++ trunk/src/main/org/jboss/jms/server/ServerPeer.java	2006-09-05 16:08:05 UTC (rev 1255)
@@ -52,8 +52,10 @@
 import org.jboss.messaging.core.plugin.contract.Exchange;
 import org.jboss.messaging.core.plugin.contract.MessageStore;
 import org.jboss.messaging.core.plugin.contract.PersistenceManager;
-import org.jboss.messaging.core.plugin.exchange.ClusteredTopicExchange;
+import org.jboss.messaging.core.plugin.contract.ShutdownLogger;
 import org.jboss.messaging.core.plugin.exchange.DirectExchange;
+import org.jboss.messaging.core.plugin.exchange.TopicExchange;
+import org.jboss.messaging.core.plugin.exchange.cluster.ClusteredTopicExchange;
 import org.jboss.messaging.core.tx.TransactionRepository;
 import org.jboss.messaging.util.Util;
 import org.jboss.mx.loading.UnifiedClassLoader3;
@@ -103,6 +105,8 @@
    private boolean started;
 
    private int objectIDSequence = Integer.MIN_VALUE + 1;
+   
+   private boolean crashed;
 
    // wired components
 
@@ -129,6 +133,8 @@
    protected Exchange topicExchangeDelegate;
    protected ObjectName JMSUserManagerObjectName;
    protected JMSUserManager JMSUserManagerDelegate;
+   protected ObjectName shutdownLoggerObjectName;
+   protected ShutdownLogger shutdownLoggerDelegate;
 
    private JMSServerInvocationHandler handler;
 
@@ -210,6 +216,12 @@
          
          JMSUserManagerDelegate = (JMSUserManager)mbeanServer.
             getAttribute(JMSUserManagerObjectName, "Instance");
+         
+         shutdownLoggerDelegate = (ShutdownLogger)mbeanServer.
+            getAttribute(shutdownLoggerObjectName, "Instance");
+         
+         //Did the server crash last time?
+         crashed = shutdownLoggerDelegate.startup(serverPeerID);
                   
          //TODO Make block size configurable
          messageIdManager = new IdManager("MESSAGE_ID", 8192, persistenceManagerDelegate);
@@ -223,13 +235,24 @@
                                                                     channelIdManager,
                                                                     queuedExecutorPool);
                            
-         ((ClusteredTopicExchange)topicExchangeDelegate).injectAttributes(null, null, null, "Topic", serverPeerID,
-                                                                   messageStore, 
-                                                                   channelIdManager,
-                                                                   queuedExecutorPool,
-                                                                   txRepository,
-                                                                   persistenceManagerDelegate);
+//         ((ClusteredTopicExchange)topicExchangeDelegate).injectAttributes(null, null, null, "Topic", serverPeerID,
+//                                                                   messageStore, 
+//                                                                   channelIdManager,
+//                                                                   queuedExecutorPool,
+//                                                                   txRepository,
+//                                                                   persistenceManagerDelegate);
          
+         ((TopicExchange)topicExchangeDelegate).injectAttributes("Topic", serverPeerID,
+                                                                messageStore, 
+                                                                channelIdManager,
+                                                                queuedExecutorPool,
+                                                                txRepository);
+         
+         if (crashed)
+         {
+            topicExchangeDelegate.recover();
+         }
+         
          txRepository.injectAttributes(persistenceManagerDelegate, transactionIdManager);
          
          // start the rest of the internal components
@@ -284,6 +307,8 @@
          // TODO unloadClientAOPConfig();
          
          queuedExecutorPool.shutdown();
+         
+         shutdownLoggerDelegate.shutdown(serverPeerID);         
    
          log.info("JMS " + this + " stopped");
       }
@@ -334,7 +359,17 @@
    {
       JMSUserManagerObjectName = on;
    }
+   
+   public ObjectName getShutdownLogger()
+   {
+      return shutdownLoggerObjectName;
+   }
 
+   public void setShutdownLogger(ObjectName on)
+   {
+      shutdownLoggerObjectName = on;
+   }
+
    public Object getInstance()
    {
       return this;
@@ -542,6 +577,11 @@
    {
       return version;
    }
+   
+   public boolean crashedLastTime()
+   {
+      return crashed;
+   }
 
    // access to hard-wired server extensions
 
@@ -602,7 +642,12 @@
       return topicExchangeDelegate;
    }
    
+   public ShutdownLogger getShutdownLoggerDelegate()
+   {
+      return shutdownLoggerDelegate;
+   }
    
+   
 
    public synchronized int getNextObjectID()
    {

Modified: trunk/src/main/org/jboss/jms/server/destination/Queue.java
===================================================================
--- trunk/src/main/org/jboss/jms/server/destination/Queue.java	2006-09-03 17:56:48 UTC (rev 1254)
+++ trunk/src/main/org/jboss/jms/server/destination/Queue.java	2006-09-05 16:08:05 UTC (rev 1255)
@@ -115,17 +115,26 @@
          MessageStore ms = serverPeer.getMessageStore();
          PersistenceManager pm = serverPeer.getPersistenceManagerDelegate(); 
          //Binding might already exist
+         
+         log.info("Deploying queue");
+         
          Binding binding = exchange.getBindingForName(name);
          
+         log.info("binding is: " + binding);
+         
          if (binding != null)
          {
             //Reload the queue for the binding
+            log.info("reloading queue");
             exchange.reloadQueues(name, ms, pm, fullSize, pageSize, downCacheSize);
+            log.info("reloaded queue");
          }
          else
          {         
             //Make a binding for this queue
+            log.info("bidning queue");
             exchange.bindQueue(name, name, null, false, true, ms, pm, fullSize, pageSize, downCacheSize);
+            log.info("bound queue");
          }
          
          JBossQueue q = new JBossQueue(name, fullSize, pageSize, downCacheSize);

Modified: trunk/src/main/org/jboss/jms/server/endpoint/ServerConsumerEndpoint.java
===================================================================
--- trunk/src/main/org/jboss/jms/server/endpoint/ServerConsumerEndpoint.java	2006-09-03 17:56:48 UTC (rev 1254)
+++ trunk/src/main/org/jboss/jms/server/endpoint/ServerConsumerEndpoint.java	2006-09-05 16:08:05 UTC (rev 1255)
@@ -474,12 +474,12 @@
          d = (Delivery)deliveries.get(new Long(messageID));
       }
       
-      DeliveryCallback deliveryCallback = (DeliveryCallback)tx.getKeyedCallback(this);
+      DeliveryCallback deliveryCallback = (DeliveryCallback)tx.getCallback(this);
             
       if (deliveryCallback == null)
       {
          deliveryCallback = new DeliveryCallback();
-         tx.addKeyedCallback(deliveryCallback, this);
+         tx.addCallback(deliveryCallback, this);
       }
       deliveryCallback.addMessageID(messageID);
          

Modified: trunk/src/main/org/jboss/jms/server/plugin/JDBCJMSUserManager.java
===================================================================
--- trunk/src/main/org/jboss/jms/server/plugin/JDBCJMSUserManager.java	2006-09-03 17:56:48 UTC (rev 1254)
+++ trunk/src/main/org/jboss/jms/server/plugin/JDBCJMSUserManager.java	2006-09-05 16:08:05 UTC (rev 1255)
@@ -100,7 +100,7 @@
       {
          conn = ds.getConnection();
          
-         ps = conn.prepareStatement(getSQLStatement("GET_PRECONF_CLIENTID"));
+         ps = conn.prepareStatement(getSQLStatement("SELECT_PRECONF_CLIENTID"));
          
          ps.setString(1, username);
          

Modified: trunk/src/main/org/jboss/messaging/core/ChannelSupport.java
===================================================================
--- trunk/src/main/org/jboss/messaging/core/ChannelSupport.java	2006-09-03 17:56:48 UTC (rev 1254)
+++ trunk/src/main/org/jboss/messaging/core/ChannelSupport.java	2006-09-05 16:08:05 UTC (rev 1255)
@@ -841,13 +841,13 @@
 
    protected InMemoryCallback getCallback(Transaction tx)
    {
-      InMemoryCallback callback = (InMemoryCallback) tx.getKeyedCallback(this);
+      InMemoryCallback callback = (InMemoryCallback) tx.getCallback(this);
 
       if (callback == null)
       {
          callback = new InMemoryCallback();
 
-         tx.addKeyedCallback(callback, this);
+         tx.addCallback(callback, this);
       }
 
       return callback;
@@ -869,8 +869,6 @@
 
       private List deliveriesToRemove;
 
-      private long minOrder;
-
       private InMemoryCallback()
       {
          refsToAdd = new ArrayList();
@@ -881,8 +879,6 @@
       private void addRef(MessageReference ref)
       {
          refsToAdd.add(ref);
-
-         minOrder = Math.min(minOrder, ref.getPagingOrder());
       }
 
       private void addDelivery(Delivery del)

Modified: trunk/src/main/org/jboss/messaging/core/PagingChannel.java
===================================================================
--- trunk/src/main/org/jboss/messaging/core/PagingChannel.java	2006-09-03 17:56:48 UTC (rev 1254)
+++ trunk/src/main/org/jboss/messaging/core/PagingChannel.java	2006-09-05 16:08:05 UTC (rev 1255)
@@ -88,11 +88,6 @@
    protected long nextPagingOrder;
    
    /**
-    * Are there any paged references in storage?
-    */
-   //protected boolean refsInStorage;
-   
-   /**
     * @param channelID
     * @param ms
     * @param pm
@@ -146,16 +141,14 @@
 
          if (ili.getMaxPageOrdering() != null)            
          {
-            //refsInStorage = true;
-            
             firstPagingOrder = ili.getMinPageOrdering().longValue();
             
             nextPagingOrder = ili.getMaxPageOrdering().longValue() + 1;
+            
+            paging = true;
          }
          else
          {
-            //refsInStorage = false;
-            
             firstPagingOrder = nextPagingOrder = 0;
          }
          

Modified: trunk/src/main/org/jboss/messaging/core/plugin/JDBCPersistenceManager.java
===================================================================
--- trunk/src/main/org/jboss/messaging/core/plugin/JDBCPersistenceManager.java	2006-09-03 17:56:48 UTC (rev 1254)
+++ trunk/src/main/org/jboss/messaging/core/plugin/JDBCPersistenceManager.java	2006-09-05 16:08:05 UTC (rev 1255)
@@ -145,7 +145,6 @@
    }
    
    // PersistenceManager implementation -------------------------
-
    
    // Related to counters
    // ==================
@@ -1801,6 +1800,74 @@
          wrap.end();
       }
    }
+   
+   public boolean referenceExists(long channelID, long messageID) throws Exception
+   {
+      Connection conn = null;
+      PreparedStatement st = null;
+      ResultSet rs = null;
+      TransactionWrapper wrap = new TransactionWrapper();
+      
+      try
+      {
+         conn = ds.getConnection();
+         
+         st = conn.prepareStatement(getSQLStatement("SELECT_EXISTS_REF"));
+         st.setLong(1, channelID);
+         st.setLong(2, messageID);
+         
+         rs = st.executeQuery();
+         
+         if (rs.next())
+         {
+            return true;
+         }
+         else
+         {
+            return false;
+         }
+      }
+      catch (Exception e)
+      {
+         wrap.exceptionOccurred();
+         throw e;
+      }
+      finally
+      {
+         if (rs != null)
+         {
+            try
+            {
+               rs.close();
+            }
+            catch (Throwable e)
+            {
+            }
+         }
+         if (st != null)
+         {
+            try
+            {
+               st.close();
+            }
+            catch (Throwable e)
+            {
+            }
+         }
+         if (conn != null)
+         {
+            try
+            {
+               conn.close();
+            }
+            catch (Throwable e)
+            {
+            }
+         }
+         wrap.end();
+      }
+   }
+   
   
    // Public --------------------------------------------------------
    
@@ -1843,13 +1910,13 @@
       
    protected TransactionCallback getCallback(Transaction tx)
    {
-      TransactionCallback callback = (TransactionCallback) tx.getKeyedCallback(this);
+      TransactionCallback callback = (TransactionCallback) tx.getCallback(this);
 
       if (callback == null)
       {
          callback = new TransactionCallback(tx);
 
-         tx.addKeyedCallback(callback, this);
+         tx.addCallback(callback, this);
       }
 
       return callback;
@@ -3782,6 +3849,7 @@
       map.put("DELETE_UNRELIABLE_REFS", "DELETE FROM JMS_MESSAGE_REFERENCE WHERE RELIABLE = 'N'");
       map.put("SHIFT_PAGE_ORDER", "UPDATE JMS_MESSAGE_REFERENCE SET PAGE_ORD = PAGE_ORD + ? WHERE CHANNELID = ?");
       map.put("SELECT_MIN_MAX_PAGE_ORD", "SELECT MIN(PAGE_ORD), MAX(PAGE_ORD) FROM JMS_MESSAGE_REFERENCE WHERE CHANNELID = ?");
+      map.put("SELECT_EXISTS_REF", "SELECT MESSAGEID FROM JMS_MESSAGE_REFERENCE WHERE CHANNELID = ? AND MESSAGEID = ?");
       //Message
       map.put("LOAD_MESSAGES",
               "SELECT MESSAGEID, RELIABLE, EXPIRATION, TIMESTAMP, " +
@@ -3811,7 +3879,7 @@
       map.put("SELECT_COUNTER", "SELECT NEXT_ID FROM JMS_COUNTER WHERE NAME=?");
       map.put("INSERT_COUNTER", "INSERT INTO JMS_COUNTER (NAME, NEXT_ID) VALUES (?, ?)");
       //Other
-      map.put("SELECT_ALL_CHANNELS", "SELECT DISTINCT(CHANNELID) FROM JMS_MESSAGE_REFERENCE");
+      map.put("SELECT_ALL_CHANNELS", "SELECT DISTINCT(CHANNELID) FROM JMS_MESSAGE_REFERENCE");      
       return map;
    }
    

Added: trunk/src/main/org/jboss/messaging/core/plugin/JDBCShutdownLogger.java
===================================================================
--- trunk/src/main/org/jboss/messaging/core/plugin/JDBCShutdownLogger.java	2006-09-03 17:56:48 UTC (rev 1254)
+++ trunk/src/main/org/jboss/messaging/core/plugin/JDBCShutdownLogger.java	2006-09-05 16:08:05 UTC (rev 1255)
@@ -0,0 +1,256 @@
+/*
+ * JBoss, Home of Professional Open Source
+ * Copyright 2005, JBoss Inc., and individual contributors as indicated
+ * by the @authors tag. See the copyright.txt in the distribution for a
+ * full listing of individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+package org.jboss.messaging.core.plugin;
+
+import java.sql.Connection;
+import java.sql.PreparedStatement;
+import java.sql.ResultSet;
+import java.util.HashMap;
+import java.util.Map;
+
+import org.jboss.logging.Logger;
+import org.jboss.messaging.core.plugin.contract.ShutdownLogger;
+
+/**
+ * A ShutdownLogger
+ *
+ * @author <a href="mailto:tim.fox at jboss.com">Tim Fox</a>
+ * @version <tt>$Revision: 1.1 $</tt>
+ *
+ * $Id$
+ *
+ */
+public class JDBCShutdownLogger extends JDBCServiceSupport implements ShutdownLogger
+{
+   private static final Logger log = Logger.getLogger(JDBCShutdownLogger.class); 
+   
+   protected Map getDefaultDDLStatements()
+   {
+      Map sql = new HashMap();
+      
+      sql.put("CREATE_STARTUP", "CREATE TABLE JMS_STARTUP (NODE_ID CHAR(1) PRIMARY KEY)");
+      
+      return sql;
+   }
+
+   protected Map getDefaultDMLStatements()
+   {
+      Map sql = new HashMap();
+      
+      sql.put("SELECT_STARTUP", "SELECT NODE_ID FROM JMS_STARTUP WHERE NODE_ID = ?");
+      sql.put("DELETE_STARTUP", "DELETE FROM JMS_STARTUP WHERE NODE_ID = ?");
+      sql.put("INSERT_STARTUP", "INSERT INTO JMS_STARTUP (NODE_ID) VALUES (?)");
+      
+      return sql;
+   }
+
+   public boolean shutdown(String nodeId) throws Exception
+   {
+      boolean exists = existsStartup(nodeId);
+      
+      if (!exists)
+      {
+         //This shouldn't really happen
+         log.warn("It appears the server did not start up properly!");
+         return false;
+      }
+      else
+      {      
+         removeStartup(nodeId);
+         
+         return true;
+      }      
+   }
+
+   public boolean startup(String nodeId) throws Exception
+   {
+      boolean crashed = existsStartup(nodeId);
+      
+      if (crashed)
+      {
+         //These means the server didn't shutdown cleanly last time - 
+         //we must assume it crashed
+         
+         log.warn("It appears the server was not shutdown cleanly last time. We assume that the server crashed");
+         
+         //Remove the old startup row
+         removeStartup(nodeId);
+      }
+      
+      //Insert a new startup row
+      insertStartup(nodeId);
+      
+      return crashed;
+   }
+   
+   private boolean existsStartup(String nodeId) throws Exception
+   {
+      Connection conn = null;
+      PreparedStatement ps = null;
+      ResultSet rs = null;
+      TransactionWrapper wrap = new TransactionWrapper();
+      
+      try
+      {
+         conn = ds.getConnection();
+         ps = conn.prepareStatement(getSQLStatement("SELECT_STARTUP"));
+         ps.setString(1, nodeId);
+         
+         rs = ps.executeQuery();
+         
+         return rs.next();
+        
+      }
+      catch (Exception e)
+      {
+         wrap.exceptionOccurred();
+         throw e;
+      }
+      finally
+      {
+         if (rs != null)
+         {
+            try
+            {
+               rs.close();
+            }
+            catch (Throwable e)
+            {
+            }
+         }
+         if (ps != null)
+         {
+            try
+            {
+               ps.close();
+            }
+            catch (Throwable e)
+            {
+            }
+         }
+         if (conn != null)
+         {
+            try
+            {
+               conn.close();
+            }
+            catch (Throwable e)
+            {
+            }
+         }
+         wrap.end();
+      }
+   }
+   
+   private void removeStartup(String nodeId) throws Exception
+   {
+      Connection conn = null;
+      PreparedStatement ps = null;
+      TransactionWrapper wrap = new TransactionWrapper();
+      
+      try
+      {
+         conn = ds.getConnection();
+         ps = conn.prepareStatement(getSQLStatement("DELETE_STARTUP"));
+         ps.setString(1, nodeId);
+         
+         ps.executeUpdate();
+        
+      }
+      catch (Exception e)
+      {
+         wrap.exceptionOccurred();
+         throw e;
+      }
+      finally
+      {
+         if (ps != null)
+         {
+            try
+            {
+               ps.close();
+            }
+            catch (Throwable e)
+            {
+            }
+         }
+         if (conn != null)
+         {
+            try
+            {
+               conn.close();
+            }
+            catch (Throwable e)
+            {
+            }
+         }
+         wrap.end();
+      }
+   }
+   
+   private void insertStartup(String nodeId) throws Exception
+   {
+      Connection conn = null;
+      PreparedStatement ps = null;
+      TransactionWrapper wrap = new TransactionWrapper();
+      
+      try
+      {
+         conn = ds.getConnection();
+         ps = conn.prepareStatement(getSQLStatement("INSERT_STARTUP"));
+         ps.setString(1, nodeId);
+         
+         ps.executeUpdate();
+        
+      }
+      catch (Exception e)
+      {
+         wrap.exceptionOccurred();
+         throw e;
+      }
+      finally
+      {
+         if (ps != null)
+         {
+            try
+            {
+               ps.close();
+            }
+            catch (Throwable e)
+            {
+            }
+         }
+         if (conn != null)
+         {
+            try
+            {
+               conn.close();
+            }
+            catch (Throwable e)
+            {
+            }
+         }
+         wrap.end();
+      }
+   }
+
+}

Modified: trunk/src/main/org/jboss/messaging/core/plugin/contract/Exchange.java
===================================================================
--- trunk/src/main/org/jboss/messaging/core/plugin/contract/Exchange.java	2006-09-03 17:56:48 UTC (rev 1254)
+++ trunk/src/main/org/jboss/messaging/core/plugin/contract/Exchange.java	2006-09-05 16:08:05 UTC (rev 1255)
@@ -139,4 +139,10 @@
     * @throws Exception
     */
    boolean route(MessageReference ref, String routingKey, Transaction tx) throws Exception;   
+   
+   /**
+    * Recover the exchange
+    * @throws Exception
+    */
+   void recover() throws Exception;
 }

Modified: trunk/src/main/org/jboss/messaging/core/plugin/contract/PersistenceManager.java
===================================================================
--- trunk/src/main/org/jboss/messaging/core/plugin/contract/PersistenceManager.java	2006-09-03 17:56:48 UTC (rev 1254)
+++ trunk/src/main/org/jboss/messaging/core/plugin/contract/PersistenceManager.java	2006-09-05 16:08:05 UTC (rev 1255)
@@ -65,7 +65,10 @@
    
    long reserveIDBlock(String counterName, int size) throws Exception;
    
-      
+   // Clustering recovery related functionality
+   
+   boolean referenceExists(long channelID, long messageID) throws Exception;
+     
    // Interface value classes
    //---------------------------------------------------------------
    

Added: trunk/src/main/org/jboss/messaging/core/plugin/contract/ShutdownLogger.java
===================================================================
--- trunk/src/main/org/jboss/messaging/core/plugin/contract/ShutdownLogger.java	2006-09-03 17:56:48 UTC (rev 1254)
+++ trunk/src/main/org/jboss/messaging/core/plugin/contract/ShutdownLogger.java	2006-09-05 16:08:05 UTC (rev 1255)
@@ -0,0 +1,38 @@
+/*
+ * JBoss, Home of Professional Open Source
+ * Copyright 2005, JBoss Inc., and individual contributors as indicated
+ * by the @authors tag. See the copyright.txt in the distribution for a
+ * full listing of individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+package org.jboss.messaging.core.plugin.contract;
+
+/**
+ * A ShutdownLogger
+ *
+ * @author <a href="mailto:tim.fox at jboss.com">Tim Fox</a>
+ * @version <tt>$Revision: 1.1 $</tt>
+ *
+ * $Id$
+ *
+ */
+public interface ShutdownLogger extends ServerPlugin
+{
+   boolean startup(String nodeId) throws Exception;
+   
+   boolean shutdown(String nodeId) throws Exception;
+}

Deleted: trunk/src/main/org/jboss/messaging/core/plugin/exchange/ClusteredExchangeSupport.java
===================================================================
--- trunk/src/main/org/jboss/messaging/core/plugin/exchange/ClusteredExchangeSupport.java	2006-09-03 17:56:48 UTC (rev 1254)
+++ trunk/src/main/org/jboss/messaging/core/plugin/exchange/ClusteredExchangeSupport.java	2006-09-05 16:08:05 UTC (rev 1255)
@@ -1,762 +0,0 @@
-/*
- * JBoss, Home of Professional Open Source
- * Copyright 2005, JBoss Inc., and individual contributors as indicated
- * by the @authors tag. See the copyright.txt in the distribution for a
- * full listing of individual contributors.
- *
- * This is free software; you can redistribute it and/or modify it
- * under the terms of the GNU Lesser General Public License as
- * published by the Free Software Foundation; either version 2.1 of
- * the License, or (at your option) any later version.
- *
- * This software is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this software; if not, write to the Free
- * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
- * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
- */
-package org.jboss.messaging.core.plugin.exchange;
-
-import java.util.ArrayList;
-import java.util.HashMap;
-import java.util.Iterator;
-import java.util.List;
-import java.util.Map;
-
-import javax.sql.DataSource;
-import javax.transaction.TransactionManager;
-
-import org.jboss.jms.server.QueuedExecutorPool;
-import org.jboss.logging.Logger;
-import org.jboss.messaging.core.Filter;
-import org.jboss.messaging.core.MessageReference;
-import org.jboss.messaging.core.plugin.IdManager;
-import org.jboss.messaging.core.plugin.contract.MessageStore;
-import org.jboss.messaging.core.plugin.contract.PersistenceManager;
-import org.jboss.messaging.core.plugin.exchange.request.BindRequest;
-import org.jboss.messaging.core.plugin.exchange.request.MessageRequest;
-import org.jboss.messaging.core.plugin.exchange.request.SendNodeIdRequest;
-import org.jboss.messaging.core.plugin.exchange.request.UnbindRequest;
-import org.jgroups.Address;
-import org.jgroups.Channel;
-import org.jgroups.MembershipListener;
-import org.jgroups.Message;
-import org.jgroups.MessageListener;
-import org.jgroups.Receiver;
-import org.jgroups.View;
-import org.jgroups.blocks.GroupRequest;
-import org.jgroups.blocks.MessageDispatcher;
-import org.jgroups.blocks.RequestHandler;
-import org.jgroups.util.Util;
-
-/**
- * A ClusteredExchangeSupport
- *
- * @author <a href="mailto:tim.fox at jboss.com">Tim Fox</a>
- * @version <tt>$Revision: 1.1 $</tt>
- *
- * $Id$
- *
- */
-public abstract class ClusteredExchangeSupport extends ExchangeSupport
-{
-   private static final Logger log = Logger.getLogger(ClusteredExchangeSupport.class);
-      
-   //TODO - make configurable
-   private static final int GET_STATE_TIMEOUT = 5000;
-   
-   private static final int CAST_TIMEOUT = 5000;
-                    
-   protected Channel controlChannel;
-   
-   protected Channel dataChannel;
-   
-   private MessageDispatcher controlMessageDispatcher;
-   
-   private MessageListener controlMessageListener;
-   
-   private Receiver dataReceiver;
-   
-   private MembershipListener controlMembershipListener;
-   
-   private RequestHandler requestHandler;
-   
-   private Object setStateLock = new Object();
-   
-   private boolean stateSet;
-   
-   private String groupName;
-   
-   private View currentView;
-   
-   private Address currentAddress;
-   
-   //Map < Address, node id>
-   private Map nodeIdAddressMap;
-   
-   
-   public ClusteredExchangeSupport() throws Exception
-   {                  
-   }
-   
-   /*
-    * This constructor should only be used for testing
-    */
-   protected ClusteredExchangeSupport(DataSource ds, TransactionManager tm)
-   {
-      super(ds, tm);
-   }
-   
-   protected void injectAttributes(Channel controlChannel, Channel dataChannel,
-                                   String groupName, String exchangeName, String nodeID,
-                                   MessageStore ms, IdManager im, QueuedExecutorPool pool) throws Exception
-   {
-      super.injectAttributes(exchangeName, nodeID, ms, im, pool);
-      
-      this.controlChannel = controlChannel;
-      
-      this.dataChannel = dataChannel;
-      
-      this.groupName = groupName;
-      
-      this.nodeIdAddressMap = new HashMap();
-      
-      //We don't want to receive local messages on any of the channels
-      controlChannel.setOpt(Channel.LOCAL, Boolean.FALSE);
-      dataChannel.setOpt(Channel.LOCAL, Boolean.FALSE);
-
-      this.controlMessageListener = new ControlMessageListener();
-        
-      this.requestHandler = new ExchangeRequestHandler();
-      
-      this.controlMembershipListener = new ControlMembershipListener();
-      
-      this.controlMessageDispatcher = new MessageDispatcher(controlChannel, controlMessageListener,
-                                                            controlMembershipListener, requestHandler, true);      
-      this.dataReceiver = new DataReceiver();
-      
-      dataChannel.setReceiver(dataReceiver);                  
-   }
-   
-   // ServiceMBeanSupport overrides ---------------------------------
-   
-   protected void startService() throws Exception
-   {
-      controlChannel.connect(groupName);
-      
-      dataChannel.connect(groupName);
-
-      currentAddress = controlChannel.getLocalAddress();
-       
-      super.startService();  
-      
-      handleAddressNodeMapping(currentAddress, nodeId);
-      
-      sendNodeIdRequest(currentAddress, nodeId);      
-   }
-   
-   protected void stopService() throws Exception
-   {
-      super.stopService();
-      
-      controlChannel.close();
-      
-      dataChannel.close();
-   }
-   
-   // Exchange implementation ---------------------------------------        
-   
-   public Binding bindQueue(String queueName, String condition, Filter filter, boolean noLocal, boolean durable,
-                            MessageStore ms, PersistenceManager pm,
-                            int fullSize, int pageSize, int downCacheSize) throws Exception
-   {           
-      Binding binding = super.bindQueue(queueName, condition, filter, noLocal, durable,
-                                        ms, pm, fullSize, pageSize, downCacheSize);
-      
-      sendBindMessage(queueName, condition, filter == null ? null : filter.getFilterString(), noLocal,
-                      binding.getChannelId(), durable);
-
-      return binding;
-   }
-   
-   public Binding unbindQueue(String queueName) throws Throwable
-   {
-      Binding binding = super.unbindQueue(queueName);
-      
-      sendUnbindMessage(binding.getQueueName());
-    
-      return binding;
-   }
-   
-   //ExchangeSupport overrides -------------------------------------------------
-   
-   protected void loadBindings() throws Exception
-   {
-      // TODO I need to know whether this call times out - how do I know this??
-      boolean isState = controlChannel.getState(null, GET_STATE_TIMEOUT);
-                              
-      if (!isState)
-      {       
-         //Must be first member in group or non clustered- we load the state ourself from the database
-         super.loadBindings();      
-      }
-      else
-      {
-         //The state will be set in due course via the MessageListener - we must wait until this happens
-         
-         synchronized (setStateLock)
-         {
-            //TODO we should implement a timeout on this
-            while (!stateSet)
-            {
-               setStateLock.wait();
-            } 
-         }
-      }
-   }
-   
-   // Protected ---------------------------------------------------------------------------------------
-   
-   /*
-    * Asynchronously cast the message.
-    * I.e. we just hand the message to JGroups and return immediately
-    * JGroups will then take care of delivering the message
-    */
-   protected void asyncCastMessage(String routingKey, org.jboss.messaging.core.Message msg) throws Exception
-   {            
-      MessageRequest request = new MessageRequest(routingKey, msg);
-      
-      //TODO - handle serialization more efficiently
-
-      dataChannel.send(new Message(null, null, request));
-   }
-   
-   protected abstract void routeFromCluster(MessageReference ref, String routingKey) throws Exception;
-      
-   // Private ------------------------------------------------------------------------------------------
-      
-   /*
-    * Called when another node adds a binding
-    */
-   private void addBindingFromCluster(String nodeId, String queueName, String condition,
-                                      String filterString, boolean noLocal, long channelID, boolean durable)
-      throws Exception
-   {
-      lock.writeLock().acquire();
-      
-      try
-      {                     
-         //Sanity
-         if (!nodeIdAddressMap.containsKey(nodeId))
-         {
-            throw new IllegalStateException("Cannot find address for node: " + nodeId);
-         }
-         
-         // We currently only allow one binding per name per node
-         Map nameMap = (Map)nameMaps.get(nodeId);
-         
-         Binding binding = null;
-         
-         if (nameMap != null)
-         {
-            binding = (Binding)nameMap.get(queueName);
-         }
-         
-         if (binding != null)
-         {
-            throw new IllegalArgumentException(this.nodeId + "Binding already exists for node Id " + nodeId + " queue name " + queueName);
-         }
-         
-         binding = new SimpleBinding(nodeId, queueName, condition, filterString,
-                                     noLocal, channelID, durable); 
-         
-         binding.activate();
-         
-         addBinding(binding);         
-      }
-      finally
-      {
-         lock.writeLock().release();
-      }
-   }
-   
-   /*
-    * Called when another node removes a binding
-    */
-   private void removeBindingFromCluster(String nodeId, String queueName) throws Exception
-   {
-      lock.writeLock().acquire();
-      
-      try
-      {         
-         // Sanity
-         if (!nodeIdAddressMap.containsKey(nodeId))
-         {
-            throw new IllegalStateException("Cannot find address for node: " + nodeId);
-         }
-         
-         removeBinding(nodeId, queueName);         
-      }
-      finally
-      {
-         lock.writeLock().release();
-      }
-   }
-   
-   private void handleAddressNodeMapping(Address address, String nodeId) throws Exception
-   {
-      lock.writeLock().acquire();
-      
-      try
-      { 
-         nodeIdAddressMap.put(nodeId, address.toString());
-      }
-      finally
-      {
-         lock.writeLock().release();
-      }
-   }
-      
-   private void removeBindingsForAddress(String address) throws Exception
-   {
-      lock.writeLock().acquire();
-      
-      try
-      { 
-         Iterator iter = nodeIdAddressMap.entrySet().iterator();
-         
-         String nodeId = null;
-         while (iter.hasNext())
-         {
-            Map.Entry entry = (Map.Entry)iter.next();
-            
-            String str = (String)entry.getValue();
-            
-            if (str.equals(address))
-            {
-               nodeId = (String)entry.getKey();
-            }
-         }
-         
-         if (nodeId == null)
-         {
-            throw new IllegalStateException("Cannot find node id for address: " + address);
-         }
-         
-         Map nameMap = (Map)nameMaps.get(nodeId);
-
-         if (nameMap != null)
-         {
-            List toRemove = new ArrayList();
-            
-            iter = nameMap.values().iterator();
-            
-            while (iter.hasNext())
-            {
-               Binding binding = (Binding)iter.next();
-               
-               if (!binding.isDurable())
-               {
-                  toRemove.add(binding);
-               }
-            }
-            
-            iter = toRemove.iterator();
-            
-            while (iter.hasNext())
-            {
-               Binding binding = (Binding)iter.next();
-               
-               removeBinding(nodeId, binding.getQueueName());
-            }
-         }
-      }
-      finally
-      {
-         lock.writeLock().release();
-      }
-   }
-   
-   /*
-    * Multicast a bind request to all clustered exchange instances in the group
-    */
-   private void sendBindMessage(String queueName, String condition,
-                                String filterString, boolean noLocal,
-                                long channelId, boolean durable) throws Exception
-   {
-      // TODO handle serialization more efficiently
-      
-      BindRequest request =
-         new BindRequest(nodeId, queueName, condition, filterString, noLocal, channelId, durable);
-      
-      Message message = new Message(null, null, request);
-      
-      controlMessageDispatcher.castMessage(null, message, GroupRequest.GET_ALL, CAST_TIMEOUT);
-      
-      //We don't actually care if some of the members didn't receive the message (e.g. by crashing)
-      //so we ignore the return value
-      
-      // TODO - How do we know if the call timed out???
-      //We need to handle this
-      
-   }
-   
-   /*
-    * Multicast a unbind request to all clustered exchange instances in the group
-    */
-   private void sendUnbindMessage(String queueName) throws Exception
-   {
-      //TODO handle serialization more efficiently
-      
-      UnbindRequest request = new UnbindRequest(nodeId, queueName);
-      
-      Message message = new Message(null, null, request);
-      
-      controlMessageDispatcher.castMessage(null, message, GroupRequest.GET_ALL, CAST_TIMEOUT);
-      
-      //We don't actually care if some of the members didn't receive the message (e.g. by crashing)
-      //so we ignore the return value
-      
-      //TODO - How do we know if the call timed out???
-      //We need to handle this      
-   }
-   
-   private void sendNodeIdRequest(Address address, String nodeId) throws Exception
-   {
-      SendNodeIdRequest request = new SendNodeIdRequest(address, nodeId);
-      
-      Message message = new Message(null, null, request);
-      
-      controlMessageDispatcher.castMessage(null, message, GroupRequest.GET_ALL, CAST_TIMEOUT);      
-   }
-   
-   //TODO - Sort out serialization properly
-   
-   private byte[] getStateAsBytes() throws Exception
-   {
-      List bindings = new ArrayList();
-      
-      Iterator iter = nameMaps.values().iterator();
-      
-      while (iter.hasNext())
-      {
-         Map map  = (Map)iter.next();
-         
-         Iterator iter2 = map.values().iterator();
-         
-         while (iter2.hasNext())
-         {
-            bindings.add(iter2.next());
-         }
-      }
-      
-      SharedState state = new SharedState(bindings, nodeIdAddressMap);
-      
-      byte[] bytes = Util.objectToByteBuffer(state);
-      
-      return bytes;
-   }
-   
-   private void processStateBytes(byte[] bytes) throws Exception
-   {
-      SharedState state = (SharedState)Util.objectFromByteBuffer(bytes);
-      
-      nameMaps.clear();
-      
-      conditionMap.clear();
-                 
-      List bindings = state.getBindings();
-      
-      Iterator iter = bindings.iterator();
-      
-      while (iter.hasNext())
-      {
-         Binding binding = (Binding)iter.next();
-         
-         addBinding(binding);
-      }
-      
-      this.nodeIdAddressMap.clear();
-      
-      this.nodeIdAddressMap.putAll(state.getNodeIdAddressMap());
-   }
-   
-
-   
-   // Inner classes -------------------------------------------------------------------
-    
-   /*
-    * This class is used to manage state on the control channel
-    */
-   private class ControlMessageListener implements MessageListener
-   {
-      public byte[] getState()
-      {     
-         try
-         {
-            lock.writeLock().acquire();
-         }
-         catch (InterruptedException e)
-         {
-            log.error("Thread Interrupted", e);
-         }
-         try
-         {
-            return getStateAsBytes();
-         }
-         catch (Exception e)
-         {
-            IllegalStateException e2 = new IllegalStateException(e.getMessage());
-            e2.setStackTrace(e.getStackTrace());
-            throw e2;
-         }     
-         finally
-         {
-            lock.writeLock().release();
-         }
-      }
-      
-      public void receive(Message message)
-      {         
-         log.info("Received message on control channel: " + message);
-      }
-      
-      public void setState(byte[] bytes)
-      {
-         if (bytes != null)
-         {
-            
-            try
-            {
-               lock.writeLock().acquire();         
-            }
-            catch (InterruptedException e)
-            {
-               log.error("Thread interrupted", e);
-            }
-            try
-            {
-               processStateBytes(bytes);               
-            }
-            catch (Exception e)
-            {
-               IllegalStateException e2 = new IllegalStateException(e.getMessage());
-               e2.setStackTrace(e.getStackTrace());
-               throw e2;
-            }
-            finally
-            {
-               lock.writeLock().release();
-            }
-         }
-               
-         synchronized (setStateLock)
-         {
-            stateSet = true;
-            setStateLock.notify();
-         }
-      }      
-   }
-   
-   
-   /*
-    * This class is used to listen for messages on the data channel
-    */
-   private class DataReceiver implements Receiver
-   {
-      public void block()
-      {   
-         //NOOP
-      }
-
-      public void suspect(Address address)
-      { 
-         //NOOP
-      }
-
-      public void viewAccepted(View view)
-      { 
-         //NOOP
-      }
-
-      public byte[] getState()
-      {         
-         //NOOP
-         return null;
-      }
-      
-      public void receive(Message message)
-      {
-         try
-         {
-            //TODO handle deserialization more efficiently
-            
-            Object object = message.getObject();
-            
-            if (object instanceof MessageRequest)
-            {
-               MessageRequest request = (MessageRequest)object;
-               
-               //Need to reference the message
-               MessageReference ref = null;
-               try
-               {
-                  ref = ms.reference(request.getMessage());
-                  
-                  routeFromCluster(ref, request.getRoutingKey());
-               }
-               finally
-               {
-                  if (ref != null)
-                  {
-                     ref.releaseMemoryReference();
-                  }
-               }
-            }
-         }
-         catch (Exception e)
-         {
-            IllegalStateException e2 = new IllegalStateException(e.getMessage());
-            e2.setStackTrace(e.getStackTrace());
-            throw e2;
-         }
-         
-      }
-      
-      public void setState(byte[] bytes)
-      {
-         //NOOP         
-      }      
-   }
-     
-   /*
-    * We use this class so we notice when members leave the group
-    */
-   private class ControlMembershipListener implements MembershipListener
-   {
-      public void block()
-      {
-         //NOOP
-      }
-
-      public void suspect(Address address)
-      {
-         //NOOP
-      }
-
-      public void viewAccepted(View view)
-      {
-         if (currentView != null)
-         {
-            Iterator iter = currentView.getMembers().iterator();
-            
-            while (iter.hasNext())
-            {
-               Address address = (Address)iter.next();
-               
-               if (!view.containsMember(address))
-               {
-                  //Member must have left
-                  
-                  //We don't remove bindings for ourself
-                  
-                  if (!address.equals(currentAddress))
-                  {                  
-                     try
-                     {
-                        removeBindingsForAddress(address.toString());
-                     }               
-                     catch (Exception e)
-                     {
-                        IllegalStateException e2 = new IllegalStateException(e.getMessage());
-                        e2.setStackTrace(e.getStackTrace());
-                        throw e2;
-                     }
-                  }
-               }
-            }
-         }
-         
-         currentView = view;
-      }
-
-      public byte[] getState()
-      {        
-         //NOOP
-         return null;
-      }     
-   }
-   
-   /*
-    * This class is used to handle synchronous requests
-    */
-   private class ExchangeRequestHandler implements RequestHandler
-   {
-      public Object handle(Message message)
-      {
-         //TODO should we propagate the exceptions up??
-         
-         //TODO handle deserialization more efficiently
-         
-         Object request = message.getObject();
-              
-         if (request instanceof BindRequest)
-         {
-            BindRequest br = (BindRequest)request;
-            
-            try
-            {            
-               addBindingFromCluster(br.getNodeId(), br.getQueueName(), br.getCondition(),
-                                     br.getFilterString(), br.isNoLocal(), br.getChannelId(), br.isDurable());
-            }
-            catch (Exception e)
-            {
-               IllegalStateException e2 = new IllegalStateException(e.getMessage());
-               e2.setStackTrace(e.getStackTrace());
-               throw e2;
-            }
-         }
-         else if (request instanceof UnbindRequest)
-         {
-            UnbindRequest ubr = (UnbindRequest)request;
-            
-            try
-            {
-               removeBindingFromCluster(ubr.getNodeId(), ubr.getQueueName());
-            }
-            catch (Exception e)
-            {
-               IllegalStateException e2 = new IllegalStateException(e.getMessage());
-               e2.setStackTrace(e.getStackTrace());
-               throw e2;
-            }
-         }
-         else if (request instanceof SendNodeIdRequest)
-         {
-            SendNodeIdRequest snr = (SendNodeIdRequest)request;
-            
-            try
-            {
-               handleAddressNodeMapping(snr.getAddress(), snr.getNodeId());
-            }
-            catch (Exception e)
-            {
-               IllegalStateException e2 = new IllegalStateException(e.getMessage());
-               e2.setStackTrace(e.getStackTrace());
-               throw e2;
-            }
-         }
-         else
-         {
-            throw new IllegalArgumentException("Invalid request: " + request);
-         }
-            
-         return null;
-      }
-      
-   }   
-}
\ No newline at end of file

Deleted: trunk/src/main/org/jboss/messaging/core/plugin/exchange/ClusteredTopicExchange.java
===================================================================
--- trunk/src/main/org/jboss/messaging/core/plugin/exchange/ClusteredTopicExchange.java	2006-09-03 17:56:48 UTC (rev 1254)
+++ trunk/src/main/org/jboss/messaging/core/plugin/exchange/ClusteredTopicExchange.java	2006-09-05 16:08:05 UTC (rev 1255)
@@ -1,371 +0,0 @@
-/*
- * JBoss, Home of Professional Open Source
- * Copyright 2005, JBoss Inc., and individual contributors as indicated
- * by the @authors tag. See the copyright.txt in the distribution for a
- * full listing of individual contributors.
- *
- * This is free software; you can redistribute it and/or modify it
- * under the terms of the GNU Lesser General Public License as
- * published by the Free Software Foundation; either version 2.1 of
- * the License, or (at your option) any later version.
- *
- * This software is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this software; if not, write to the Free
- * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
- * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
- */
-package org.jboss.messaging.core.plugin.exchange;
-
-import java.util.ArrayList;
-import java.util.Iterator;
-import java.util.List;
-
-import javax.sql.DataSource;
-import javax.transaction.TransactionManager;
-
-import org.jboss.jms.server.QueuedExecutorPool;
-import org.jboss.logging.Logger;
-import org.jboss.messaging.core.Message;
-import org.jboss.messaging.core.MessageReference;
-import org.jboss.messaging.core.local.MessageQueue;
-import org.jboss.messaging.core.plugin.IdManager;
-import org.jboss.messaging.core.plugin.contract.MessageStore;
-import org.jboss.messaging.core.plugin.contract.PersistenceManager;
-import org.jboss.messaging.core.tx.Transaction;
-import org.jboss.messaging.core.tx.TransactionRepository;
-import org.jboss.messaging.core.tx.TxCallback;
-import org.jgroups.Channel;
-
-/**
- * A Clustered TopicExchange
- * 
- * Roughly based on the AMQP topic exchange
- *
- * Currently we don't support hierarchies of topics, but it should be fairly
- * straightforward to extend this class to support them.
- * 
- * For the topic exchange the condition should be just be the topic name
- * 
- * When we support topic hierarchies this will change to a proper wildcard.
- * 
- * @author <a href="mailto:tim.fox at jboss.com">Tim Fox</a>
- * @version <tt>$Revision: 1.1 $</tt>
- *
- * $Id$
- *
- */
-public class ClusteredTopicExchange extends ClusteredExchangeSupport
-{
-   private static final Logger log = Logger.getLogger(ClusteredTopicExchange.class);     
-   
-   protected TransactionRepository tr;  
-   
-   protected PersistenceManager pm;
-   
-   protected boolean strictPersistentMessageReliability;
-      
-   public ClusteredTopicExchange() throws Exception
-   { 
-   }      
-   
-   /*
-    * This constructor should only be used for testing
-    */
-   public ClusteredTopicExchange(DataSource ds, TransactionManager tm)
-   {
-      super(ds, tm);
-   }
-   
-   public void injectAttributes(Channel controlChannel, Channel dataChannel,
-                                String groupName, String exchangeName, String nodeID,
-                                MessageStore ms, IdManager im, QueuedExecutorPool pool,
-                                TransactionRepository tr, PersistenceManager pm) throws Exception
-   {
-      super.injectAttributes(controlChannel, dataChannel,
-                             groupName, exchangeName, nodeID, ms, im, pool);
-      
-      this.tr = tr;
-      
-      this.pm = pm;
-   }     
-   
-   public boolean route(MessageReference ref, String routingKey, Transaction tx) throws Exception
-   {
-      if (ref == null)
-      {
-         throw new IllegalArgumentException("Message reference is null");
-      }
-      
-      if (routingKey == null)
-      {
-         throw new IllegalArgumentException("Routing key is null");
-      }
-      
-      lock.readLock().acquire();
-      
-      try
-      {      
-         // We route on the condition
-         List bindings = (List)conditionMap.get(routingKey);
-      
-         if (bindings != null)
-         {                
-            //When routing a reliable message to multiple durable subscriptions we
-            //must ensure that the message is persisted in all durable subscriptions
-            //Therefore if the message is reliable and there is more than one durable subscription
-            //Then we create an internal transaction and route the message in the context of that
-            
-            //TODO we can optimise this out by storing this as a flag somewhere
-            boolean startInternalTx = false;
-            
-            if (tx == null)
-            {
-               if (ref.isReliable())
-               {
-                  Iterator iter = bindings.iterator();
-                  
-                  int count = 0;
-                  
-                  while (iter.hasNext())
-                  {
-                     Binding binding = (Binding)iter.next();
-                     
-                     if (binding.isDurable())
-                     {
-                        count++;
-                        
-                        if (count == 2)
-                        {
-                           startInternalTx = true;
-                           
-                           break;
-                        }                          
-                     }
-                  }
-               }
-               
-               if (startInternalTx)
-               {
-                  tx = tr.createTransaction();
-               }
-            }
-                       
-            Iterator iter = bindings.iterator();
-            
-            boolean sendRemotely = false;
-
-            while (iter.hasNext())
-            {
-               Binding binding = (Binding)iter.next();
-               
-               if (binding.isActive())
-               {            
-                  if (binding.getNodeId().equals(this.nodeId))
-                  {
-                     //It's a local binding so we pass the message on to the subscription
-                     MessageQueue subscription = binding.getQueue();
-                  
-                     subscription.handle(null, ref, tx);
-                  }
-                  else
-                  {
-                     //It's a binding on a different exchange instance on the cluster
-                     sendRemotely = true;                     
-                     
-                     //For remote durable subscriptions we persist the message *before* sending
-                     //it to the remote node. We do this for two reasons
-                     //1) For reliable messages we must ensure that the message is persisted in all durable subscriptions
-                     // and not a subset in case of failure - if we were persisting on receipt at the remote
-                     // durable sub then we would have to use expensive 2PC to ensure this
-                     //2) We can insert in all the durable subs in a single JDBC tx rather than many
-                     
-                     if (ref.isReliable() && binding.isDurable())
-                     {
-                        //Insert the reference into the database
-                        pm.addReference(binding.getChannelId(), ref, tx);
-                     }
-                  }                     
-               }
-            } 
-            
-            //Now we've sent the message to all the local subscriptions, we might also need
-            //to multicast the message to the other exchange instances on the cluster if there are
-            //subscriptions on those nodes that need to receive the message
-            if (sendRemotely)
-            {
-               if (tx == null)
-               {
-                  //We just throw the message on the network - no need to wait for any reply                     
-                  asyncCastMessage(routingKey, ref.getMessage());               
-                  
-                  //Big TODO - is this ok for reliable messages ?????????
-                  //What if this node fails and the other nodes don't receive the cast?
-                  //We have already persisted the message so we won't lose it
-                  //but the message won't be available to be consumed on the other node
-                  //until that node restarts - which might be 10 years from now.
-                  //What we should really do is, for persistent messages, save and cast them as 2 participants
-                  //in a fully recoverable 2pc transaction - but this is going to be a performance hit                                    
-                  //
-                  //Need to think about this some more
-                  
-               }
-               else
-               {
-                  CastingCallback callback = (CastingCallback)tx.getKeyedCallback(this);
-                  
-                  if (callback == null)
-                  {
-                     callback = new CastingCallback();
-                     
-                     tx.addKeyedCallback(callback, this);
-                  }
-                      
-                  callback.addMessage(routingKey, ref.getMessage());                  
-               }
-            }
-            
-            if (startInternalTx)
-            {
-               tx.commit();
-            }
-         }
-      }
-      finally
-      {                  
-         lock.readLock().release();
-      }
-         
-      // We don't care if the individual subscriptions accepted the reference
-      // We always return true for a topic
-      return true; 
-   }
-   
-   /*
-    * We have received a reference cast from another node - and we need to route it to our local
-    * subscriptions    
-    */
-   protected void routeFromCluster(MessageReference ref, String routingKey) throws Exception
-   {
-      lock.readLock().acquire();
-      
-      try
-      {      
-         // We route on the condition
-         List bindings = (List)conditionMap.get(routingKey);
-      
-         if (bindings != null)
-         {                                
-            Iterator iter = bindings.iterator();
-            
-            while (iter.hasNext())
-            {
-               Binding binding = (Binding)iter.next();
-               
-               if (binding.isActive())
-               {            
-                  if (binding.getNodeId().equals(this.nodeId))
-                  {
-//                     //When receiving a reliable message from the network and routing to
-//                     //a durable subscription, then the message has always been persisted
-//                     //before the send
-//                     if (ref.isReliable() && binding.isDurable())
-//                     {
-//                        //Do what?
-//                     }
-                     
-                     //It's a local binding so we pass the message on to the subscription
-                     MessageQueue subscription = binding.getQueue();
-                  
-                     subscription.handleDontPersist(null, ref, null);
-                  }                               
-               }
-            }                          
-         }
-      }
-      finally
-      {                  
-         lock.readLock().release();
-      }
-   }
-   
-   /*
-    * This class casts messages across the cluster on commit of a transaction
-    */
-   private class CastingCallback implements TxCallback
-   {           
-      private List messages = new ArrayList();
-      
-      private void addMessage(String routingKey, Message message)
-      {
-         messages.add(new MessageHolder(routingKey, message));
-      }
-      
-      private CastingCallback()
-      {
-         messages = new ArrayList();
-      }
-
-      public void afterCommit(boolean onePhase) throws Exception
-      {
-         //Cast the messages
-         //TODO - would it be any more performant if we cast them in a single jgroups message?
-         Iterator iter = messages.iterator();
-         
-         while (iter.hasNext())
-         {
-            MessageHolder holder = (MessageHolder)iter.next();
-            
-            asyncCastMessage(holder.getRoutingKey(), holder.getMessage());
-         }
-      }
-
-      public void afterPrepare() throws Exception
-      { 
-      }
-
-      public void afterRollback(boolean onePhase) throws Exception
-      {
-      }
-
-      public void beforeCommit(boolean onePhase) throws Exception
-      {
-      }
-
-      public void beforePrepare() throws Exception
-      {
-      }
-
-      public void beforeRollback(boolean onePhase) throws Exception
-      {
-      }
-      
-      private class MessageHolder
-      {
-         String routingKey;
-         
-         Message message;
-         
-         private MessageHolder(String routingKey, Message message)
-         {
-            this.routingKey = routingKey;
-            this.message = message;
-         }
-         
-         private String getRoutingKey()
-         {
-            return routingKey;
-         }
-         
-         private Message getMessage()
-         {
-            return message;
-         }
-      }
-     
-   }    
-}

Added: trunk/src/main/org/jboss/messaging/core/plugin/exchange/DefaultBinding.java
===================================================================
--- trunk/src/main/org/jboss/messaging/core/plugin/exchange/DefaultBinding.java	2006-09-03 17:56:48 UTC (rev 1254)
+++ trunk/src/main/org/jboss/messaging/core/plugin/exchange/DefaultBinding.java	2006-09-05 16:08:05 UTC (rev 1255)
@@ -0,0 +1,243 @@
+/*
+ * JBoss, Home of Professional Open Source
+ * Copyright 2005, JBoss Inc., and individual contributors as indicated
+ * by the @authors tag. See the copyright.txt in the distribution for a
+ * full listing of individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+package org.jboss.messaging.core.plugin.exchange;
+
+import java.io.DataInput;
+import java.io.DataOutput;
+import java.io.Externalizable;
+import java.io.IOException;
+import java.io.ObjectInput;
+import java.io.ObjectOutput;
+
+import org.jboss.logging.Logger;
+import org.jboss.messaging.core.local.MessageQueue;
+
+/**
+ * A DefaultBinding
+ * 
+ * Inspired from an AMQP binding
+ * 
+ * A binding describes how a queue is bound into an exchange
+ * 
+ * Bindings have a condition, the condition describes how messages are routed to the
+ * queue.
+ * 
+ * For a direct exchange, which would be used for point to point queues then the condition
+ * is something like "routing_key=name" - so the queue would receive the message if the routing
+ * key matched the name excactly.
+ * 
+ * For a topic, the queue (subscription) name is not relevant, so the condition would be something like
+ * "routing_key=news.uk.*", so the subscription would receive any messages sent with a routing key
+ * that starts with "news.uk."
+ * 
+ * 
+ * @author <a href="mailto:tim.fox at jboss.com">Tim Fox</a>
+ * @version <tt>$Revision: 1.1 $</tt>
+ *
+ * $Id$
+ *
+ */
+public class DefaultBinding implements Binding, Externalizable
+{
+   private static final long serialVersionUID = -5518552214992031242L;
+
+   private static final Logger log = Logger.getLogger(DefaultBinding.class);
+   
+   private static final byte NULL = 0;
+   
+   private static final byte NOT_NULL = 1;   
+
+   private String nodeId;
+   
+   private String queueName;
+   
+   private String condition;
+   
+   private MessageQueue queue;
+    
+   private boolean noLocal;
+   
+   private boolean active;
+   
+   private String selector;
+   
+   private long channelId;
+     
+   private boolean durable;
+   
+   public DefaultBinding()
+   {      
+   }
+
+   public DefaultBinding(String nodeId, String queueName, String condition, String selector,
+                        boolean noLocal, long channelId, boolean durable)
+   {
+      this.nodeId = nodeId;
+      
+      this.queueName = queueName;
+      
+      this.condition = condition;      
+      
+      this.noLocal = noLocal;
+      
+      this.selector = selector;
+      
+      this.channelId = channelId;
+         
+      //Bindings are always created de-activated
+      this.active = false;
+      
+      this.durable = durable;          
+   }
+   
+   public String getNodeId()
+   {
+      return nodeId;
+   }
+     
+   public String getQueueName()
+   {
+      return queueName;
+   }
+   
+   public String getCondition()
+   {
+      return condition;
+   }
+   
+   public MessageQueue getQueue()
+   {
+      return queue;
+   }
+
+   public boolean isNoLocal()
+   {
+      return noLocal;
+   }
+   
+   public void activate()
+   {
+      active = true;
+   }
+   
+   public void deactivate()
+   {
+      active = false;
+   }
+   
+   public boolean isActive()
+   {
+      return active;
+   }
+   
+   public String getSelector()
+   {
+      return selector;
+   }
+   
+   public long getChannelId()
+   {
+      return channelId;
+   }
+    
+   public boolean isDurable()
+   {
+      return durable;
+   }
+   
+   public void setQueue(MessageQueue queue)
+   {
+      this.queue = queue;
+      
+      if (queue != null)
+      {
+         this.channelId = queue.getChannelID();
+      }            
+   }
+   
+
+   public void readExternal(ObjectInput in) throws IOException, ClassNotFoundException
+   {
+      nodeId = in.readUTF();
+      
+      queueName = in.readUTF();
+      
+      condition = in.readUTF();
+      
+      noLocal = in.readBoolean();
+      
+      active = in.readBoolean();
+      
+      selector = readString(in);
+      
+      channelId = in.readLong();
+      
+      durable = in.readBoolean();
+   }
+
+   public void writeExternal(ObjectOutput out) throws IOException
+   {
+      out.writeUTF(nodeId);
+      
+      out.writeUTF(queueName);
+      
+      out.writeUTF(condition);
+      
+      out.writeBoolean(noLocal);
+      
+      out.writeBoolean(active);
+      
+      writeString(selector, out);
+      
+      out.writeLong(channelId);
+      
+      out.writeBoolean(durable);
+   }
+   
+   private void writeString(String string, DataOutput out) throws IOException
+   {
+      if (string == null)
+      {
+         out.writeByte(NULL);
+      }
+      else
+      {
+         out.writeByte(NOT_NULL);
+         out.writeUTF(string);
+      }
+   }
+   
+   private String readString(DataInput in) throws IOException
+   {
+      byte b = in.readByte();
+      
+      if (b == NULL)
+      {
+         return null;
+      }
+      else
+      {
+         return in.readUTF();
+      }
+   }
+   
+}

Modified: trunk/src/main/org/jboss/messaging/core/plugin/exchange/DirectExchange.java
===================================================================
--- trunk/src/main/org/jboss/messaging/core/plugin/exchange/DirectExchange.java	2006-09-03 17:56:48 UTC (rev 1254)
+++ trunk/src/main/org/jboss/messaging/core/plugin/exchange/DirectExchange.java	2006-09-05 16:08:05 UTC (rev 1255)
@@ -27,6 +27,7 @@
 import javax.transaction.TransactionManager;
 
 import org.jboss.jms.server.QueuedExecutorPool;
+import org.jboss.logging.Logger;
 import org.jboss.messaging.core.Delivery;
 import org.jboss.messaging.core.MessageReference;
 import org.jboss.messaging.core.local.MessageQueue;
@@ -50,6 +51,8 @@
  */
 public class DirectExchange extends ExchangeSupport
 {
+   private static final Logger log = Logger.getLogger(DirectExchange.class);
+      
    //To avoid having to lookup the name map based on the node id every time we route a message
    //we store a reference here
    private Map shortcutNameMap;
@@ -65,7 +68,8 @@
    {
       super(ds, tm);
    }
-      
+   
+     
    /*
     * Direct exchanges aren't clustered
     *

Modified: trunk/src/main/org/jboss/messaging/core/plugin/exchange/ExchangeSupport.java
===================================================================
--- trunk/src/main/org/jboss/messaging/core/plugin/exchange/ExchangeSupport.java	2006-09-03 17:56:48 UTC (rev 1254)
+++ trunk/src/main/org/jboss/messaging/core/plugin/exchange/ExchangeSupport.java	2006-09-05 16:08:05 UTC (rev 1255)
@@ -100,8 +100,7 @@
    protected void injectAttributes(String exchangeName, String nodeID,
                                    MessageStore ms, IdManager im, QueuedExecutorPool pool)
       throws Exception
-   {
-            
+   {            
       this.exchangeName = exchangeName;
       
       this.nodeId = nodeID;
@@ -111,17 +110,13 @@
       this.idManager = im;
       
       this.queuedExecutorPool = pool;            
+      
+      //We can't load the bindings until attributes have been set - so we can't do it in
+      //startService()
+      loadBindings();
    }
    
-   // ServiceMBeanSupport overrides ---------------------------------
    
-   protected void startService() throws Exception
-   {
-      super.startService();
-       
-      loadBindings();
-   }
-   
    // Exchange implementation ---------------------------------------        
       
    public Binding bindQueue(String queueName, String condition, Filter filter, boolean noLocal, boolean durable,
@@ -167,17 +162,17 @@
                                                (QueuedExecutor)queuedExecutorPool.get(),
                                                filter);
             
-         binding = new SimpleBinding(nodeId, queueName, condition, filter == null ? null : filter.getFilterString(),
+         binding = new DefaultBinding(nodeId, queueName, condition, filter == null ? null : filter.getFilterString(),
                                      noLocal, queue.getChannelID(), durable);         
          
          binding.setQueue(queue);
          
          binding.activate();
          
-         if (durable)
-         {
-            queue.load();
-         }
+//         if (durable)
+//         {
+//            queue.load();
+//         }
          
          addBinding(binding);
                
@@ -185,7 +180,8 @@
          {
             //Need to write the binding to the db
             
-            insertBinding(binding);            
+            insertBinding(binding);       
+            log.info("Inserted binding");
          }
                            
          return binding;   
@@ -375,6 +371,11 @@
          lock.writeLock().release();
       }
    }
+   
+   public void recover() throws Exception
+   {
+      //NOOP
+   }
      
    // Protected -----------------------------------------------------
    
@@ -382,6 +383,8 @@
    {
       lock.writeLock().acquire();
       
+      log.info(this + " loading bindings");
+      
       try
       {
          List list = getBindings();
@@ -392,7 +395,9 @@
          {
             Binding binding = (Binding)iter.next();
             
-            addBinding(binding);                        
+            addBinding(binding);              
+            
+            log.info(this + "added binding: " + binding.getQueueName());
          }
       }
       finally
@@ -414,6 +419,10 @@
          conn = ds.getConnection();
          
          ps = conn.prepareStatement(getSQLStatement("INSERT_BINDING"));
+         
+         log.info("SQL:" + getSQLStatement("INSERT_BINDING"));
+         log.info(binding.getQueueName());
+         log.info(exchangeName);
           
          ps.setString(1, this.exchangeName);
          ps.setString(2, this.nodeId);
@@ -445,6 +454,8 @@
       PreparedStatement ps  = null;
       TransactionWrapper wrap = new TransactionWrapper();
       
+      log.info("deleting binding: " + queueName);
+      
       try
       {
          conn = ds.getConnection();
@@ -491,8 +502,27 @@
       {
          conn = ds.getConnection();
          
-         ps = conn.prepareStatement(this.getSQLStatement("LOAD_BINDINGS"));
          
+         ps = conn.prepareStatement("SELECT EXCHANGE_NAME FROM JMS_EXCHANGE_BINDING");
+         rs = ps.executeQuery();
+         if (rs.next())
+         {
+            String exchangeName = rs.getString(1);
+            log.info("*************** THERE IS " + exchangeName + " ROWS");
+         }
+         else
+         {
+            log.info("************ NO ROWS");
+         }
+         rs.close();
+         ps.close();
+         
+         ps = conn.prepareStatement(getSQLStatement("LOAD_BINDINGS"));
+         
+         log.info("SQL:" + getSQLStatement("LOAD_BINDINGS"));
+         
+         log.info("exchange name:" + this.exchangeName);
+         
          ps.setString(1, this.exchangeName);
 
          rs = ps.executeQuery();
@@ -514,10 +544,12 @@
             //We don't load the actual queue - this is because we don't know the paging params until
             //activation time
                     
-            Binding binding = new SimpleBinding(nodeId, queueName, condition, selector, noLocal, channelId, true);
+            Binding binding = new DefaultBinding(nodeId, queueName, condition, selector, noLocal, channelId, true);
             
             list.add(binding);
          }
+         
+         log.info("Loaded: " + list.size() + " bindings");
              
          return list;
       }

Deleted: trunk/src/main/org/jboss/messaging/core/plugin/exchange/SharedState.java
===================================================================
--- trunk/src/main/org/jboss/messaging/core/plugin/exchange/SharedState.java	2006-09-03 17:56:48 UTC (rev 1254)
+++ trunk/src/main/org/jboss/messaging/core/plugin/exchange/SharedState.java	2006-09-05 16:08:05 UTC (rev 1255)
@@ -1,61 +0,0 @@
-/*
- * JBoss, Home of Professional Open Source
- * Copyright 2005, JBoss Inc., and individual contributors as indicated
- * by the @authors tag. See the copyright.txt in the distribution for a
- * full listing of individual contributors.
- *
- * This is free software; you can redistribute it and/or modify it
- * under the terms of the GNU Lesser General Public License as
- * published by the Free Software Foundation; either version 2.1 of
- * the License, or (at your option) any later version.
- *
- * This software is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this software; if not, write to the Free
- * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
- * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
- */
-package org.jboss.messaging.core.plugin.exchange;
-
-import java.io.Serializable;
-import java.util.List;
-import java.util.Map;
-
-/**
- * A SharedState
- *
- * @author <a href="mailto:tim.fox at jboss.com">Tim Fox</a>
- * @version <tt>$Revision: 1.1 $</tt>
- *
- * $Id$
- *
- */
-public class SharedState implements Serializable
-{
-   private static final long serialVersionUID = 7782131373080845107L;
-
-   private List bindings;
-   
-   private Map nodeIdAddressMap;
-   
-   public SharedState(List bindings, Map nodeIdAddressMap)
-   {
-      this.bindings = bindings;
-      
-      this.nodeIdAddressMap = nodeIdAddressMap;
-   }
-   
-   public List getBindings()
-   {
-      return bindings;
-   }
-   
-   public Map getNodeIdAddressMap()
-   {
-      return nodeIdAddressMap;
-   }
-}

Deleted: trunk/src/main/org/jboss/messaging/core/plugin/exchange/SimpleBinding.java
===================================================================
--- trunk/src/main/org/jboss/messaging/core/plugin/exchange/SimpleBinding.java	2006-09-03 17:56:48 UTC (rev 1254)
+++ trunk/src/main/org/jboss/messaging/core/plugin/exchange/SimpleBinding.java	2006-09-05 16:08:05 UTC (rev 1255)
@@ -1,243 +0,0 @@
-/*
- * JBoss, Home of Professional Open Source
- * Copyright 2005, JBoss Inc., and individual contributors as indicated
- * by the @authors tag. See the copyright.txt in the distribution for a
- * full listing of individual contributors.
- *
- * This is free software; you can redistribute it and/or modify it
- * under the terms of the GNU Lesser General Public License as
- * published by the Free Software Foundation; either version 2.1 of
- * the License, or (at your option) any later version.
- *
- * This software is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this software; if not, write to the Free
- * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
- * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
- */
-package org.jboss.messaging.core.plugin.exchange;
-
-import java.io.DataInput;
-import java.io.DataOutput;
-import java.io.Externalizable;
-import java.io.IOException;
-import java.io.ObjectInput;
-import java.io.ObjectOutput;
-
-import org.jboss.logging.Logger;
-import org.jboss.messaging.core.local.MessageQueue;
-
-/**
- * A SimpleBinding
- * 
- * Inspired from an AMQP binding
- * 
- * A binding describes how a queue is bound into an exchange
- * 
- * Bindings have a condition, the condition describes how messages are routed to the
- * queue.
- * 
- * For a direct exchange, which would be used for point to point queues then the condition
- * is something like "routing_key=name" - so the queue would receive the message if the routing
- * key matched the name excactly.
- * 
- * For a topic, the queue (subscription) name is not relevant, so the condition would be something like
- * "routing_key=news.uk.*", so the subscription would receive any messages sent with a routing key
- * that starts with "news.uk."
- * 
- * 
- * @author <a href="mailto:tim.fox at jboss.com">Tim Fox</a>
- * @version <tt>$Revision: 1.1 $</tt>
- *
- * $Id$
- *
- */
-public class SimpleBinding implements Binding, Externalizable
-{
-   private static final long serialVersionUID = -5518552214992031242L;
-
-   private static final Logger log = Logger.getLogger(SimpleBinding.class);
-   
-   private static final byte NULL = 0;
-   
-   private static final byte NOT_NULL = 1;   
-
-   private String nodeId;
-   
-   private String queueName;
-   
-   private String condition;
-   
-   private MessageQueue queue;
-    
-   private boolean noLocal;
-   
-   private boolean active;
-   
-   private String selector;
-   
-   private long channelId;
-     
-   private boolean durable;
-   
-   public SimpleBinding()
-   {      
-   }
-
-   public SimpleBinding(String nodeId, String queueName, String condition, String selector,
-                        boolean noLocal, long channelId, boolean durable)
-   {
-      this.nodeId = nodeId;
-      
-      this.queueName = queueName;
-      
-      this.condition = condition;      
-      
-      this.noLocal = noLocal;
-      
-      this.selector = selector;
-      
-      this.channelId = channelId;
-         
-      //Bindings are always created de-activated
-      this.active = false;
-      
-      this.durable = durable;          
-   }
-   
-   public String getNodeId()
-   {
-      return nodeId;
-   }
-     
-   public String getQueueName()
-   {
-      return queueName;
-   }
-   
-   public String getCondition()
-   {
-      return condition;
-   }
-   
-   public MessageQueue getQueue()
-   {
-      return queue;
-   }
-
-   public boolean isNoLocal()
-   {
-      return noLocal;
-   }
-   
-   public void activate()
-   {
-      active = true;
-   }
-   
-   public void deactivate()
-   {
-      active = false;
-   }
-   
-   public boolean isActive()
-   {
-      return active;
-   }
-   
-   public String getSelector()
-   {
-      return selector;
-   }
-   
-   public long getChannelId()
-   {
-      return channelId;
-   }
-    
-   public boolean isDurable()
-   {
-      return durable;
-   }
-   
-   public void setQueue(MessageQueue queue)
-   {
-      this.queue = queue;
-      
-      if (queue != null)
-      {
-         this.channelId = queue.getChannelID();
-      }            
-   }
-   
-
-   public void readExternal(ObjectInput in) throws IOException, ClassNotFoundException
-   {
-      nodeId = in.readUTF();
-      
-      queueName = in.readUTF();
-      
-      condition = in.readUTF();
-      
-      noLocal = in.readBoolean();
-      
-      active = in.readBoolean();
-      
-      selector = readString(in);
-      
-      channelId = in.readLong();
-      
-      durable = in.readBoolean();
-   }
-
-   public void writeExternal(ObjectOutput out) throws IOException
-   {
-      out.writeUTF(nodeId);
-      
-      out.writeUTF(queueName);
-      
-      out.writeUTF(condition);
-      
-      out.writeBoolean(noLocal);
-      
-      out.writeBoolean(active);
-      
-      writeString(selector, out);
-      
-      out.writeLong(channelId);
-      
-      out.writeBoolean(durable);
-   }
-   
-   private void writeString(String string, DataOutput out) throws IOException
-   {
-      if (string == null)
-      {
-         out.writeByte(NULL);
-      }
-      else
-      {
-         out.writeByte(NOT_NULL);
-         out.writeUTF(string);
-      }
-   }
-   
-   private String readString(DataInput in) throws IOException
-   {
-      byte b = in.readByte();
-      
-      if (b == NULL)
-      {
-         return null;
-      }
-      else
-      {
-         return in.readUTF();
-      }
-   }
-   
-}

Modified: trunk/src/main/org/jboss/messaging/core/plugin/exchange/TopicExchange.java
===================================================================
--- trunk/src/main/org/jboss/messaging/core/plugin/exchange/TopicExchange.java	2006-09-03 17:56:48 UTC (rev 1254)
+++ trunk/src/main/org/jboss/messaging/core/plugin/exchange/TopicExchange.java	2006-09-05 16:08:05 UTC (rev 1255)
@@ -33,13 +33,14 @@
 import org.jboss.messaging.core.local.MessageQueue;
 import org.jboss.messaging.core.plugin.IdManager;
 import org.jboss.messaging.core.plugin.contract.MessageStore;
+import org.jboss.messaging.core.plugin.exchange.cluster.ClusteredTopicExchange;
 import org.jboss.messaging.core.tx.Transaction;
 import org.jboss.messaging.core.tx.TransactionRepository;
 
 /**
  * A non-clustered TopicExchange
  * 
- * Roughly based on the AMQP topic exchange
+ * Similar in some ways to the AMQP topic exchange
  *
  * Currently we don't support hierarchies of topics, but it should be fairly
  * straightforward to extend this class to support them.

Added: trunk/src/main/org/jboss/messaging/core/plugin/exchange/cluster/BindRequest.java
===================================================================
--- trunk/src/main/org/jboss/messaging/core/plugin/exchange/cluster/BindRequest.java	2006-09-03 17:56:48 UTC (rev 1254)
+++ trunk/src/main/org/jboss/messaging/core/plugin/exchange/cluster/BindRequest.java	2006-09-05 16:08:05 UTC (rev 1255)
@@ -0,0 +1,75 @@
+/*
+ * JBoss, Home of Professional Open Source
+ * Copyright 2005, JBoss Inc., and individual contributors as indicated
+ * by the @authors tag. See the copyright.txt in the distribution for a
+ * full listing of individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+package org.jboss.messaging.core.plugin.exchange.cluster;
+
+/**
+ * A BindRequest
+ *
+ * @author <a href="mailto:tim.fox at jboss.com">Tim Fox</a>
+ * @version <tt>$Revision: 1.1 $</tt>
+ *
+ * $Id$
+ *
+ */
+class BindRequest implements ExchangeRequest
+{
+   private static final long serialVersionUID = -2881616453863261327L;
+   
+   private String nodeId;   
+   
+   private String queueName;   
+   
+   private String condition;   
+   
+   private String filterString; 
+   
+   private boolean noLocal;   
+   
+   private long channelId;   
+   
+   private boolean durable;
+   
+   BindRequest(String nodeId, String queueName, String condition, String filterString,
+               boolean noLocal, long channelId, boolean durable)
+   {
+      this.nodeId = nodeId;
+      
+      this.queueName = queueName;
+      
+      this.condition = condition;
+      
+      this.filterString = filterString;
+      
+      this.noLocal = noLocal;
+      
+      this.channelId = channelId;
+      
+      this.durable = durable;
+   }
+
+   public void execute(ExchangeInternal exchange) throws Exception
+   {
+      exchange.addBindingFromCluster(nodeId, queueName, condition,
+                                     filterString, noLocal, channelId, durable);
+      
+   }
+}

Added: trunk/src/main/org/jboss/messaging/core/plugin/exchange/cluster/CastMessagesCallback.java
===================================================================
--- trunk/src/main/org/jboss/messaging/core/plugin/exchange/cluster/CastMessagesCallback.java	2006-09-03 17:56:48 UTC (rev 1254)
+++ trunk/src/main/org/jboss/messaging/core/plugin/exchange/cluster/CastMessagesCallback.java	2006-09-05 16:08:05 UTC (rev 1255)
@@ -0,0 +1,154 @@
+/*
+ * JBoss, Home of Professional Open Source
+ * Copyright 2005, JBoss Inc., and individual contributors as indicated
+ * by the @authors tag. See the copyright.txt in the distribution for a
+ * full listing of individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+package org.jboss.messaging.core.plugin.exchange.cluster;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.jboss.messaging.core.Message;
+import org.jboss.messaging.core.tx.TxCallback;
+
+/**
+ * A CastMessageCallback
+ * 
+ * When we want to send persistent message(s) across the group to remote subscriptions
+ * and there is at least one remote durable subscription we do the following:
+ * 1) Cast the message(s) to group members. They are held in a "holding area" on the remote node
+ * and not immediately sent to the channels.
+ * 2) Persist the message(s) in the durable subscription(s) on the sending node.
+ * 3) Cast another message to the group members telling them to process the messages in the "holding" area
+ * for a particular transaction id
+ * This allows us to avoid an expensive 2PC protocol which involve extra database updates
+ * When the sending node starts up, it records a flag in the database, on clean shutdown it deletes the flag.
+ * If the server finds the flag in the database at start-up it knows it crashed the last time, so it
+ * sends a "check" message to all members of the group.
+ * On receipt of the "check" message, the receiving node checks in it's holding area for any holding messages for
+ * that node id, if they exist AND they also exist in the db (i.e. they were persisted ok) then they are processed
+ * otherwise they are discarded.
+ * 
+ * The execution order of callbacks must be as follows:
+ * 
+ * CastMessagesCallback.beforeCommit() - cast message(s) to holding areas
+ * JDBCPersistenceManager.TransactionCallback.beforeCommit() - persist message(s) in database
+ * CastMessagesCallback.afterCommit() - send "commit" message to holding areas
+ *
+ * @author <a href="mailto:tim.fox at jboss.com">Tim Fox</a>
+ * @version <tt>$Revision: 1.1 $</tt>
+ *
+ * $Id$
+ *
+ */
+class CastMessagesCallback implements TxCallback
+{           
+   private List persistent;
+   
+   private List nonPersistent;
+   
+   private String nodeId;
+   
+   private long txId;
+   
+   private ExchangeInternal exchange;
+   
+   void addMessage(String routingKey, Message message)
+   {
+      MessageHolder holder = new MessageHolder(routingKey, message);
+      
+      if (message.isReliable())
+      {
+         if (persistent == null)
+         {
+            persistent = new ArrayList();
+         }
+         persistent.add(holder);
+      }
+      else
+      {
+         if (nonPersistent == null)
+         {
+            nonPersistent = new ArrayList();
+         }
+         nonPersistent.add(holder);
+      }
+   }
+   
+   CastMessagesCallback(String nodeId, long txId, ExchangeInternal exchange)
+   {
+      this.nodeId = nodeId;
+      
+      this.txId = txId;
+      
+      this.exchange = exchange;
+   }
+
+   public void afterCommit(boolean onePhase) throws Exception
+   {            
+      if (nonPersistent != null)
+      {
+         // Cast the non persistent - this don't need to go into a holding area on the receiving node
+         ExchangeRequest req = new MessagesRequest(nonPersistent);
+         
+         exchange.asyncSendRequest(req);
+      }
+      
+      if (persistent != null)
+      {
+         // Cast a commit message
+         ExchangeRequest req = new TransactionRequest(nodeId, txId);
+         
+         // Stack must be FIFO
+         exchange.asyncSendRequest(req);
+      }
+      
+      nonPersistent = persistent = null;
+   }
+
+   public void afterPrepare() throws Exception
+   { 
+   }
+
+   public void afterRollback(boolean onePhase) throws Exception
+   {
+   }
+
+   public void beforeCommit(boolean onePhase) throws Exception
+   {
+      if (persistent != null)
+      {
+         //We send the persistent messages which go into the "holding area" on
+         //the receiving nodes
+         ExchangeRequest req = new TransactionRequest(nodeId, txId, persistent);
+         
+         //Stack must be FIFO
+         exchange.asyncSendRequest(req);
+      }
+   }
+
+   public void beforePrepare() throws Exception
+   {
+   }
+
+   public void beforeRollback(boolean onePhase) throws Exception
+   {
+   }
+      
+}    

Added: trunk/src/main/org/jboss/messaging/core/plugin/exchange/cluster/CheckMessage.java
===================================================================
--- trunk/src/main/org/jboss/messaging/core/plugin/exchange/cluster/CheckMessage.java	2006-09-03 17:56:48 UTC (rev 1254)
+++ trunk/src/main/org/jboss/messaging/core/plugin/exchange/cluster/CheckMessage.java	2006-09-05 16:08:05 UTC (rev 1255)
@@ -0,0 +1,48 @@
+/*
+ * JBoss, Home of Professional Open Source
+ * Copyright 2005, JBoss Inc., and individual contributors as indicated
+ * by the @authors tag. See the copyright.txt in the distribution for a
+ * full listing of individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+package org.jboss.messaging.core.plugin.exchange.cluster;
+
+/**
+ * A CheckMessage
+ *
+ * @author <a href="mailto:tim.fox at jboss.com">Tim Fox</a>
+ * @version <tt>$Revision: 1.1 $</tt>
+ *
+ * $Id$
+ *
+ */
+class CheckMessage implements ExchangeRequest
+{
+   private static final long serialVersionUID = 6254127318656179872L;
+   
+   private String nodeId;
+   
+   CheckMessage(String nodeId)
+   {
+      this.nodeId = nodeId;
+   }
+   
+   public void execute(ExchangeInternal exchange) throws Exception
+   {
+      exchange.check(nodeId);
+   }
+}

Added: trunk/src/main/org/jboss/messaging/core/plugin/exchange/cluster/ClusteredExchangeSupport.java
===================================================================
--- trunk/src/main/org/jboss/messaging/core/plugin/exchange/cluster/ClusteredExchangeSupport.java	2006-09-03 17:56:48 UTC (rev 1254)
+++ trunk/src/main/org/jboss/messaging/core/plugin/exchange/cluster/ClusteredExchangeSupport.java	2006-09-05 16:08:05 UTC (rev 1255)
@@ -0,0 +1,828 @@
+/*
+ * JBoss, Home of Professional Open Source
+ * Copyright 2005, JBoss Inc., and individual contributors as indicated
+ * by the @authors tag. See the copyright.txt in the distribution for a
+ * full listing of individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+package org.jboss.messaging.core.plugin.exchange.cluster;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+
+import javax.sql.DataSource;
+import javax.transaction.TransactionManager;
+
+import org.jboss.jms.server.QueuedExecutorPool;
+import org.jboss.logging.Logger;
+import org.jboss.messaging.core.Filter;
+import org.jboss.messaging.core.MessageReference;
+import org.jboss.messaging.core.plugin.IdManager;
+import org.jboss.messaging.core.plugin.contract.MessageStore;
+import org.jboss.messaging.core.plugin.contract.PersistenceManager;
+import org.jboss.messaging.core.plugin.exchange.Binding;
+import org.jboss.messaging.core.plugin.exchange.DefaultBinding;
+import org.jboss.messaging.core.plugin.exchange.ExchangeSupport;
+import org.jgroups.Address;
+import org.jgroups.Channel;
+import org.jgroups.MembershipListener;
+import org.jgroups.Message;
+import org.jgroups.MessageListener;
+import org.jgroups.Receiver;
+import org.jgroups.View;
+import org.jgroups.blocks.GroupRequest;
+import org.jgroups.blocks.MessageDispatcher;
+import org.jgroups.blocks.RequestHandler;
+import org.jgroups.util.Util;
+
+import EDU.oswego.cs.dl.util.concurrent.ReadWriteLock;
+import EDU.oswego.cs.dl.util.concurrent.WriterPreferenceReadWriteLock;
+
+/**
+ * A ClusteredExchangeSupport
+ *
+ * @author <a href="mailto:tim.fox at jboss.com">Tim Fox</a>
+ * @version <tt>$Revision: 1.1 $</tt>
+ *
+ * $Id$
+ *
+ */
+public abstract class ClusteredExchangeSupport extends ExchangeSupport implements ExchangeInternal
+{
+   private static final Logger log = Logger.getLogger(ClusteredExchangeSupport.class);
+      
+   //TODO - make configurable
+   private static final int GET_STATE_TIMEOUT = 5000;
+   
+   private static final int CAST_TIMEOUT = 5000;
+                    
+   protected Channel syncChannel;
+   
+   protected Channel asyncChannel;
+   
+   private MessageDispatcher controlMessageDispatcher;
+   
+   private MessageListener controlMessageListener;
+   
+   private Receiver dataReceiver;
+   
+   private MembershipListener controlMembershipListener;
+   
+   private RequestHandler requestHandler;
+   
+   private Object setStateLock = new Object();
+   
+   private boolean stateSet;
+   
+   private View currentView;
+   
+   private Address currentAddress;
+   
+   //Map < Address, node id>
+   private Map nodeIdAddressMap;
+   
+   private Map holdingArea;
+   
+   protected PersistenceManager pm;
+   
+   public ClusteredExchangeSupport() throws Exception
+   {          
+   }
+   
+   /*
+    * This constructor should only be used for testing
+    */
+   protected ClusteredExchangeSupport(DataSource ds, TransactionManager tm)
+   {
+      super(ds, tm);
+   }
+   
+   //TODO - this is a bit of a mess - this stuff should go into startService
+   //but we can't currently do that since startService will get called
+   //before we get a chance to inject the attributes
+   protected void injectAttributes(Channel syncChannel, Channel asynchChannel,
+                                   String groupName, String exchangeName, String nodeID,
+                                   MessageStore ms, IdManager im, QueuedExecutorPool pool,
+                                   PersistenceManager pm) throws Exception
+   { 
+      this.syncChannel = syncChannel;
+      
+      this.asyncChannel = asynchChannel;
+       
+      this.nodeIdAddressMap = new HashMap();
+      
+      this.holdingArea = new HashMap();
+      
+      this.pm = pm;
+             
+      //We don't want to receive local messages on any of the channels
+      syncChannel.setOpt(Channel.LOCAL, Boolean.FALSE);
+      asynchChannel.setOpt(Channel.LOCAL, Boolean.FALSE);
+
+      this.controlMessageListener = new ControlMessageListener();
+        
+      this.requestHandler = new ExchangeRequestHandler();
+      
+      this.controlMembershipListener = new ControlMembershipListener();
+      
+      this.controlMessageDispatcher = new MessageDispatcher(syncChannel, controlMessageListener,
+                                                            controlMembershipListener, requestHandler, true);      
+      this.dataReceiver = new DataReceiver();
+      
+      asyncChannel.setReceiver(dataReceiver);               
+      
+      syncChannel.connect(groupName);
+      
+      asynchChannel.connect(groupName);
+
+      currentAddress = syncChannel.getLocalAddress();
+      
+      super.injectAttributes(exchangeName, nodeID, ms, im, pool);      
+        
+      handleAddressNodeMapping(currentAddress, nodeId);
+      
+      syncSendRequest(new SendNodeIdRequest(currentAddress, nodeId));
+   }
+   
+   // ServiceMBeanSupport overrides ---------------------------------
+   
+   protected void startService() throws Exception
+   {      
+      super.startService();
+   }
+   
+   protected void stopService() throws Exception
+   {
+      super.stopService();
+      
+      syncChannel.close();
+      
+      asyncChannel.close();
+   }
+   
+   // Exchange implementation ---------------------------------------        
+   
+   public Binding bindQueue(String queueName, String condition, Filter filter, boolean noLocal, boolean durable,
+                            MessageStore ms, PersistenceManager pm,
+                            int fullSize, int pageSize, int downCacheSize) throws Exception
+   {           
+      Binding binding = super.bindQueue(queueName, condition, filter, noLocal, durable,
+                                        ms, pm, fullSize, pageSize, downCacheSize);
+      
+      BindRequest request =
+         new BindRequest(nodeId, queueName, condition, filter == null ? null : filter.getFilterString(),
+                         noLocal, binding.getChannelId(), durable);
+      
+      syncSendRequest(request);
+      
+      return binding;
+   }
+   
+   public Binding unbindQueue(String queueName) throws Throwable
+   {
+      Binding binding = super.unbindQueue(queueName);
+      
+      UnbindRequest request = new UnbindRequest(nodeId, queueName);
+      
+      syncSendRequest(request);
+      
+      return binding;
+   }
+   
+   /*
+    * This is called by the server peer if it determines that the server crashed last time it was run
+    */
+   public void recover() throws Exception
+   {
+      //We send a "check" message to all nodes of the cluster
+      this.asyncSendRequest(new CheckMessage(nodeId));
+   }
+   
+   // ExchangeInternal implementation ------------------------------------------------------------------
+   
+   /*
+    * Called when another node adds a binding
+    */
+   public void addBindingFromCluster(String nodeId, String queueName, String condition,
+                                      String filterString, boolean noLocal, long channelID, boolean durable)
+      throws Exception
+   {
+      lock.writeLock().acquire();
+      
+      try
+      {                     
+         //Sanity
+         if (!nodeIdAddressMap.containsKey(nodeId))
+         {
+            throw new IllegalStateException("Cannot find address for node: " + nodeId);
+         }
+         
+         // We currently only allow one binding per name per node
+         Map nameMap = (Map)nameMaps.get(nodeId);
+         
+         Binding binding = null;
+         
+         if (nameMap != null)
+         {
+            binding = (Binding)nameMap.get(queueName);
+         }
+         
+         if (binding != null)
+         {
+            throw new IllegalArgumentException(this.nodeId + "Binding already exists for node Id " + nodeId + " queue name " + queueName);
+         }
+         
+         binding = new DefaultBinding(nodeId, queueName, condition, filterString,
+                                     noLocal, channelID, durable); 
+         
+         binding.activate();
+         
+         addBinding(binding);         
+      }
+      finally
+      {
+         lock.writeLock().release();
+      }
+   }
+   
+   /*
+    * Called when another node removes a binding
+    */
+   public void removeBindingFromCluster(String nodeId, String queueName) throws Exception
+   {
+      lock.writeLock().acquire();
+      
+      try
+      {         
+         // Sanity
+         if (!nodeIdAddressMap.containsKey(nodeId))
+         {
+            throw new IllegalStateException("Cannot find address for node: " + nodeId);
+         }
+         
+         removeBinding(nodeId, queueName);         
+      }
+      finally
+      {
+         lock.writeLock().release();
+      }
+   }
+   
+   public void handleAddressNodeMapping(Address address, String nodeId) throws Exception
+   {
+      lock.writeLock().acquire();
+      
+      try
+      { 
+         nodeIdAddressMap.put(nodeId, address.toString());
+      }
+      finally
+      {
+         lock.writeLock().release();
+      }
+   }
+   
+   public void routeFromCluster(org.jboss.messaging.core.Message message, String routingKey) throws Exception
+   {
+      // Need to reference the message
+      MessageReference ref = null;
+      try
+      {
+         ref = ms.reference(message);
+         
+         //Route immediately
+         routeFromCluster(ref, routingKey); 
+      }
+      finally
+      {
+         if (ref != null)
+         {
+            ref.releaseMemoryReference();
+         }
+      }
+   }
+   
+   public void asyncSendRequest(ExchangeRequest request) throws Exception
+   {            
+      //TODO - handle serialization more efficiently
+      asyncChannel.send(new Message(null, null, request));
+   }
+   
+   public void addToHoldingArea(TransactionId id, List messageHolders) throws Exception
+   {
+      synchronized (holdingArea)
+      {
+         holdingArea.put(id, messageHolders);
+      }      
+   }
+         
+   public void commitTransaction(TransactionId id) throws Exception
+   {
+      List messageHolders = null;
+      
+      synchronized (holdingArea)
+      {
+         messageHolders = (List)holdingArea.remove(id);
+      }
+      
+      if (messageHolders == null)
+      {
+         throw new IllegalStateException("Cannot find messages for transaction id: " + id);
+      }
+      
+      Iterator iter = messageHolders.iterator();
+      
+      while (iter.hasNext())
+      {
+         MessageHolder holder = (MessageHolder)iter.next();
+         
+         routeFromCluster(holder.getMessage(), holder.getRoutingKey());
+      }
+   }
+   
+   /*
+    * Called by a node if it starts and it detects that it crashed since it's last start-up.
+    * This method then checks to see if there any messages from that node in the holding area
+    * and if they are also in the database they will be processed
+    */
+   public void check(String nodeId) throws Exception
+   {
+      synchronized (holdingArea)
+      {
+         Iterator iter = holdingArea.entrySet().iterator();
+         
+         List toRemove = new ArrayList();
+         
+         while (iter.hasNext())
+         {
+            Map.Entry entry = (Map.Entry)iter.next();
+            
+            TransactionId id = (TransactionId)entry.getKey();
+            
+            if (id.getNodeId().equals(nodeId))
+            {
+               List holders = (List)entry.getValue();
+               
+               boolean wasCommitted = checkTransaction(holders);               
+               
+               if (wasCommitted)
+               {
+                  //We can process the transaction
+                  Iterator iter2 = holders.iterator();
+                  
+                  while (iter2.hasNext())
+                  {
+                     MessageHolder holder = (MessageHolder)iter2.next();
+                     
+                     routeFromCluster(holder.getMessage(), holder.getRoutingKey());
+                  }
+                  
+                  toRemove.add(id);
+               }
+            }
+         }
+         
+         //Remove the transactions from the holding area
+         
+         iter = toRemove.iterator();
+         
+         while (iter.hasNext())
+         {
+            TransactionId id = (TransactionId)iter.next();
+            
+            holdingArea.remove(id);
+         }
+      }
+   }
+   
+   private boolean checkTransaction(List messageHolders) throws Exception
+   {
+      Iterator iter = messageHolders.iterator();
+      
+      //We only need to check that one of the refs made it to the database - the refs would have
+      //been inserted into the db transactionally, so either they're all there or none are
+      MessageHolder holder = (MessageHolder)iter.next();
+      
+      List bindings = listBindingsForWildcard(holder.getRoutingKey());
+      
+      if (bindings == null)
+      {
+         throw new IllegalStateException("Cannot find bindings for key: " + holder.getRoutingKey());
+      }
+      
+      Iterator iter2 = bindings.iterator();
+      
+      long channelID = -1;
+      boolean found = false;
+      
+      while (iter2.hasNext())
+      {
+         Binding binding = (Binding)iter2.next();
+         
+         if (binding.isDurable())
+         {
+            found = true;
+            
+            channelID = binding.getChannelId();
+         }
+      }
+      
+      if (!found)
+      {
+         throw new IllegalStateException("Cannot find bindings");
+      }
+      
+      if (pm.referenceExists(channelID, holder.getMessage().getMessageID()))
+      {
+         return true;
+      }
+      else
+      {
+         return false;
+      }
+   }
+   
+   //ExchangeSupport overrides -------------------------------------------------
+   
+   protected void loadBindings() throws Exception
+   {
+      // TODO I need to know whether this call times out - how do I know this??
+      boolean isState = syncChannel.getState(null, GET_STATE_TIMEOUT);
+                              
+      if (!isState)
+      {       
+         //Must be first member in group or non clustered- we load the state ourself from the database
+         super.loadBindings();      
+      }
+      else
+      {
+         //The state will be set in due course via the MessageListener - we must wait until this happens
+         
+         synchronized (setStateLock)
+         {
+            //TODO we should implement a timeout on this
+            while (!stateSet)
+            {
+               setStateLock.wait();
+            } 
+         }
+      }
+   }
+   
+   // Public ------------------------------------------------------------------------------------------
+   
+   
+   // Protected ---------------------------------------------------------------------------------------
+   
+   
+   protected void syncSendRequest(ExchangeRequest request) throws Exception
+   {            
+      //TODO - handle serialization more efficiently
+      
+      Message message = new Message(null, null, request);      
+      
+      controlMessageDispatcher.castMessage(null, message, GroupRequest.GET_ALL, CAST_TIMEOUT);
+   }
+   
+   protected abstract void routeFromCluster(MessageReference ref, String routingKey) throws Exception;      
+       
+   // Private ------------------------------------------------------------------------------------------
+             
+   private void removeBindingsForAddress(String address) throws Exception
+   {
+      lock.writeLock().acquire();
+      
+      try
+      { 
+         Iterator iter = nodeIdAddressMap.entrySet().iterator();
+         
+         String nodeId = null;
+         while (iter.hasNext())
+         {
+            Map.Entry entry = (Map.Entry)iter.next();
+            
+            String str = (String)entry.getValue();
+            
+            if (str.equals(address))
+            {
+               nodeId = (String)entry.getKey();
+            }
+         }
+         
+         if (nodeId == null)
+         {
+            throw new IllegalStateException("Cannot find node id for address: " + address);
+         }
+         
+         Map nameMap = (Map)nameMaps.get(nodeId);
+
+         if (nameMap != null)
+         {
+            List toRemove = new ArrayList();
+            
+            iter = nameMap.values().iterator();
+            
+            while (iter.hasNext())
+            {
+               Binding binding = (Binding)iter.next();
+               
+               if (!binding.isDurable())
+               {
+                  toRemove.add(binding);
+               }
+            }
+            
+            iter = toRemove.iterator();
+            
+            while (iter.hasNext())
+            {
+               Binding binding = (Binding)iter.next();
+               
+               removeBinding(nodeId, binding.getQueueName());
+            }
+         }
+         
+         //Remove the address mapping
+         nodeIdAddressMap.remove(nodeId);
+      }
+      finally
+      {
+         lock.writeLock().release();
+      }
+   }
+      
+   //TODO - Sort out serialization properly
+   
+   private byte[] getStateAsBytes() throws Exception
+   {
+      List bindings = new ArrayList();
+      
+      Iterator iter = nameMaps.values().iterator();
+      
+      while (iter.hasNext())
+      {
+         Map map  = (Map)iter.next();
+         
+         Iterator iter2 = map.values().iterator();
+         
+         while (iter2.hasNext())
+         {
+            bindings.add(iter2.next());
+         }
+      }
+      
+      SharedState state = new SharedState(bindings, nodeIdAddressMap);
+      
+      byte[] bytes = Util.objectToByteBuffer(state);
+      
+      return bytes;
+   }
+   
+   private void processStateBytes(byte[] bytes) throws Exception
+   {
+      SharedState state = (SharedState)Util.objectFromByteBuffer(bytes);
+      
+      nameMaps.clear();
+      
+      conditionMap.clear();
+                 
+      List bindings = state.getBindings();
+      
+      Iterator iter = bindings.iterator();
+      
+      while (iter.hasNext())
+      {
+         Binding binding = (Binding)iter.next();
+         
+         addBinding(binding);
+      }
+      
+      this.nodeIdAddressMap.clear();
+      
+      this.nodeIdAddressMap.putAll(state.getNodeIdAddressMap());
+   }
+   
+   // Inner classes -------------------------------------------------------------------
+    
+   /*
+    * This class is used to manage state on the control channel
+    */
+   private class ControlMessageListener implements MessageListener
+   {
+      public byte[] getState()
+      {     
+         try
+         {
+            lock.writeLock().acquire();
+         }
+         catch (InterruptedException e)
+         {
+            log.error("Thread Interrupted", e);
+         }
+         try
+         {
+            return getStateAsBytes();
+         }
+         catch (Exception e)
+         {
+            IllegalStateException e2 = new IllegalStateException(e.getMessage());
+            e2.setStackTrace(e.getStackTrace());
+            throw e2;
+         }     
+         finally
+         {
+            lock.writeLock().release();
+         }
+      }
+      
+      public void receive(Message message)
+      {         
+         log.info("Received message on control channel: " + message);
+      }
+      
+      public void setState(byte[] bytes)
+      {
+         if (bytes != null)
+         {
+            
+            try
+            {
+               lock.writeLock().acquire();         
+            }
+            catch (InterruptedException e)
+            {
+               log.error("Thread interrupted", e);
+            }
+            try
+            {
+               processStateBytes(bytes);               
+            }
+            catch (Exception e)
+            {
+               IllegalStateException e2 = new IllegalStateException(e.getMessage());
+               e2.setStackTrace(e.getStackTrace());
+               throw e2;
+            }
+            finally
+            {
+               lock.writeLock().release();
+            }
+         }
+               
+         synchronized (setStateLock)
+         {
+            stateSet = true;
+            setStateLock.notify();
+         }
+      }      
+   }
+   
+   /*
+    * We use this class so we notice when members leave the group
+    */
+   private class ControlMembershipListener implements MembershipListener
+   {
+      public void block()
+      {
+         //NOOP
+      }
+
+      public void suspect(Address address)
+      {
+         //NOOP
+      }
+
+      public void viewAccepted(View view)
+      {
+         if (currentView != null)
+         {
+            Iterator iter = currentView.getMembers().iterator();
+            
+            while (iter.hasNext())
+            {
+               Address address = (Address)iter.next();
+               
+               if (!view.containsMember(address))
+               {
+                  //Member must have left                  
+                  //We don't remove bindings for ourself
+                  
+                  if (!address.equals(currentAddress))
+                  {                  
+                     try
+                     {
+                        removeBindingsForAddress(address.toString());
+                     }               
+                     catch (Exception e)
+                     {
+                        IllegalStateException e2 = new IllegalStateException(e.getMessage());
+                        e2.setStackTrace(e.getStackTrace());
+                        throw e2;
+                     }
+                  }
+               }
+            }
+         }
+         
+         currentView = view;
+      }
+
+      public byte[] getState()
+      {        
+         //NOOP
+         return null;
+      }     
+   }
+   
+   
+   /*
+    * This class is used to listen for messages on the data channel
+    */
+   private class DataReceiver implements Receiver
+   {
+      public void block()
+      {   
+         //NOOP
+      }
+
+      public void suspect(Address address)
+      { 
+         //NOOP
+      }
+
+      public void viewAccepted(View view)
+      { 
+         //NOOP
+      }
+
+      public byte[] getState()
+      {         
+         //NOOP
+         return null;
+      }
+      
+      public void receive(Message message)
+      {
+         try
+         {
+            //TODO handle deserialization more efficiently            
+            MessageRequest request = (MessageRequest)message.getObject();
+            
+            request.execute(ClusteredExchangeSupport.this);
+         }
+         catch (Exception e)
+         {
+            IllegalStateException e2 = new IllegalStateException(e.getMessage());
+            e2.setStackTrace(e.getStackTrace());
+            throw e2;
+         }         
+      }
+      
+      public void setState(byte[] bytes)
+      {
+         //NOOP         
+      }      
+   }
+          
+   /*
+    * This class is used to handle synchronous requests
+    */
+   private class ExchangeRequestHandler implements RequestHandler
+   {
+      public Object handle(Message message)
+      {
+         //TODO handle deserialization more efficiently
+         
+         MessageRequest request = (MessageRequest)message.getObject();
+              
+         try
+         {            
+            request.execute(ClusteredExchangeSupport.this);
+         }
+         catch (Exception e)
+         {
+            IllegalStateException e2 = new IllegalStateException(e.getMessage());
+            e2.setStackTrace(e.getStackTrace());
+            throw e2;
+         }
+         return null;
+      }      
+   }   
+}
\ No newline at end of file

Added: trunk/src/main/org/jboss/messaging/core/plugin/exchange/cluster/ClusteredTopicExchange.java
===================================================================
--- trunk/src/main/org/jboss/messaging/core/plugin/exchange/cluster/ClusteredTopicExchange.java	2006-09-03 17:56:48 UTC (rev 1254)
+++ trunk/src/main/org/jboss/messaging/core/plugin/exchange/cluster/ClusteredTopicExchange.java	2006-09-05 16:08:05 UTC (rev 1255)
@@ -0,0 +1,268 @@
+/*
+ * JBoss, Home of Professional Open Source
+ * Copyright 2005, JBoss Inc., and individual contributors as indicated
+ * by the @authors tag. See the copyright.txt in the distribution for a
+ * full listing of individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+package org.jboss.messaging.core.plugin.exchange.cluster;
+
+import java.util.Iterator;
+import java.util.List;
+
+import javax.sql.DataSource;
+import javax.transaction.TransactionManager;
+
+import org.jboss.jms.server.QueuedExecutorPool;
+import org.jboss.logging.Logger;
+import org.jboss.messaging.core.MessageReference;
+import org.jboss.messaging.core.local.MessageQueue;
+import org.jboss.messaging.core.plugin.IdManager;
+import org.jboss.messaging.core.plugin.contract.MessageStore;
+import org.jboss.messaging.core.plugin.contract.PersistenceManager;
+import org.jboss.messaging.core.plugin.exchange.Binding;
+import org.jboss.messaging.core.tx.Transaction;
+import org.jboss.messaging.core.tx.TransactionRepository;
+import org.jgroups.Channel;
+
+/**
+ * A Clustered TopicExchange
+ * 
+ * Similar in some ways to the AMQP topic exchange
+ *
+ * Currently we don't support hierarchies of topics, but it should be fairly
+ * straightforward to extend this class to support them.
+ * 
+ * For the topic exchange the condition should be just be the topic name
+ * 
+ * When we support topic hierarchies this will change to a proper wildcard.
+ * 
+ * @author <a href="mailto:tim.fox at jboss.com">Tim Fox</a>
+ * @version <tt>$Revision: 1.1 $</tt>
+ *
+ * $Id$
+ *
+ */
+public class ClusteredTopicExchange extends ClusteredExchangeSupport
+{
+   private static final Logger log = Logger.getLogger(ClusteredTopicExchange.class);     
+   
+   protected TransactionRepository tr;  
+    
+   /*
+    * This constructor should only be used for testing
+    */
+   public ClusteredTopicExchange(DataSource ds, TransactionManager tm)
+   {
+      super(ds, tm);
+   }
+   
+   public void injectAttributes(Channel controlChannel, Channel dataChannel,
+                                String groupName, String exchangeName, String nodeID,
+                                MessageStore ms, IdManager im, QueuedExecutorPool pool,
+                                TransactionRepository tr, PersistenceManager pm) throws Exception
+   {
+      super.injectAttributes(controlChannel, dataChannel,
+                             groupName, exchangeName, nodeID, ms, im, pool, pm);
+      
+      this.tr = tr;
+   }     
+   
+   public boolean route(MessageReference ref, String routingKey, Transaction tx) throws Exception
+   {
+      if (ref == null)
+      {
+         throw new IllegalArgumentException("Message reference is null");
+      }
+      
+      if (routingKey == null)
+      {
+         throw new IllegalArgumentException("Routing key is null");
+      }
+      
+      lock.readLock().acquire();
+      
+      try
+      {      
+         // We route on the condition
+         List bindings = (List)conditionMap.get(routingKey);
+      
+         if (bindings != null)
+         {                
+            // When routing a persistent message without a transaction then we may need to start an 
+            // internal transaction in order to route it.
+            // We do this if the message is reliable AND:
+            // (
+            // a) The message needs to be routed to more than one durable subscription. This is so we
+            // can guarantee the message is persisted on all the durable subscriptions or none if failure
+            // occurs - i.e. the persistence is transactional
+            // OR
+            // b) There is at least one durable subscription on a different node.
+            // In this case we need to start a transaction since we want to add a callback on the transaction
+            // to cast the message to other nodes
+            // )
+                        
+            //TODO we can optimise this out by storing this as a flag somewhere
+            boolean startInternalTx = false;
+      
+            if (tx == null)
+            {
+               if (ref.isReliable())
+               {
+                  Iterator iter = bindings.iterator();
+                  
+                  int count = 0;
+                  
+                  while (iter.hasNext())
+                  {
+                     Binding binding = (Binding)iter.next();
+                     
+                     if (binding.isDurable())
+                     {
+                        count++;
+                        
+                        if (count == 2 || !binding.getNodeId().equals(this.nodeId))
+                        {
+                           startInternalTx = true;
+                           
+                           break;
+                        }                          
+                     }
+                  }
+               }
+               
+               if (startInternalTx)
+               {
+                  tx = tr.createTransaction();
+               }
+            }
+                       
+            Iterator iter = bindings.iterator();
+            
+            boolean sendRemotely = false;
+
+            while (iter.hasNext())
+            {
+               Binding binding = (Binding)iter.next();
+               
+               if (binding.isActive())
+               {            
+                  if (binding.getNodeId().equals(this.nodeId))
+                  {
+                     //It's a local binding so we pass the message on to the subscription
+                     MessageQueue subscription = binding.getQueue();
+                  
+                     subscription.handle(null, ref, tx);
+                  }
+                  else
+                  {
+                     //It's a binding on a different exchange instance on the cluster
+                     sendRemotely = true;                     
+                      
+                     if (ref.isReliable() && binding.isDurable())
+                     {
+                        //Insert the reference into the database
+                        pm.addReference(binding.getChannelId(), ref, tx);
+                     }
+                  }                     
+               }
+            } 
+            
+            //Now we've sent the message to all the local subscriptions, we might also need
+            //to multicast the message to the other exchange instances on the cluster if there are
+            //subscriptions on those nodes that need to receive the message
+            if (sendRemotely)
+            {
+               if (tx == null)
+               {
+                  //We just throw the message on the network - no need to wait for any reply            
+                  asyncSendRequest(new MessageRequest(routingKey, ref.getMessage()));               
+               }
+               else
+               {
+                  CastMessagesCallback callback = (CastMessagesCallback)tx.getCallback(this);
+                  
+                  if (callback == null)
+                  {
+                     callback = new CastMessagesCallback(nodeId, tx.getId(), ClusteredTopicExchange.this);
+                     
+                     //This callback must be executed first
+                     tx.addFirstCallback(callback, this);
+                  }
+                      
+                  callback.addMessage(routingKey, ref.getMessage());                  
+               }
+            }
+            
+            if (startInternalTx)
+            {
+               tx.commit();
+            }
+         }
+      }
+      finally
+      {                  
+         lock.readLock().release();
+      }
+         
+      // We don't care if the individual subscriptions accepted the reference
+      // We always return true for a topic
+      return true; 
+   }
+   
+   /*
+    * We have received a reference cast from another node - and we need to route it to our local
+    * subscriptions    
+    */
+   protected void routeFromCluster(MessageReference ref, String routingKey) throws Exception
+   {
+      lock.readLock().acquire();
+      
+      try
+      {      
+         // We route on the condition
+         List bindings = (List)conditionMap.get(routingKey);
+      
+         if (bindings != null)
+         {                                
+            Iterator iter = bindings.iterator();
+            
+            while (iter.hasNext())
+            {
+               Binding binding = (Binding)iter.next();
+               
+               if (binding.isActive())
+               {            
+                  if (binding.getNodeId().equals(this.nodeId))
+                  {  
+                     //It's a local binding so we pass the message on to the subscription
+                     MessageQueue subscription = binding.getQueue();
+                  
+                     //TODO instead of adding a new method on the channel
+                     //we should set a header and use the same method
+                     subscription.handleDontPersist(null, ref, null);
+                  }                               
+               }
+            }                          
+         }
+      }
+      finally
+      {                  
+         lock.readLock().release();
+      }
+   }            
+}

Added: trunk/src/main/org/jboss/messaging/core/plugin/exchange/cluster/ExchangeInternal.java
===================================================================
--- trunk/src/main/org/jboss/messaging/core/plugin/exchange/cluster/ExchangeInternal.java	2006-09-03 17:56:48 UTC (rev 1254)
+++ trunk/src/main/org/jboss/messaging/core/plugin/exchange/cluster/ExchangeInternal.java	2006-09-05 16:08:05 UTC (rev 1255)
@@ -0,0 +1,59 @@
+/*
+ * JBoss, Home of Professional Open Source
+ * Copyright 2005, JBoss Inc., and individual contributors as indicated
+ * by the @authors tag. See the copyright.txt in the distribution for a
+ * full listing of individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+package org.jboss.messaging.core.plugin.exchange.cluster;
+
+import java.util.List;
+
+import org.jboss.messaging.core.Message;
+import org.jgroups.Address;
+
+/**
+ * A ExchangeInternal
+ *
+ * @author <a href="mailto:tim.fox at jboss.com">Tim Fox</a>
+ * @version <tt>$Revision: 1.1 $</tt>
+ *
+ * $Id$
+ *
+ */
+interface ExchangeInternal
+{
+   void addBindingFromCluster(String nodeId, String queueName, String condition,
+                              String filterString, boolean noLocal, long channelId, boolean durable)
+      throws Exception;
+   
+   void removeBindingFromCluster(String nodeId, String queueName)
+      throws Exception;
+   
+   void handleAddressNodeMapping(Address address, String nodeId)
+      throws Exception;
+   
+   void routeFromCluster(Message message, String routingKey) throws Exception;
+   
+   void asyncSendRequest(ExchangeRequest request) throws Exception;
+   
+   void addToHoldingArea(TransactionId id, List messageHolders) throws Exception;
+   
+   void commitTransaction(TransactionId id) throws Exception;
+   
+   void check(String nodeId) throws Exception;
+}

Added: trunk/src/main/org/jboss/messaging/core/plugin/exchange/cluster/ExchangeRequest.java
===================================================================
--- trunk/src/main/org/jboss/messaging/core/plugin/exchange/cluster/ExchangeRequest.java	2006-09-03 17:56:48 UTC (rev 1254)
+++ trunk/src/main/org/jboss/messaging/core/plugin/exchange/cluster/ExchangeRequest.java	2006-09-05 16:08:05 UTC (rev 1255)
@@ -0,0 +1,39 @@
+/*
+ * JBoss, Home of Professional Open Source
+ * Copyright 2005, JBoss Inc., and individual contributors as indicated
+ * by the @authors tag. See the copyright.txt in the distribution for a
+ * full listing of individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+package org.jboss.messaging.core.plugin.exchange.cluster;
+
+import java.io.Serializable;
+
+
+/**
+ * A ExchangeRequest
+ *
+ * @author <a href="mailto:tim.fox at jboss.com">Tim Fox</a>
+ * @version <tt>$Revision: 1.1 $</tt>
+ *
+ * $Id$
+ *
+ */
+interface ExchangeRequest extends Serializable
+{
+   void execute(ExchangeInternal exchange) throws Exception;
+}

Added: trunk/src/main/org/jboss/messaging/core/plugin/exchange/cluster/MessageHolder.java
===================================================================
--- trunk/src/main/org/jboss/messaging/core/plugin/exchange/cluster/MessageHolder.java	2006-09-03 17:56:48 UTC (rev 1254)
+++ trunk/src/main/org/jboss/messaging/core/plugin/exchange/cluster/MessageHolder.java	2006-09-05 16:08:05 UTC (rev 1255)
@@ -0,0 +1,57 @@
+/*
+ * JBoss, Home of Professional Open Source
+ * Copyright 2005, JBoss Inc., and individual contributors as indicated
+ * by the @authors tag. See the copyright.txt in the distribution for a
+ * full listing of individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+package org.jboss.messaging.core.plugin.exchange.cluster;
+
+import org.jboss.messaging.core.Message;
+
+/**
+ * A MessageHolder
+ *
+ * @author <a href="mailto:tim.fox at jboss.com">Tim Fox</a>
+ * @version <tt>$Revision: 1.1 $</tt>
+ *
+ * $Id$
+ *
+ */
+class MessageHolder
+{
+   String routingKey;
+   
+   Message message;
+   
+   MessageHolder(String routingKey, Message message)
+   {
+      this.routingKey = routingKey;
+      
+      this.message = message;
+   }
+   
+   String getRoutingKey()
+   {
+      return routingKey;
+   }
+   
+   Message getMessage()
+   {
+      return message;
+   }
+}     

Added: trunk/src/main/org/jboss/messaging/core/plugin/exchange/cluster/MessageRequest.java
===================================================================
--- trunk/src/main/org/jboss/messaging/core/plugin/exchange/cluster/MessageRequest.java	2006-09-03 17:56:48 UTC (rev 1254)
+++ trunk/src/main/org/jboss/messaging/core/plugin/exchange/cluster/MessageRequest.java	2006-09-05 16:08:05 UTC (rev 1255)
@@ -0,0 +1,56 @@
+/*
+ * JBoss, Home of Professional Open Source
+ * Copyright 2005, JBoss Inc., and individual contributors as indicated
+ * by the @authors tag. See the copyright.txt in the distribution for a
+ * full listing of individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+package org.jboss.messaging.core.plugin.exchange.cluster;
+
+import org.jboss.messaging.core.Message;
+
+/**
+ * A MessageRequest
+ * 
+ * Used when sending a single message non reliably across the group
+ *
+ * @author <a href="mailto:tim.fox at jboss.com">Tim Fox</a>
+ * @version <tt>$Revision: 1.1 $</tt>
+ *
+ * $Id$
+ *
+ */
+class MessageRequest implements ExchangeRequest
+{
+   private static final long serialVersionUID = 6681458404259394725L;
+   
+   private String routingKey;   
+   
+   private Message message;
+   
+   MessageRequest(String routingKey, Message message)
+   {
+      this.routingKey = routingKey;
+      
+      this.message = message;
+   }
+   
+   public void execute(ExchangeInternal exchange) throws Exception
+   {
+      exchange.routeFromCluster(message, routingKey);      
+   }   
+}

Added: trunk/src/main/org/jboss/messaging/core/plugin/exchange/cluster/MessagesRequest.java
===================================================================
--- trunk/src/main/org/jboss/messaging/core/plugin/exchange/cluster/MessagesRequest.java	2006-09-03 17:56:48 UTC (rev 1254)
+++ trunk/src/main/org/jboss/messaging/core/plugin/exchange/cluster/MessagesRequest.java	2006-09-05 16:08:05 UTC (rev 1255)
@@ -0,0 +1,61 @@
+/*
+ * JBoss, Home of Professional Open Source
+ * Copyright 2005, JBoss Inc., and individual contributors as indicated
+ * by the @authors tag. See the copyright.txt in the distribution for a
+ * full listing of individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+package org.jboss.messaging.core.plugin.exchange.cluster;
+
+import java.util.Iterator;
+import java.util.List;
+
+/**
+ * A MessagesRequest
+ * 
+ * Used when sending multiple messages non reliably across the group
+ *
+ * @author <a href="mailto:tim.fox at jboss.com">Tim Fox</a>
+ * @version <tt>$Revision: 1.1 $</tt>
+ *
+ * $Id$
+ *
+ */
+class MessagesRequest implements ExchangeRequest
+{
+   private static final long serialVersionUID = 3069447863470810127L;
+   
+   private List messageHolders;
+   
+   MessagesRequest(List messageHolders)
+   {
+      this.messageHolders = messageHolders;
+   }
+   
+   public void execute(ExchangeInternal exchange) throws Exception
+   {
+      Iterator iter = messageHolders.iterator();
+      
+      while (iter.hasNext())
+      {
+         MessageHolder holder = (MessageHolder)iter.next();
+         
+         exchange.routeFromCluster(holder.getMessage(), holder.getRoutingKey());
+      }
+   }   
+}
+

Added: trunk/src/main/org/jboss/messaging/core/plugin/exchange/cluster/SendNodeIdRequest.java
===================================================================
--- trunk/src/main/org/jboss/messaging/core/plugin/exchange/cluster/SendNodeIdRequest.java	2006-09-03 17:56:48 UTC (rev 1254)
+++ trunk/src/main/org/jboss/messaging/core/plugin/exchange/cluster/SendNodeIdRequest.java	2006-09-05 16:08:05 UTC (rev 1255)
@@ -0,0 +1,55 @@
+/*
+ * JBoss, Home of Professional Open Source
+ * Copyright 2005, JBoss Inc., and individual contributors as indicated
+ * by the @authors tag. See the copyright.txt in the distribution for a
+ * full listing of individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+package org.jboss.messaging.core.plugin.exchange.cluster;
+
+import org.jgroups.Address;
+
+/**
+ * A SendNodeIdRequest
+ * 
+ *
+ * @author <a href="mailto:tim.fox at jboss.com">Tim Fox</a>
+ * @version <tt>$Revision: 1.1 $</tt>
+ *
+ * $Id$
+ *
+ */
+class SendNodeIdRequest implements ExchangeRequest
+{
+   private static final long serialVersionUID = -3463428410402454526L;
+
+   private Address address;
+   
+   private String nodeId;
+   
+   SendNodeIdRequest(Address address, String nodeId)
+   {
+      this.address = address;
+      
+      this.nodeId = nodeId;      
+   }
+   
+   public void execute(ExchangeInternal exchange) throws Exception
+   {
+      exchange.handleAddressNodeMapping(address, nodeId);
+   }
+}

Added: trunk/src/main/org/jboss/messaging/core/plugin/exchange/cluster/SharedState.java
===================================================================
--- trunk/src/main/org/jboss/messaging/core/plugin/exchange/cluster/SharedState.java	2006-09-03 17:56:48 UTC (rev 1254)
+++ trunk/src/main/org/jboss/messaging/core/plugin/exchange/cluster/SharedState.java	2006-09-05 16:08:05 UTC (rev 1255)
@@ -0,0 +1,61 @@
+/*
+ * JBoss, Home of Professional Open Source
+ * Copyright 2005, JBoss Inc., and individual contributors as indicated
+ * by the @authors tag. See the copyright.txt in the distribution for a
+ * full listing of individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+package org.jboss.messaging.core.plugin.exchange.cluster;
+
+import java.io.Serializable;
+import java.util.List;
+import java.util.Map;
+
+/**
+ * A SharedState
+ *
+ * @author <a href="mailto:tim.fox at jboss.com">Tim Fox</a>
+ * @version <tt>$Revision: 1.1 $</tt>
+ *
+ * $Id$
+ *
+ */
+class SharedState implements Serializable
+{
+   private static final long serialVersionUID = 7782131373080845107L;
+
+   private List bindings;
+   
+   private Map nodeIdAddressMap;
+   
+   SharedState(List bindings, Map nodeIdAddressMap)
+   {
+      this.bindings = bindings;
+      
+      this.nodeIdAddressMap = nodeIdAddressMap;
+   }
+   
+   List getBindings()
+   {
+      return bindings;
+   }
+   
+   Map getNodeIdAddressMap()
+   {
+      return nodeIdAddressMap;
+   }
+}

Added: trunk/src/main/org/jboss/messaging/core/plugin/exchange/cluster/TransactionId.java
===================================================================
--- trunk/src/main/org/jboss/messaging/core/plugin/exchange/cluster/TransactionId.java	2006-09-03 17:56:48 UTC (rev 1254)
+++ trunk/src/main/org/jboss/messaging/core/plugin/exchange/cluster/TransactionId.java	2006-09-05 16:08:05 UTC (rev 1255)
@@ -0,0 +1,95 @@
+/*
+ * JBoss, Home of Professional Open Source
+ * Copyright 2005, JBoss Inc., and individual contributors as indicated
+ * by the @authors tag. See the copyright.txt in the distribution for a
+ * full listing of individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+package org.jboss.messaging.core.plugin.exchange.cluster;
+
+/**
+ * A Transactionid
+ *
+ * @author <a href="mailto:tim.fox at jboss.com">Tim Fox</a>
+ * @version <tt>$Revision: 1.1 $</tt>
+ *
+ * $Id$
+ *
+ */
+class TransactionId
+{
+   private String nodeId;
+   
+   private long txId;
+   
+   private int hash;
+   
+   TransactionId(String nodeId, long txId)
+   {
+      this.nodeId = nodeId;
+      
+      this.txId = txId;
+      
+      calculateHash();
+   }
+   
+   String getNodeId()
+   {
+      return nodeId;
+   }
+   
+   long getTxId()
+   {
+      return txId;
+   }
+   
+   public int hashCode()
+   {
+      return hash;
+   }
+   
+   public boolean equals(Object other)
+   {
+      if (other == this)
+      {
+         return true;
+      }
+      
+      if (!(other instanceof TransactionId))
+      {
+         return false;
+      }
+      
+      TransactionId tother = (TransactionId)other;
+      
+      return tother.txId == this.txId && tother.nodeId.equals(this.nodeId);
+   }
+   
+   public String toString()
+   {
+      return "TransactionId [" + System.identityHashCode(this) + "] nodeId: " + nodeId + " txId: " + txId;
+   }
+   
+   private void calculateHash()
+   {
+      hash = 17;
+      
+      hash = 37 * hash + (int)(txId ^ (txId >>> 32));
+      
+      hash = 37 * hash + nodeId.hashCode();
+   }
+}

Added: trunk/src/main/org/jboss/messaging/core/plugin/exchange/cluster/TransactionRequest.java
===================================================================
--- trunk/src/main/org/jboss/messaging/core/plugin/exchange/cluster/TransactionRequest.java	2006-09-03 17:56:48 UTC (rev 1254)
+++ trunk/src/main/org/jboss/messaging/core/plugin/exchange/cluster/TransactionRequest.java	2006-09-05 16:08:05 UTC (rev 1255)
@@ -0,0 +1,83 @@
+/*
+ * JBoss, Home of Professional Open Source
+ * Copyright 2005, JBoss Inc., and individual contributors as indicated
+ * by the @authors tag. See the copyright.txt in the distribution for a
+ * full listing of individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+package org.jboss.messaging.core.plugin.exchange.cluster;
+
+import java.util.List;
+
+/**
+ * A TransactionRequest
+ * 
+ * Used for sending persistent messages transactionally across the network
+ *
+ * @author <a href="mailto:tim.fox at jboss.com">Tim Fox</a>
+ * @version <tt>$Revision: 1.1 $</tt>
+ *
+ * $Id$
+ *
+ */
+class TransactionRequest implements ExchangeRequest
+{
+   private static final long serialVersionUID = 644500948910063649L;
+
+   private String nodeId;
+   
+   private long txId;
+ 
+   private List messageHolders;
+   
+   private boolean tryTransaction;
+      
+   TransactionRequest(String nodeId, long txId, List messageHolders)
+   {
+      this.nodeId = nodeId;
+      
+      this.txId= txId;
+
+      this.messageHolders = messageHolders;  
+      
+      tryTransaction = true;
+   }
+   
+   TransactionRequest(String nodeId, long txId)
+   {
+      this.nodeId = nodeId;
+      
+      this.txId= txId;
+      
+      tryTransaction = false;
+   }
+   
+   public void execute(ExchangeInternal exchange) throws Exception
+   {
+      TransactionId id = new TransactionId(nodeId, txId);
+      
+      if (tryTransaction)
+      {
+         exchange.addToHoldingArea(id, messageHolders);
+      }
+      else
+      {
+         exchange.commitTransaction(id);
+      }
+   }   
+}
+

Added: trunk/src/main/org/jboss/messaging/core/plugin/exchange/cluster/UnbindRequest.java
===================================================================
--- trunk/src/main/org/jboss/messaging/core/plugin/exchange/cluster/UnbindRequest.java	2006-09-03 17:56:48 UTC (rev 1254)
+++ trunk/src/main/org/jboss/messaging/core/plugin/exchange/cluster/UnbindRequest.java	2006-09-05 16:08:05 UTC (rev 1255)
@@ -0,0 +1,53 @@
+/*
+ * JBoss, Home of Professional Open Source
+ * Copyright 2005, JBoss Inc., and individual contributors as indicated
+ * by the @authors tag. See the copyright.txt in the distribution for a
+ * full listing of individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+package org.jboss.messaging.core.plugin.exchange.cluster;
+
+
+/**
+ * A UnbindRequest
+ *
+ * @author <a href="mailto:tim.fox at jboss.com">Tim Fox</a>
+ * @version <tt>$Revision: 1.1 $</tt>
+ *
+ * $Id$
+ *
+ */
+class UnbindRequest implements ExchangeRequest
+{
+   private static final long serialVersionUID = 6597644036507360965L;
+
+   private String nodeId;   
+   
+   private String queueName;
+
+   UnbindRequest(String nodeId, String queueName)
+   {
+      this.nodeId = nodeId;
+      
+      this.queueName = queueName;
+   }
+
+   public void execute(ExchangeInternal exchange) throws Exception
+   {
+      exchange.removeBindingFromCluster(nodeId, queueName);
+   }      
+}

Modified: trunk/src/main/org/jboss/messaging/core/tx/Transaction.java
===================================================================
--- trunk/src/main/org/jboss/messaging/core/tx/Transaction.java	2006-09-03 17:56:48 UTC (rev 1254)
+++ trunk/src/main/org/jboss/messaging/core/tx/Transaction.java	2006-09-05 16:08:05 UTC (rev 1255)
@@ -58,9 +58,10 @@
    
    protected List callbacks;
    
-   protected List keyedCallbacks;
+   protected Map callbackMap;
    
-   protected Map keyedCallbackMap;
+   //A special first callback that is ensured to be executed first
+   protected TxCallback firstCallback;
    
    // Static --------------------------------------------------------
    
@@ -109,8 +110,7 @@
       this.id = id;
       state = STATE_ACTIVE;
       callbacks = new ArrayList();
-      keyedCallbacks = new ArrayList();
-      keyedCallbackMap = new HashMap();
+      callbackMap = new HashMap();
    }
    
    Transaction(long id, Xid xid)
@@ -130,22 +130,29 @@
    {
       return xid;
    }
+
+   public void addCallback(TxCallback callback, Object key)
+   {            
+      callbacks.add(callback);
       
-   public void addCallback(TxCallback callback)
-   {
-      callbacks.add(callback);
+      callbackMap.put(key, callback);
    } 
    
-   public void addKeyedCallback(TxCallback callback, Object key)
-   {
-      keyedCallbacks.add(callback);
+   public void addFirstCallback(TxCallback callback, Object key)
+   {            
+      if (firstCallback != null)
+      {
+         throw new IllegalStateException("There is already a first callback");
+      }
       
-      keyedCallbackMap.put(key, callback);
-   } 
+      this.firstCallback = callback;
+      
+      callbackMap.put(key, callback);
+   }
    
-   public TxCallback getKeyedCallback(Object key)
+   public TxCallback getCallback(Object key)
    {
-      return (TxCallback)keyedCallbackMap.get(key);
+      return (TxCallback)callbackMap.get(key);
    }
       
    public synchronized void commit() throws Exception
@@ -167,10 +174,12 @@
        
       boolean onePhase = state != STATE_PREPARED;
       
-      List cb = new ArrayList(callbacks);
-      cb.addAll(keyedCallbacks);
+      if (firstCallback != null)
+      {
+         firstCallback.beforeCommit(onePhase);
+      }
       
-      Iterator iter = cb.iterator();
+      Iterator iter = callbacks.iterator();
       
       while (iter.hasNext())
       {
@@ -183,22 +192,27 @@
       
       if (trace) { log.trace("committed " + this); }
       
-      iter = cb.iterator();
+      iter = callbacks.iterator();
       
       if (trace) { log.trace("executing after commit hooks " + this); }
       
+      if (firstCallback != null)
+      {
+         firstCallback.afterCommit(onePhase);
+      }
+      
       while (iter.hasNext())
       {
          TxCallback callback = (TxCallback)iter.next();
          
          callback.afterCommit(onePhase);
       }
-      
+          
       callbacks = null;
       
-      keyedCallbacks = null;
+      callbackMap = null;      
       
-      keyedCallbackMap = null;      
+      firstCallback = null;
       
       if (trace) { log.trace("commit process complete " + this); }
    }
@@ -212,10 +226,12 @@
       
       if (trace) { log.trace("executing before prepare hooks " + this); }
       
-      List cb = new ArrayList(callbacks);
-      cb.addAll(keyedCallbacks);
+      if (firstCallback != null)
+      {
+         firstCallback.beforePrepare();
+      }
       
-      Iterator iter = cb.iterator();
+      Iterator iter = callbacks.iterator();
       
       while (iter.hasNext())
       {
@@ -228,8 +244,13 @@
       
       if (trace) { log.trace("prepared " + this); }
       
-      iter = cb.iterator();
+      if (firstCallback != null)
+      {
+         firstCallback.afterPrepare();
+      }
       
+      iter = callbacks.iterator();
+      
       if (trace) { log.trace("executing after prepare hooks " + this); }
       
       while (iter.hasNext())
@@ -257,11 +278,13 @@
       
       boolean onePhase = state != STATE_PREPARED;
       
-      List cb = new ArrayList(callbacks);
-      cb.addAll(keyedCallbacks);
-      
-      for(Iterator i = cb.iterator(); i.hasNext(); )
+      if (firstCallback != null)
       {
+         firstCallback.beforeRollback(onePhase);
+      }
+
+      for(Iterator i = callbacks.iterator(); i.hasNext(); )
+      {
          TxCallback callback = (TxCallback)i.next();
          callback.beforeRollback(onePhase);
       }
@@ -272,15 +295,19 @@
 
       if (trace) { log.trace("executing after prepare hooks " + this); }
 
-      for(Iterator i = cb.iterator(); i.hasNext();)
+      if (firstCallback != null)
       {
+         firstCallback.afterRollback(onePhase);
+      }
+      
+      for(Iterator i = callbacks.iterator(); i.hasNext();)
+      {
          TxCallback callback = (TxCallback)i.next();
          callback.afterRollback(onePhase);
       }            
       
       callbacks = null;
-      keyedCallbacks = null;
-      keyedCallbackMap = null;
+      callbackMap = null;
       
       if (trace) { log.trace("rollback process complete " + this); }
    }

Modified: trunk/tests/build.xml
===================================================================
--- trunk/tests/build.xml	2006-09-03 17:56:48 UTC (rev 1254)
+++ trunk/tests/build.xml	2006-09-05 16:08:05 UTC (rev 1255)
@@ -338,16 +338,11 @@
                     haltonerror="${junit.batchtest.haltonerror}">
             <formatter type="plain" usefile="${junit.formatter.usefile}"/>
             <fileset dir="${build.tests.classes}">
-               <!--
-               <include name="org/jboss/test/messaging/jms/JMSTest.class"/>
-               -->
                <include name="**/messaging/core/**/*Test.class"/>
                <include name="**/messaging/jms/**/*Test.class"/>
                <exclude name="**/jms/stress/**"/>
                <exclude name="**/jms/crash/*Test.class"/>
                <exclude name="**/jms/MemLeakTest.class"/>
-               <!-- TODO Exclude all distributed tests until after 1.0 release -->
-               <exclude name="**/messaging/core/distributed/**/*Test.class"/>
             </fileset>
          </batchtest>
       </junit>
@@ -385,10 +380,7 @@
                     haltonerror="${junit.batchtest.haltonerror}">
             <formatter type="plain" usefile="${junit.formatter.usefile}"/>
             <fileset dir="${build.tests.classes}">
-               <!-- <include name="org/jboss/test/messaging/jms/JMSTest.class"/> -->
                <include name="**/jms/MemLeakTest.class"/>
-               <!-- TODO Exclude all distributed tests until after 1.0 release -->
-               <exclude name="**/messaging/core/distributed/**/*Test.class"/>
             </fileset>
          </batchtest>
       </junit>
@@ -428,8 +420,6 @@
                <exclude name="**/jms/stress/**"/>
                <exclude name="**/jms/crash/*Test.class"/>
                <exclude name="**/jms/MemLeakTest.class"/>
-               <!-- TODO Exclude all distributed tests until after 1.0 release -->
-               <exclude name="**/messaging/core/distributed/**/*Test.class"/>
             </fileset>
          </batchtest>
       </junit>

Modified: trunk/tests/src/org/jboss/test/messaging/core/SimpleReceiver.java
===================================================================
--- trunk/tests/src/org/jboss/test/messaging/core/SimpleReceiver.java	2006-09-03 17:56:48 UTC (rev 1254)
+++ trunk/tests/src/org/jboss/test/messaging/core/SimpleReceiver.java	2006-09-05 16:08:05 UTC (rev 1255)
@@ -38,6 +38,7 @@
 import org.jboss.messaging.core.SimpleDelivery;
 import org.jboss.messaging.core.tx.Transaction;
 import org.jboss.messaging.core.tx.TxCallback;
+import org.jboss.util.id.GUID;
 
 /**
  * A simple Receiver implementation that consumes undelivered by storing them internally. Used for
@@ -316,7 +317,7 @@
       // make sure I get rid of message if the transaction is rolled back
       if (tx != null)
       {
-         tx.addCallback(new PostAcknowledgeCommitCallback(touple));
+         tx.addCallback(new PostAcknowledgeCommitCallback(touple), new GUID().toString());
       }
    }
 

Modified: trunk/tests/src/org/jboss/test/messaging/core/base/MessageQueueTestBase.java
===================================================================
--- trunk/tests/src/org/jboss/test/messaging/core/base/MessageQueueTestBase.java	2006-09-03 17:56:48 UTC (rev 1254)
+++ trunk/tests/src/org/jboss/test/messaging/core/base/MessageQueueTestBase.java	2006-09-05 16:08:05 UTC (rev 1255)
@@ -5243,6 +5243,9 @@
       assertEquals(0, ackm.getMessageID());
 
       // an extra acknowledgment should be discarded
+      
+      //TODO - why should it be discarded?
+      //If you acknowledge twice surely this is a usage error?
       r.acknowledge(ackm, null);
 
       assertTrue(messageQueue.browse().isEmpty());

Modified: trunk/tests/src/org/jboss/test/messaging/core/local/RoundRobinPointToPointRouterTest.java
===================================================================
--- trunk/tests/src/org/jboss/test/messaging/core/local/RoundRobinPointToPointRouterTest.java	2006-09-03 17:56:48 UTC (rev 1254)
+++ trunk/tests/src/org/jboss/test/messaging/core/local/RoundRobinPointToPointRouterTest.java	2006-09-05 16:08:05 UTC (rev 1255)
@@ -379,13 +379,13 @@
       MessageReference ref = new SimpleMessageReference();
       
       Delivery del = router.handle(null, ref, null);
-      assertNotNull(del);
+      assertNull(del);
       
       del = router.handle(null, ref, null);
-      assertNotNull(del);
+      assertNull(del);
       
       del = router.handle(null, ref, null);
-      assertNotNull(del);    
+      assertNull(del);    
    }
 
 

Modified: trunk/tests/src/org/jboss/test/messaging/core/paging/ChannelShare_NP_2PCTest.java
===================================================================
--- trunk/tests/src/org/jboss/test/messaging/core/paging/ChannelShare_NP_2PCTest.java	2006-09-03 17:56:48 UTC (rev 1254)
+++ trunk/tests/src/org/jboss/test/messaging/core/paging/ChannelShare_NP_2PCTest.java	2006-09-05 16:08:05 UTC (rev 1255)
@@ -95,7 +95,7 @@
       tx.commit();
       
       //Queue1
-      List refIds = getReferenceIds(queue1.getChannelID());
+      List refIds = getReferenceIdsOrderedByPageOrd(queue1.getChannelID());
       assertEquals(0, refIds.size());
                                     
       assertEquals(50, queue1.memoryRefCount());
@@ -108,7 +108,7 @@
       
       //Queue2
       
-      refIds = getReferenceIds(queue2.getChannelID());
+      refIds = getReferenceIdsOrderedByPageOrd(queue2.getChannelID());
       assertEquals(0, refIds.size());
                               
       assertEquals(50, queue2.memoryRefCount());
@@ -149,7 +149,7 @@
       tx.commit();
       
       //Queue1
-      refIds = getReferenceIds(queue1.getChannelID());
+      refIds = getReferenceIdsOrderedByPageOrd(queue1.getChannelID());
               
       assertEquals(0, refIds.size());
                                     
@@ -163,7 +163,7 @@
       
       //Queue2
       
-      refIds = getReferenceIds(queue2.getChannelID());
+      refIds = getReferenceIdsOrderedByPageOrd(queue2.getChannelID());
       assertEquals(25, refIds.size());
                               
       assertEquals(50, queue2.memoryRefCount());
@@ -205,7 +205,7 @@
       tx.commit();
       
       //Queue1
-      refIds = getReferenceIds(queue1.getChannelID());
+      refIds = getReferenceIdsOrderedByPageOrd(queue1.getChannelID());
                 
       assertEquals(0, refIds.size());
                                     
@@ -219,7 +219,7 @@
       
       //Queue2
       
-      refIds = getReferenceIds(queue2.getChannelID());
+      refIds = getReferenceIdsOrderedByPageOrd(queue2.getChannelID());
       assertEquals(50, refIds.size());
                               
       assertEquals(50, queue2.memoryRefCount());
@@ -260,7 +260,7 @@
       tx.commit();
       
       //Queue1
-      refIds = getReferenceIds(queue1.getChannelID());
+      refIds = getReferenceIdsOrderedByPageOrd(queue1.getChannelID());
                 
       assertEquals(50, refIds.size());
                                     
@@ -274,7 +274,7 @@
       
       //Queue2
       
-      refIds = getReferenceIds(queue2.getChannelID());
+      refIds = getReferenceIdsOrderedByPageOrd(queue2.getChannelID());
       assertEquals(100, refIds.size());
                               
       assertEquals(50, queue2.memoryRefCount());
@@ -303,7 +303,7 @@
       this.consumeIn2PCTx(queue2, 0, refs2, 150);
       
       //    Queue1
-      refIds = getReferenceIds(queue1.getChannelID());
+      refIds = getReferenceIdsOrderedByPageOrd(queue1.getChannelID());
                 
       assertEquals(0, refIds.size());
                                     
@@ -317,7 +317,7 @@
       
       //Queue2
       
-      refIds = getReferenceIds(queue2.getChannelID());
+      refIds = getReferenceIdsOrderedByPageOrd(queue2.getChannelID());
       assertEquals(0, refIds.size());
                               
       assertEquals(0, queue2.memoryRefCount());

Modified: trunk/tests/src/org/jboss/test/messaging/core/paging/ChannelShare_NP_NTTest.java
===================================================================
--- trunk/tests/src/org/jboss/test/messaging/core/paging/ChannelShare_NP_NTTest.java	2006-09-03 17:56:48 UTC (rev 1254)
+++ trunk/tests/src/org/jboss/test/messaging/core/paging/ChannelShare_NP_NTTest.java	2006-09-05 16:08:05 UTC (rev 1255)
@@ -93,7 +93,7 @@
       }
       
       //Queue1
-      List refIds = getReferenceIds(queue1.getChannelID());
+      List refIds = getReferenceIdsOrderedByPageOrd(queue1.getChannelID());
       assertEquals(0, refIds.size());
                                     
       assertEquals(50, queue1.memoryRefCount());
@@ -106,7 +106,7 @@
       
       //Queue2
       
-      refIds = getReferenceIds(queue2.getChannelID());
+      refIds = getReferenceIdsOrderedByPageOrd(queue2.getChannelID());
       assertEquals(0, refIds.size());
                               
       assertEquals(50, queue2.memoryRefCount());
@@ -144,7 +144,7 @@
       }
       
       //Queue1
-      refIds = getReferenceIds(queue1.getChannelID());
+      refIds = getReferenceIdsOrderedByPageOrd(queue1.getChannelID());
               
       assertEquals(0, refIds.size());
                                     
@@ -158,7 +158,7 @@
       
       //Queue2
       
-      refIds = getReferenceIds(queue2.getChannelID());
+      refIds = getReferenceIdsOrderedByPageOrd(queue2.getChannelID());
       assertEquals(25, refIds.size());
                               
       assertEquals(50, queue2.memoryRefCount());
@@ -198,7 +198,7 @@
       }
       
       //Queue1
-      refIds = getReferenceIds(queue1.getChannelID());
+      refIds = getReferenceIdsOrderedByPageOrd(queue1.getChannelID());
                 
       assertEquals(0, refIds.size());
                                     
@@ -212,7 +212,7 @@
       
       //Queue2
       
-      refIds = getReferenceIds(queue2.getChannelID());
+      refIds = getReferenceIdsOrderedByPageOrd(queue2.getChannelID());
       assertEquals(50, refIds.size());
                               
       assertEquals(50, queue2.memoryRefCount());
@@ -251,7 +251,7 @@
       }
       
       //Queue1
-      refIds = getReferenceIds(queue1.getChannelID());
+      refIds = getReferenceIdsOrderedByPageOrd(queue1.getChannelID());
                 
       assertEquals(50, refIds.size());
                                     
@@ -265,7 +265,7 @@
       
       //Queue2
       
-      refIds = getReferenceIds(queue2.getChannelID());
+      refIds = getReferenceIdsOrderedByPageOrd(queue2.getChannelID());
       assertEquals(100, refIds.size());
                               
       assertEquals(50, queue2.memoryRefCount());
@@ -295,7 +295,7 @@
       this.consume(queue2, 0, refs2, 150);
       
       //    Queue1
-      refIds = getReferenceIds(queue1.getChannelID());
+      refIds = getReferenceIdsOrderedByPageOrd(queue1.getChannelID());
                 
       assertEquals(0, refIds.size());
                                     
@@ -309,7 +309,7 @@
       
       //Queue2
       
-      refIds = getReferenceIds(queue2.getChannelID());
+      refIds = getReferenceIdsOrderedByPageOrd(queue2.getChannelID());
       assertEquals(0, refIds.size());
                               
       assertEquals(0, queue2.memoryRefCount());

Modified: trunk/tests/src/org/jboss/test/messaging/core/paging/ChannelShare_NP_TTest.java
===================================================================
--- trunk/tests/src/org/jboss/test/messaging/core/paging/ChannelShare_NP_TTest.java	2006-09-03 17:56:48 UTC (rev 1254)
+++ trunk/tests/src/org/jboss/test/messaging/core/paging/ChannelShare_NP_TTest.java	2006-09-05 16:08:05 UTC (rev 1255)
@@ -96,7 +96,7 @@
       tx.commit();
       
       //Queue1
-      List refIds = getReferenceIds(queue1.getChannelID());
+      List refIds = getReferenceIdsOrderedByPageOrd(queue1.getChannelID());
       assertEquals(0, refIds.size());
                                     
       assertEquals(50, queue1.memoryRefCount());
@@ -109,7 +109,7 @@
       
       //Queue2
       
-      refIds = getReferenceIds(queue2.getChannelID());
+      refIds = getReferenceIdsOrderedByPageOrd(queue2.getChannelID());
       assertEquals(0, refIds.size());
                               
       assertEquals(50, queue2.memoryRefCount());
@@ -149,7 +149,7 @@
       tx.commit();
       
       //Queue1
-      refIds = getReferenceIds(queue1.getChannelID());
+      refIds = getReferenceIdsOrderedByPageOrd(queue1.getChannelID());
               
       assertEquals(0, refIds.size());
                                     
@@ -163,7 +163,7 @@
       
       //Queue2
       
-      refIds = getReferenceIds(queue2.getChannelID());
+      refIds = getReferenceIdsOrderedByPageOrd(queue2.getChannelID());
       assertEquals(25, refIds.size());
                               
       assertEquals(50, queue2.memoryRefCount());
@@ -204,7 +204,7 @@
       tx.commit();
       
       //Queue1
-      refIds = getReferenceIds(queue1.getChannelID());
+      refIds = getReferenceIdsOrderedByPageOrd(queue1.getChannelID());
                 
       assertEquals(0, refIds.size());
                                     
@@ -218,7 +218,7 @@
       
       //Queue2
       
-      refIds = getReferenceIds(queue2.getChannelID());
+      refIds = getReferenceIdsOrderedByPageOrd(queue2.getChannelID());
       assertEquals(50, refIds.size());
                               
       assertEquals(50, queue2.memoryRefCount());
@@ -258,7 +258,7 @@
       tx.commit();
       
       //Queue1
-      refIds = getReferenceIds(queue1.getChannelID());
+      refIds = getReferenceIdsOrderedByPageOrd(queue1.getChannelID());
                 
       assertEquals(50, refIds.size());
                                     
@@ -272,7 +272,7 @@
       
       //Queue2
       
-      refIds = getReferenceIds(queue2.getChannelID());
+      refIds = getReferenceIdsOrderedByPageOrd(queue2.getChannelID());
       assertEquals(100, refIds.size());
                               
       assertEquals(50, queue2.memoryRefCount());
@@ -302,7 +302,7 @@
       this.consumeInTx(queue2, 0, refs2, 150);
       
       //    Queue1
-      refIds = getReferenceIds(queue1.getChannelID());
+      refIds = getReferenceIdsOrderedByPageOrd(queue1.getChannelID());
                 
       assertEquals(0, refIds.size());
                                     
@@ -316,7 +316,7 @@
       
       //Queue2
       
-      refIds = getReferenceIds(queue2.getChannelID());
+      refIds = getReferenceIdsOrderedByPageOrd(queue2.getChannelID());
       assertEquals(0, refIds.size());
                               
       assertEquals(0, queue2.memoryRefCount());

Modified: trunk/tests/src/org/jboss/test/messaging/core/paging/ChannelShare_P_2PCTest.java
===================================================================
--- trunk/tests/src/org/jboss/test/messaging/core/paging/ChannelShare_P_2PCTest.java	2006-09-03 17:56:48 UTC (rev 1254)
+++ trunk/tests/src/org/jboss/test/messaging/core/paging/ChannelShare_P_2PCTest.java	2006-09-05 16:08:05 UTC (rev 1255)
@@ -94,7 +94,7 @@
       List refIds = getPagedReferenceIds(queue1.getChannelID());
       assertEquals(0, refIds.size());
       
-      refIds = getReferenceIds(queue1.getChannelID());
+      refIds = getReferenceIdsOrderedByOrd(queue1.getChannelID());
       assertEquals(50, refIds.size());
                                     
       assertEquals(50, queue1.memoryRefCount());
@@ -110,7 +110,7 @@
       refIds = getPagedReferenceIds(queue2.getChannelID());
       assertEquals(0, refIds.size());
       
-      refIds = getReferenceIds(queue2.getChannelID());
+      refIds = getReferenceIdsOrderedByOrd(queue2.getChannelID());
       assertEquals(50, refIds.size());
                               
       assertEquals(50, queue2.memoryRefCount());
@@ -154,7 +154,7 @@
               
       assertEquals(0, refIds.size());
       
-      refIds = getReferenceIds(queue1.getChannelID());
+      refIds = getReferenceIdsOrderedByOrd(queue1.getChannelID());
       assertEquals(75, refIds.size());
                                     
       assertEquals(75, queue1.memoryRefCount());
@@ -170,7 +170,7 @@
       refIds = getPagedReferenceIds(queue2.getChannelID());
       assertEquals(25, refIds.size());
       
-      refIds = getReferenceIds(queue2.getChannelID());
+      refIds = getReferenceIdsOrderedByOrd(queue2.getChannelID());
       assertEquals(75, refIds.size());
                               
       assertEquals(50, queue2.memoryRefCount());
@@ -216,7 +216,7 @@
                 
       assertEquals(0, refIds.size());
       
-      refIds = getReferenceIds(queue1.getChannelID());
+      refIds = getReferenceIdsOrderedByOrd(queue1.getChannelID());
       assertEquals(100, refIds.size());
                                     
       assertEquals(100, queue1.memoryRefCount());
@@ -232,7 +232,7 @@
       refIds = getPagedReferenceIds(queue2.getChannelID());
       assertEquals(50, refIds.size());
       
-      refIds = getReferenceIds(queue2.getChannelID());
+      refIds = getReferenceIdsOrderedByOrd(queue2.getChannelID());
       assertEquals(100, refIds.size());
                               
       assertEquals(50, queue2.memoryRefCount());
@@ -277,7 +277,7 @@
                 
       assertEquals(50, refIds.size());
       
-      refIds = getReferenceIds(queue1.getChannelID());
+      refIds = getReferenceIdsOrderedByOrd(queue1.getChannelID());
       assertEquals(150, refIds.size());
                                     
       assertEquals(100, queue1.memoryRefCount());
@@ -293,7 +293,7 @@
       refIds = getPagedReferenceIds(queue2.getChannelID());
       assertEquals(100, refIds.size());
       
-      refIds = getReferenceIds(queue2.getChannelID());
+      refIds = getReferenceIdsOrderedByOrd(queue2.getChannelID());
       assertEquals(150, refIds.size());
                               
       assertEquals(50, queue2.memoryRefCount());
@@ -323,7 +323,7 @@
       this.consumeIn2PCTx(queue2, 0, refs2, 150);
       
       //    Queue1
-      refIds = getReferenceIds(queue1.getChannelID());
+      refIds = getReferenceIdsOrderedByOrd(queue1.getChannelID());
                 
       assertEquals(0, refIds.size());
                                     
@@ -337,7 +337,7 @@
       
       //Queue2
       
-      refIds = getReferenceIds(queue2.getChannelID());
+      refIds = getReferenceIdsOrderedByOrd(queue2.getChannelID());
       assertEquals(0, refIds.size());
                               
       assertEquals(0, queue2.memoryRefCount());

Modified: trunk/tests/src/org/jboss/test/messaging/core/paging/ChannelShare_P_NTTest.java
===================================================================
--- trunk/tests/src/org/jboss/test/messaging/core/paging/ChannelShare_P_NTTest.java	2006-09-03 17:56:48 UTC (rev 1254)
+++ trunk/tests/src/org/jboss/test/messaging/core/paging/ChannelShare_P_NTTest.java	2006-09-05 16:08:05 UTC (rev 1255)
@@ -96,7 +96,7 @@
       List refIds = getPagedReferenceIds(queue1.getChannelID());
       assertEquals(0, refIds.size());
       
-      refIds = getReferenceIds(queue1.getChannelID());
+      refIds = getReferenceIdsOrderedByOrd(queue1.getChannelID());
       assertEquals(50, refIds.size());
                                     
       assertEquals(50, queue1.memoryRefCount());
@@ -112,7 +112,7 @@
       refIds = getPagedReferenceIds(queue2.getChannelID());
       assertEquals(0, refIds.size());
       
-      refIds = getReferenceIds(queue2.getChannelID());
+      refIds = getReferenceIdsOrderedByOrd(queue2.getChannelID());
       assertEquals(50, refIds.size());
                               
       assertEquals(50, queue2.memoryRefCount());
@@ -154,7 +154,7 @@
               
       assertEquals(0, refIds.size());
       
-      refIds = getReferenceIds(queue1.getChannelID());
+      refIds = getReferenceIdsOrderedByOrd(queue1.getChannelID());
       assertEquals(75, refIds.size());
                                     
       assertEquals(75, queue1.memoryRefCount());
@@ -170,7 +170,7 @@
       refIds = getPagedReferenceIds(queue2.getChannelID());
       assertEquals(25, refIds.size());
       
-      refIds = getReferenceIds(queue2.getChannelID());
+      refIds = getReferenceIdsOrderedByOrd(queue2.getChannelID());
       assertEquals(75, refIds.size());
                               
       assertEquals(50, queue2.memoryRefCount());
@@ -214,7 +214,7 @@
                 
       assertEquals(0, refIds.size());
       
-      refIds = getReferenceIds(queue1.getChannelID());
+      refIds = getReferenceIdsOrderedByOrd(queue1.getChannelID());
       assertEquals(100, refIds.size());
                                     
       assertEquals(100, queue1.memoryRefCount());
@@ -230,7 +230,7 @@
       refIds = getPagedReferenceIds(queue2.getChannelID());
       assertEquals(50, refIds.size());
       
-      refIds = getReferenceIds(queue2.getChannelID());
+      refIds = getReferenceIdsOrderedByOrd(queue2.getChannelID());
       assertEquals(100, refIds.size());
                               
       assertEquals(50, queue2.memoryRefCount());
@@ -273,7 +273,7 @@
                 
       assertEquals(50, refIds.size());
       
-      refIds = getReferenceIds(queue1.getChannelID());
+      refIds = getReferenceIdsOrderedByOrd(queue1.getChannelID());
       assertEquals(150, refIds.size());
                                     
       assertEquals(100, queue1.memoryRefCount());
@@ -289,7 +289,7 @@
       refIds = getPagedReferenceIds(queue2.getChannelID());
       assertEquals(100, refIds.size());
       
-      refIds = getReferenceIds(queue2.getChannelID());
+      refIds = getReferenceIdsOrderedByOrd(queue2.getChannelID());
       assertEquals(150, refIds.size());
                               
       assertEquals(50, queue2.memoryRefCount());
@@ -319,7 +319,7 @@
       this.consume(queue2, 0, refs2, 150);
       
       //    Queue1
-      refIds = getReferenceIds(queue1.getChannelID());
+      refIds = getReferenceIdsOrderedByOrd(queue1.getChannelID());
                 
       assertEquals(0, refIds.size());
                                     
@@ -333,7 +333,7 @@
       
       //Queue2
       
-      refIds = getReferenceIds(queue2.getChannelID());
+      refIds = getReferenceIdsOrderedByOrd(queue2.getChannelID());
       assertEquals(0, refIds.size());
                               
       assertEquals(0, queue2.memoryRefCount());

Modified: trunk/tests/src/org/jboss/test/messaging/core/paging/ChannelShare_P_TTest.java
===================================================================
--- trunk/tests/src/org/jboss/test/messaging/core/paging/ChannelShare_P_TTest.java	2006-09-03 17:56:48 UTC (rev 1254)
+++ trunk/tests/src/org/jboss/test/messaging/core/paging/ChannelShare_P_TTest.java	2006-09-05 16:08:05 UTC (rev 1255)
@@ -97,7 +97,7 @@
       List refIds = getPagedReferenceIds(queue1.getChannelID());
       assertEquals(0, refIds.size());
       
-      refIds = getReferenceIds(queue1.getChannelID());
+      refIds = getReferenceIdsOrderedByOrd(queue1.getChannelID());
       assertEquals(50, refIds.size());
                                     
       assertEquals(50, queue1.memoryRefCount());
@@ -113,7 +113,7 @@
       refIds = getPagedReferenceIds(queue2.getChannelID());
       assertEquals(0, refIds.size());
       
-      refIds = getReferenceIds(queue2.getChannelID());
+      refIds = getReferenceIdsOrderedByOrd(queue2.getChannelID());
       assertEquals(50, refIds.size());
                               
       assertEquals(50, queue2.memoryRefCount());
@@ -156,7 +156,7 @@
               
       assertEquals(0, refIds.size());
       
-      refIds = getReferenceIds(queue1.getChannelID());
+      refIds = getReferenceIdsOrderedByOrd(queue1.getChannelID());
       assertEquals(75, refIds.size());
                                     
       assertEquals(75, queue1.memoryRefCount());
@@ -172,7 +172,7 @@
       refIds = getPagedReferenceIds(queue2.getChannelID());
       assertEquals(25, refIds.size());
       
-      refIds = getReferenceIds(queue2.getChannelID());
+      refIds = getReferenceIdsOrderedByOrd(queue2.getChannelID());
       assertEquals(75, refIds.size());
                               
       assertEquals(50, queue2.memoryRefCount());
@@ -217,7 +217,7 @@
                 
       assertEquals(0, refIds.size());
       
-      refIds = getReferenceIds(queue1.getChannelID());
+      refIds = getReferenceIdsOrderedByOrd(queue1.getChannelID());
       assertEquals(100, refIds.size());
                                     
       assertEquals(100, queue1.memoryRefCount());
@@ -233,7 +233,7 @@
       refIds = getPagedReferenceIds(queue2.getChannelID());
       assertEquals(50, refIds.size());
       
-      refIds = getReferenceIds(queue2.getChannelID());
+      refIds = getReferenceIdsOrderedByOrd(queue2.getChannelID());
       assertEquals(100, refIds.size());
                               
       assertEquals(50, queue2.memoryRefCount());
@@ -277,7 +277,7 @@
                 
       assertEquals(50, refIds.size());
       
-      refIds = getReferenceIds(queue1.getChannelID());
+      refIds = getReferenceIdsOrderedByOrd(queue1.getChannelID());
       assertEquals(150, refIds.size());
                                     
       assertEquals(100, queue1.memoryRefCount());
@@ -293,7 +293,7 @@
       refIds = getPagedReferenceIds(queue2.getChannelID());
       assertEquals(100, refIds.size());
       
-      refIds = getReferenceIds(queue2.getChannelID());
+      refIds = getReferenceIdsOrderedByOrd(queue2.getChannelID());
       assertEquals(150, refIds.size());
                               
       assertEquals(50, queue2.memoryRefCount());
@@ -323,7 +323,7 @@
       this.consumeInTx(queue2, 0, refs2, 150);
       
       //    Queue1
-      refIds = getReferenceIds(queue1.getChannelID());
+      refIds = getReferenceIdsOrderedByOrd(queue1.getChannelID());
                 
       assertEquals(0, refIds.size());
                                     
@@ -337,7 +337,7 @@
       
       //Queue2
       
-      refIds = getReferenceIds(queue2.getChannelID());
+      refIds = getReferenceIdsOrderedByOrd(queue2.getChannelID());
       assertEquals(0, refIds.size());
                               
       assertEquals(0, queue2.memoryRefCount());

Modified: trunk/tests/src/org/jboss/test/messaging/core/paging/PagingStateTestBase.java
===================================================================
--- trunk/tests/src/org/jboss/test/messaging/core/paging/PagingStateTestBase.java	2006-09-03 17:56:48 UTC (rev 1254)
+++ trunk/tests/src/org/jboss/test/messaging/core/paging/PagingStateTestBase.java	2006-09-05 16:08:05 UTC (rev 1255)
@@ -413,7 +413,7 @@
    }
    
    
-   protected List getReferenceIds(long channelId) throws Exception
+   protected List getReferenceIdsOrderedByOrd(long channelId) throws Exception
    {
       InitialContext ctx = new InitialContext();
 
@@ -424,25 +424,32 @@
       mgr.begin();
 
       Connection conn = ds.getConnection();
-      String sql = "SELECT MESSAGEID, ORD, PAGE_ORD FROM JMS_MESSAGE_REFERENCE WHERE CHANNELID=? ORDER BY PAGE_ORD";
+      
+      List msgIds = new ArrayList();
+
+      String sql = "SELECT MESSAGEID, ORD, PAGE_ORD FROM JMS_MESSAGE_REFERENCE WHERE CHANNELID=? ORDER BY ORD";
       PreparedStatement ps = conn.prepareStatement(sql);
       ps.setLong(1, channelId);
    
+      log.info("************* refs");
+      
       ResultSet rs = ps.executeQuery();
-      
-      List msgIds = new ArrayList();
-      
+            
       while (rs.next())
       {
          long msgId = rs.getLong(1);
-         long ord = rs.getLong(2);
-         long pageOrd = rs.getLong(3);
+         long ord = rs.getLong(2);         
          
+         log.info("msgid:" + msgId + " ord:" + ord + " pageord: null");
+         
          msgIds.add(new Long(msgId));
       }
       rs.close();
       ps.close();
+       
       conn.close();
+      
+      log.info("*************** end refs");
 
       mgr.commit();
 
@@ -454,6 +461,46 @@
       return msgIds;
    }
    
+   protected List getReferenceIdsOrderedByPageOrd(long channelId) throws Exception
+   {
+      InitialContext ctx = new InitialContext();
+
+      TransactionManager mgr = (TransactionManager)ctx.lookup(TransactionManagerService.JNDI_NAME);
+      DataSource ds = (DataSource)ctx.lookup("java:/DefaultDS");
+      
+      javax.transaction.Transaction txOld = mgr.suspend();
+      mgr.begin();
+
+      Connection conn = ds.getConnection();
+      
+      List msgIds = new ArrayList();
+
+      String sql = "SELECT MESSAGEID, ORD, PAGE_ORD FROM JMS_MESSAGE_REFERENCE WHERE CHANNELID=? ORDER BY PAGE_ORD";
+      PreparedStatement ps = conn.prepareStatement(sql);
+      ps.setLong(1, channelId);
+   
+      ResultSet rs = ps.executeQuery();
+            
+      while (rs.next())
+      {
+         long msgId = rs.getLong(1);           
+         msgIds.add(new Long(msgId));
+      }
+      rs.close();
+      ps.close();
+       
+      conn.close();
+
+      mgr.commit();
+
+      if (txOld != null)
+      {
+         mgr.resume(txOld);
+      }
+      
+      return msgIds;
+   }
+   
    protected List getPagedReferenceIds(long channelId) throws Exception
    {
       InitialContext ctx = new InitialContext();

Modified: trunk/tests/src/org/jboss/test/messaging/core/paging/SingleChannel_NP_2PCTest.java
===================================================================
--- trunk/tests/src/org/jboss/test/messaging/core/paging/SingleChannel_NP_2PCTest.java	2006-09-03 17:56:48 UTC (rev 1254)
+++ trunk/tests/src/org/jboss/test/messaging/core/paging/SingleChannel_NP_2PCTest.java	2006-09-05 16:08:05 UTC (rev 1255)
@@ -90,7 +90,7 @@
       
       //verify no refs in storage
             
-      List refIds = getReferenceIds(queue.getChannelID());
+      List refIds = getReferenceIdsOrderedByPageOrd(queue.getChannelID());
       assertTrue(refIds.isEmpty());
       
       //Verify no msgs in storage
@@ -127,7 +127,7 @@
       
       //verify no refs in storage
       
-      refIds = getReferenceIds(queue.getChannelID());
+      refIds = getReferenceIdsOrderedByPageOrd(queue.getChannelID());
       assertTrue(refIds.isEmpty());
       
       //Verify no msgs in storage
@@ -165,7 +165,7 @@
       
       //verify no refs in storage
       
-      refIds = getReferenceIds(queue.getChannelID());
+      refIds = getReferenceIdsOrderedByPageOrd(queue.getChannelID());
       assertTrue(refIds.isEmpty());
       
       //Verify no msgs in storage
@@ -202,7 +202,7 @@
       
       //verify 10 refs in storage
       
-      refIds = getReferenceIds(queue.getChannelID());
+      refIds = getReferenceIdsOrderedByPageOrd(queue.getChannelID());
       assertEquals(10, refIds.size());
       assertSameIds(refIds, refs, 100, 109);
       
@@ -240,7 +240,7 @@
       
       //verify 10 refs in storage
       
-      refIds = getReferenceIds(queue.getChannelID());
+      refIds = getReferenceIdsOrderedByPageOrd(queue.getChannelID());
       assertEquals(10, refIds.size());
       assertSameIds(refIds, refs, 100, 109);
       
@@ -281,7 +281,7 @@
       
       //verify 20 refs in storage
       
-      refIds = getReferenceIds(queue.getChannelID());
+      refIds = getReferenceIdsOrderedByPageOrd(queue.getChannelID());
       assertEquals(20, refIds.size());
       assertSameIds(refIds, refs, 100, 119);
       
@@ -333,7 +333,7 @@
       
       //verify 30 refs in storage
       
-      refIds = getReferenceIds(queue.getChannelID());
+      refIds = getReferenceIdsOrderedByPageOrd(queue.getChannelID());
       assertEquals(30, refIds.size());
       assertSameIds(refIds, refs, 100, 129);
       
@@ -375,7 +375,7 @@
       
       //verify 40 refs in storage
       
-      refIds = getReferenceIds(queue.getChannelID());
+      refIds = getReferenceIdsOrderedByPageOrd(queue.getChannelID());
       assertEquals(40, refIds.size());
       assertSameIds(refIds, refs, 100, 139);
       
@@ -414,7 +414,7 @@
       
       //verify 40 refs in storage
       
-      refIds = getReferenceIds(queue.getChannelID());
+      refIds = getReferenceIdsOrderedByPageOrd(queue.getChannelID());
       assertEquals(40, refIds.size());
       assertSameIds(refIds, refs, 100, 139);
       
@@ -448,7 +448,7 @@
       
       //verify 40 refs in storage
       
-      refIds = getReferenceIds(queue.getChannelID());
+      refIds = getReferenceIdsOrderedByPageOrd(queue.getChannelID());
       assertEquals(40, refIds.size());
       assertSameIds(refIds, refs, 100, 139);
       
@@ -485,7 +485,7 @@
       
       //verify 40 refs in storage
       
-      refIds = getReferenceIds(queue.getChannelID());
+      refIds = getReferenceIdsOrderedByPageOrd(queue.getChannelID());
       assertEquals(40, refIds.size());
       assertSameIds(refIds, refs, 100, 139);
       
@@ -519,7 +519,7 @@
       
       //verify 21 refs in storage
       
-      refIds = getReferenceIds(queue.getChannelID());
+      refIds = getReferenceIdsOrderedByPageOrd(queue.getChannelID());
       assertEquals(21, refIds.size());
       assertSameIds(refIds, refs, 120, 140);
       
@@ -553,7 +553,7 @@
       
       //verify 1 ref in storage
       
-      refIds = getReferenceIds(queue.getChannelID());
+      refIds = getReferenceIdsOrderedByPageOrd(queue.getChannelID());
       assertEquals(1, refIds.size());
       assertSameIds(refIds, refs, 140, 140);
       
@@ -587,7 +587,7 @@
       
       //verify 0 ref in storage
       
-      refIds = getReferenceIds(queue.getChannelID());
+      refIds = getReferenceIdsOrderedByPageOrd(queue.getChannelID());
       assertEquals(0, refIds.size());
       
       //Verify 0 msgs in storage
@@ -619,7 +619,7 @@
       
       //verify 0 ref in storage
       
-      refIds = getReferenceIds(queue.getChannelID());
+      refIds = getReferenceIdsOrderedByPageOrd(queue.getChannelID());
       assertEquals(0, refIds.size());
       
       //Verify 0 msgs in storage
@@ -651,7 +651,7 @@
       
       //verify 0 ref in storage
       
-      refIds = getReferenceIds(queue.getChannelID());
+      refIds = getReferenceIdsOrderedByPageOrd(queue.getChannelID());
       assertEquals(0, refIds.size());
       
       //Verify 0 msgs in storage
@@ -689,7 +689,7 @@
       
       //verify 0 ref in storage
       
-      refIds = getReferenceIds(queue.getChannelID());
+      refIds = getReferenceIdsOrderedByPageOrd(queue.getChannelID());
       assertEquals(0, refIds.size());
       
       //Verify 0 msgs in storage
@@ -728,7 +728,7 @@
       
       //verify 0 ref in storage
       
-      refIds = getReferenceIds(queue.getChannelID());
+      refIds = getReferenceIdsOrderedByPageOrd(queue.getChannelID());
       assertEquals(0, refIds.size());
       
       //Verify 0 msgs in storage
@@ -766,7 +766,7 @@
       
       //verify 20 ref in storage
       
-      refIds = getReferenceIds(queue.getChannelID());
+      refIds = getReferenceIdsOrderedByPageOrd(queue.getChannelID());
       assertEquals(20, refIds.size());
       assertSameIds(refIds, refs, 221, 240);
       
@@ -801,7 +801,7 @@
                   
       //verify 0 ref in storage
       
-      refIds = getReferenceIds(queue.getChannelID());
+      refIds = getReferenceIdsOrderedByPageOrd(queue.getChannelID());
       assertEquals(0, refIds.size());
       
       //Verify 0 msgs in storage
@@ -833,7 +833,7 @@
       
       //verify 0 ref in storage
       
-      refIds = getReferenceIds(queue.getChannelID());
+      refIds = getReferenceIdsOrderedByPageOrd(queue.getChannelID());
       assertEquals(0, refIds.size());
       
       //Verify 0 msgs in storage
@@ -863,7 +863,7 @@
       
       //verify 10 ref in storage
       
-      refIds = getReferenceIds(queue.getChannelID());
+      refIds = getReferenceIdsOrderedByPageOrd(queue.getChannelID());
       assertEquals(10, refIds.size());
       assertSameIds(refIds, refs, 231, 240);
       
@@ -897,7 +897,7 @@
       
       //verify 20 ref in storage
       
-      refIds = getReferenceIds(queue.getChannelID());
+      refIds = getReferenceIdsOrderedByPageOrd(queue.getChannelID());
       assertEquals(20, refIds.size());
       assertSameIds(refIds, refs, 221, 240);
       
@@ -928,7 +928,7 @@
       
       //verify 0 ref in storage
       
-      refIds = getReferenceIds(queue.getChannelID());
+      refIds = getReferenceIdsOrderedByPageOrd(queue.getChannelID());
       assertEquals(0, refIds.size());     
       
       //Verify 0 msgs in storage
@@ -955,7 +955,7 @@
       
       //verify 0 ref in storage
       
-      refIds = getReferenceIds(queue.getChannelID());
+      refIds = getReferenceIdsOrderedByPageOrd(queue.getChannelID());
       assertEquals(0, refIds.size());     
       
       //Verify 0 msgs in storage

Modified: trunk/tests/src/org/jboss/test/messaging/core/paging/SingleChannel_NP_NTTest.java
===================================================================
--- trunk/tests/src/org/jboss/test/messaging/core/paging/SingleChannel_NP_NTTest.java	2006-09-03 17:56:48 UTC (rev 1254)
+++ trunk/tests/src/org/jboss/test/messaging/core/paging/SingleChannel_NP_NTTest.java	2006-09-05 16:08:05 UTC (rev 1255)
@@ -83,7 +83,7 @@
       
       //verify no refs in storage
             
-      List refIds = getReferenceIds(queue.getChannelID());
+      List refIds = getReferenceIdsOrderedByPageOrd(queue.getChannelID());
       assertTrue(refIds.isEmpty());
       
       //Verify no msgs in storage
@@ -115,7 +115,7 @@
       
       //verify no refs in storage
       
-      refIds = getReferenceIds(queue.getChannelID());
+      refIds = getReferenceIdsOrderedByPageOrd(queue.getChannelID());
       assertTrue(refIds.isEmpty());
       
       //Verify no msgs in storage
@@ -149,7 +149,7 @@
       
       //verify no refs in storage
       
-      refIds = getReferenceIds(queue.getChannelID());
+      refIds = getReferenceIdsOrderedByPageOrd(queue.getChannelID());
       assertTrue(refIds.isEmpty());
       
       //Verify no msgs in storage
@@ -183,7 +183,7 @@
       
       //verify 10 refs in storage
       
-      refIds = getReferenceIds(queue.getChannelID());
+      refIds = getReferenceIdsOrderedByPageOrd(queue.getChannelID());
       assertEquals(10, refIds.size());
       assertSameIds(refIds, refs, 100, 109);
       
@@ -218,7 +218,7 @@
       
       //verify 10 refs in storage
       
-      refIds = getReferenceIds(queue.getChannelID());
+      refIds = getReferenceIdsOrderedByPageOrd(queue.getChannelID());
       assertEquals(10, refIds.size());
       assertSameIds(refIds, refs, 100, 109);
       
@@ -256,7 +256,7 @@
       
       //verify 20 refs in storage
       
-      refIds = getReferenceIds(queue.getChannelID());
+      refIds = getReferenceIdsOrderedByPageOrd(queue.getChannelID());
       assertEquals(20, refIds.size());
       assertSameIds(refIds, refs, 100, 119);
       
@@ -295,7 +295,7 @@
       
       //verify 30 refs in storage
       
-      refIds = getReferenceIds(queue.getChannelID());
+      refIds = getReferenceIdsOrderedByPageOrd(queue.getChannelID());
       assertEquals(30, refIds.size());
       assertSameIds(refIds, refs, 100, 129);
       
@@ -334,7 +334,7 @@
       
       //verify 40 refs in storage
       
-      refIds = getReferenceIds(queue.getChannelID());
+      refIds = getReferenceIdsOrderedByPageOrd(queue.getChannelID());
       assertEquals(40, refIds.size());
       assertSameIds(refIds, refs, 100, 139);
       
@@ -370,7 +370,7 @@
       
       //verify 40 refs in storage
       
-      refIds = getReferenceIds(queue.getChannelID());
+      refIds = getReferenceIdsOrderedByPageOrd(queue.getChannelID());
       assertEquals(40, refIds.size());
       assertSameIds(refIds, refs, 100, 139);
       
@@ -404,7 +404,7 @@
       
       //verify 40 refs in storage
       
-      refIds = getReferenceIds(queue.getChannelID());
+      refIds = getReferenceIdsOrderedByPageOrd(queue.getChannelID());
       assertEquals(40, refIds.size());
       assertSameIds(refIds, refs, 100, 139);
       
@@ -441,7 +441,7 @@
       
       //verify 40 refs in storage
       
-      refIds = getReferenceIds(queue.getChannelID());
+      refIds = getReferenceIdsOrderedByPageOrd(queue.getChannelID());
       assertEquals(40, refIds.size());
       assertSameIds(refIds, refs, 100, 139);
       
@@ -477,7 +477,7 @@
       
       //verify 21 refs in storage
       
-      refIds = getReferenceIds(queue.getChannelID());
+      refIds = getReferenceIdsOrderedByPageOrd(queue.getChannelID());
       
       assertEquals(21, refIds.size());
       assertSameIds(refIds, refs, 120, 140);
@@ -512,7 +512,7 @@
       
       //verify 1 ref in storage
       
-      refIds = getReferenceIds(queue.getChannelID());
+      refIds = getReferenceIdsOrderedByPageOrd(queue.getChannelID());
       assertEquals(1, refIds.size());
       assertSameIds(refIds, refs, 140, 140);
       
@@ -546,7 +546,7 @@
       
       //verify 0 ref in storage
       
-      refIds = getReferenceIds(queue.getChannelID());
+      refIds = getReferenceIdsOrderedByPageOrd(queue.getChannelID());
       assertEquals(0, refIds.size());
       
       //Verify 0 msgs in storage
@@ -578,7 +578,7 @@
       
       //verify 0 ref in storage
       
-      refIds = getReferenceIds(queue.getChannelID());
+      refIds = getReferenceIdsOrderedByPageOrd(queue.getChannelID());
       assertEquals(0, refIds.size());
       
       //Verify 0 msgs in storage
@@ -610,7 +610,7 @@
       
       //verify 0 ref in storage
       
-      refIds = getReferenceIds(queue.getChannelID());
+      refIds = getReferenceIdsOrderedByPageOrd(queue.getChannelID());
       assertEquals(0, refIds.size());
       
       //Verify 0 msgs in storage
@@ -645,7 +645,7 @@
       
       //verify 0 ref in storage
       
-      refIds = getReferenceIds(queue.getChannelID());
+      refIds = getReferenceIdsOrderedByPageOrd(queue.getChannelID());
       assertEquals(0, refIds.size());
       
       //Verify 0 msgs in storage
@@ -681,7 +681,7 @@
       
       //verify 0 ref in storage
       
-      refIds = getReferenceIds(queue.getChannelID());
+      refIds = getReferenceIdsOrderedByPageOrd(queue.getChannelID());
       assertEquals(0, refIds.size());
       
       //Verify 0 msgs in storage
@@ -716,7 +716,7 @@
       
       //verify 20 ref in storage
       
-      refIds = getReferenceIds(queue.getChannelID());
+      refIds = getReferenceIdsOrderedByPageOrd(queue.getChannelID());
       assertEquals(20, refIds.size());
       assertSameIds(refIds, refs, 221, 240);
       
@@ -753,7 +753,7 @@
       
       //verify 0 ref in storage
       
-      refIds = getReferenceIds(queue.getChannelID());
+      refIds = getReferenceIdsOrderedByPageOrd(queue.getChannelID());
       assertEquals(0, refIds.size());
       
       //Verify 0 msgs in storage
@@ -785,7 +785,7 @@
       
       //verify 0 ref in storage
       
-      refIds = getReferenceIds(queue.getChannelID());
+      refIds = getReferenceIdsOrderedByPageOrd(queue.getChannelID());
       assertEquals(0, refIds.size());
       
       //Verify 0 msgs in storage
@@ -817,7 +817,7 @@
       
       //verify 10 ref in storage
       
-      refIds = getReferenceIds(queue.getChannelID());
+      refIds = getReferenceIdsOrderedByPageOrd(queue.getChannelID());
       assertEquals(10, refIds.size());
       assertSameIds(refIds, refs, 231, 240);
       
@@ -853,7 +853,7 @@
       
       //verify 20 ref in storage
       
-      refIds = getReferenceIds(queue.getChannelID());
+      refIds = getReferenceIdsOrderedByPageOrd(queue.getChannelID());
       assertEquals(20, refIds.size());
       assertSameIds(refIds, refs, 221, 240);
       
@@ -886,7 +886,7 @@
 
       //verify 0 ref in storage
       
-      refIds = getReferenceIds(queue.getChannelID());
+      refIds = getReferenceIdsOrderedByPageOrd(queue.getChannelID());
       assertEquals(0, refIds.size());     
       
       //Verify 0 msgs in storage
@@ -919,7 +919,7 @@
       
       //verify 0 ref in storage
       
-      refIds = getReferenceIds(queue.getChannelID());
+      refIds = getReferenceIdsOrderedByPageOrd(queue.getChannelID());
       assertEquals(0, refIds.size());     
       
       //Verify 0 msgs in storage

Modified: trunk/tests/src/org/jboss/test/messaging/core/paging/SingleChannel_NP_TTest.java
===================================================================
--- trunk/tests/src/org/jboss/test/messaging/core/paging/SingleChannel_NP_TTest.java	2006-09-03 17:56:48 UTC (rev 1254)
+++ trunk/tests/src/org/jboss/test/messaging/core/paging/SingleChannel_NP_TTest.java	2006-09-05 16:08:05 UTC (rev 1255)
@@ -88,7 +88,7 @@
       
       //verify no refs in storage
             
-      List refIds = getReferenceIds(queue.getChannelID());
+      List refIds = getReferenceIdsOrderedByPageOrd(queue.getChannelID());
       assertTrue(refIds.isEmpty());
       
       //Verify no msgs in storage
@@ -124,7 +124,7 @@
       
       //verify no refs in storage
       
-      refIds = getReferenceIds(queue.getChannelID());
+      refIds = getReferenceIdsOrderedByPageOrd(queue.getChannelID());
       assertTrue(refIds.isEmpty());
       
       //Verify no msgs in storage
@@ -161,7 +161,7 @@
       
       //verify no refs in storage
       
-      refIds = getReferenceIds(queue.getChannelID());
+      refIds = getReferenceIdsOrderedByPageOrd(queue.getChannelID());
       assertTrue(refIds.isEmpty());
       
       //Verify no msgs in storage
@@ -197,7 +197,7 @@
       
       //verify 10 refs in storage
       
-      refIds = getReferenceIds(queue.getChannelID());
+      refIds = getReferenceIdsOrderedByPageOrd(queue.getChannelID());
       assertEquals(10, refIds.size());
       assertSameIds(refIds, refs, 100, 109);
       
@@ -234,7 +234,7 @@
       
       //verify 10 refs in storage
       
-      refIds = getReferenceIds(queue.getChannelID());
+      refIds = getReferenceIdsOrderedByPageOrd(queue.getChannelID());
       assertEquals(10, refIds.size());
       assertSameIds(refIds, refs, 100, 109);
       
@@ -274,7 +274,7 @@
       
       //verify 20 refs in storage
       
-      refIds = getReferenceIds(queue.getChannelID());
+      refIds = getReferenceIdsOrderedByPageOrd(queue.getChannelID());
       assertEquals(20, refIds.size());
       assertSameIds(refIds, refs, 100, 119);
       
@@ -325,7 +325,7 @@
       
       //verify 30 refs in storage
       
-      refIds = getReferenceIds(queue.getChannelID());
+      refIds = getReferenceIdsOrderedByPageOrd(queue.getChannelID());
       assertEquals(30, refIds.size());
       assertSameIds(refIds, refs, 100, 129);
       
@@ -366,7 +366,7 @@
       
       //verify 40 refs in storage
       
-      refIds = getReferenceIds(queue.getChannelID());
+      refIds = getReferenceIdsOrderedByPageOrd(queue.getChannelID());
       assertEquals(40, refIds.size());
       assertSameIds(refIds, refs, 100, 139);
       
@@ -404,7 +404,7 @@
       
       //verify 40 refs in storage
       
-      refIds = getReferenceIds(queue.getChannelID());
+      refIds = getReferenceIdsOrderedByPageOrd(queue.getChannelID());
       assertEquals(40, refIds.size());
       assertSameIds(refIds, refs, 100, 139);
       
@@ -438,7 +438,7 @@
       
       //verify 40 refs in storage
       
-      refIds = getReferenceIds(queue.getChannelID());
+      refIds = getReferenceIdsOrderedByPageOrd(queue.getChannelID());
       assertEquals(40, refIds.size());
       assertSameIds(refIds, refs, 100, 139);
       
@@ -475,7 +475,7 @@
       
       //verify 40 refs in storage
       
-      refIds = getReferenceIds(queue.getChannelID());
+      refIds = getReferenceIdsOrderedByPageOrd(queue.getChannelID());
       assertEquals(40, refIds.size());
       assertSameIds(refIds, refs, 100, 139);
       
@@ -511,7 +511,7 @@
       
       //verify 21 refs in storage
       
-      refIds = getReferenceIds(queue.getChannelID());
+      refIds = getReferenceIdsOrderedByPageOrd(queue.getChannelID());
       assertEquals(21, refIds.size());
       assertSameIds(refIds, refs, 120, 140);
       
@@ -545,7 +545,7 @@
       
       //verify 1 ref in storage
       
-      refIds = getReferenceIds(queue.getChannelID());
+      refIds = getReferenceIdsOrderedByPageOrd(queue.getChannelID());
       assertEquals(1, refIds.size());
       assertSameIds(refIds, refs, 140, 140);
       
@@ -579,7 +579,7 @@
       
       //verify 0 ref in storage
       
-      refIds = getReferenceIds(queue.getChannelID());
+      refIds = getReferenceIdsOrderedByPageOrd(queue.getChannelID());
       assertEquals(0, refIds.size());
       
       //Verify 0 msgs in storage
@@ -611,7 +611,7 @@
       
       //verify 0 ref in storage
       
-      refIds = getReferenceIds(queue.getChannelID());
+      refIds = getReferenceIdsOrderedByPageOrd(queue.getChannelID());
       assertEquals(0, refIds.size());
       
       //Verify 0 msgs in storage
@@ -643,7 +643,7 @@
       
       //verify 0 ref in storage
       
-      refIds = getReferenceIds(queue.getChannelID());
+      refIds = getReferenceIdsOrderedByPageOrd(queue.getChannelID());
       assertEquals(0, refIds.size());
       
       //Verify 0 msgs in storage
@@ -680,7 +680,7 @@
       
       //verify 0 ref in storage
       
-      refIds = getReferenceIds(queue.getChannelID());
+      refIds = getReferenceIdsOrderedByPageOrd(queue.getChannelID());
       assertEquals(0, refIds.size());
       
       //Verify 0 msgs in storage
@@ -718,7 +718,7 @@
       
       //verify 0 ref in storage
       
-      refIds = getReferenceIds(queue.getChannelID());
+      refIds = getReferenceIdsOrderedByPageOrd(queue.getChannelID());
       assertEquals(0, refIds.size());
       
       //Verify 0 msgs in storage
@@ -755,7 +755,7 @@
       
       //verify 20 ref in storage
       
-      refIds = getReferenceIds(queue.getChannelID());
+      refIds = getReferenceIdsOrderedByPageOrd(queue.getChannelID());
       assertEquals(20, refIds.size());
       assertSameIds(refIds, refs, 221, 240);
       
@@ -791,7 +791,7 @@
       
       //verify 0 ref in storage
       
-      refIds = getReferenceIds(queue.getChannelID());
+      refIds = getReferenceIdsOrderedByPageOrd(queue.getChannelID());
       assertEquals(0, refIds.size());
       
       //Verify 0 msgs in storage
@@ -823,7 +823,7 @@
       
       //verify 0 ref in storage
       
-      refIds = getReferenceIds(queue.getChannelID());
+      refIds = getReferenceIdsOrderedByPageOrd(queue.getChannelID());
       assertEquals(0, refIds.size());
       
       //Verify 0 msgs in storage
@@ -855,7 +855,7 @@
       
       //verify 10 ref in storage
       
-      refIds = getReferenceIds(queue.getChannelID());
+      refIds = getReferenceIdsOrderedByPageOrd(queue.getChannelID());
       assertEquals(10, refIds.size());
       assertSameIds(refIds, refs, 231, 240);
       
@@ -890,7 +890,7 @@
       
       //verify 20 ref in storage
       
-      refIds = getReferenceIds(queue.getChannelID());
+      refIds = getReferenceIdsOrderedByPageOrd(queue.getChannelID());
       assertEquals(20, refIds.size());
       assertSameIds(refIds, refs, 221, 240);
       
@@ -921,7 +921,7 @@
       
       //verify 0 ref in storage
       
-      refIds = getReferenceIds(queue.getChannelID());
+      refIds = getReferenceIdsOrderedByPageOrd(queue.getChannelID());
       assertEquals(0, refIds.size());     
       
       //Verify 0 msgs in storage
@@ -948,7 +948,7 @@
       
       //verify 0 ref in storage
       
-      refIds = getReferenceIds(queue.getChannelID());
+      refIds = getReferenceIdsOrderedByPageOrd(queue.getChannelID());
       assertEquals(0, refIds.size());     
       
       //Verify 0 msgs in storage

Modified: trunk/tests/src/org/jboss/test/messaging/core/paging/SingleChannel_P_2PCTest.java
===================================================================
--- trunk/tests/src/org/jboss/test/messaging/core/paging/SingleChannel_P_2PCTest.java	2006-09-03 17:56:48 UTC (rev 1254)
+++ trunk/tests/src/org/jboss/test/messaging/core/paging/SingleChannel_P_2PCTest.java	2006-09-05 16:08:05 UTC (rev 1255)
@@ -91,7 +91,7 @@
       assertTrue(refIds.isEmpty());
       
       //verify 99 refs in storage
-      refIds = getReferenceIds(queue.getChannelID());
+      refIds = getReferenceIdsOrderedByOrd(queue.getChannelID());
       assertEquals(99, refIds.size());
       assertSameIds(refIds, refs, 0, 98);
       
@@ -132,7 +132,7 @@
       assertTrue(refIds.isEmpty());
       
       //verify 100 refs in storage
-      refIds = getReferenceIds(queue.getChannelID());
+      refIds = getReferenceIdsOrderedByOrd(queue.getChannelID());
       assertEquals(100, refIds.size());
       assertSameIds(refIds, refs, 0, 99);
       
@@ -176,7 +176,7 @@
       assertTrue(refIds.isEmpty());
       
       //verify 109 refs in storage
-      refIds = getReferenceIds(queue.getChannelID());
+      refIds = getReferenceIdsOrderedByOrd(queue.getChannelID());
       assertEquals(109, refIds.size());
       assertSameIds(refIds, refs, 0, 108);      
       
@@ -220,7 +220,7 @@
       assertSameIds(refIds, refs, 100, 109);
       
       //verify 110 refs in storage
-      refIds = getReferenceIds(queue.getChannelID());
+      refIds = getReferenceIdsOrderedByOrd(queue.getChannelID());
       assertEquals(110, refIds.size());
       assertSameIds(refIds, refs, 0, 109);
       
@@ -262,7 +262,7 @@
       assertSameIds(refIds, refs, 100, 109);
       
       //verify 111 refs in storage
-      refIds = getReferenceIds(queue.getChannelID());
+      refIds = getReferenceIdsOrderedByOrd(queue.getChannelID());
       assertEquals(111, refIds.size());
       assertSameIds(refIds, refs, 0, 110);
       
@@ -307,7 +307,7 @@
       assertSameIds(refIds, refs, 100, 119);
       
       //verify 120 refs in storage
-      refIds = getReferenceIds(queue.getChannelID());
+      refIds = getReferenceIdsOrderedByOrd(queue.getChannelID());
       assertEquals(120, refIds.size());
       assertSameIds(refIds, refs, 0, 119);
       
@@ -363,7 +363,7 @@
       assertSameIds(refIds, refs, 100, 129);
       
       //verify 130 refs in storage
-      refIds = getReferenceIds(queue.getChannelID());
+      refIds = getReferenceIdsOrderedByOrd(queue.getChannelID());
       assertEquals(130, refIds.size());
       assertSameIds(refIds, refs, 0, 129);
       
@@ -409,7 +409,7 @@
       assertSameIds(refIds, refs, 100, 139);
       
       //verify 140 refs in storage
-      refIds = getReferenceIds(queue.getChannelID());
+      refIds = getReferenceIdsOrderedByOrd(queue.getChannelID());
       assertEquals(140, refIds.size());
       assertSameIds(refIds, refs, 0, 139);
       
@@ -452,7 +452,7 @@
       assertSameIds(refIds, refs, 100, 139);
       
       //verify 141 refs in storage
-      refIds = getReferenceIds(queue.getChannelID());
+      refIds = getReferenceIdsOrderedByOrd(queue.getChannelID());
       assertEquals(141, refIds.size());
       assertSameIds(refIds, refs, 0, 140);
       
@@ -490,7 +490,7 @@
       assertSameIds(refIds, refs, 100, 139);
       
       //verify 140 refs in storage
-      refIds = getReferenceIds(queue.getChannelID());
+      refIds = getReferenceIdsOrderedByOrd(queue.getChannelID());
       assertEquals(140, refIds.size());
       assertSameIds(refIds, refs, 1, 140);      
       
@@ -532,7 +532,7 @@
       assertSameIds(refIds, refs, 100, 139);
       
       //Verify 122 refs in storage
-      refIds = getReferenceIds(queue.getChannelID());
+      refIds = getReferenceIdsOrderedByOrd(queue.getChannelID());
       assertEquals(122, refIds.size()); 
       assertSameIds(refIds, refs, 19, 140);
       
@@ -573,7 +573,7 @@
       assertSameIds(refIds, refs, 120, 140);
       
       //Verify 121 refs in storage
-      refIds = getReferenceIds(queue.getChannelID());
+      refIds = getReferenceIdsOrderedByOrd(queue.getChannelID());
       assertEquals(121, refIds.size()); 
       assertSameIds(refIds, refs, 20, 140);
       
@@ -612,7 +612,7 @@
       assertSameIds(refIds, refs, 140, 140);
       
       //Verify 120 refs in storage
-      refIds = getReferenceIds(queue.getChannelID());
+      refIds = getReferenceIdsOrderedByOrd(queue.getChannelID());
       assertEquals(101, refIds.size()); 
       assertSameIds(refIds, refs, 40, 140);
       
@@ -650,7 +650,7 @@
       assertEquals(0, refIds.size());
       
       //Verify 100 refs in storage
-      refIds = getReferenceIds(queue.getChannelID());
+      refIds = getReferenceIdsOrderedByOrd(queue.getChannelID());
       assertEquals(100, refIds.size()); 
       assertSameIds(refIds, refs, 41, 140);
       
@@ -688,7 +688,7 @@
       assertEquals(0, refIds.size());
       
       //Verify 80 refs in storage
-      refIds = getReferenceIds(queue.getChannelID());
+      refIds = getReferenceIdsOrderedByOrd(queue.getChannelID());
       assertEquals(80, refIds.size()); 
       assertSameIds(refIds, refs, 61, 140);
       
@@ -726,7 +726,7 @@
       assertEquals(0, refIds.size());
       
       //Verify 20 refs in storage
-      refIds = getReferenceIds(queue.getChannelID());
+      refIds = getReferenceIdsOrderedByOrd(queue.getChannelID());
       assertEquals(20, refIds.size()); 
       assertSameIds(refIds, refs, 121, 140);
       
@@ -768,7 +768,7 @@
       assertEquals(0, refIds.size());
       
       //Verify 40 refs in storage
-      refIds = getReferenceIds(queue.getChannelID());
+      refIds = getReferenceIdsOrderedByOrd(queue.getChannelID());
       assertEquals(40, refIds.size()); 
       assertSameIds(refIds, refs, 121, 160);
       
@@ -811,7 +811,7 @@
       assertEquals(0, refIds.size());
       
       //Verify 60 refs in storage
-      refIds = getReferenceIds(queue.getChannelID());
+      refIds = getReferenceIdsOrderedByOrd(queue.getChannelID());
       assertEquals(60, refIds.size()); 
       assertSameIds(refIds, refs, 121, 180);
       
@@ -856,7 +856,7 @@
       assertSameIds(refIds, refs, 221, 240);
       
       // Verify 120 refs in storage
-      refIds = getReferenceIds(queue.getChannelID());
+      refIds = getReferenceIdsOrderedByOrd(queue.getChannelID());
       assertEquals(120, refIds.size()); 
       assertSameIds(refIds, refs, 121, 240);
       
@@ -896,7 +896,7 @@
       assertEquals(0, refIds.size());
       
       // Verify 120 refs in storage
-      refIds = getReferenceIds(queue.getChannelID());
+      refIds = getReferenceIdsOrderedByOrd(queue.getChannelID());
       assertEquals(120, refIds.size()); 
       assertSameIds(refIds, refs, 121, 240);
       
@@ -934,7 +934,7 @@
       assertEquals(0, refIds.size());
       
       // Verify 120 refs in storage
-      refIds = getReferenceIds(queue.getChannelID());
+      refIds = getReferenceIdsOrderedByOrd(queue.getChannelID());
       assertEquals(120, refIds.size()); 
       assertSameIds(refIds, refs, 121, 240);
       
@@ -973,7 +973,7 @@
       assertSameIds(refIds, refs, 231, 240);
       
       // Verify 120 refs in storage
-      refIds = getReferenceIds(queue.getChannelID());
+      refIds = getReferenceIdsOrderedByOrd(queue.getChannelID());
       assertEquals(120, refIds.size()); 
       assertSameIds(refIds, refs, 121, 240);
       
@@ -1014,7 +1014,7 @@
       assertSameIds(refIds, refs, 221, 240);
       
       // Verify 120 refs in storage
-      refIds = getReferenceIds(queue.getChannelID());
+      refIds = getReferenceIdsOrderedByOrd(queue.getChannelID());
       assertEquals(120, refIds.size()); 
       assertSameIds(refIds, refs, 121, 240);
       
@@ -1051,7 +1051,7 @@
       assertEquals(0, refIds.size());     
       
       // Verify 70 refs in storage
-      refIds = getReferenceIds(queue.getChannelID());
+      refIds = getReferenceIdsOrderedByOrd(queue.getChannelID());
       assertEquals(70, refIds.size()); 
       assertSameIds(refIds, refs, 171, 240);
       
@@ -1085,7 +1085,7 @@
       refIds = getPagedReferenceIds(queue.getChannelID());
       assertEquals(0, refIds.size());     
       
-      refIds = getReferenceIds(queue.getChannelID());
+      refIds = getReferenceIdsOrderedByOrd(queue.getChannelID());
       assertEquals(0, refIds.size());     
       
       //Verify 0 msgs in storage

Modified: trunk/tests/src/org/jboss/test/messaging/core/paging/SingleChannel_P_NTTest.java
===================================================================
--- trunk/tests/src/org/jboss/test/messaging/core/paging/SingleChannel_P_NTTest.java	2006-09-03 17:56:48 UTC (rev 1254)
+++ trunk/tests/src/org/jboss/test/messaging/core/paging/SingleChannel_P_NTTest.java	2006-09-05 16:08:05 UTC (rev 1255)
@@ -87,7 +87,7 @@
       assertTrue(refIds.isEmpty());
       
       //verify 99 refs in storage
-      refIds = getReferenceIds(queue.getChannelID());
+      refIds = getReferenceIdsOrderedByOrd(queue.getChannelID());
       assertEquals(99, refIds.size());
       assertSameIds(refIds, refs, 0, 98);
       
@@ -125,7 +125,7 @@
       assertTrue(refIds.isEmpty());
       
       //verify 100 refs in storage
-      refIds = getReferenceIds(queue.getChannelID());
+      refIds = getReferenceIdsOrderedByOrd(queue.getChannelID());
       assertEquals(100, refIds.size());
       assertSameIds(refIds, refs, 0, 99);
       
@@ -166,7 +166,7 @@
       assertTrue(refIds.isEmpty());
       
       //verify 109 refs in storage
-      refIds = getReferenceIds(queue.getChannelID());
+      refIds = getReferenceIdsOrderedByOrd(queue.getChannelID());
       assertEquals(109, refIds.size());
       assertSameIds(refIds, refs, 0, 108);      
       
@@ -204,7 +204,7 @@
       assertSameIds(refIds, refs, 100, 109);
       
       //verify 110 refs in storage
-      refIds = getReferenceIds(queue.getChannelID());      
+      refIds = getReferenceIdsOrderedByOrd(queue.getChannelID());      
       assertEquals(110, refIds.size());
       assertSameIds(refIds, refs, 0, 109);
       
@@ -244,7 +244,7 @@
       assertSameIds(refIds, refs, 100, 109);
       
       //verify 111 refs in storage
-      refIds = getReferenceIds(queue.getChannelID());
+      refIds = getReferenceIdsOrderedByOrd(queue.getChannelID());
       assertEquals(111, refIds.size());
       assertSameIds(refIds, refs, 0, 110);
       
@@ -287,7 +287,7 @@
       assertSameIds(refIds, refs, 100, 119);
       
       //verify 120 refs in storage
-      refIds = getReferenceIds(queue.getChannelID());
+      refIds = getReferenceIdsOrderedByOrd(queue.getChannelID());
       assertEquals(120, refIds.size());
       assertSameIds(refIds, refs, 0, 119);
       
@@ -331,7 +331,7 @@
       assertSameIds(refIds, refs, 100, 129);
       
       //verify 130 refs in storage
-      refIds = getReferenceIds(queue.getChannelID());
+      refIds = getReferenceIdsOrderedByOrd(queue.getChannelID());
       assertEquals(130, refIds.size());
       assertSameIds(refIds, refs, 0, 129);
       
@@ -375,7 +375,7 @@
       assertSameIds(refIds, refs, 100, 139);
       
       //verify 140 refs in storage
-      refIds = getReferenceIds(queue.getChannelID());
+      refIds = getReferenceIdsOrderedByOrd(queue.getChannelID());
       assertEquals(140, refIds.size());
       assertSameIds(refIds, refs, 0, 139);
       
@@ -416,7 +416,7 @@
       assertSameIds(refIds, refs, 100, 139);
       
       //verify 141 refs in storage
-      refIds = getReferenceIds(queue.getChannelID());
+      refIds = getReferenceIdsOrderedByOrd(queue.getChannelID());
       assertEquals(141, refIds.size());
       assertSameIds(refIds, refs, 0, 140);
       
@@ -455,7 +455,7 @@
       assertSameIds(refIds, refs, 100, 139);
       
       //verify 140 refs in storage
-      refIds = getReferenceIds(queue.getChannelID());
+      refIds = getReferenceIdsOrderedByOrd(queue.getChannelID());
       assertEquals(140, refIds.size());
       assertSameIds(refIds, refs, 1, 140);      
       
@@ -496,7 +496,7 @@
       assertSameIds(refIds, refs, 100, 139);
       
       //Verify 122 refs in storage
-      refIds = getReferenceIds(queue.getChannelID());
+      refIds = getReferenceIdsOrderedByOrd(queue.getChannelID());
       assertEquals(122, refIds.size()); 
       assertSameIds(refIds, refs, 19, 140);
       
@@ -537,7 +537,7 @@
       assertSameIds(refIds, refs, 120, 140);
       
       //Verify 121 refs in storage
-      refIds = getReferenceIds(queue.getChannelID());
+      refIds = getReferenceIdsOrderedByOrd(queue.getChannelID());
       assertEquals(121, refIds.size()); 
       assertSameIds(refIds, refs, 20, 140);
       
@@ -576,7 +576,7 @@
       assertSameIds(refIds, refs, 140, 140);
       
       //Verify 120 refs in storage
-      refIds = getReferenceIds(queue.getChannelID());
+      refIds = getReferenceIdsOrderedByOrd(queue.getChannelID());
       assertEquals(101, refIds.size()); 
       assertSameIds(refIds, refs, 40, 140);
       
@@ -614,7 +614,7 @@
       assertEquals(0, refIds.size());
       
       //Verify 100 refs in storage
-      refIds = getReferenceIds(queue.getChannelID());
+      refIds = getReferenceIdsOrderedByOrd(queue.getChannelID());
       assertEquals(100, refIds.size()); 
       assertSameIds(refIds, refs, 41, 140);
       
@@ -652,7 +652,7 @@
       assertEquals(0, refIds.size());
       
       //Verify 80 refs in storage
-      refIds = getReferenceIds(queue.getChannelID());
+      refIds = getReferenceIdsOrderedByOrd(queue.getChannelID());
       assertEquals(80, refIds.size()); 
       assertSameIds(refIds, refs, 61, 140);
       
@@ -689,7 +689,7 @@
       assertEquals(0, refIds.size());
       
       //Verify 20 refs in storage
-      refIds = getReferenceIds(queue.getChannelID());
+      refIds = getReferenceIdsOrderedByOrd(queue.getChannelID());
       assertEquals(20, refIds.size()); 
       assertSameIds(refIds, refs, 121, 140);
       
@@ -728,7 +728,7 @@
       assertEquals(0, refIds.size());
       
       //Verify 40 refs in storage
-      refIds = getReferenceIds(queue.getChannelID());
+      refIds = getReferenceIdsOrderedByOrd(queue.getChannelID());
       assertEquals(40, refIds.size()); 
       assertSameIds(refIds, refs, 121, 160);
       
@@ -768,7 +768,7 @@
       assertEquals(0, refIds.size());
       
       //Verify 60 refs in storage
-      refIds = getReferenceIds(queue.getChannelID());
+      refIds = getReferenceIdsOrderedByOrd(queue.getChannelID());
       assertEquals(60, refIds.size()); 
       assertSameIds(refIds, refs, 121, 180);
       
@@ -810,7 +810,7 @@
       assertSameIds(refIds, refs, 221, 240);
       
       // Verify 120 refs in storage
-      refIds = getReferenceIds(queue.getChannelID());
+      refIds = getReferenceIdsOrderedByOrd(queue.getChannelID());
       assertEquals(120, refIds.size()); 
       assertSameIds(refIds, refs, 121, 240);
       
@@ -850,7 +850,7 @@
       assertEquals(0, refIds.size());
       
       // Verify 120 refs in storage
-      refIds = getReferenceIds(queue.getChannelID());
+      refIds = getReferenceIdsOrderedByOrd(queue.getChannelID());
       assertEquals(120, refIds.size()); 
       assertSameIds(refIds, refs, 121, 240);
       
@@ -888,7 +888,7 @@
       assertEquals(0, refIds.size());
       
       // Verify 120 refs in storage
-      refIds = getReferenceIds(queue.getChannelID());
+      refIds = getReferenceIdsOrderedByOrd(queue.getChannelID());
       assertEquals(120, refIds.size()); 
       assertSameIds(refIds, refs, 121, 240);
       
@@ -927,7 +927,7 @@
       assertSameIds(refIds, refs, 231, 240);
       
       // Verify 120 refs in storage
-      refIds = getReferenceIds(queue.getChannelID());
+      refIds = getReferenceIdsOrderedByOrd(queue.getChannelID());
       assertEquals(120, refIds.size()); 
       assertSameIds(refIds, refs, 121, 240);
       
@@ -968,7 +968,7 @@
       assertSameIds(refIds, refs, 221, 240);
       
       // Verify 120 refs in storage
-      refIds = getReferenceIds(queue.getChannelID());
+      refIds = getReferenceIdsOrderedByOrd(queue.getChannelID());
       assertEquals(120, refIds.size()); 
       assertSameIds(refIds, refs, 121, 240);
       
@@ -1005,7 +1005,7 @@
       assertEquals(0, refIds.size());     
       
       // Verify 70 refs in storage
-      refIds = getReferenceIds(queue.getChannelID());
+      refIds = getReferenceIdsOrderedByOrd(queue.getChannelID());
       assertEquals(70, refIds.size()); 
       assertSameIds(refIds, refs, 171, 240);
       
@@ -1039,7 +1039,7 @@
       refIds = getPagedReferenceIds(queue.getChannelID());
       assertEquals(0, refIds.size());     
       
-      refIds = getReferenceIds(queue.getChannelID());
+      refIds = getReferenceIdsOrderedByOrd(queue.getChannelID());
       assertEquals(0, refIds.size());     
       
       //Verify 0 msgs in storage

Modified: trunk/tests/src/org/jboss/test/messaging/core/paging/SingleChannel_P_TTest.java
===================================================================
--- trunk/tests/src/org/jboss/test/messaging/core/paging/SingleChannel_P_TTest.java	2006-09-03 17:56:48 UTC (rev 1254)
+++ trunk/tests/src/org/jboss/test/messaging/core/paging/SingleChannel_P_TTest.java	2006-09-05 16:08:05 UTC (rev 1255)
@@ -90,7 +90,7 @@
       assertTrue(refIds.isEmpty());
       
       //verify 99 refs in storage
-      refIds = getReferenceIds(queue.getChannelID());
+      refIds = getReferenceIdsOrderedByOrd(queue.getChannelID());
       assertEquals(99, refIds.size());
       assertSameIds(refIds, refs, 0, 98);
       
@@ -130,7 +130,7 @@
       assertTrue(refIds.isEmpty());
       
       //verify 100 refs in storage
-      refIds = getReferenceIds(queue.getChannelID());
+      refIds = getReferenceIdsOrderedByOrd(queue.getChannelID());
       assertEquals(100, refIds.size());
       assertSameIds(refIds, refs, 0, 99);
       
@@ -173,7 +173,7 @@
       assertTrue(refIds.isEmpty());
       
       //verify 109 refs in storage
-      refIds = getReferenceIds(queue.getChannelID());
+      refIds = getReferenceIdsOrderedByOrd(queue.getChannelID());
       assertEquals(109, refIds.size());
       assertSameIds(refIds, refs, 0, 108);      
       
@@ -216,7 +216,7 @@
       assertSameIds(refIds, refs, 100, 109);
       
       //verify 110 refs in storage
-      refIds = getReferenceIds(queue.getChannelID());
+      refIds = getReferenceIdsOrderedByOrd(queue.getChannelID());
       assertEquals(110, refIds.size());
       assertSameIds(refIds, refs, 0, 109);
       
@@ -257,7 +257,7 @@
       assertSameIds(refIds, refs, 100, 109);
       
       //verify 111 refs in storage
-      refIds = getReferenceIds(queue.getChannelID());
+      refIds = getReferenceIdsOrderedByOrd(queue.getChannelID());
       assertEquals(111, refIds.size());
       assertSameIds(refIds, refs, 0, 110);
       
@@ -301,7 +301,7 @@
       assertSameIds(refIds, refs, 100, 119);
       
       //verify 120 refs in storage
-      refIds = getReferenceIds(queue.getChannelID());
+      refIds = getReferenceIdsOrderedByOrd(queue.getChannelID());
       assertEquals(120, refIds.size());
       assertSameIds(refIds, refs, 0, 119);
       
@@ -346,7 +346,7 @@
       assertSameIds(refIds, refs, 100, 129);
       
       //verify 130 refs in storage
-      refIds = getReferenceIds(queue.getChannelID());
+      refIds = getReferenceIdsOrderedByOrd(queue.getChannelID());
       assertEquals(130, refIds.size());
       assertSameIds(refIds, refs, 0, 129);
       
@@ -400,7 +400,7 @@
       assertSameIds(refIds, refs, 100, 139);
       
       //verify 140 refs in storage
-      refIds = getReferenceIds(queue.getChannelID());
+      refIds = getReferenceIdsOrderedByOrd(queue.getChannelID());
       assertEquals(140, refIds.size());
       assertSameIds(refIds, refs, 0, 139);
       
@@ -442,7 +442,7 @@
       assertSameIds(refIds, refs, 100, 139);
       
       //verify 141 refs in storage
-      refIds = getReferenceIds(queue.getChannelID());
+      refIds = getReferenceIdsOrderedByOrd(queue.getChannelID());
       assertEquals(141, refIds.size());
       assertSameIds(refIds, refs, 0, 140);
       
@@ -480,7 +480,7 @@
       assertSameIds(refIds, refs, 100, 139);
       
       //verify 140 refs in storage
-      refIds = getReferenceIds(queue.getChannelID());
+      refIds = getReferenceIdsOrderedByOrd(queue.getChannelID());
       assertEquals(140, refIds.size());
       assertSameIds(refIds, refs, 1, 140);      
       
@@ -522,7 +522,7 @@
       assertSameIds(refIds, refs, 100, 139);
       
       //Verify 122 refs in storage
-      refIds = getReferenceIds(queue.getChannelID());
+      refIds = getReferenceIdsOrderedByOrd(queue.getChannelID());
       assertEquals(122, refIds.size()); 
       assertSameIds(refIds, refs, 19, 140);
       
@@ -563,7 +563,7 @@
       assertSameIds(refIds, refs, 120, 140);
       
       //Verify 121 refs in storage
-      refIds = getReferenceIds(queue.getChannelID());
+      refIds = getReferenceIdsOrderedByOrd(queue.getChannelID());
       assertEquals(121, refIds.size()); 
       assertSameIds(refIds, refs, 20, 140);
       
@@ -602,7 +602,7 @@
       assertSameIds(refIds, refs, 140, 140);
       
       //Verify 120 refs in storage
-      refIds = getReferenceIds(queue.getChannelID());
+      refIds = getReferenceIdsOrderedByOrd(queue.getChannelID());
       assertEquals(101, refIds.size()); 
       assertSameIds(refIds, refs, 40, 140);
       
@@ -640,7 +640,7 @@
       assertEquals(0, refIds.size());
       
       //Verify 100 refs in storage
-      refIds = getReferenceIds(queue.getChannelID());
+      refIds = getReferenceIdsOrderedByOrd(queue.getChannelID());
       assertEquals(100, refIds.size()); 
       assertSameIds(refIds, refs, 41, 140);
       
@@ -678,7 +678,7 @@
       assertEquals(0, refIds.size());
       
       //Verify 80 refs in storage
-      refIds = getReferenceIds(queue.getChannelID());
+      refIds = getReferenceIdsOrderedByOrd(queue.getChannelID());
       assertEquals(80, refIds.size()); 
       assertSameIds(refIds, refs, 61, 140);
       
@@ -716,7 +716,7 @@
       assertEquals(0, refIds.size());
       
       //Verify 20 refs in storage
-      refIds = getReferenceIds(queue.getChannelID());
+      refIds = getReferenceIdsOrderedByOrd(queue.getChannelID());
       assertEquals(20, refIds.size()); 
       assertSameIds(refIds, refs, 121, 140);
       
@@ -757,7 +757,7 @@
       assertEquals(0, refIds.size());
       
       //Verify 40 refs in storage
-      refIds = getReferenceIds(queue.getChannelID());
+      refIds = getReferenceIdsOrderedByOrd(queue.getChannelID());
       assertEquals(40, refIds.size()); 
       assertSameIds(refIds, refs, 121, 160);
       
@@ -799,7 +799,7 @@
       assertEquals(0, refIds.size());
       
       //Verify 60 refs in storage
-      refIds = getReferenceIds(queue.getChannelID());
+      refIds = getReferenceIdsOrderedByOrd(queue.getChannelID());
       assertEquals(60, refIds.size()); 
       assertSameIds(refIds, refs, 121, 180);
       
@@ -843,7 +843,7 @@
       assertSameIds(refIds, refs, 221, 240);
       
       // Verify 120 refs in storage
-      refIds = getReferenceIds(queue.getChannelID());
+      refIds = getReferenceIdsOrderedByOrd(queue.getChannelID());
       assertEquals(120, refIds.size()); 
       assertSameIds(refIds, refs, 121, 240);
       
@@ -883,7 +883,7 @@
       assertEquals(0, refIds.size());
       
       // Verify 120 refs in storage
-      refIds = getReferenceIds(queue.getChannelID());
+      refIds = getReferenceIdsOrderedByOrd(queue.getChannelID());
       assertEquals(120, refIds.size()); 
       assertSameIds(refIds, refs, 121, 240);
       
@@ -921,7 +921,7 @@
       assertEquals(0, refIds.size());
       
       // Verify 120 refs in storage
-      refIds = getReferenceIds(queue.getChannelID());
+      refIds = getReferenceIdsOrderedByOrd(queue.getChannelID());
       assertEquals(120, refIds.size()); 
       assertSameIds(refIds, refs, 121, 240);
       
@@ -960,7 +960,7 @@
       assertSameIds(refIds, refs, 231, 240);
       
       // Verify 120 refs in storage
-      refIds = getReferenceIds(queue.getChannelID());
+      refIds = getReferenceIdsOrderedByOrd(queue.getChannelID());
       assertEquals(120, refIds.size()); 
       assertSameIds(refIds, refs, 121, 240);
       
@@ -1001,7 +1001,7 @@
       assertSameIds(refIds, refs, 221, 240);
       
       // Verify 120 refs in storage
-      refIds = getReferenceIds(queue.getChannelID());
+      refIds = getReferenceIdsOrderedByOrd(queue.getChannelID());
       assertEquals(120, refIds.size()); 
       assertSameIds(refIds, refs, 121, 240);
       
@@ -1038,7 +1038,7 @@
       assertEquals(0, refIds.size());     
       
       // Verify 70 refs in storage
-      refIds = getReferenceIds(queue.getChannelID());
+      refIds = getReferenceIdsOrderedByOrd(queue.getChannelID());
       assertEquals(70, refIds.size()); 
       assertSameIds(refIds, refs, 171, 240);
       
@@ -1072,7 +1072,7 @@
       refIds = getPagedReferenceIds(queue.getChannelID());
       assertEquals(0, refIds.size());     
       
-      refIds = getReferenceIds(queue.getChannelID());
+      refIds = getReferenceIdsOrderedByOrd(queue.getChannelID());
       assertEquals(0, refIds.size());     
       
       //Verify 0 msgs in storage

Modified: trunk/tests/src/org/jboss/test/messaging/core/paging/SingleChannel_ReloadTest.java
===================================================================
--- trunk/tests/src/org/jboss/test/messaging/core/paging/SingleChannel_ReloadTest.java	2006-09-03 17:56:48 UTC (rev 1254)
+++ trunk/tests/src/org/jboss/test/messaging/core/paging/SingleChannel_ReloadTest.java	2006-09-05 16:08:05 UTC (rev 1255)
@@ -95,7 +95,7 @@
          refs[i].releaseMemoryReference();
       }
 
-      List refIds = getReferenceIds(queue.getChannelID());
+      List refIds = getReferenceIdsOrderedByPageOrd(queue.getChannelID());
       assertEquals(100, refIds.size());
                                                 
       assertEquals(100, queue.memoryRefCount());
@@ -125,12 +125,12 @@
       
       queue2.load();
       
-      refIds = getReferenceIds(queue.getChannelID());
+      refIds = getReferenceIdsOrderedByPageOrd(queue.getChannelID());
       assertEquals(50, refIds.size());
                    
       this.consume(queue2, 150, refs, 50);
       
-      refIds = getReferenceIds(queue2.getChannelID());
+      refIds = getReferenceIdsOrderedByPageOrd(queue2.getChannelID());
       assertEquals(0, refIds.size());
                                                 
       assertEquals(0, queue2.memoryRefCount());
@@ -180,7 +180,7 @@
          refs[i].releaseMemoryReference();
       }
 
-      List refIds = getReferenceIds(queue.getChannelID());
+      List refIds = getReferenceIdsOrderedByPageOrd(queue.getChannelID());
       assertEquals(100, refIds.size());
                                                 
       assertEquals(100, queue.memoryRefCount());
@@ -210,7 +210,7 @@
       
       queue2.load();
       
-      refIds = getReferenceIds(queue.getChannelID());
+      refIds = getReferenceIdsOrderedByPageOrd(queue.getChannelID());
       assertEquals(0, refIds.size());
       
       List msgIds = getMessageIds();
@@ -263,7 +263,7 @@
          refs[i].releaseMemoryReference();
       }
 
-      List refIds = getReferenceIds(queue.getChannelID());
+      List refIds = getReferenceIdsOrderedByPageOrd(queue.getChannelID());
       assertEquals(100, refIds.size());
                                                 
       assertEquals(100, queue.memoryRefCount());
@@ -276,7 +276,7 @@
       
       queue.removeAllReferences();
       
-      refIds = getReferenceIds(queue.getChannelID());
+      refIds = getReferenceIdsOrderedByPageOrd(queue.getChannelID());
       assertEquals(0, refIds.size());
       
       List msgIds = getMessageIds();
@@ -315,7 +315,7 @@
          refs[i].releaseMemoryReference();
       }
 
-      List refIds = getReferenceIds(queue.getChannelID());
+      List refIds = getReferenceIdsOrderedByPageOrd(queue.getChannelID());
       assertEquals(150, refIds.size());
                                                 
       assertEquals(100, queue.memoryRefCount());
@@ -351,7 +351,7 @@
       
       queue2.load();
       
-      refIds = getReferenceIds(queue.getChannelID());
+      refIds = getReferenceIdsOrderedByPageOrd(queue.getChannelID());
       assertEquals(150, refIds.size());
       
       List msgIds = getMessageIds();
@@ -370,7 +370,7 @@
       //Consume all the messages
       this.consume(queue2, 0, refs, 150);
       
-      refIds = getReferenceIds(queue.getChannelID());
+      refIds = getReferenceIdsOrderedByPageOrd(queue.getChannelID());
       assertEquals(0, refIds.size());
       
       msgIds = getMessageIds();
@@ -409,7 +409,7 @@
          refs[i].releaseMemoryReference();
       }
 
-      List refIds = getReferenceIds(queue.getChannelID());
+      List refIds = getReferenceIdsOrderedByPageOrd(queue.getChannelID());
       assertEquals(150, refIds.size());
                                                 
       assertEquals(100, queue.memoryRefCount());
@@ -445,7 +445,7 @@
       
       queue2.load();
       
-      refIds = getReferenceIds(queue.getChannelID());
+      refIds = getReferenceIdsOrderedByPageOrd(queue.getChannelID());
       assertEquals(150, refIds.size());
       
       List msgIds = getMessageIds();
@@ -464,7 +464,7 @@
       //Consume all the messages
       this.consume(queue2, 0, refs, 150);
       
-      refIds = getReferenceIds(queue.getChannelID());
+      refIds = getReferenceIdsOrderedByPageOrd(queue.getChannelID());
       assertEquals(0, refIds.size());
       
       msgIds = getMessageIds();

Modified: trunk/tests/src/org/jboss/test/messaging/core/plugin/ClusteredTopicExchangeTest.java
===================================================================
--- trunk/tests/src/org/jboss/test/messaging/core/plugin/ClusteredTopicExchangeTest.java	2006-09-03 17:56:48 UTC (rev 1254)
+++ trunk/tests/src/org/jboss/test/messaging/core/plugin/ClusteredTopicExchangeTest.java	2006-09-05 16:08:05 UTC (rev 1255)
@@ -30,7 +30,7 @@
 import org.jboss.messaging.core.message.MessageFactory;
 import org.jboss.messaging.core.plugin.contract.Exchange;
 import org.jboss.messaging.core.plugin.exchange.Binding;
-import org.jboss.messaging.core.plugin.exchange.ClusteredTopicExchange;
+import org.jboss.messaging.core.plugin.exchange.cluster.ClusteredTopicExchange;
 import org.jboss.messaging.core.tx.Transaction;
 import org.jboss.test.messaging.core.SimpleReceiver;
 import org.jgroups.Channel;
@@ -1156,11 +1156,10 @@
       
       Channel controlChannel = new JChannel(JGroupsUtil.getControlStackProperties(50, 1));
       Channel dataChannel = new JChannel(JGroupsUtil.getDataStackProperties(50, 1));
-      
-      ((ClusteredTopicExchange)exchange).injectAttributes(controlChannel, dataChannel, "group1", "Topic", "node1", ms, im, pool, tr, pm);
-      
       exchange.start();
       
+      ((ClusteredTopicExchange)exchange).injectAttributes(controlChannel, dataChannel, "group1", "Topic", "node1", ms, im, pool, tr, pm);
+                  
       return exchange;
    }
    
@@ -1171,10 +1170,10 @@
       Channel controlChannel = new JChannel(JGroupsUtil.getControlStackProperties(50, 1));
       Channel dataChannel = new JChannel(JGroupsUtil.getDataStackProperties(50, 1));
       
-      ((ClusteredTopicExchange)exchange).injectAttributes(controlChannel, dataChannel, groupName, "Topic", nodeId, ms, im, pool, tr, pm);
+      exchange.start();      
       
-      exchange.start();
-      
+      ((ClusteredTopicExchange)exchange).injectAttributes(controlChannel, dataChannel, groupName, "Topic", nodeId, ms, im, pool, tr, pm);
+            
       return exchange;
    }
 

Modified: trunk/tests/src/org/jboss/test/messaging/core/plugin/DirectExchangeTest.java
===================================================================
--- trunk/tests/src/org/jboss/test/messaging/core/plugin/DirectExchangeTest.java	2006-09-03 17:56:48 UTC (rev 1254)
+++ trunk/tests/src/org/jboss/test/messaging/core/plugin/DirectExchangeTest.java	2006-09-05 16:08:05 UTC (rev 1255)
@@ -437,10 +437,10 @@
    {
       DirectExchange exchange = new DirectExchange(sc.getDataSource(), sc.getTransactionManager());
       
+      exchange.start();            
+      
       ((DirectExchange)exchange).injectAttributes("Direct", "node1", ms, im, pool);
-      
-      exchange.start();      
-      
+            
       return exchange;
    }
 

Modified: trunk/tests/src/org/jboss/test/messaging/core/plugin/TopicExchangeTest.java
===================================================================
--- trunk/tests/src/org/jboss/test/messaging/core/plugin/TopicExchangeTest.java	2006-09-03 17:56:48 UTC (rev 1254)
+++ trunk/tests/src/org/jboss/test/messaging/core/plugin/TopicExchangeTest.java	2006-09-05 16:08:05 UTC (rev 1255)
@@ -701,10 +701,10 @@
    {
       TopicExchange exchange = new TopicExchange(sc.getDataSource(), sc.getTransactionManager());      
       
+      exchange.start();      
+      
       ((TopicExchange)exchange).injectAttributes("Topic", "node1", ms, im, pool, tr);
       
-      exchange.start();
-      
       return exchange;
    }
 

Modified: trunk/tests/src/org/jboss/test/messaging/core/plugin/base/MessageStoreTestBase.java
===================================================================
--- trunk/tests/src/org/jboss/test/messaging/core/plugin/base/MessageStoreTestBase.java	2006-09-03 17:56:48 UTC (rev 1254)
+++ trunk/tests/src/org/jboss/test/messaging/core/plugin/base/MessageStoreTestBase.java	2006-09-05 16:08:05 UTC (rev 1255)
@@ -124,10 +124,6 @@
       super.tearDown();
    }
 
-   //
-   // Non-recoverable message store
-   //
-
    ////
    //// Non-reliable message
    ////
@@ -140,244 +136,11 @@
    //////// One strong reference
    ////////
 
-   public void testNonRecoverableMessageStore_1() throws Exception
+   public void testMessageStore_1() throws Exception
    {
-      Message m =
-         MessageFactory.createCoreMessage(0, false, 777l, 888l, (byte)9, headers, "payload");
-
-      // non-recoverable store, non-reliable message, one message
-      MessageReference ref = ms.reference(m);
-      assertCorrectReference(ref, m);
-
-      assertCorrectReference(ref, m);
-  
-      ref.releaseMemoryReference();
-
-      // the message store should be cleaned of everything that pertains to that message
-
-      ref = ms.reference(m.getMessageID());
-      assertNull(ref);
-   }
-
-   ////////
-   //////// Two strong references
-   ////////
-
-   public void testNonRecoverableMessageStore_1_1() throws Exception
-   {
-      Message m =
-         MessageFactory.createCoreMessage(0, false, 777l, 888l, (byte)9, headers, "payload");
-
-      // non-recoverable store, non-reliable message, one message
-      MessageReference ref = ms.reference(m);
-      assertCorrectReference(ref, m);
-
-      MessageReference ref2 = ms.reference(m);
-
-      assertCorrectReference(ref2, m);
-   }
-
-   //////
-   ////// Multiple messages
-   //////
-
-   public void testNonRecoverableMessageStore_2() throws Exception
-   {
-      Message[] m = new Message[NUMBER_OF_MESSAGES];
-      MessageReference[] refs = new MessageReference[NUMBER_OF_MESSAGES];
-      for(int i = 0; i < NUMBER_OF_MESSAGES; i++ )
-      {
-         m[i] = MessageFactory.createCoreMessage(i, false, 700 + i, 800 + i,
-                                             (byte)(i % 10), headers, "payload" + i);
-
-         // non-recoverable store, non-reliable message, one message
-         refs[i] = ms.reference(m[i]);
-         assertCorrectReference(refs[i], m[i]);
-      }
-
-      for (int i = 0; i < NUMBER_OF_MESSAGES; i++)
-      {         
-         assertCorrectReference(refs[i], m[i]);
-         refs[i].releaseMemoryReference();
-      }
-
-      // there are no strong references to the message reference anymore, so the message store
-      // should be cleaned of everything that pertains to those message
-
-      for (int i = 0; i < NUMBER_OF_MESSAGES; i++)
-      {
-         assertNull(ms.reference(m[i].getMessageID()));
-      }
-   }
-
-   ////
-   //// Reliable message
-   ////
-
-   //////
-   ////// The non-reliable store does NOT accept reliable messages
-   //////
-
-   //////
-   ////// One message
-   //////
-
-   public void testNonRecoverableMessageStore_3() throws Exception
-   {
       Message m = MessageFactory.
-      createCoreMessage(0, true, 777l, 888l, (byte)9, headers, "payload");
-
-      // non-recoverable store, reliable message, one message
-      try
-      {
-         ms.reference(m);
-         fail("should throw IllegalStateException");
-      }
-      catch(IllegalStateException e)
-      {
-         // OK
-      }
-   }
-
-   //////
-   ////// The non-reliable store accepts reliable messages
-   //////
-
-   ////////
-   //////// One message
-   ////////
-
-   public void testNonRecoverableMessageStore_4() throws Exception
-   {
-      Message m = MessageFactory.
       createCoreMessage(0, false, 777l, 888l, (byte)9, headers, "payload");
 
-      // non-recoverable store, non-reliable message, one message
-      MessageReference ref = ms.reference(m);
-      assertCorrectReference(ref, m);
-      
-      ref.releaseMemoryReference();
-
-      // there's no strong reference to the unique message reference anymore, so the message store
-      // should be cleaned of everything that pertains to that message
-
-      ref = ms.reference(m.getMessageID());
-      assertNull(ref);
-   }
-
-   ////////
-   //////// Multiple messages
-   ////////
-
-   public void testNonRecoverableMessageStore_5() throws Exception
-   {
-      Message[] m = new Message[NUMBER_OF_MESSAGES];
-      MessageReference[] refs = new MessageReference[NUMBER_OF_MESSAGES];
-      for(int i = 0; i < NUMBER_OF_MESSAGES; i++ )
-      {
-         m[i] = MessageFactory.createCoreMessage(i, false, 700 + i, 800 + i,
-                                             (byte)(i % 10), headers, "payload" + i);
-
-         // non-recoverable store, non-reliable message, one message
-         refs[i] = ms.reference(m[i]);
-         assertCorrectReference(refs[i], m[i]);
-      }
-
-      // get reachable reference
-
-      for (int i = 0; i < NUMBER_OF_MESSAGES; i++)
-      {         
-         assertCorrectReference(refs[i], m[i]);
-         refs[i].releaseMemoryReference();
-      }
-
-      // there are no strong references to the message reference anymore, so the message store
-      // should be cleaned of everything that pertains to those message
-
-      for (int i = 0; i < NUMBER_OF_MESSAGES; i++)
-      {
-         assertNull(ms.reference(m[i].getMessageID()));
-      }
-   }
-   
-   public void testNonRecoverableMessageStore_6() throws Exception
-   {
-      Message m = MessageFactory.
-      createCoreMessage(0, false, 777l, 888l, (byte)9, headers, "payload");
-
-      // non-recoverable store, non-reliable message, one message
-      MessageReference ref = ms.reference(m);
-      assertCorrectReference(ref, m);
-      
-      //Create another reference from that reference
-      MessageReference ref2 = ms.reference(m.getMessageID());
-      
-      ref.releaseMemoryReference();
-      
-      MessageReference ref3 = ms.reference(m.getMessageID());
-      assertNotNull(ref3);
-      
-      assertCorrectReference(ref3, m);
-      
-      ref2.releaseMemoryReference();
-      
-      ref3.releaseMemoryReference();
-
-      // there's no strong reference to the unique message reference anymore, so the message store
-      // should be cleaned of everything that pertains to that message
-
-      ref3 = ms.reference(m.getMessageID());
-      assertNull(ref3);
-   }
-   
-   public void testNonRecoverableMessageStore_7() throws Exception
-   {
-      Message m = MessageFactory.
-      createCoreMessage(0, false, 777l, 888l, (byte)9, headers, "payload");
-
-      // non-recoverable store, non-reliable message, one message
-      MessageReference ref = ms.reference(m);
-      assertCorrectReference(ref, m);
-      
-      MessageReference ref2 = ms.reference(ref.getMessageID());
-      assertNotNull(ref2);      
-      assertCorrectReference(ref2, m);
-        
-      MessageReference ref3 = ms.reference(ref.getMessageID());
-      assertNotNull(ref3);      
-      assertCorrectReference(ref3, m);
-      
-      ref.releaseMemoryReference();
-      ref2.releaseMemoryReference();
-      ref3.releaseMemoryReference();
-      
-      MessageReference ref4 = ms.reference(ref.getMessageID());
- 
-      assertNull(ref4);    
-      
-   }
-
-   //
-   // Recoverable message store
-   //
-
-   ////
-   //// Non-reliable message
-   ////
-
-   //////
-   ////// One message
-   //////
-
-   ////////
-   //////// One strong reference
-   ////////
-
-   public void testRecoverableMessageStore_1() throws Exception
-   {
-      Message m = MessageFactory.
-      createCoreMessage(0, false, 777l, 888l, (byte)9, headers, "payload");
-
       // recoverable store, non-reliable message, one message
       MessageReference ref = ms.reference(m);
       assertCorrectReference(ref, m);
@@ -391,7 +154,7 @@
    //////// Two strong references
    ////////
 
-   public void testRecoverableMessageStore_1_1() throws Exception
+   public void testMessageStore_1_1() throws Exception
    {
 
       Message m = MessageFactory.
@@ -410,7 +173,7 @@
    ////// Multiple messages
    //////
 
-   public void testRecoverableMessageStore_2() throws Exception
+   public void testMessageStore_2() throws Exception
    {
       Message[] m = new Message[NUMBER_OF_MESSAGES];
       MessageReference[] refs = new MessageReference[NUMBER_OF_MESSAGES];
@@ -450,7 +213,7 @@
    //////// One strong reference
    ////////
 
-   public void testRecoverableMessageStore_3() throws Exception
+   public void testMessageStore_3() throws Exception
    {
       Message m = MessageFactory.
       createCoreMessage(0, true, 777l, 888l, (byte)9, headers, "payload");
@@ -472,7 +235,7 @@
    //////// Two strong references
    ////////
 
-   public void testRecoverableMessageStore_3_1() throws Exception
+   public void testMessageStore_3_1() throws Exception
    {
       Message m = MessageFactory.
       createCoreMessage(0, true, 777l, 888l, (byte)9, headers, "payload");
@@ -490,7 +253,7 @@
    ////// Multiple messages
    //////
 
-   public void testRecoverableMessageStore_4() throws Exception
+   public void testMessageStore_4() throws Exception
    {
       Message[] m = new Message[NUMBER_OF_MESSAGES];
       MessageReference[] refs = new MessageReference[NUMBER_OF_MESSAGES];
@@ -520,7 +283,7 @@
       }
    }
    
-   public void testRecoverableMessageStore_6() throws Exception
+   public void testMessageStore_6() throws Exception
    {
 
       Message m = MessageFactory.
@@ -550,7 +313,7 @@
       assertNull(ref3);
    }
    
-   public void testRecoverableMessageStore_7() throws Exception
+   public void testMessageStore_7() throws Exception
    {
       Message m = MessageFactory.
       createCoreMessage(0, true, 777l, 888l, (byte)9, headers, "payload");

Copied: trunk/tests/src/org/jboss/test/messaging/jms/AcknowledgementTest.java (from rev 1248, trunk/tests/src/org/jboss/test/messaging/jms/AcknowledgmentTest.java)
===================================================================
--- trunk/tests/src/org/jboss/test/messaging/jms/AcknowledgmentTest.java	2006-09-01 02:32:34 UTC (rev 1248)
+++ trunk/tests/src/org/jboss/test/messaging/jms/AcknowledgementTest.java	2006-09-05 16:08:05 UTC (rev 1255)
@@ -0,0 +1,1207 @@
+/*
+  * JBoss, Home of Professional Open Source
+  * Copyright 2005, JBoss Inc., and individual contributors as indicated
+  * by the @authors tag. See the copyright.txt in the distribution for a
+  * full listing of individual contributors.
+  *
+  * This is free software; you can redistribute it and/or modify it
+  * under the terms of the GNU Lesser General Public License as
+  * published by the Free Software Foundation; either version 2.1 of
+  * the License, or (at your option) any later version.
+  *
+  * This software is distributed in the hope that it will be useful,
+  * but WITHOUT ANY WARRANTY; without even the implied warranty of
+  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+  * Lesser General Public License for more details.
+  *
+  * You should have received a copy of the GNU Lesser General Public
+  * License along with this software; if not, write to the Free
+  * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+  * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+  */
+package org.jboss.test.messaging.jms;
+
+import javax.jms.Connection;
+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.Session;
+import javax.jms.TextMessage;
+import javax.jms.Topic;
+import javax.jms.TopicConnection;
+import javax.jms.TopicPublisher;
+import javax.jms.TopicSession;
+import javax.jms.TopicSubscriber;
+import javax.management.ObjectName;
+import javax.naming.InitialContext;
+
+import org.jboss.jms.client.JBossConnectionFactory;
+import org.jboss.test.messaging.MessagingTestCase;
+import org.jboss.test.messaging.tools.ServerManagement;
+
+import EDU.oswego.cs.dl.util.concurrent.Latch;
+
+/**
+ * @author <a href="mailto:tim.fox at jboss.com">Tim Fox</a>
+ *
+ * $Id$
+ */
+public class AcknowledgementTest extends MessagingTestCase
+{
+   // Constants -----------------------------------------------------
+
+   // Static --------------------------------------------------------
+   
+   // Attributes ----------------------------------------------------
+
+   protected InitialContext initialContext;
+   
+   protected JBossConnectionFactory cf;
+   protected Destination queue;
+   protected Topic topic;
+
+   // Constructors --------------------------------------------------
+
+   public AcknowledgementTest(String name)
+   {
+      super(name);
+   }
+
+   // TestCase overrides -------------------------------------------
+
+   public void setUp() throws Exception
+   {
+      super.setUp();
+      ServerManagement.start("all");
+                  
+      initialContext = new InitialContext(ServerManagement.getJNDIEnvironment());
+      cf = (JBossConnectionFactory)initialContext.lookup("/ConnectionFactory");
+                 
+      ServerManagement.undeployQueue("Queue");
+      ServerManagement.deployQueue("Queue");
+      ServerManagement.undeployTopic("Topic");
+      ServerManagement.deployTopic("Topic");
+      queue = (Destination)initialContext.lookup("/queue/Queue"); 
+      topic = (Topic)initialContext.lookup("/topic/Topic");     
+      
+      drainDestination(cf, queue);
+
+      log.debug("setup done");
+   }
+
+   public void tearDown() throws Exception
+   {
+      ServerManagement.undeployQueue("Queue");
+      ServerManagement.undeployTopic("Topic");
+      
+      super.tearDown();
+      
+   }
+
+
+   // Public --------------------------------------------------------
+   
+   
+   /* Topics shouldn't hold on to messages if there are no subscribers */
+   public void testPersistentMessagesForTopicDropped() throws Exception
+   {
+      TopicConnection conn = null;
+      
+      try
+      {
+         conn = cf.createTopicConnection();
+         TopicSession sess = conn.createTopicSession(true, 0);
+         TopicPublisher pub = sess.createPublisher(topic);
+         pub.setDeliveryMode(DeliveryMode.PERSISTENT);
+         
+         Message m = sess.createTextMessage("testing123");
+         pub.publish(m);
+         sess.commit();
+         
+         conn.close();
+         conn = cf.createTopicConnection();
+         conn.start();
+         
+         TopicSession newsess = conn.createTopicSession(true, 0);
+         TopicSubscriber newcons = newsess.createSubscriber(topic);
+         
+         Message m2 = (Message)newcons.receive(200);
+         assertNull(m2);
+      }
+      finally
+      {
+         if (conn != null)
+         {
+            conn.close();
+         }
+      }
+   }
+   
+   /* Topics shouldn't hold on to messages when the non-durable subscribers close */
+   public void testPersistentMessagesForTopicDropped2() throws Exception
+   {
+      TopicConnection conn = null;
+      
+      try
+      {
+         conn = cf.createTopicConnection();
+         conn.start();
+         TopicSession sess = conn.createTopicSession(true, 0);
+         TopicPublisher pub = sess.createPublisher(topic);
+         TopicSubscriber sub = sess.createSubscriber(topic);
+         pub.setDeliveryMode(DeliveryMode.PERSISTENT);
+         
+         Message m = sess.createTextMessage("testing123");
+         pub.publish(m);
+         sess.commit();
+         
+         //receive but rollback
+         TextMessage m2 = (TextMessage)sub.receive(3000);
+            
+         assertNotNull(m2);
+         assertEquals("testing123", m2.getText());
+         
+         sess.rollback();
+         
+         conn.close();
+         conn = cf.createTopicConnection();
+         conn.start();
+         
+         TopicSession newsess = conn.createTopicSession(true, 0);
+         TopicSubscriber newcons = newsess.createSubscriber(topic);
+         
+         Message m3 = (Message)newcons.receive(200);
+         assertNull(m3);
+      }
+      finally
+      {
+         if (conn != null)
+         {
+            conn.close();
+         }
+      }
+   }
+   
+   public void testRollbackRecover() throws Exception
+   {
+      TopicConnection conn = null;
+      
+      try
+      {
+         conn = cf.createTopicConnection();
+         TopicSession sess = conn.createTopicSession(true, 0);
+         TopicPublisher pub = sess.createPublisher(topic);
+         TopicSubscriber cons = sess.createSubscriber(topic);
+         conn.start();
+         
+         Message m = sess.createTextMessage("testing123");
+         pub.publish(m);
+         sess.commit();
+         
+         TextMessage m2 = (TextMessage)cons.receive(3000);
+         assertNotNull(m2);
+         assertEquals("testing123", m2.getText());
+         
+         sess.rollback();
+         
+         m2 = (TextMessage)cons.receive(3000);
+         assertNotNull(m2);
+         assertEquals("testing123", m2.getText());
+         
+         conn.close();
+         
+         conn = cf.createTopicConnection();
+         conn.start();
+         
+         //test 2
+         
+         TopicSession newsess = conn.createTopicSession(true, 0);
+         TopicPublisher newpub = newsess.createPublisher(topic);
+         TopicSubscriber newcons = newsess.createSubscriber(topic);
+         
+         Message m3 = newsess.createTextMessage("testing456");
+         newpub.publish(m3);
+         newsess.commit();
+         
+         TextMessage m4 = (TextMessage)newcons.receive(3000);
+         assertNotNull(m4);
+         assertEquals("testing456", m4.getText());
+         
+         newsess.commit();
+         
+         newpub.publish(m3);
+         newsess.commit();
+         
+         TextMessage m5 = (TextMessage)newcons.receive(3000);
+         assertNotNull(m5);
+         assertEquals("testing456", m5.getText());
+         
+         newsess.rollback();
+         
+         TextMessage m6 = (TextMessage)newcons.receive(3000);
+         assertNotNull(m6);
+         assertEquals("testing456", m6.getText());
+         
+         newsess.commit();
+         
+      }
+      finally
+      {
+         if (conn != null)
+         {
+            conn.close();
+         }
+      }
+   }
+   
+   public void testTransactionalAcknowlegment() throws Exception
+   {
+
+      Connection conn = cf.createConnection();
+
+      Session producerSess = conn.createSession(true, Session.SESSION_TRANSACTED);
+      MessageProducer producer = producerSess.createProducer(queue);
+
+      Session consumerSess = conn.createSession(true, Session.SESSION_TRANSACTED);
+      MessageConsumer consumer = consumerSess.createConsumer(queue);
+      conn.start();
+
+      final int NUM_MESSAGES = 20;
+
+      //Send some messages
+      for (int i = 0; i < NUM_MESSAGES; i++)
+      {
+         Message m = producerSess.createMessage();
+         producer.send(m);
+      }
+      
+      assertRemainingMessages(0);
+      
+      producerSess.rollback();
+      
+      //Send some messages
+      for (int i = 0; i < NUM_MESSAGES; i++)
+      {
+         Message m = producerSess.createMessage();
+         producer.send(m);
+      }
+      assertRemainingMessages(0);
+      
+      producerSess.commit();
+      
+      assertRemainingMessages(NUM_MESSAGES);
+
+      log.trace("Sent messages");
+
+      int count = 0;
+      while (true)
+      {
+         Message m = consumer.receive(200);
+         if (m == null) break;
+         count++;
+      }
+      
+      assertRemainingMessages(NUM_MESSAGES);
+
+      log.trace("Received " + count +  " messages");
+
+      assertEquals(count, NUM_MESSAGES);
+
+      consumerSess.rollback();
+      
+      assertRemainingMessages(NUM_MESSAGES);
+
+      log.trace("Session rollback called");
+
+      Message m = null;
+
+      int i = 0;
+      for(; i < NUM_MESSAGES; i++)
+      {
+         m = consumer.receive();
+         log.trace("Received message " + i);
+
+      }
+      
+      assertRemainingMessages(NUM_MESSAGES);
+
+      // if I don't receive enough messages, the test will timeout
+
+      log.trace("Received " + i +  " messages after recover");
+      
+      consumerSess.commit();
+      
+      assertRemainingMessages(0);
+
+      // make sure I don't receive anything else
+
+      m = consumer.receive(200);
+      assertNull(m);
+
+      conn.close();
+
+   }
+
+	/**
+	 * Send some messages, don't acknowledge them and verify that they are re-sent on recovery.
+	 */
+	public void testClientAcknowledgeNoAcknowlegment() throws Exception
+   {
+
+		Connection conn = cf.createConnection();
+
+		Session producerSess = conn.createSession(false, Session.CLIENT_ACKNOWLEDGE);
+		MessageProducer producer = producerSess.createProducer(queue);
+
+		Session consumerSess = conn.createSession(false, Session.CLIENT_ACKNOWLEDGE);
+		MessageConsumer consumer = consumerSess.createConsumer(queue);
+		conn.start();
+
+		final int NUM_MESSAGES = 20;
+
+		//Send some messages
+		for (int i = 0; i < NUM_MESSAGES; i++)
+		{
+			Message m = producerSess.createMessage();
+			producer.send(m);
+		}
+      
+      assertRemainingMessages(NUM_MESSAGES);
+
+		log.trace("Sent messages");
+
+		int count = 0;
+		while (true)
+		{
+			Message m = consumer.receive(200);
+			if (m == null) break;
+			count++;
+		}
+      
+      assertRemainingMessages(NUM_MESSAGES);
+
+		log.trace("Received " + count +  " messages");
+
+		assertEquals(count, NUM_MESSAGES);
+
+		consumerSess.recover();
+      
+      assertRemainingMessages(NUM_MESSAGES);
+
+		log.trace("Session recover called");
+
+      Message m = null;
+
+      int i = 0;
+      for(; i < NUM_MESSAGES; i++)
+      {
+         m = consumer.receive();
+         log.trace("Received message " + i);
+
+      }
+      
+      assertRemainingMessages(NUM_MESSAGES);
+
+      // if I don't receive enough messages, the test will timeout
+
+		log.trace("Received " + i +  " messages after recover");
+      
+      m.acknowledge();
+      
+      assertRemainingMessages(0);
+
+      // make sure I don't receive anything else
+
+      m = consumer.receive(200);
+      assertNull(m);
+
+		conn.close();
+
+   }
+
+	
+	
+	/**
+	 * Send some messages, acknowledge them individually and verify they are not resent after
+    * recovery.
+	 */
+	public void testIndividualClientAcknowledge() throws Exception
+   {
+		
+		Connection conn = cf.createConnection();     
+		
+		Session producerSess = conn.createSession(false, Session.CLIENT_ACKNOWLEDGE);
+		MessageProducer producer = producerSess.createProducer(queue);
+		
+		Session consumerSess = conn.createSession(false, Session.CLIENT_ACKNOWLEDGE);
+		MessageConsumer consumer = consumerSess.createConsumer(queue);
+		conn.start();
+		
+		final int NUM_MESSAGES = 20;
+		
+		for (int i = 0; i < NUM_MESSAGES; i++)
+		{
+			Message m = producerSess.createMessage();
+			producer.send(m);
+		}
+      
+      assertRemainingMessages(NUM_MESSAGES);
+		
+		log.trace("Sent " + NUM_MESSAGES + " messages");
+		
+		int count = 0;
+		while (true)		
+		{
+			Message m = consumer.receive(200);
+         log.trace("Received message " + m);
+			if (m == null)
+         {
+            break;
+         }
+         log.trace("Acking session");
+         
+         assertRemainingMessages(NUM_MESSAGES - count);
+         
+			m.acknowledge();
+         
+         assertRemainingMessages(NUM_MESSAGES - (count + 1));
+			count++;
+		}
+
+      assertRemainingMessages(0);
+      
+      assertEquals(NUM_MESSAGES, count);
+      log.trace("received and acknowledged " + count +  " messages");
+
+      Message m = consumer.receive(200);
+		assertNull(m);
+      
+      log.trace("mesage is " + m);
+
+      log.trace("calling session recover()");
+		consumerSess.recover();
+		log.trace("recover called");
+		
+		m = consumer.receive(200);
+		assertNull(m);
+		
+		conn.close();
+		
+   }
+
+
+	/**
+	 * Send some messages, acknowledge them once after all have been received verify they are not
+    * resent after recovery
+	 */
+	public void testBulkClientAcknowledge() throws Exception
+   {
+
+		Connection conn = cf.createConnection();
+
+		Session producerSess = conn.createSession(false, Session.CLIENT_ACKNOWLEDGE);
+		MessageProducer producer = producerSess.createProducer(queue);
+
+		Session consumerSess = conn.createSession(false, Session.CLIENT_ACKNOWLEDGE);
+		MessageConsumer consumer = consumerSess.createConsumer(queue);
+		conn.start();
+
+		final int NUM_MESSAGES = 20;
+
+		//Send some messages
+		for (int i = 0; i < NUM_MESSAGES; i++)
+		{
+			Message m = producerSess.createMessage();
+			producer.send(m);
+		}
+      
+      assertRemainingMessages(NUM_MESSAGES);
+
+		log.trace("Sent messages");
+
+		Message m = null;
+		int count = 0;
+		for (int i = 0; i < NUM_MESSAGES; i++)
+		{
+			m = consumer.receive(200);
+			if (m == null) break;
+			count++;
+		}
+      
+      assertRemainingMessages(NUM_MESSAGES);
+
+		assertNotNull(m);
+
+		m.acknowledge();
+      
+      assertRemainingMessages(0);
+
+		log.trace("Received " + count +  " messages");
+
+		assertEquals(count, NUM_MESSAGES);
+
+		consumerSess.recover();
+
+		log.trace("Session recover called");
+
+		m = consumer.receive(200);
+
+		log.trace("Message is:" + m);
+
+		assertNull(m);
+
+		conn.close();
+
+   }
+
+
+	/**
+	 * Send some messages, acknowledge some of them, and verify that the others are resent after
+    * delivery
+	 */
+	public void testPartialClientAcknowledge() throws Exception
+   {
+
+		Connection conn = cf.createConnection();
+
+		Session producerSess = conn.createSession(false, Session.CLIENT_ACKNOWLEDGE);
+		MessageProducer producer = producerSess.createProducer(queue);
+
+		Session consumerSess = conn.createSession(false, Session.CLIENT_ACKNOWLEDGE);
+		MessageConsumer consumer = consumerSess.createConsumer(queue);
+		conn.start();
+
+		final int NUM_MESSAGES = 20;
+		final int ACKED_MESSAGES = 11;
+
+		//Send some messages
+		for (int i = 0; i < NUM_MESSAGES; i++)
+		{
+			Message m = producerSess.createMessage();
+			producer.send(m);
+		}
+      
+      assertRemainingMessages(NUM_MESSAGES);
+
+		log.trace("Sent messages");
+
+		int count = 0;
+
+		Message m = null;
+		for (int i = 0; i < NUM_MESSAGES; i++)
+		{
+			m = consumer.receive(200);
+			if (m == null)
+         {
+            break;
+         }
+			if (count == ACKED_MESSAGES -1)
+         {
+            m.acknowledge();
+         }
+			count++;
+		}
+      
+      assertRemainingMessages(NUM_MESSAGES - ACKED_MESSAGES);
+      
+		assertNotNull(m);
+
+		log.trace("Received " + count +  " messages");
+
+		assertEquals(count, NUM_MESSAGES);
+
+		consumerSess.recover();
+
+		log.trace("Session recover called");
+
+		count = 0;
+		while (true)
+		{
+			m = consumer.receive(200);
+			if (m == null) break;
+			count++;
+		}
+
+		assertEquals(NUM_MESSAGES - ACKED_MESSAGES, count);            
+
+		conn.close();
+
+   }
+
+
+
+	/*
+	 * Send some messages, consume them and verify the messages are not sent upon recovery
+	 *
+	 */
+	public void testAutoAcknowledge() throws Exception
+   {
+
+		Connection conn = cf.createConnection();
+
+		Session producerSess = conn.createSession(false, Session.AUTO_ACKNOWLEDGE);
+		MessageProducer producer = producerSess.createProducer(queue);
+
+		Session consumerSess = conn.createSession(false, Session.AUTO_ACKNOWLEDGE);
+		MessageConsumer consumer = consumerSess.createConsumer(queue);
+		conn.start();
+
+		final int NUM_MESSAGES = 20;
+
+		//Send some messages
+		for (int i = 0; i < NUM_MESSAGES; i++)
+		{
+			Message m = producerSess.createMessage();
+			producer.send(m);
+		}
+      
+      assertRemainingMessages(NUM_MESSAGES);
+
+		log.trace("Sent messages");
+
+		int count = 0;
+
+		Message m = null;
+		for (int i = 0; i < NUM_MESSAGES; i++)
+		{
+         assertRemainingMessages(NUM_MESSAGES - i);
+         
+			m = consumer.receive(200);
+         
+         assertRemainingMessages(NUM_MESSAGES - (i + 1));
+         
+			if (m == null) break;
+			count++;
+		}
+      
+      assertRemainingMessages(0);      		
+
+		assertNotNull(m);
+
+		log.trace("Received " + count +  " messages");
+
+		assertEquals(count, NUM_MESSAGES);
+
+		consumerSess.recover();
+
+		log.trace("Session recover called");
+
+		m = consumer.receive(200);
+
+		log.trace("Message is:" + m);
+
+		assertNull(m);
+
+		conn.close();
+
+   }
+
+
+	/*
+	 * Send some messages, consume them and verify the messages are not sent upon recovery
+	 *
+	 */
+	public void testLazyAcknowledge() throws Exception
+   {
+
+		Connection conn = cf.createConnection();
+
+		Session producerSess = conn.createSession(false, Session.DUPS_OK_ACKNOWLEDGE);
+		MessageProducer producer = producerSess.createProducer(queue);
+
+		Session consumerSess = conn.createSession(false, Session.DUPS_OK_ACKNOWLEDGE);
+		MessageConsumer consumer = consumerSess.createConsumer(queue);
+		conn.start();
+
+		final int NUM_MESSAGES = 20;
+
+		//Send some messages
+		for (int i = 0; i < NUM_MESSAGES; i++)
+		{
+			Message m = producerSess.createMessage();
+			producer.send(m);
+		}
+
+      assertRemainingMessages(NUM_MESSAGES);
+      
+		log.trace("Sent messages");
+
+		int count = 0;
+
+		Message m = null;
+		for (int i = 0; i < NUM_MESSAGES; i++)
+		{
+			m = consumer.receive(200);
+			if (m == null) break;
+			count++;
+		}
+      
+      assertRemainingMessages(0);
+      
+		assertNotNull(m);
+
+		log.trace("Received " + count +  " messages");
+
+		assertEquals(count, NUM_MESSAGES);
+
+		consumerSess.recover();
+
+		log.trace("Session recover called");
+
+		m = consumer.receive(200);
+
+		log.trace("Message is:" + m);
+
+		assertNull(m);
+
+		conn.close();
+
+   }
+   
+   public void testMessageListenerAutoAck() throws Exception
+   {
+      Connection conn = cf.createConnection();
+      Session sessSend = conn.createSession(false, Session.AUTO_ACKNOWLEDGE);
+      MessageProducer prod = sessSend.createProducer(queue);
+      prod.setDeliveryMode(DeliveryMode.NON_PERSISTENT);
+      TextMessage tm1 = sessSend.createTextMessage("a");
+      TextMessage tm2 = sessSend.createTextMessage("b");
+      TextMessage tm3 = sessSend.createTextMessage("c");
+      prod.send(tm1);
+      prod.send(tm2);
+      prod.send(tm3);
+      sessSend.close();
+      
+      assertRemainingMessages(3);
+   
+      conn.start();
+
+      Session sessReceive = conn.createSession(false, Session.AUTO_ACKNOWLEDGE);
+      MessageConsumer cons = sessReceive.createConsumer(queue);
+      
+      MessageListenerAutoAck listener = new MessageListenerAutoAck(sessReceive);
+      cons.setMessageListener(listener);
+
+      listener.waitForMessages();
+      
+      assertRemainingMessages(0);
+      
+      conn.close();
+      assertFalse(listener.failed);
+   }
+   
+   public void testMessageListenerClientAck() throws Exception
+   {
+      Connection conn = cf.createConnection();
+      Session sessSend = conn.createSession(false, Session.AUTO_ACKNOWLEDGE);
+      MessageProducer prod = sessSend.createProducer(queue);
+      prod.setDeliveryMode(DeliveryMode.NON_PERSISTENT);
+      TextMessage tm1 = sessSend.createTextMessage("a");
+      TextMessage tm2 = sessSend.createTextMessage("b");
+      TextMessage tm3 = sessSend.createTextMessage("c");
+      prod.send(tm1);
+      prod.send(tm2);
+      prod.send(tm3);
+      sessSend.close();
+      
+      assertRemainingMessages(3);
+      
+      conn.start();
+      Session sessReceive = conn.createSession(false, Session.CLIENT_ACKNOWLEDGE);
+      MessageConsumer cons = sessReceive.createConsumer(queue);
+      MessageListenerClientAck listener = new MessageListenerClientAck(sessReceive);
+      cons.setMessageListener(listener);
+      
+      listener.waitForMessages();
+      
+      assertRemainingMessages(0);
+      
+      conn.close();
+      
+      assertFalse(listener.failed);
+   }
+   
+   
+   public void testMessageListenerTransactionalAck() throws Exception
+   {
+      Connection conn = cf.createConnection();
+      Session sessSend = conn.createSession(false, Session.AUTO_ACKNOWLEDGE);
+      MessageProducer prod = sessSend.createProducer(queue);
+      prod.setDeliveryMode(DeliveryMode.NON_PERSISTENT);
+      TextMessage tm1 = sessSend.createTextMessage("a");
+      TextMessage tm2 = sessSend.createTextMessage("b");
+      TextMessage tm3 = sessSend.createTextMessage("c");
+      prod.send(tm1);
+      prod.send(tm2);
+      prod.send(tm3);
+      sessSend.close();
+      
+      assertRemainingMessages(3);
+      
+      conn.start();
+      Session sessReceive = conn.createSession(true, Session.SESSION_TRANSACTED);
+      MessageConsumer cons = sessReceive.createConsumer(queue);
+      MessageListenerTransactionalAck listener = new MessageListenerTransactionalAck(sessReceive);
+      cons.setMessageListener(listener);
+      listener.waitForMessages();
+      
+      assertRemainingMessages(0);
+      
+      conn.close();
+      
+      assertFalse(listener.failed);
+   }
+   
+   
+   // Package protected ---------------------------------------------
+   
+   // Protected -----------------------------------------------------
+   
+   // Private -------------------------------------------------------
+   
+   // Inner classes -------------------------------------------------
+   
+   
+   private class MessageListenerAutoAck implements MessageListener
+   {
+      
+      private Latch latch = new Latch();
+      
+      private Session sess;
+      
+      private int count = 0;
+      
+      boolean failed;
+      
+      MessageListenerAutoAck(Session sess)
+      {
+         this.sess = sess;
+      }
+      
+      public void waitForMessages() throws InterruptedException
+      {
+         latch.acquire();
+         Thread.sleep(500);
+      }
+
+      public void onMessage(Message m)
+      {
+         try
+         {
+            count++;
+                  
+            TextMessage tm = (TextMessage)m;
+                      
+            // Receive first three messages then recover() session
+            // Only last message should be redelivered
+            if (count == 1)
+            {
+               assertRemainingMessages(3);
+               
+               if (!"a".equals(tm.getText()))
+               {
+                  failed = true;
+                  latch.release();
+               }
+            }
+            if (count == 2)
+            {
+               assertRemainingMessages(2);
+               
+               if (!"b".equals(tm.getText()))
+               {
+                  failed = true;
+                  latch.release();
+               }
+            }
+            if (count == 3)
+            {
+               assertRemainingMessages(1);
+               
+               if (!"c".equals(tm.getText()))
+               {
+                  failed = true;
+                  latch.release();
+               }
+               sess.recover();
+            }
+            if (count == 4)
+            {
+               assertRemainingMessages(1);
+               
+               if (!"c".equals(tm.getText()))
+               {
+                  failed = true;
+                  latch.release();
+               }               
+               latch.release();
+            }            
+               
+         }
+         catch (Exception e)
+         {
+            failed = true;
+            latch.release();
+         }
+      }
+            
+   }
+   
+   
+   private class MessageListenerClientAck implements MessageListener
+   {
+      
+      private Latch latch = new Latch();
+      
+      private Session sess;
+      
+      private int count = 0;
+      
+      boolean failed;
+      
+      MessageListenerClientAck(Session sess)
+      {
+         this.sess = sess;
+      }
+
+      
+      public void waitForMessages() throws InterruptedException
+      {
+         latch.acquire();
+         Thread.sleep(500);
+      }
+
+      public void onMessage(Message m)
+      {
+         try
+         {
+            count++;
+            
+            TextMessage tm = (TextMessage)m;
+
+            if (count == 1)
+            {
+               assertRemainingMessages(3);
+               if (!"a".equals(tm.getText()))
+               {
+                  log.trace("Expected a but got " + tm.getText());
+                  failed = true;
+                  latch.release();
+               }               
+            }
+            if (count == 2)
+            {
+               assertRemainingMessages(3);
+               if (!"b".equals(tm.getText()))
+               {
+                  log.trace("Expected b but got " + tm.getText());
+                  failed = true;
+                  latch.release();
+               }               
+            }
+            if (count == 3)
+            {
+               assertRemainingMessages(3);
+               if (!"c".equals(tm.getText()))
+               {
+                  log.trace("Expected c but got " + tm.getText());
+                  failed = true;
+                  latch.release();
+               }
+               sess.recover();
+            }
+            if (count == 4)
+            {
+               assertRemainingMessages(3);
+               if (!"a".equals(tm.getText()))
+               {
+                  log.trace("Expected a but got " + tm.getText());
+                  failed = true;
+                  latch.release();
+               }     
+               tm.acknowledge();
+               assertRemainingMessages(2);
+               sess.recover();
+            } 
+            if (count == 5)
+            {
+               assertRemainingMessages(2);
+               if (!"b".equals(tm.getText()))
+               {
+                  log.trace("Expected b but got " + tm.getText());
+                  failed = true;
+                  latch.release();
+               }  
+               sess.recover();
+            }
+            if (count == 6)
+            {
+               assertRemainingMessages(2);
+               if (!"b".equals(tm.getText()))
+               {
+                  log.trace("Expected b but got " + tm.getText());
+                  failed = true;
+                  latch.release();
+               }               
+            }
+            if (count == 7)
+            {
+               assertRemainingMessages(2);
+               if (!"c".equals(tm.getText()))
+               {
+                  log.trace("Expected c but got " + tm.getText());
+                  failed = true;
+                  latch.release();
+               }
+               tm.acknowledge();
+               assertRemainingMessages(0);
+               latch.release();
+            }
+               
+         }
+         catch (Exception e)
+         {
+            log.error("Caught exception", e);
+            failed = true;
+            latch.release();
+         }
+      }
+            
+   }
+   
+   private class MessageListenerTransactionalAck implements MessageListener
+   {
+      
+      private Latch latch = new Latch();
+      
+      private Session sess;
+      
+      private int count = 0;
+      
+      boolean failed;
+      
+      MessageListenerTransactionalAck(Session sess)
+      {
+         this.sess = sess;
+      }
+
+      
+      public void waitForMessages() throws InterruptedException
+      {
+         latch.acquire();
+         
+         //Wait for postdeliver to be called
+         Thread.sleep(500);
+      }
+
+      public void onMessage(Message m)
+      {
+         try
+         {
+            count++;
+            
+            TextMessage tm = (TextMessage)m;
+                   
+            if (count == 1)
+            {
+               assertRemainingMessages(3);
+               if (!"a".equals(tm.getText()))
+               {
+                  failed = true;
+                  latch.release();
+               }               
+            }
+            if (count == 2)
+            {
+               assertRemainingMessages(3);
+               if (!"b".equals(tm.getText()))
+               {
+                  failed = true;
+                  latch.release();
+               }               
+            }
+            if (count == 3)
+            {
+               assertRemainingMessages(3);
+               if (!"c".equals(tm.getText()))
+               {
+                  failed = true;
+                  latch.release();
+               }
+               log.trace("Rollback");
+               sess.rollback();
+            }
+            if (count == 4)
+            {
+               assertRemainingMessages(3);
+               if (!"a".equals(tm.getText()))
+               {
+                  failed = true;
+                  latch.release();
+               }     
+            } 
+            if (count == 5)
+            {
+               assertRemainingMessages(3);
+               if (!"b".equals(tm.getText()))
+               {
+                  failed = true;
+                  latch.release();
+               }  
+               log.trace("commit");
+               sess.commit();
+               assertRemainingMessages(1);
+            }
+            if (count == 6)
+            {
+               assertRemainingMessages(1);
+               if (!"c".equals(tm.getText()))
+               {
+                  failed = true;
+                  latch.release();
+               }  
+               log.trace("recover");
+               sess.rollback();
+            }
+            if (count == 7)
+            {
+               assertRemainingMessages(1);
+               if (!"c".equals(tm.getText()))
+               {
+                  failed = true;
+                  latch.release();
+               }  
+               log.trace("Commit");
+               sess.commit();
+               assertRemainingMessages(0);
+               latch.release();
+            }        
+         }
+         catch (Exception e)
+         {
+            //log.error(e);
+            failed = true;
+            latch.release();
+         }
+      }
+            
+   }
+   
+   private boolean assertRemainingMessages(int expected) throws Exception
+   {
+      //Need to pause since delivery may still be in progress
+      Thread.sleep(500);
+      ObjectName destObjectName = 
+         new ObjectName("jboss.messaging.destination:service=Queue,name=Queue");
+      Integer messageCount = (Integer)ServerManagement.getAttribute(destObjectName, "MessageCount");      
+      assertEquals(expected, messageCount.intValue());      
+      return expected == messageCount.intValue();
+   }
+   
+
+}
+
+

Deleted: trunk/tests/src/org/jboss/test/messaging/jms/AcknowledgmentTest.java
===================================================================
--- trunk/tests/src/org/jboss/test/messaging/jms/AcknowledgmentTest.java	2006-09-03 17:56:48 UTC (rev 1254)
+++ trunk/tests/src/org/jboss/test/messaging/jms/AcknowledgmentTest.java	2006-09-05 16:08:05 UTC (rev 1255)
@@ -1,1207 +0,0 @@
-/*
-  * JBoss, Home of Professional Open Source
-  * Copyright 2005, JBoss Inc., and individual contributors as indicated
-  * by the @authors tag. See the copyright.txt in the distribution for a
-  * full listing of individual contributors.
-  *
-  * This is free software; you can redistribute it and/or modify it
-  * under the terms of the GNU Lesser General Public License as
-  * published by the Free Software Foundation; either version 2.1 of
-  * the License, or (at your option) any later version.
-  *
-  * This software is distributed in the hope that it will be useful,
-  * but WITHOUT ANY WARRANTY; without even the implied warranty of
-  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-  * Lesser General Public License for more details.
-  *
-  * You should have received a copy of the GNU Lesser General Public
-  * License along with this software; if not, write to the Free
-  * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
-  * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
-  */
-package org.jboss.test.messaging.jms;
-
-import javax.jms.Connection;
-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.Session;
-import javax.jms.TextMessage;
-import javax.jms.Topic;
-import javax.jms.TopicConnection;
-import javax.jms.TopicPublisher;
-import javax.jms.TopicSession;
-import javax.jms.TopicSubscriber;
-import javax.management.ObjectName;
-import javax.naming.InitialContext;
-
-import org.jboss.jms.client.JBossConnectionFactory;
-import org.jboss.test.messaging.MessagingTestCase;
-import org.jboss.test.messaging.tools.ServerManagement;
-
-import EDU.oswego.cs.dl.util.concurrent.Latch;
-
-/**
- * @author <a href="mailto:tim.fox at jboss.com">Tim Fox</a>
- *
- * $Id$
- */
-public class AcknowledgmentTest extends MessagingTestCase
-{
-   // Constants -----------------------------------------------------
-
-   // Static --------------------------------------------------------
-   
-   // Attributes ----------------------------------------------------
-
-   protected InitialContext initialContext;
-   
-   protected JBossConnectionFactory cf;
-   protected Destination queue;
-   protected Topic topic;
-
-   // Constructors --------------------------------------------------
-
-   public AcknowledgmentTest(String name)
-   {
-      super(name);
-   }
-
-   // TestCase overrides -------------------------------------------
-
-   public void setUp() throws Exception
-   {
-      super.setUp();
-      ServerManagement.start("all");
-                  
-      initialContext = new InitialContext(ServerManagement.getJNDIEnvironment());
-      cf = (JBossConnectionFactory)initialContext.lookup("/ConnectionFactory");
-                 
-      ServerManagement.undeployQueue("Queue");
-      ServerManagement.deployQueue("Queue");
-      ServerManagement.undeployTopic("Topic");
-      ServerManagement.deployTopic("Topic");
-      queue = (Destination)initialContext.lookup("/queue/Queue"); 
-      topic = (Topic)initialContext.lookup("/topic/Topic");     
-      
-      drainDestination(cf, queue);
-
-      log.debug("setup done");
-   }
-
-   public void tearDown() throws Exception
-   {
-      ServerManagement.undeployQueue("Queue");
-      ServerManagement.undeployTopic("Topic");
-      
-      super.tearDown();
-      
-   }
-
-
-   // Public --------------------------------------------------------
-//   
-//   
-//   /* Topics shouldn't hold on to messages if there are no subscribers */
-//   public void testPersistentMessagesForTopicDropped() throws Exception
-//   {
-//      TopicConnection conn = null;
-//      
-//      try
-//      {
-//         conn = cf.createTopicConnection();
-//         TopicSession sess = conn.createTopicSession(true, 0);
-//         TopicPublisher pub = sess.createPublisher(topic);
-//         pub.setDeliveryMode(DeliveryMode.PERSISTENT);
-//         
-//         Message m = sess.createTextMessage("testing123");
-//         pub.publish(m);
-//         sess.commit();
-//         
-//         conn.close();
-//         conn = cf.createTopicConnection();
-//         conn.start();
-//         
-//         TopicSession newsess = conn.createTopicSession(true, 0);
-//         TopicSubscriber newcons = newsess.createSubscriber(topic);
-//         
-//         Message m2 = (Message)newcons.receive(200);
-//         assertNull(m2);
-//      }
-//      finally
-//      {
-//         if (conn != null)
-//         {
-//            conn.close();
-//         }
-//      }
-//   }
-//   
-//   /* Topics shouldn't hold on to messages when the non-durable subscribers close */
-//   public void testPersistentMessagesForTopicDropped2() throws Exception
-//   {
-//      TopicConnection conn = null;
-//      
-//      try
-//      {
-//         conn = cf.createTopicConnection();
-//         conn.start();
-//         TopicSession sess = conn.createTopicSession(true, 0);
-//         TopicPublisher pub = sess.createPublisher(topic);
-//         TopicSubscriber sub = sess.createSubscriber(topic);
-//         pub.setDeliveryMode(DeliveryMode.PERSISTENT);
-//         
-//         Message m = sess.createTextMessage("testing123");
-//         pub.publish(m);
-//         sess.commit();
-//         
-//         //receive but rollback
-//         TextMessage m2 = (TextMessage)sub.receive(3000);
-//            
-//         assertNotNull(m2);
-//         assertEquals("testing123", m2.getText());
-//         
-//         sess.rollback();
-//         
-//         conn.close();
-//         conn = cf.createTopicConnection();
-//         conn.start();
-//         
-//         TopicSession newsess = conn.createTopicSession(true, 0);
-//         TopicSubscriber newcons = newsess.createSubscriber(topic);
-//         
-//         Message m3 = (Message)newcons.receive(200);
-//         assertNull(m3);
-//      }
-//      finally
-//      {
-//         if (conn != null)
-//         {
-//            conn.close();
-//         }
-//      }
-//   }
-//   
-//   public void testRollbackRecover() throws Exception
-//   {
-//      TopicConnection conn = null;
-//      
-//      try
-//      {
-//         conn = cf.createTopicConnection();
-//         TopicSession sess = conn.createTopicSession(true, 0);
-//         TopicPublisher pub = sess.createPublisher(topic);
-//         TopicSubscriber cons = sess.createSubscriber(topic);
-//         conn.start();
-//         
-//         Message m = sess.createTextMessage("testing123");
-//         pub.publish(m);
-//         sess.commit();
-//         
-//         TextMessage m2 = (TextMessage)cons.receive(3000);
-//         assertNotNull(m2);
-//         assertEquals("testing123", m2.getText());
-//         
-//         sess.rollback();
-//         
-//         m2 = (TextMessage)cons.receive(3000);
-//         assertNotNull(m2);
-//         assertEquals("testing123", m2.getText());
-//         
-//         conn.close();
-//         
-//         conn = cf.createTopicConnection();
-//         conn.start();
-//         
-//         //test 2
-//         
-//         TopicSession newsess = conn.createTopicSession(true, 0);
-//         TopicPublisher newpub = newsess.createPublisher(topic);
-//         TopicSubscriber newcons = newsess.createSubscriber(topic);
-//         
-//         Message m3 = newsess.createTextMessage("testing456");
-//         newpub.publish(m3);
-//         newsess.commit();
-//         
-//         TextMessage m4 = (TextMessage)newcons.receive(3000);
-//         assertNotNull(m4);
-//         assertEquals("testing456", m4.getText());
-//         
-//         newsess.commit();
-//         
-//         newpub.publish(m3);
-//         newsess.commit();
-//         
-//         TextMessage m5 = (TextMessage)newcons.receive(3000);
-//         assertNotNull(m5);
-//         assertEquals("testing456", m5.getText());
-//         
-//         newsess.rollback();
-//         
-//         TextMessage m6 = (TextMessage)newcons.receive(3000);
-//         assertNotNull(m6);
-//         assertEquals("testing456", m6.getText());
-//         
-//         newsess.commit();
-//         
-//      }
-//      finally
-//      {
-//         if (conn != null)
-//         {
-//            conn.close();
-//         }
-//      }
-//   }
-   
-   public void testTransactionalAcknowlegment() throws Exception
-   {
-
-      Connection conn = cf.createConnection();
-
-      Session producerSess = conn.createSession(true, Session.SESSION_TRANSACTED);
-      MessageProducer producer = producerSess.createProducer(queue);
-
-      Session consumerSess = conn.createSession(true, Session.SESSION_TRANSACTED);
-      MessageConsumer consumer = consumerSess.createConsumer(queue);
-      conn.start();
-
-      final int NUM_MESSAGES = 20;
-
-      //Send some messages
-      for (int i = 0; i < NUM_MESSAGES; i++)
-      {
-         Message m = producerSess.createMessage();
-         producer.send(m);
-      }
-      
-      assertRemainingMessages(0);
-      
-      producerSess.rollback();
-      
-      //Send some messages
-      for (int i = 0; i < NUM_MESSAGES; i++)
-      {
-         Message m = producerSess.createMessage();
-         producer.send(m);
-      }
-      assertRemainingMessages(0);
-      
-      producerSess.commit();
-      
-      assertRemainingMessages(NUM_MESSAGES);
-
-      log.trace("Sent messages");
-
-      int count = 0;
-      while (true)
-      {
-         Message m = consumer.receive(200);
-         if (m == null) break;
-         count++;
-      }
-      
-      assertRemainingMessages(NUM_MESSAGES);
-
-      log.trace("Received " + count +  " messages");
-
-      assertEquals(count, NUM_MESSAGES);
-
-      consumerSess.rollback();
-      
-      assertRemainingMessages(NUM_MESSAGES);
-
-      log.trace("Session rollback called");
-
-      Message m = null;
-
-      int i = 0;
-      for(; i < NUM_MESSAGES; i++)
-      {
-         m = consumer.receive();
-         log.trace("Received message " + i);
-
-      }
-      
-      assertRemainingMessages(NUM_MESSAGES);
-
-      // if I don't receive enough messages, the test will timeout
-
-      log.trace("Received " + i +  " messages after recover");
-      
-      consumerSess.commit();
-      
-      assertRemainingMessages(0);
-
-      // make sure I don't receive anything else
-
-      m = consumer.receive(200);
-      assertNull(m);
-
-      conn.close();
-
-   }
-
-	/**
-	 * Send some messages, don't acknowledge them and verify that they are re-sent on recovery.
-	 */
-	public void testClientAcknowledgeNoAcknowlegment() throws Exception
-   {
-
-		Connection conn = cf.createConnection();
-
-		Session producerSess = conn.createSession(false, Session.CLIENT_ACKNOWLEDGE);
-		MessageProducer producer = producerSess.createProducer(queue);
-
-		Session consumerSess = conn.createSession(false, Session.CLIENT_ACKNOWLEDGE);
-		MessageConsumer consumer = consumerSess.createConsumer(queue);
-		conn.start();
-
-		final int NUM_MESSAGES = 20;
-
-		//Send some messages
-		for (int i = 0; i < NUM_MESSAGES; i++)
-		{
-			Message m = producerSess.createMessage();
-			producer.send(m);
-		}
-      
-      assertRemainingMessages(NUM_MESSAGES);
-
-		log.trace("Sent messages");
-
-		int count = 0;
-		while (true)
-		{
-			Message m = consumer.receive(200);
-			if (m == null) break;
-			count++;
-		}
-      
-      assertRemainingMessages(NUM_MESSAGES);
-
-		log.trace("Received " + count +  " messages");
-
-		assertEquals(count, NUM_MESSAGES);
-
-		consumerSess.recover();
-      
-      assertRemainingMessages(NUM_MESSAGES);
-
-		log.trace("Session recover called");
-
-      Message m = null;
-
-      int i = 0;
-      for(; i < NUM_MESSAGES; i++)
-      {
-         m = consumer.receive();
-         log.trace("Received message " + i);
-
-      }
-      
-      assertRemainingMessages(NUM_MESSAGES);
-
-      // if I don't receive enough messages, the test will timeout
-
-		log.trace("Received " + i +  " messages after recover");
-      
-      m.acknowledge();
-      
-      assertRemainingMessages(0);
-
-      // make sure I don't receive anything else
-
-      m = consumer.receive(200);
-      assertNull(m);
-
-		conn.close();
-
-   }
-
-	
-//	
-//	/**
-//	 * Send some messages, acknowledge them individually and verify they are not resent after
-//    * recovery.
-//	 */
-//	public void testIndividualClientAcknowledge() throws Exception
-//   {
-//		
-//		Connection conn = cf.createConnection();     
-//		
-//		Session producerSess = conn.createSession(false, Session.CLIENT_ACKNOWLEDGE);
-//		MessageProducer producer = producerSess.createProducer(queue);
-//		
-//		Session consumerSess = conn.createSession(false, Session.CLIENT_ACKNOWLEDGE);
-//		MessageConsumer consumer = consumerSess.createConsumer(queue);
-//		conn.start();
-//		
-//		final int NUM_MESSAGES = 20;
-//		
-//		for (int i = 0; i < NUM_MESSAGES; i++)
-//		{
-//			Message m = producerSess.createMessage();
-//			producer.send(m);
-//		}
-//      
-//      assertRemainingMessages(NUM_MESSAGES);
-//		
-//		log.trace("Sent " + NUM_MESSAGES + " messages");
-//		
-//		int count = 0;
-//		while (true)		
-//		{
-//			Message m = consumer.receive(200);
-//         log.trace("Received message " + m);
-//			if (m == null)
-//         {
-//            break;
-//         }
-//         log.trace("Acking session");
-//         
-//         assertRemainingMessages(NUM_MESSAGES - count);
-//         
-//			m.acknowledge();
-//         
-//         assertRemainingMessages(NUM_MESSAGES - (count + 1));
-//			count++;
-//		}
-//
-//      assertRemainingMessages(0);
-//      
-//      assertEquals(NUM_MESSAGES, count);
-//      log.trace("received and acknowledged " + count +  " messages");
-//
-//      Message m = consumer.receive(200);
-//		assertNull(m);
-//      
-//      log.trace("mesage is " + m);
-//
-//      log.trace("calling session recover()");
-//		consumerSess.recover();
-//		log.trace("recover called");
-//		
-//		m = consumer.receive(200);
-//		assertNull(m);
-//		
-//		conn.close();
-//		
-//   }
-//
-//
-//	/**
-//	 * Send some messages, acknowledge them once after all have been received verify they are not
-//    * resent after recovery
-//	 */
-//	public void testBulkClientAcknowledge() throws Exception
-//   {
-//
-//		Connection conn = cf.createConnection();
-//
-//		Session producerSess = conn.createSession(false, Session.CLIENT_ACKNOWLEDGE);
-//		MessageProducer producer = producerSess.createProducer(queue);
-//
-//		Session consumerSess = conn.createSession(false, Session.CLIENT_ACKNOWLEDGE);
-//		MessageConsumer consumer = consumerSess.createConsumer(queue);
-//		conn.start();
-//
-//		final int NUM_MESSAGES = 20;
-//
-//		//Send some messages
-//		for (int i = 0; i < NUM_MESSAGES; i++)
-//		{
-//			Message m = producerSess.createMessage();
-//			producer.send(m);
-//		}
-//      
-//      assertRemainingMessages(NUM_MESSAGES);
-//
-//		log.trace("Sent messages");
-//
-//		Message m = null;
-//		int count = 0;
-//		for (int i = 0; i < NUM_MESSAGES; i++)
-//		{
-//			m = consumer.receive(200);
-//			if (m == null) break;
-//			count++;
-//		}
-//      
-//      assertRemainingMessages(NUM_MESSAGES);
-//
-//		assertNotNull(m);
-//
-//		m.acknowledge();
-//      
-//      assertRemainingMessages(0);
-//
-//		log.trace("Received " + count +  " messages");
-//
-//		assertEquals(count, NUM_MESSAGES);
-//
-//		consumerSess.recover();
-//
-//		log.trace("Session recover called");
-//
-//		m = consumer.receive(200);
-//
-//		log.trace("Message is:" + m);
-//
-//		assertNull(m);
-//
-//		conn.close();
-//
-//   }
-//
-//
-//	/**
-//	 * Send some messages, acknowledge some of them, and verify that the others are resent after
-//    * delivery
-//	 */
-//	public void testPartialClientAcknowledge() throws Exception
-//   {
-//
-//		Connection conn = cf.createConnection();
-//
-//		Session producerSess = conn.createSession(false, Session.CLIENT_ACKNOWLEDGE);
-//		MessageProducer producer = producerSess.createProducer(queue);
-//
-//		Session consumerSess = conn.createSession(false, Session.CLIENT_ACKNOWLEDGE);
-//		MessageConsumer consumer = consumerSess.createConsumer(queue);
-//		conn.start();
-//
-//		final int NUM_MESSAGES = 20;
-//		final int ACKED_MESSAGES = 11;
-//
-//		//Send some messages
-//		for (int i = 0; i < NUM_MESSAGES; i++)
-//		{
-//			Message m = producerSess.createMessage();
-//			producer.send(m);
-//		}
-//      
-//      assertRemainingMessages(NUM_MESSAGES);
-//
-//		log.trace("Sent messages");
-//
-//		int count = 0;
-//
-//		Message m = null;
-//		for (int i = 0; i < NUM_MESSAGES; i++)
-//		{
-//			m = consumer.receive(200);
-//			if (m == null)
-//         {
-//            break;
-//         }
-//			if (count == ACKED_MESSAGES -1)
-//         {
-//            m.acknowledge();
-//         }
-//			count++;
-//		}
-//      
-//      assertRemainingMessages(NUM_MESSAGES - ACKED_MESSAGES);
-//      
-//		assertNotNull(m);
-//
-//		log.trace("Received " + count +  " messages");
-//
-//		assertEquals(count, NUM_MESSAGES);
-//
-//		consumerSess.recover();
-//
-//		log.trace("Session recover called");
-//
-//		count = 0;
-//		while (true)
-//		{
-//			m = consumer.receive(200);
-//			if (m == null) break;
-//			count++;
-//		}
-//
-//		assertEquals(NUM_MESSAGES - ACKED_MESSAGES, count);            
-//
-//		conn.close();
-//
-//   }
-//
-//
-//
-//	/*
-//	 * Send some messages, consume them and verify the messages are not sent upon recovery
-//	 *
-//	 */
-//	public void testAutoAcknowledge() throws Exception
-//   {
-//
-//		Connection conn = cf.createConnection();
-//
-//		Session producerSess = conn.createSession(false, Session.AUTO_ACKNOWLEDGE);
-//		MessageProducer producer = producerSess.createProducer(queue);
-//
-//		Session consumerSess = conn.createSession(false, Session.AUTO_ACKNOWLEDGE);
-//		MessageConsumer consumer = consumerSess.createConsumer(queue);
-//		conn.start();
-//
-//		final int NUM_MESSAGES = 20;
-//
-//		//Send some messages
-//		for (int i = 0; i < NUM_MESSAGES; i++)
-//		{
-//			Message m = producerSess.createMessage();
-//			producer.send(m);
-//		}
-//      
-//      assertRemainingMessages(NUM_MESSAGES);
-//
-//		log.trace("Sent messages");
-//
-//		int count = 0;
-//
-//		Message m = null;
-//		for (int i = 0; i < NUM_MESSAGES; i++)
-//		{
-//         assertRemainingMessages(NUM_MESSAGES - i);
-//         
-//			m = consumer.receive(200);
-//         
-//         assertRemainingMessages(NUM_MESSAGES - (i + 1));
-//         
-//			if (m == null) break;
-//			count++;
-//		}
-//      
-//      assertRemainingMessages(0);      		
-//
-//		assertNotNull(m);
-//
-//		log.trace("Received " + count +  " messages");
-//
-//		assertEquals(count, NUM_MESSAGES);
-//
-//		consumerSess.recover();
-//
-//		log.trace("Session recover called");
-//
-//		m = consumer.receive(200);
-//
-//		log.trace("Message is:" + m);
-//
-//		assertNull(m);
-//
-//		conn.close();
-//
-//   }
-//
-//
-//	/*
-//	 * Send some messages, consume them and verify the messages are not sent upon recovery
-//	 *
-//	 */
-//	public void testLazyAcknowledge() throws Exception
-//   {
-//
-//		Connection conn = cf.createConnection();
-//
-//		Session producerSess = conn.createSession(false, Session.DUPS_OK_ACKNOWLEDGE);
-//		MessageProducer producer = producerSess.createProducer(queue);
-//
-//		Session consumerSess = conn.createSession(false, Session.DUPS_OK_ACKNOWLEDGE);
-//		MessageConsumer consumer = consumerSess.createConsumer(queue);
-//		conn.start();
-//
-//		final int NUM_MESSAGES = 20;
-//
-//		//Send some messages
-//		for (int i = 0; i < NUM_MESSAGES; i++)
-//		{
-//			Message m = producerSess.createMessage();
-//			producer.send(m);
-//		}
-//
-//      assertRemainingMessages(NUM_MESSAGES);
-//      
-//		log.trace("Sent messages");
-//
-//		int count = 0;
-//
-//		Message m = null;
-//		for (int i = 0; i < NUM_MESSAGES; i++)
-//		{
-//			m = consumer.receive(200);
-//			if (m == null) break;
-//			count++;
-//		}
-//      
-//      assertRemainingMessages(0);
-//      
-//		assertNotNull(m);
-//
-//		log.trace("Received " + count +  " messages");
-//
-//		assertEquals(count, NUM_MESSAGES);
-//
-//		consumerSess.recover();
-//
-//		log.trace("Session recover called");
-//
-//		m = consumer.receive(200);
-//
-//		log.trace("Message is:" + m);
-//
-//		assertNull(m);
-//
-//		conn.close();
-//
-//   }
-//   
-//   public void testMessageListenerAutoAck() throws Exception
-//   {
-//      Connection conn = cf.createConnection();
-//      Session sessSend = conn.createSession(false, Session.AUTO_ACKNOWLEDGE);
-//      MessageProducer prod = sessSend.createProducer(queue);
-//      prod.setDeliveryMode(DeliveryMode.NON_PERSISTENT);
-//      TextMessage tm1 = sessSend.createTextMessage("a");
-//      TextMessage tm2 = sessSend.createTextMessage("b");
-//      TextMessage tm3 = sessSend.createTextMessage("c");
-//      prod.send(tm1);
-//      prod.send(tm2);
-//      prod.send(tm3);
-//      sessSend.close();
-//      
-//      assertRemainingMessages(3);
-//   
-//      conn.start();
-//
-//      Session sessReceive = conn.createSession(false, Session.AUTO_ACKNOWLEDGE);
-//      MessageConsumer cons = sessReceive.createConsumer(queue);
-//      
-//      MessageListenerAutoAck listener = new MessageListenerAutoAck(sessReceive);
-//      cons.setMessageListener(listener);
-//
-//      listener.waitForMessages();
-//      
-//      assertRemainingMessages(0);
-//      
-//      conn.close();
-//      assertFalse(listener.failed);
-//   }
-//   
-//   public void testMessageListenerClientAck() throws Exception
-//   {
-//      Connection conn = cf.createConnection();
-//      Session sessSend = conn.createSession(false, Session.AUTO_ACKNOWLEDGE);
-//      MessageProducer prod = sessSend.createProducer(queue);
-//      prod.setDeliveryMode(DeliveryMode.NON_PERSISTENT);
-//      TextMessage tm1 = sessSend.createTextMessage("a");
-//      TextMessage tm2 = sessSend.createTextMessage("b");
-//      TextMessage tm3 = sessSend.createTextMessage("c");
-//      prod.send(tm1);
-//      prod.send(tm2);
-//      prod.send(tm3);
-//      sessSend.close();
-//      
-//      assertRemainingMessages(3);
-//      
-//      conn.start();
-//      Session sessReceive = conn.createSession(false, Session.CLIENT_ACKNOWLEDGE);
-//      MessageConsumer cons = sessReceive.createConsumer(queue);
-//      MessageListenerClientAck listener = new MessageListenerClientAck(sessReceive);
-//      cons.setMessageListener(listener);
-//      
-//      listener.waitForMessages();
-//      
-//      assertRemainingMessages(0);
-//      
-//      conn.close();
-//      
-//      assertFalse(listener.failed);
-//   }
-//   
-//   
-//   public void testMessageListenerTransactionalAck() throws Exception
-//   {
-//      Connection conn = cf.createConnection();
-//      Session sessSend = conn.createSession(false, Session.AUTO_ACKNOWLEDGE);
-//      MessageProducer prod = sessSend.createProducer(queue);
-//      prod.setDeliveryMode(DeliveryMode.NON_PERSISTENT);
-//      TextMessage tm1 = sessSend.createTextMessage("a");
-//      TextMessage tm2 = sessSend.createTextMessage("b");
-//      TextMessage tm3 = sessSend.createTextMessage("c");
-//      prod.send(tm1);
-//      prod.send(tm2);
-//      prod.send(tm3);
-//      sessSend.close();
-//      
-//      assertRemainingMessages(3);
-//      
-//      conn.start();
-//      Session sessReceive = conn.createSession(true, Session.SESSION_TRANSACTED);
-//      MessageConsumer cons = sessReceive.createConsumer(queue);
-//      MessageListenerTransactionalAck listener = new MessageListenerTransactionalAck(sessReceive);
-//      cons.setMessageListener(listener);
-//      listener.waitForMessages();
-//      
-//      assertRemainingMessages(0);
-//      
-//      conn.close();
-//      
-//      assertFalse(listener.failed);
-//   }
-//   
-   
-   // Package protected ---------------------------------------------
-   
-   // Protected -----------------------------------------------------
-   
-   // Private -------------------------------------------------------
-   
-   // Inner classes -------------------------------------------------
-   
-   
-   private class MessageListenerAutoAck implements MessageListener
-   {
-      
-      private Latch latch = new Latch();
-      
-      private Session sess;
-      
-      private int count = 0;
-      
-      boolean failed;
-      
-      MessageListenerAutoAck(Session sess)
-      {
-         this.sess = sess;
-      }
-      
-      public void waitForMessages() throws InterruptedException
-      {
-         latch.acquire();
-         Thread.sleep(500);
-      }
-
-      public void onMessage(Message m)
-      {
-         try
-         {
-            count++;
-                  
-            TextMessage tm = (TextMessage)m;
-                      
-            // Receive first three messages then recover() session
-            // Only last message should be redelivered
-            if (count == 1)
-            {
-               assertRemainingMessages(3);
-               
-               if (!"a".equals(tm.getText()))
-               {
-                  failed = true;
-                  latch.release();
-               }
-            }
-            if (count == 2)
-            {
-               assertRemainingMessages(2);
-               
-               if (!"b".equals(tm.getText()))
-               {
-                  failed = true;
-                  latch.release();
-               }
-            }
-            if (count == 3)
-            {
-               assertRemainingMessages(1);
-               
-               if (!"c".equals(tm.getText()))
-               {
-                  failed = true;
-                  latch.release();
-               }
-               sess.recover();
-            }
-            if (count == 4)
-            {
-               assertRemainingMessages(1);
-               
-               if (!"c".equals(tm.getText()))
-               {
-                  failed = true;
-                  latch.release();
-               }               
-               latch.release();
-            }            
-               
-         }
-         catch (Exception e)
-         {
-            failed = true;
-            latch.release();
-         }
-      }
-            
-   }
-   
-   
-   private class MessageListenerClientAck implements MessageListener
-   {
-      
-      private Latch latch = new Latch();
-      
-      private Session sess;
-      
-      private int count = 0;
-      
-      boolean failed;
-      
-      MessageListenerClientAck(Session sess)
-      {
-         this.sess = sess;
-      }
-
-      
-      public void waitForMessages() throws InterruptedException
-      {
-         latch.acquire();
-         Thread.sleep(500);
-      }
-
-      public void onMessage(Message m)
-      {
-         try
-         {
-            count++;
-            
-            TextMessage tm = (TextMessage)m;
-
-            if (count == 1)
-            {
-               assertRemainingMessages(3);
-               if (!"a".equals(tm.getText()))
-               {
-                  log.trace("Expected a but got " + tm.getText());
-                  failed = true;
-                  latch.release();
-               }               
-            }
-            if (count == 2)
-            {
-               assertRemainingMessages(3);
-               if (!"b".equals(tm.getText()))
-               {
-                  log.trace("Expected b but got " + tm.getText());
-                  failed = true;
-                  latch.release();
-               }               
-            }
-            if (count == 3)
-            {
-               assertRemainingMessages(3);
-               if (!"c".equals(tm.getText()))
-               {
-                  log.trace("Expected c but got " + tm.getText());
-                  failed = true;
-                  latch.release();
-               }
-               sess.recover();
-            }
-            if (count == 4)
-            {
-               assertRemainingMessages(3);
-               if (!"a".equals(tm.getText()))
-               {
-                  log.trace("Expected a but got " + tm.getText());
-                  failed = true;
-                  latch.release();
-               }     
-               tm.acknowledge();
-               assertRemainingMessages(2);
-               sess.recover();
-            } 
-            if (count == 5)
-            {
-               assertRemainingMessages(2);
-               if (!"b".equals(tm.getText()))
-               {
-                  log.trace("Expected b but got " + tm.getText());
-                  failed = true;
-                  latch.release();
-               }  
-               sess.recover();
-            }
-            if (count == 6)
-            {
-               assertRemainingMessages(2);
-               if (!"b".equals(tm.getText()))
-               {
-                  log.trace("Expected b but got " + tm.getText());
-                  failed = true;
-                  latch.release();
-               }               
-            }
-            if (count == 7)
-            {
-               assertRemainingMessages(2);
-               if (!"c".equals(tm.getText()))
-               {
-                  log.trace("Expected c but got " + tm.getText());
-                  failed = true;
-                  latch.release();
-               }
-               tm.acknowledge();
-               assertRemainingMessages(0);
-               latch.release();
-            }
-               
-         }
-         catch (Exception e)
-         {
-            log.error("Caught exception", e);
-            failed = true;
-            latch.release();
-         }
-      }
-            
-   }
-   
-   private class MessageListenerTransactionalAck implements MessageListener
-   {
-      
-      private Latch latch = new Latch();
-      
-      private Session sess;
-      
-      private int count = 0;
-      
-      boolean failed;
-      
-      MessageListenerTransactionalAck(Session sess)
-      {
-         this.sess = sess;
-      }
-
-      
-      public void waitForMessages() throws InterruptedException
-      {
-         latch.acquire();
-         
-         //Wait for postdeliver to be called
-         Thread.sleep(500);
-      }
-
-      public void onMessage(Message m)
-      {
-         try
-         {
-            count++;
-            
-            TextMessage tm = (TextMessage)m;
-                   
-            if (count == 1)
-            {
-               assertRemainingMessages(3);
-               if (!"a".equals(tm.getText()))
-               {
-                  failed = true;
-                  latch.release();
-               }               
-            }
-            if (count == 2)
-            {
-               assertRemainingMessages(3);
-               if (!"b".equals(tm.getText()))
-               {
-                  failed = true;
-                  latch.release();
-               }               
-            }
-            if (count == 3)
-            {
-               assertRemainingMessages(3);
-               if (!"c".equals(tm.getText()))
-               {
-                  failed = true;
-                  latch.release();
-               }
-               log.trace("Rollback");
-               sess.rollback();
-            }
-            if (count == 4)
-            {
-               assertRemainingMessages(3);
-               if (!"a".equals(tm.getText()))
-               {
-                  failed = true;
-                  latch.release();
-               }     
-            } 
-            if (count == 5)
-            {
-               assertRemainingMessages(3);
-               if (!"b".equals(tm.getText()))
-               {
-                  failed = true;
-                  latch.release();
-               }  
-               log.trace("commit");
-               sess.commit();
-               assertRemainingMessages(1);
-            }
-            if (count == 6)
-            {
-               assertRemainingMessages(1);
-               if (!"c".equals(tm.getText()))
-               {
-                  failed = true;
-                  latch.release();
-               }  
-               log.trace("recover");
-               sess.rollback();
-            }
-            if (count == 7)
-            {
-               assertRemainingMessages(1);
-               if (!"c".equals(tm.getText()))
-               {
-                  failed = true;
-                  latch.release();
-               }  
-               log.trace("Commit");
-               sess.commit();
-               assertRemainingMessages(0);
-               latch.release();
-            }        
-         }
-         catch (Exception e)
-         {
-            //log.error(e);
-            failed = true;
-            latch.release();
-         }
-      }
-            
-   }
-   
-   private boolean assertRemainingMessages(int expected) throws Exception
-   {
-      //Need to pause since delivery may still be in progress
-      Thread.sleep(500);
-      ObjectName destObjectName = 
-         new ObjectName("jboss.messaging.destination:service=Queue,name=Queue");
-      Integer messageCount = (Integer)ServerManagement.getAttribute(destObjectName, "MessageCount");      
-      assertEquals(expected, messageCount.intValue());      
-      return expected == messageCount.intValue();
-   }
-   
-
-}
-
-

Modified: trunk/tests/src/org/jboss/test/messaging/jms/PersistenceTest.java
===================================================================
--- trunk/tests/src/org/jboss/test/messaging/jms/PersistenceTest.java	2006-09-03 17:56:48 UTC (rev 1254)
+++ trunk/tests/src/org/jboss/test/messaging/jms/PersistenceTest.java	2006-09-05 16:08:05 UTC (rev 1255)
@@ -127,11 +127,9 @@
       ServerManagement.stopServerPeer();
       
       
-      log.info("******************** restartiong");
+      log.info("******************** restarting");
       ServerManagement.startServerPeer();
       
-      
-
       // Messaging server restart implies new ConnectionFactory lookup
       cf = (ConnectionFactory)initialContext.lookup("/ConnectionFactory");
 
@@ -151,8 +149,7 @@
          }
          assertEquals("message" + i, tm.getText());
       }
-      
-     
+           
       conn.close();
    }
    

Modified: trunk/tests/src/org/jboss/test/messaging/tools/jmx/rmi/LocalTestServer.java
===================================================================
--- trunk/tests/src/org/jboss/test/messaging/tools/jmx/rmi/LocalTestServer.java	2006-09-03 17:56:48 UTC (rev 1254)
+++ trunk/tests/src/org/jboss/test/messaging/tools/jmx/rmi/LocalTestServer.java	2006-09-05 16:08:05 UTC (rev 1255)
@@ -73,6 +73,7 @@
    private ObjectName directExchangeObjectName;
    private ObjectName topicExchangeObjectName;
    private ObjectName jmsUserManagerObjectName;
+   private ObjectName shutdownLoggerObjectName;
 
    // the server MBean itself
    private ObjectName serverPeerObjectName;
@@ -269,7 +270,13 @@
          (MBeanConfigurationElement)pdd.query("service", "JMSUserManager").iterator().next();
       jmsUserManagerObjectName = sc.registerAndConfigureService(jmsUserManagerConfig);
       sc.invoke(jmsUserManagerObjectName, "create", new Object[0], new String[0]);
-      sc.invoke(jmsUserManagerObjectName, "start", new Object[0], new String[0]);      
+      sc.invoke(jmsUserManagerObjectName, "start", new Object[0], new String[0]);  
+      
+      MBeanConfigurationElement shutdownLoggerConfig =
+         (MBeanConfigurationElement)pdd.query("service", "ShutdownLogger").iterator().next();
+      shutdownLoggerObjectName = sc.registerAndConfigureService(shutdownLoggerConfig);
+      sc.invoke(shutdownLoggerObjectName, "create", new Object[0], new String[0]);
+      sc.invoke(shutdownLoggerObjectName, "start", new Object[0], new String[0]); 
 
       // register server peer as a service, dependencies are injected automatically
       MBeanConfigurationElement serverPeerConfig =




More information about the jboss-cvs-commits mailing list