[Jboss-cvs] JBoss Messaging SVN: r1237 - in trunk: . src/etc/server/default/deploy src/etc/xmdesc src/main/org/jboss/jms/destination src/main/org/jboss/jms/message src/main/org/jboss/jms/selector src/main/org/jboss/jms/server src/main/org/jboss/jms/server/connectionfactory 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/jms/server/plugin/contract src/main/org/jboss/jms/tx src/main/org/jboss/jms/util src/main/org/jboss/messaging/core src/main/org/jboss/messaging/core/local src/main/org/jboss/messaging/core/message src/main/org/jboss/messaging/core/persistence src/main/org/jboss/messaging/core/plugin src/main/org/jboss/messaging/core/plugin/contract src/main/org/jboss/messaging/core/plugin/contract/ib src/main/org/jboss/messaging/core/plugin/exchange src/main/org/jboss/messaging/core/plugin/exchange/request src/main/org/jboss/messaging/core/tx src/main/org/jboss/messaging/core/util src/main/! org/jboss/messaging/util tests tests/src/org/jboss/test/messaging 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/local/base tests/src/org/jboss/test/messaging/core/message tests/src/org/jboss/test/messaging/core/message/base tests/src/org/jboss/test/messaging/core/paging tests/src/org/jboss/test/messaging/core/persistence 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/jms/message tests/src/org/jboss/test/messaging/jms/persistence tests/src/org/jboss/test/messaging/jms/server/connectionfactory tests/src/org/jboss/test/messaging/jms/server/connectormanager tests/src/org/jboss/test/messaging/jms/server/destination/base tests/src/org/jboss/test/messaging/jms/server/plugin tests/src/org/jboss/test/messaging/jms/util tests/src/org/jbo! ss/test/messaging/tools tests/src/org/jboss/test/messaging/tools/jmx/rmi

jboss-cvs-commits at lists.jboss.org jboss-cvs-commits at lists.jboss.org
Wed Aug 30 14:38:10 EDT 2006


Author: timfox
Date: 2006-08-30 14:36:36 -0400 (Wed, 30 Aug 2006)
New Revision: 1237

Added:
   trunk/src/etc/xmdesc/Exchange-xmbean.xml
   trunk/src/etc/xmdesc/JMSUserManager-xmbean.xml
   trunk/src/main/org/jboss/jms/server/plugin/JDBCJMSUserManager.java
   trunk/src/main/org/jboss/jms/server/plugin/contract/JMSUserManager.java
   trunk/src/main/org/jboss/jms/util/MessageQueueNameHelper.java
   trunk/src/main/org/jboss/messaging/core/PagingChannel.java
   trunk/src/main/org/jboss/messaging/core/local/MessageQueue.java
   trunk/src/main/org/jboss/messaging/core/plugin/JDBCServiceSupport.java
   trunk/src/main/org/jboss/messaging/core/plugin/contract/Exchange.java
   trunk/src/main/org/jboss/messaging/core/plugin/contract/ib/
   trunk/src/main/org/jboss/messaging/core/plugin/contract/ib/BalancePolicy.java
   trunk/src/main/org/jboss/messaging/core/plugin/contract/ib/Balanceable.java
   trunk/src/main/org/jboss/messaging/core/plugin/contract/ib/Instruction.java
   trunk/src/main/org/jboss/messaging/core/plugin/contract/ib/IntelligentBalancer.java
   trunk/src/main/org/jboss/messaging/core/plugin/contract/ib/Statistic.java
   trunk/src/main/org/jboss/messaging/core/plugin/exchange/
   trunk/src/main/org/jboss/messaging/core/plugin/exchange/Binding.java
   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/DirectExchange.java
   trunk/src/main/org/jboss/messaging/core/plugin/exchange/ExchangeSupport.java
   trunk/src/main/org/jboss/messaging/core/plugin/exchange/SimpleBinding.java
   trunk/src/main/org/jboss/messaging/core/plugin/exchange/TopicExchange.java
   trunk/src/main/org/jboss/messaging/core/plugin/exchange/request/
   trunk/src/main/org/jboss/messaging/core/plugin/exchange/request/BindRequest.java
   trunk/src/main/org/jboss/messaging/core/plugin/exchange/request/MessageRequest.java
   trunk/src/main/org/jboss/messaging/core/plugin/exchange/request/UnbindRequest.java
   trunk/src/main/org/jboss/messaging/util/ConcurrentHashSet.java
   trunk/src/main/org/jboss/messaging/util/ConcurrentReaderHashSet.java
   trunk/src/main/org/jboss/messaging/util/JDBCUtil.java
   trunk/src/main/org/jboss/messaging/util/Lockable.java
   trunk/src/main/org/jboss/messaging/util/SafeUTF.java
   trunk/tests/src/org/jboss/test/messaging/core/base/MessageQueueTestBase.java
   trunk/tests/src/org/jboss/test/messaging/core/local/MessageQueueWithFilterTest.java
   trunk/tests/src/org/jboss/test/messaging/core/local/NonRecoverableMessageQueueTest.java
   trunk/tests/src/org/jboss/test/messaging/core/local/RecoverableMessageQueueTest.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/JGroupsUtil.java
   trunk/tests/src/org/jboss/test/messaging/core/plugin/SimpleMessageStoreTest.java
   trunk/tests/src/org/jboss/test/messaging/core/plugin/TopicExchangeTest.java
   trunk/tests/src/org/jboss/test/messaging/core/plugin/base/ExchangeTestBase.java
   trunk/tests/src/org/jboss/test/messaging/jms/util/
   trunk/tests/src/org/jboss/test/messaging/jms/util/MessageQueueNameHelperTest.java
Removed:
   trunk/src/etc/xmdesc/JDBCChannelMapper-xmbean.xml
   trunk/src/etc/xmdesc/SimpleMessageStore-xmbean.xml
   trunk/src/main/org/jboss/jms/server/DurableSubscriptionHolder.java
   trunk/src/main/org/jboss/jms/server/plugin/JDBCChannelMapper.java
   trunk/src/main/org/jboss/jms/server/plugin/contract/ChannelMapper.java
   trunk/src/main/org/jboss/jms/server/plugin/contract/LazyLoadingDelegate.java
   trunk/src/main/org/jboss/jms/server/subscription/
   trunk/src/main/org/jboss/jms/util/RendezVous.java
   trunk/src/main/org/jboss/jms/util/SafeUTF.java
   trunk/src/main/org/jboss/messaging/core/RouterSupport.java
   trunk/src/main/org/jboss/messaging/core/SingleReceiverDelivery.java
   trunk/src/main/org/jboss/messaging/core/StatefulReceiverDelivery.java
   trunk/src/main/org/jboss/messaging/core/distributed/
   trunk/src/main/org/jboss/messaging/core/local/CoreDestination.java
   trunk/src/main/org/jboss/messaging/core/local/CoreSubscription.java
   trunk/src/main/org/jboss/messaging/core/local/Pipe.java
   trunk/src/main/org/jboss/messaging/core/local/PointToMultipointRouter.java
   trunk/src/main/org/jboss/messaging/core/local/Queue.java
   trunk/src/main/org/jboss/messaging/core/local/SingleDestinationRouter.java
   trunk/src/main/org/jboss/messaging/core/local/Topic.java
   trunk/src/main/org/jboss/messaging/core/persistence/JDBCUtil.java
   trunk/src/main/org/jboss/messaging/core/util/ConcurrentHashSet.java
   trunk/src/main/org/jboss/messaging/core/util/ConcurrentReaderHashSet.java
   trunk/src/main/org/jboss/messaging/core/util/Lockable.java
   trunk/tests/src/org/jboss/test/messaging/core/ChannelSupportTest.java
   trunk/tests/src/org/jboss/test/messaging/core/DistributorTest.java
   trunk/tests/src/org/jboss/test/messaging/core/LocalPipeAsChannelTest.java
   trunk/tests/src/org/jboss/test/messaging/core/LocalQueueAsChannelTest.java
   trunk/tests/src/org/jboss/test/messaging/core/LocalQueueAsDistributorTest.java
   trunk/tests/src/org/jboss/test/messaging/core/LocalTopicAsChannelTest.java
   trunk/tests/src/org/jboss/test/messaging/core/LocalTopicAsDistributorTest.java
   trunk/tests/src/org/jboss/test/messaging/core/PointToMultipointRouterAsDistributorTest.java
   trunk/tests/src/org/jboss/test/messaging/core/PointToPointRouterAsDistributorTest.java
   trunk/tests/src/org/jboss/test/messaging/core/ReplicatorOutputDeliveryTest.java
   trunk/tests/src/org/jboss/test/messaging/core/SingleOutputChannelSupportTest.java
   trunk/tests/src/org/jboss/test/messaging/core/TransactionalChannelSupportTest.java
   trunk/tests/src/org/jboss/test/messaging/core/base/ChannelTestBase.java
   trunk/tests/src/org/jboss/test/messaging/core/base/DeliveryTestBase.java
   trunk/tests/src/org/jboss/test/messaging/core/base/NoTestsChannelTestBase.java
   trunk/tests/src/org/jboss/test/messaging/core/base/SingleReceiverDeliveryTestBase.java
   trunk/tests/src/org/jboss/test/messaging/core/distributed/
   trunk/tests/src/org/jboss/test/messaging/core/local/NonRecoverableQueueTest.java
   trunk/tests/src/org/jboss/test/messaging/core/local/NonRecoverableSubscriptionTest.java
   trunk/tests/src/org/jboss/test/messaging/core/local/RecoverableQueueTest.java
   trunk/tests/src/org/jboss/test/messaging/core/local/RecoverableSubscriptionTest.java
   trunk/tests/src/org/jboss/test/messaging/core/local/SubscriptionWithFilterTest.java
   trunk/tests/src/org/jboss/test/messaging/core/local/TopicTest.java
   trunk/tests/src/org/jboss/test/messaging/core/local/base/QueueTestBase.java
   trunk/tests/src/org/jboss/test/messaging/core/local/base/TopicTestBase.java
   trunk/tests/src/org/jboss/test/messaging/core/plugin/MessageStoreWithPersistenceManagerTest.java
   trunk/tests/src/org/jboss/test/messaging/core/plugin/MessageStoreWithoutPersistenceManagerTest.java
   trunk/tests/src/org/jboss/test/messaging/jms/server/plugin/JDBCChannelMapperTest.java
Modified:
   trunk/.classpath
   trunk/build-messaging.xml
   trunk/build-thirdparty.xml
   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/server/default/deploy/oracle-persistence-service.xml
   trunk/src/etc/server/default/deploy/postgresql-persistence-service.xml
   trunk/src/etc/server/default/deploy/sybase-persistence-service.xml
   trunk/src/etc/xmdesc/JDBCPersistenceManager-xmbean.xml
   trunk/src/etc/xmdesc/ServerPeer-xmbean.xml
   trunk/src/main/org/jboss/jms/destination/JBossDestination.java
   trunk/src/main/org/jboss/jms/destination/JBossQueue.java
   trunk/src/main/org/jboss/jms/destination/JBossTemporaryTopic.java
   trunk/src/main/org/jboss/jms/destination/JBossTopic.java
   trunk/src/main/org/jboss/jms/message/JBossTextMessage.java
   trunk/src/main/org/jboss/jms/selector/Selector.java
   trunk/src/main/org/jboss/jms/server/ConnectionFactoryManager.java
   trunk/src/main/org/jboss/jms/server/DestinationJNDIMapper.java
   trunk/src/main/org/jboss/jms/server/DestinationManager.java
   trunk/src/main/org/jboss/jms/server/ServerPeer.java
   trunk/src/main/org/jboss/jms/server/Version.java
   trunk/src/main/org/jboss/jms/server/connectionfactory/ConnectionFactory.java
   trunk/src/main/org/jboss/jms/server/destination/DestinationServiceSupport.java
   trunk/src/main/org/jboss/jms/server/destination/Queue.java
   trunk/src/main/org/jboss/jms/server/destination/Topic.java
   trunk/src/main/org/jboss/jms/server/endpoint/ServerBrowserEndpoint.java
   trunk/src/main/org/jboss/jms/server/endpoint/ServerConnectionEndpoint.java
   trunk/src/main/org/jboss/jms/server/endpoint/ServerConnectionFactoryEndpoint.java
   trunk/src/main/org/jboss/jms/server/endpoint/ServerConsumerEndpoint.java
   trunk/src/main/org/jboss/jms/server/endpoint/ServerSessionEndpoint.java
   trunk/src/main/org/jboss/jms/tx/MessagingXAResource.java
   trunk/src/main/org/jboss/jms/tx/ResourceManager.java
   trunk/src/main/org/jboss/jms/tx/TransactionRequest.java
   trunk/src/main/org/jboss/jms/util/MessagingXAException.java
   trunk/src/main/org/jboss/messaging/core/ChannelSupport.java
   trunk/src/main/org/jboss/messaging/core/Delivery.java
   trunk/src/main/org/jboss/messaging/core/Filter.java
   trunk/src/main/org/jboss/messaging/core/MessageReference.java
   trunk/src/main/org/jboss/messaging/core/Router.java
   trunk/src/main/org/jboss/messaging/core/SimpleDelivery.java
   trunk/src/main/org/jboss/messaging/core/local/FirstReceiverPointToPointRouter.java
   trunk/src/main/org/jboss/messaging/core/local/RoundRobinPointToPointRouter.java
   trunk/src/main/org/jboss/messaging/core/message/RoutableSupport.java
   trunk/src/main/org/jboss/messaging/core/plugin/JDBCPersistenceManager.java
   trunk/src/main/org/jboss/messaging/core/plugin/SimpleMessageReference.java
   trunk/src/main/org/jboss/messaging/core/plugin/SimpleMessageStore.java
   trunk/src/main/org/jboss/messaging/core/plugin/contract/MessageStore.java
   trunk/src/main/org/jboss/messaging/core/plugin/contract/PersistenceManager.java
   trunk/src/main/org/jboss/messaging/core/tx/TransactionRepository.java
   trunk/src/main/org/jboss/messaging/core/tx/XidImpl.java
   trunk/src/main/org/jboss/messaging/util/RotatingPool.java
   trunk/tests/build.xml
   trunk/tests/src/org/jboss/test/messaging/MessagingTestCase.java
   trunk/tests/src/org/jboss/test/messaging/core/SimpleDeliveryTest.java
   trunk/tests/src/org/jboss/test/messaging/core/SimpleFilter.java
   trunk/tests/src/org/jboss/test/messaging/core/SimpleReceiver.java
   trunk/tests/src/org/jboss/test/messaging/core/local/RoundRobinPointToPointRouterTest.java
   trunk/tests/src/org/jboss/test/messaging/core/message/JBossMessageTest.java
   trunk/tests/src/org/jboss/test/messaging/core/message/SimpleMessageReferenceTest.java
   trunk/tests/src/org/jboss/test/messaging/core/message/base/MessageSupportTestBase.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/PagingTest.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/persistence/JDBCUtilTest.java
   trunk/tests/src/org/jboss/test/messaging/core/plugin/JDBCPersistenceManagerTest.java
   trunk/tests/src/org/jboss/test/messaging/core/plugin/base/MessageStoreTestBase.java
   trunk/tests/src/org/jboss/test/messaging/jms/AcknowledgmentTest.java
   trunk/tests/src/org/jboss/test/messaging/jms/CTSMiscellaneousTest.java
   trunk/tests/src/org/jboss/test/messaging/jms/ConnectionFactoryTest.java
   trunk/tests/src/org/jboss/test/messaging/jms/DurableSubscriberTest.java
   trunk/tests/src/org/jboss/test/messaging/jms/MessageConsumerTest.java
   trunk/tests/src/org/jboss/test/messaging/jms/MessageProxyTest.java
   trunk/tests/src/org/jboss/test/messaging/jms/MultipleServerInvocationHandlersTest.java
   trunk/tests/src/org/jboss/test/messaging/jms/PersistenceTest.java
   trunk/tests/src/org/jboss/test/messaging/jms/QueueRequestorTest.java
   trunk/tests/src/org/jboss/test/messaging/jms/String64KLimitTest.java
   trunk/tests/src/org/jboss/test/messaging/jms/XARecoveryTest.java
   trunk/tests/src/org/jboss/test/messaging/jms/XATest.java
   trunk/tests/src/org/jboss/test/messaging/jms/message/JMSReplyToHeaderTest.java
   trunk/tests/src/org/jboss/test/messaging/jms/message/JMSXDeliveryCountTest.java
   trunk/tests/src/org/jboss/test/messaging/jms/message/MessageBodyTest.java
   trunk/tests/src/org/jboss/test/messaging/jms/message/ObjectMessageDeliveryTest.java
   trunk/tests/src/org/jboss/test/messaging/jms/persistence/MessagePersistenceManagerTest.java
   trunk/tests/src/org/jboss/test/messaging/jms/server/connectionfactory/ConnectionFactoryTest.java
   trunk/tests/src/org/jboss/test/messaging/jms/server/connectormanager/SimpleConnectorManagerTest.java
   trunk/tests/src/org/jboss/test/messaging/jms/server/destination/base/DestinationManagementTestBase.java
   trunk/tests/src/org/jboss/test/messaging/tools/ServerManagement.java
   trunk/tests/src/org/jboss/test/messaging/tools/jmx/rmi/LocalTestServer.java
   trunk/tests/src/org/jboss/test/messaging/tools/jmx/rmi/RMITestServer.java
   trunk/tests/src/org/jboss/test/messaging/tools/jmx/rmi/RemoteTestServer.java
   trunk/tests/src/org/jboss/test/messaging/tools/jmx/rmi/Server.java
Log:

Initial commit for clustering



Modified: trunk/.classpath
===================================================================
--- trunk/.classpath	2006-08-30 09:26:13 UTC (rev 1236)
+++ trunk/.classpath	2006-08-30 18:36:36 UTC (rev 1237)
@@ -1,15 +1,6 @@
 <?xml version="1.0" encoding="UTF-8"?>
 <classpath>
 	<classpathentry excluding="**/.svn/**/*" kind="src" path="perf/src"/>
-	<classpathentry kind="src" path="docs/examples/bmt/src"/>
-	<classpathentry kind="src" path="docs/examples/common/src"/>
-	<classpathentry kind="src" path="docs/examples/ejb3mdb/src"/>
-	<classpathentry kind="src" path="docs/examples/http/src"/>
-	<classpathentry kind="src" path="docs/examples/mdb/src"/>
-	<classpathentry kind="src" path="docs/examples/queue/src"/>
-	<classpathentry kind="src" path="docs/examples/secure-socket/src"/>
-	<classpathentry kind="src" path="docs/examples/stateless/src"/>
-	<classpathentry kind="src" path="docs/examples/topic/src"/>
 	<classpathentry kind="src" path="output/gen-parsers"/>
 	<classpathentry excluding="**/.svn/**/*" kind="src" path="src/main"/>
 	<classpathentry excluding="**/.svn/**/*" kind="src" path="tests/src"/>

Modified: trunk/build-messaging.xml
===================================================================
--- trunk/build-messaging.xml	2006-08-30 09:26:13 UTC (rev 1236)
+++ trunk/build-messaging.xml	2006-08-30 18:36:36 UTC (rev 1237)
@@ -134,7 +134,7 @@
         They must available in the repository and declared as <componentrefs> in build-thirdparty.xml.
    -->
    <path id="external.dependencies.classpath">
-      <!-- <path refid="apache.commons.classpath"/> -->
+      <path refid="apache.logging.classpath"/>
       <path refid="oswego.concurrent.classpath"/>
       <path refid="javassist.classpath"/>
       <path refid="jgroups.jgroups.classpath"/>

Modified: trunk/build-thirdparty.xml
===================================================================
--- trunk/build-thirdparty.xml	2006-08-30 09:26:13 UTC (rev 1236)
+++ trunk/build-thirdparty.xml	2006-08-30 18:36:36 UTC (rev 1237)
@@ -78,7 +78,7 @@
 
 
       <!--
-           Dependencies requrired to build the project.
+           Dependencies required to build the project.
       -->
       <componentref name="retrotranslator" version="0.9.6jboss"/>
       <componentref name="sun-javacc" version="3.2"/>

Modified: trunk/src/etc/server/default/deploy/hsqldb-persistence-service.xml
===================================================================
--- trunk/src/etc/server/default/deploy/hsqldb-persistence-service.xml	2006-08-30 09:26:13 UTC (rev 1236)
+++ trunk/src/etc/server/default/deploy/hsqldb-persistence-service.xml	2006-08-30 18:36:36 UTC (rev 1237)
@@ -16,15 +16,14 @@
       -->
       <depends>jboss.jca:service=DataSourceBinding,name=DefaultDS</depends>
       <depends optional-attribute-name="TransactionManager">jboss:service=TransactionManager</depends>
-      <depends optional-attribute-name="ChannelMapper">jboss.messaging:service=ChannelMapper</depends>
       <attribute name="DataSource">java:/DefaultDS</attribute>
       <attribute name="CreateTablesOnStartup">true</attribute>
       <attribute name="UsingBatchUpdates">true</attribute>
    </mbean>
 
-   <mbean code="org.jboss.jms.server.plugin.JDBCChannelMapper"
-      name="jboss.messaging:service=ChannelMapper"
-      xmbean-dd="xmdesc/JDBCChannelMapper-xmbean.xml">
+   <mbean code="org.jboss.messaging.core.plugin.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
            the DataSource JNDI name in order to actually get a reference to it. Fix this.
       -->   
@@ -32,6 +31,30 @@
       <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.messaging.core.plugin.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
+           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> 
+   
+   <mbean code="org.jboss.jms.server.plugin.JDBCJMSUserManager"
+      name="jboss.messaging:service=JMSUserManager"
+      xmbean-dd="xmdesc/JMSUserManager-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/server/default/deploy/messaging-service.xml
===================================================================
--- trunk/src/etc/server/default/deploy/messaging-service.xml	2006-08-30 09:26:13 UTC (rev 1236)
+++ trunk/src/etc/server/default/deploy/messaging-service.xml	2006-08-30 18:36:36 UTC (rev 1237)
@@ -22,8 +22,9 @@
       </constructor>
 
       <depends optional-attribute-name="PersistenceManager">jboss.messaging:service=PersistenceManager</depends>
-      <depends optional-attribute-name="MessageStore">jboss.messaging:service=MessageStore</depends>
-      <depends optional-attribute-name="ChannelMapper">jboss.messaging:service=ChannelMapper</depends>
+      <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>
 
       <!-- Set to -1 to completely disable client leasing -->
       <attribute name="SecurityDomain">java:/jaas/messaging</attribute>
@@ -34,15 +35,4 @@
       </attribute>
    </mbean>
 
-   <!-- Plug-ins -->
-
-   <mbean code="org.jboss.messaging.core.plugin.SimpleMessageStore"
-      name="jboss.messaging:service=MessageStore"
-      xmbean-dd="xmdesc/SimpleMessageStore-xmbean.xml">
-      <constructor>
-         <!-- StoreID -->
-         <arg type="java.lang.String" value="store.0" />
-      </constructor>      
-   </mbean>
-
 </server>
\ No newline at end of file

Modified: trunk/src/etc/server/default/deploy/mysql-persistence-service.xml
===================================================================
--- trunk/src/etc/server/default/deploy/mysql-persistence-service.xml	2006-08-30 09:26:13 UTC (rev 1236)
+++ trunk/src/etc/server/default/deploy/mysql-persistence-service.xml	2006-08-30 18:36:36 UTC (rev 1237)
@@ -13,7 +13,6 @@
       xmbean-dd="xmdesc/JDBCPersistenceManager-xmbean.xml">      
       <depends>jboss.jca:service=DataSourceBinding,name=DefaultDS</depends>
       <depends optional-attribute-name="TransactionManager">jboss:service=TransactionManager</depends>
-      <depends optional-attribute-name="ChannelMapper">jboss.messaging:service=ChannelMapper</depends>
       <attribute name="DataSource">java:/DefaultDS</attribute>
       <attribute name="CreateTablesOnStartup">true</attribute>
       <attribute name="UsingBatchUpdates">true</attribute>      
@@ -61,9 +60,9 @@
       <attribute name="MaxParams">500</attribute>
    </mbean>
       
-   <mbean code="org.jboss.jms.server.plugin.JDBCChannelMapper"
-      name="jboss.messaging:service=ChannelMapper"
-      xmbean-dd="xmdesc/JDBCChannelMapper-xmbean.xml">
+   <mbean code="org.jboss.messaging.core.plugin.DirectExchange"
+      name="jboss.messaging:service=DirectExchange"
+      xmbean-dd="xmdesc/Exchange-xmbean.xml">
       <depends>jboss.jca:service=DataSourceBinding,name=DefaultDS</depends>
       <depends optional-attribute-name="TransactionManager">jboss:service=TransactionManager</depends>
       <attribute name="DataSource">java:/DefaultDS</attribute>
@@ -80,5 +79,37 @@
 SELECT_SUBSCRIPTIONS_FOR_TOPIC=SELECT ID, CLIENT_ID, JMS_SUB_NAME, SELECTOR, NO_LOCAL FROM JMS_CHANNEL_MAPPING WHERE TYPE='D' AND JMS_DEST_NAME=?      
       ]]></attribute>
    </mbean>
+   
+   <mbean code="org.jboss.messaging.core.plugin.TopicExchange"
+      name="jboss.messaging:service=TopicExchange"
+      xmbean-dd="xmdesc/Exchange-xmbean.xml">
+      <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>
+      <attribute name="SqlProperties"><![CDATA[
+CREATE_USER_TABLE=CREATE TABLE JMS_USER (USERID VARCHAR(32) NOT NULL, PASSWD VARCHAR(32) NOT NULL, CLIENTID VARCHAR(128), PRIMARY KEY(USERID))
+CREATE_ROLE_TABLE=CREATE TABLE JMS_ROLE (ROLEID VARCHAR(32) NOT NULL, USERID VARCHAR(32) NOT NULL, PRIMARY KEY(USERID, ROLEID))      
+SELECT_PRECONF_CLIENTID=SELECT CLIENTID FROM JMS_USER WHERE USERID=?
+CREATE_MAPPING_TABLE=CREATE TABLE JMS_CHANNEL_MAPPING (ID BIGINT, TYPE CHAR(1), JMS_DEST_NAME VARCHAR(1024), JMS_SUB_NAME VARCHAR(1024), CLIENT_ID VARCHAR(128), SELECTOR VARCHAR(1024), NO_LOCAL CHAR(1), PRIMARY KEY(ID))      
+INSERT_MAPPING=INSERT INTO JMS_CHANNEL_MAPPING (ID, TYPE, JMS_DEST_NAME, JMS_SUB_NAME, CLIENT_ID, SELECTOR, NO_LOCAL) VALUES (?, ?, ?, ?, ?, ?, ?)
+DELETE_MAPPING=DELETE FROM JMS_CHANNEL_MAPPING WHERE ID = ?
+SELECT_ID_FOR_DESTINATION=SELECT ID FROM JMS_CHANNEL_MAPPING WHERE TYPE=? AND JMS_DEST_NAME=?
+SELECT_DURABLE_SUB=SELECT JMS_DEST_NAME, ID, SELECTOR, NO_LOCAL FROM JMS_CHANNEL_MAPPING WHERE CLIENT_ID=? AND JMS_SUB_NAME=?            
+SELECT_SUBSCRIPTIONS_FOR_TOPIC=SELECT ID, CLIENT_ID, JMS_SUB_NAME, SELECTOR, NO_LOCAL FROM JMS_CHANNEL_MAPPING WHERE TYPE='D' AND JMS_DEST_NAME=?      
+      ]]></attribute>
+   </mbean>   
+   
+   <mbean code="org.jboss.jms.server.plugin.JDBCJMSUserManager"
+      name="jboss.messaging:service=JMSUserManager"
+      xmbean-dd="xmdesc/JMSUserManager-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/server/default/deploy/oracle-persistence-service.xml
===================================================================
--- trunk/src/etc/server/default/deploy/oracle-persistence-service.xml	2006-08-30 09:26:13 UTC (rev 1236)
+++ trunk/src/etc/server/default/deploy/oracle-persistence-service.xml	2006-08-30 18:36:36 UTC (rev 1237)
@@ -61,9 +61,9 @@
       <attribute name="MaxParams">500</attribute>
    </mbean>      
       
-   <mbean code="org.jboss.jms.server.plugin.JDBCChannelMapper"
-      name="jboss.messaging:service=ChannelMapper"
-      xmbean-dd="xmdesc/JDBCChannelMapper-xmbean.xml">
+   <mbean code="org.jboss.messaging.core.plugin.DirectExchange"
+      name="jboss.messaging:service=DirectExchange"
+      xmbean-dd="xmdesc/Exchange-xmbean.xml">
       <depends>jboss.jca:service=DataSourceBinding,name=DefaultDS</depends>
       <depends optional-attribute-name="TransactionManager">jboss:service=TransactionManager</depends>
       <attribute name="DataSource">java:/DefaultDS</attribute>
@@ -80,4 +80,36 @@
 SELECT_SUBSCRIPTIONS_FOR_TOPIC=SELECT ID, CLIENT_ID, JMS_SUB_NAME, SELECTOR, NO_LOCAL FROM JMS_CHANNEL_MAPPING WHERE TYPE='D' AND JMS_DEST_NAME=?      
       ]]></attribute>
    </mbean>
+   
+   <mbean code="org.jboss.messaging.core.plugin.TopicExchange"
+      name="jboss.messaging:service=TopicExchange"
+      xmbean-dd="xmdesc/Exchange-xmbean.xml">
+      <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>
+      <attribute name="SqlProperties"><![CDATA[
+CREATE_USER_TABLE=CREATE TABLE JMS_USER (USERID VARCHAR2(32) NOT NULL, PASSWD VARCHAR2(32) NOT NULL, CLIENTID VARCHAR2(128), PRIMARY KEY(USERID))
+CREATE_ROLE_TABLE=CREATE TABLE JMS_ROLE (ROLEID VARCHAR2(32) NOT NULL, USERID VARCHAR2(32) NOT NULL, PRIMARY KEY(USERID, ROLEID))      
+SELECT_PRECONF_CLIENTID=SELECT CLIENTID FROM JMS_USER WHERE USERID=?
+CREATE_MAPPING_TABLE=CREATE TABLE JMS_CHANNEL_MAPPING (ID INTEGER, TYPE CHAR(1), JMS_DEST_NAME VARCHAR2(1024), JMS_SUB_NAME VARCHAR2(1024), CLIENT_ID VARCHAR2(128), SELECTOR VARCHAR2(1024), NO_LOCAL CHAR(1), PRIMARY KEY(ID))      
+INSERT_MAPPING=INSERT INTO JMS_CHANNEL_MAPPING (ID, TYPE, JMS_DEST_NAME, JMS_SUB_NAME, CLIENT_ID, SELECTOR, NO_LOCAL) VALUES (?, ?, ?, ?, ?, ?, ?)
+DELETE_MAPPING=DELETE FROM JMS_CHANNEL_MAPPING WHERE ID = ?
+SELECT_ID_FOR_DESTINATION=SELECT ID FROM JMS_CHANNEL_MAPPING WHERE TYPE=? AND JMS_DEST_NAME=?
+SELECT_DURABLE_SUB=SELECT JMS_DEST_NAME, ID, SELECTOR, NO_LOCAL FROM JMS_CHANNEL_MAPPING WHERE CLIENT_ID=? AND JMS_SUB_NAME=?            
+SELECT_SUBSCRIPTIONS_FOR_TOPIC=SELECT ID, CLIENT_ID, JMS_SUB_NAME, SELECTOR, NO_LOCAL FROM JMS_CHANNEL_MAPPING WHERE TYPE='D' AND JMS_DEST_NAME=?      
+      ]]></attribute>
+   </mbean>   
+   
+   <mbean code="org.jboss.jms.server.plugin.JDBCJMSUserManager"
+      name="jboss.messaging:service=JMSUserManager"
+      xmbean-dd="xmdesc/JMSUserManager-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/server/default/deploy/postgresql-persistence-service.xml
===================================================================
--- trunk/src/etc/server/default/deploy/postgresql-persistence-service.xml	2006-08-30 09:26:13 UTC (rev 1236)
+++ trunk/src/etc/server/default/deploy/postgresql-persistence-service.xml	2006-08-30 18:36:36 UTC (rev 1237)
@@ -61,9 +61,9 @@
       <attribute name="MaxParams">500</attribute>
    </mbean>
 
-   <mbean code="org.jboss.jms.server.plugin.JDBCChannelMapper"
-          name="jboss.messaging:service=ChannelMapper"
-          xmbean-dd="xmdesc/JDBCChannelMapper-xmbean.xml">
+   <mbean code="org.jboss.messaging.core.plugin.DirectExchange"
+      name="jboss.messaging:service=DirectExchange"
+      xmbean-dd="xmdesc/Exchange-xmbean.xml">
       <depends>jboss.jca:service=DataSourceBinding,name=DefaultDS</depends>
       <depends optional-attribute-name="TransactionManager">jboss:service=TransactionManager</depends>
       <attribute name="DataSource">java:/DefaultDS</attribute>
@@ -80,5 +80,37 @@
 SELECT_SUBSCRIPTIONS_FOR_TOPIC=SELECT ID, CLIENT_ID, JMS_SUB_NAME, SELECTOR, NO_LOCAL FROM JMS_CHANNEL_MAPPING WHERE TYPE='D' AND JMS_DEST_NAME=?
            ]]></attribute>
    </mbean>
+   
+   <mbean code="org.jboss.messaging.core.plugin.TopicExchange"
+      name="jboss.messaging:service=TopicExchange"
+      xmbean-dd="xmdesc/Exchange-xmbean.xml">
+      <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>
+      <attribute name="SqlProperties"><![CDATA[
+CREATE_USER_TABLE=CREATE TABLE JMS_USER (USERID VARCHAR(32) NOT NULL, PASSWD VARCHAR(32) NOT NULL, CLIENTID VARCHAR(128), PRIMARY KEY(USERID))
+CREATE_ROLE_TABLE=CREATE TABLE JMS_ROLE (ROLEID VARCHAR(32) NOT NULL, USERID VARCHAR(32) NOT NULL, PRIMARY KEY(USERID, ROLEID))
+SELECT_PRECONF_CLIENTID=SELECT CLIENTID FROM JMS_USER WHERE USERID=?
+CREATE_MAPPING_TABLE=CREATE TABLE JMS_CHANNEL_MAPPING (ID BIGINT, TYPE CHAR(1), JMS_DEST_NAME VARCHAR(1024), JMS_SUB_NAME VARCHAR(1024), CLIENT_ID VARCHAR(128), SELECTOR VARCHAR(1024), NO_LOCAL CHAR(1), PRIMARY KEY(ID))
+INSERT_MAPPING=INSERT INTO JMS_CHANNEL_MAPPING (ID, TYPE, JMS_DEST_NAME, JMS_SUB_NAME, CLIENT_ID, SELECTOR, NO_LOCAL) VALUES (?, ?, ?, ?, ?, ?, ?)
+DELETE_MAPPING=DELETE FROM JMS_CHANNEL_MAPPING WHERE ID = ?
+SELECT_ID_FOR_DESTINATION=SELECT ID FROM JMS_CHANNEL_MAPPING WHERE TYPE=? AND JMS_DEST_NAME=?
+SELECT_DURABLE_SUB=SELECT JMS_DEST_NAME, ID, SELECTOR, NO_LOCAL FROM JMS_CHANNEL_MAPPING WHERE CLIENT_ID=? AND JMS_SUB_NAME=?
+SELECT_SUBSCRIPTIONS_FOR_TOPIC=SELECT ID, CLIENT_ID, JMS_SUB_NAME, SELECTOR, NO_LOCAL FROM JMS_CHANNEL_MAPPING WHERE TYPE='D' AND JMS_DEST_NAME=?
+           ]]></attribute>
+   </mbean>   
+   
+   <mbean code="org.jboss.jms.server.plugin.JDBCJMSUserManager"
+      name="jboss.messaging:service=JMSUserManager"
+      xmbean-dd="xmdesc/JMSUserManager-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/server/default/deploy/sybase-persistence-service.xml
===================================================================
--- trunk/src/etc/server/default/deploy/sybase-persistence-service.xml	2006-08-30 09:26:13 UTC (rev 1236)
+++ trunk/src/etc/server/default/deploy/sybase-persistence-service.xml	2006-08-30 18:36:36 UTC (rev 1237)
@@ -69,9 +69,9 @@
 		</attribute>
 	</mbean>
 
-	<mbean code="org.jboss.jms.server.plugin.JDBCChannelMapper"
-          name="jboss.messaging:service=ChannelMapper"
-          xmbean-dd="xmdesc/JDBCChannelMapper-xmbean.xml">
+   <mbean code="org.jboss.messaging.core.plugin.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
            the DataSource JNDI name in order to actually get a reference to it. Fix this.
       -->
@@ -93,4 +93,41 @@
       ]]>
 		</attribute>
 	</mbean>
+	
+	<mbean code="org.jboss.messaging.core.plugin.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
+           the DataSource JNDI name in order to actually get a reference to it. Fix this.
+      -->
+		<depends>jboss.jca:service=DataSourceBinding,name=SybaseDS</depends>
+		<depends optional-attribute-name="TransactionManager">jboss:service=TransactionManager</depends>
+		<attribute name="DataSource">SybaseDS</attribute>
+      <attribute name="CreateTablesOnStartup">true</attribute>
+
+      <attribute name="SqlProperties"><![CDATA[
+CREATE_USER_TABLE=CREATE TABLE JMS_USER (USERID VARCHAR(32) NOT NULL, PASSWD VARCHAR(32) NOT NULL, CLIENTID VARCHAR(128) NULL, PRIMARY KEY(USERID))
+CREATE_ROLE_TABLE=CREATE TABLE JMS_ROLE (ROLEID VARCHAR(32) NOT NULL, USERID VARCHAR(32) NOT NULL, PRIMARY KEY(USERID, ROLEID))
+SELECT_PRECONF_CLIENTID=SELECT CLIENTID FROM JMS_USER WHERE USERID=?
+CREATE_MAPPING_TABLE=CREATE TABLE JMS_CHANNEL_MAPPING (ID INTEGER, TYPE CHAR(1) NULL, JMS_DEST_NAME VARCHAR(1024) NULL, JMS_SUB_NAME VARCHAR(1024) NULL, CLIENT_ID VARCHAR(128) NULL, SELECTOR VARCHAR(1024) NULL, NO_LOCAL CHAR(1) NULL, PRIMARY KEY(ID))
+INSERT_MAPPING=INSERT INTO JMS_CHANNEL_MAPPING (ID, TYPE, JMS_DEST_NAME, JMS_SUB_NAME, CLIENT_ID, SELECTOR, NO_LOCAL) VALUES (?, ?, ?, ?, ?, ?, ?)
+DELETE_MAPPING=DELETE FROM JMS_CHANNEL_MAPPING WHERE ID = ?
+SELECT_ID_FOR_DESTINATION=SELECT ID FROM JMS_CHANNEL_MAPPING WHERE TYPE=? AND JMS_DEST_NAME=?
+SELECT_DURABLE_SUB=SELECT JMS_DEST_NAME, ID, SELECTOR, NO_LOCAL FROM JMS_CHANNEL_MAPPING WHERE CLIENT_ID=? AND JMS_SUB_NAME=?
+SELECT_SUBSCRIPTIONS_FOR_TOPIC=SELECT ID, CLIENT_ID, JMS_SUB_NAME, SELECTOR, NO_LOCAL FROM JMS_CHANNEL_MAPPING WHERE TYPE='D' AND JMS_DEST_NAME=?      
+      ]]>
+		</attribute>
+	</mbean>
+	
+   <mbean code="org.jboss.jms.server.plugin.JDBCJMSUserManager"
+      name="jboss.messaging:service=JMSUserManager"
+      xmbean-dd="xmdesc/JMSUserManager-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>

Added: trunk/src/etc/xmdesc/Exchange-xmbean.xml
===================================================================
--- trunk/src/etc/xmdesc/Exchange-xmbean.xml	2006-08-30 09:26:13 UTC (rev 1236)
+++ trunk/src/etc/xmdesc/Exchange-xmbean.xml	2006-08-30 18:36:36 UTC (rev 1237)
@@ -0,0 +1,80 @@
+<?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>An exchange</description>
+   <class>org.jboss.messaging.core.plugin.ExchangeSupport</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>
+
+   <!-- This operation was introduced for testing purposes. If more useful operations with a
+        similar semantics are added here, use those instead of this one
+   -->
+   
+   <operation>
+      <description>Returns the set of durable subscription names corresponding to the given clientID</description>
+      <name>getSubscriptions</name>
+      <parameter>
+         <name>clientID</name>
+         <type>java.lang.String</type>
+      </parameter>
+      <return-type>java.util.Set</return-type>
+   </operation>
+      
+</mbean>
\ No newline at end of file

Deleted: trunk/src/etc/xmdesc/JDBCChannelMapper-xmbean.xml
===================================================================
--- trunk/src/etc/xmdesc/JDBCChannelMapper-xmbean.xml	2006-08-30 09:26:13 UTC (rev 1236)
+++ trunk/src/etc/xmdesc/JDBCChannelMapper-xmbean.xml	2006-08-30 18:36:36 UTC (rev 1237)
@@ -1,80 +0,0 @@
-<?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 channel mapper</description>
-   <class>org.jboss.jms.server.plugin.JDBCChannelMapper</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>
-
-   <!-- This operation was introduced for testing purposes. If more useful operations with a
-        similar semantics are added here, use those instead of this one
-   -->
-   
-   <operation>
-      <description>Returns the set of durable subscription names corresponding to the given clientID</description>
-      <name>getSubscriptions</name>
-      <parameter>
-         <name>clientID</name>
-         <type>java.lang.String</type>
-      </parameter>
-      <return-type>java.util.Set</return-type>
-   </operation>
-      
-</mbean>
\ No newline at end of file

Modified: trunk/src/etc/xmdesc/JDBCPersistenceManager-xmbean.xml
===================================================================
--- trunk/src/etc/xmdesc/JDBCPersistenceManager-xmbean.xml	2006-08-30 09:26:13 UTC (rev 1236)
+++ trunk/src/etc/xmdesc/JDBCPersistenceManager-xmbean.xml	2006-08-30 18:36:36 UTC (rev 1237)
@@ -30,13 +30,7 @@
       <name>TransactionManager</name>
       <type>javax.management.ObjectName</type>
    </attribute>
-   
-   <attribute access="read-write" getMethod="getChannelMapper" setMethod="setChannelMapper">
-      <description>The ObjectName of the ChannelMapper used by this persistence manager</description>
-      <name>ChannelMapper</name>
-      <type>javax.management.ObjectName</type>
-   </attribute>   
-    
+     
    <attribute access="read-write" getMethod="isCreateTablesOnStartup" setMethod="setCreateTablesOnStartup">
       <description>Should database tables be created on startup?</description>
       <name>CreateTablesOnStartup</name>

Added: trunk/src/etc/xmdesc/JMSUserManager-xmbean.xml
===================================================================
--- trunk/src/etc/xmdesc/JMSUserManager-xmbean.xml	2006-08-30 09:26:13 UTC (rev 1236)
+++ trunk/src/etc/xmdesc/JMSUserManager-xmbean.xml	2006-08-30 18:36:36 UTC (rev 1237)
@@ -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>An JMS User Manager</description>
+   <class>org.jboss.server.plugin.JDBCJMSUserManager</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/etc/xmdesc/ServerPeer-xmbean.xml
===================================================================
--- trunk/src/etc/xmdesc/ServerPeer-xmbean.xml	2006-08-30 09:26:13 UTC (rev 1236)
+++ trunk/src/etc/xmdesc/ServerPeer-xmbean.xml	2006-08-30 18:36:36 UTC (rev 1237)
@@ -34,17 +34,23 @@
       <type>javax.management.ObjectName</type>
    </attribute>
 
-   <attribute access="read-write" getMethod="getMessageStore" setMethod="setMessageStore">
-      <description>The ObjectName of the message store</description>
-      <name>MessageStore</name>
+   <attribute access="read-write" getMethod="getDirectExchange" setMethod="setDirectExchange">
+      <description>The ObjectName of the direct exchange</description>
+      <name>DirectExchange</name>
       <type>javax.management.ObjectName</type>
    </attribute>
-
-   <attribute access="read-write" getMethod="getChannelMapper" setMethod="setChannelMapper">
-      <description>The ObjectName of the channel mapper</description>
-      <name>ChannelMapper</name>
+   
+   <attribute access="read-write" getMethod="getTopicExchange" setMethod="setTopicExchange">
+      <description>The ObjectName of the topic exchange</description>
+      <name>TopicExchange</name>
       <type>javax.management.ObjectName</type>
-   </attribute>
+   </attribute>   
+   
+   <attribute access="read-write" getMethod="getJMSUserManager" setMethod="setJMSUserManager">
+      <description>The ObjectName of the jms user manager</description>
+      <name>JMSUserManager</name>
+      <type>javax.management.ObjectName</type>
+   </attribute>   
 
    <!-- instance access -->
 

Deleted: trunk/src/etc/xmdesc/SimpleMessageStore-xmbean.xml
===================================================================
--- trunk/src/etc/xmdesc/SimpleMessageStore-xmbean.xml	2006-08-30 09:26:13 UTC (rev 1236)
+++ trunk/src/etc/xmdesc/SimpleMessageStore-xmbean.xml	2006-08-30 18:36:36 UTC (rev 1237)
@@ -1,58 +0,0 @@
-<?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 paging message store</description>
-   <class>org.jboss.messaging.core.plugin.SimpleMessageStore</class>
-
-   <!-- Managed constructors -->
-
-   <constructor>
-      <name>SimpleMessageStore</name>
-      <parameter>
-         <name>StoreID</name>
-         <type>java.io.Serializable</type>
-      </parameter>
-   </constructor>
-
-   <!-- 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="getPersistenceManager" setMethod="setPersistenceManager">
-      <description>The object name of the persistence manager used by this persistent message store</description>
-      <name>PersistenceManager</name>
-      <type>javax.management.ObjectName</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/destination/JBossDestination.java
===================================================================
--- trunk/src/main/org/jboss/jms/destination/JBossDestination.java	2006-08-30 09:26:13 UTC (rev 1236)
+++ trunk/src/main/org/jboss/jms/destination/JBossDestination.java	2006-08-30 18:36:36 UTC (rev 1237)
@@ -31,6 +31,7 @@
 
 /**
  * @author <a href="mailto:ovidiu at jboss.org">Ovidiu Feodorov</a>
+ * @author <a href="mailto:tim.fox at jboss.com">Tim Fox</a>
  * @version <tt>$Revision$</tt>
  *
  * $Id$
@@ -46,9 +47,24 @@
    // Attributes ----------------------------------------------------
 
    protected String name;
+   
+   //TODO There is probably a better place to put these
+   protected transient int fullSize;
+   
+   protected transient int pageSize;
+   
+   protected transient int downCacheSize;
 
    // Constructors --------------------------------------------------
 
+   public JBossDestination(String name, int fullSize, int pageSize, int downCacheSize)
+   {
+      this(name);
+      this.fullSize = fullSize;
+      this.pageSize = pageSize;
+      this.downCacheSize = downCacheSize;
+   }
+   
    public JBossDestination(String name)
    {
       this.name = name;
@@ -81,7 +97,7 @@
 
    public boolean equals(Object o)
    {
-      if(this == o)
+      if (this == o)
       {
          return true;
       }
@@ -92,20 +108,45 @@
       JBossDestination that = (JBossDestination)o;
       if (name == null)
       {
-         return that.name == null && isTopic() == that.isTopic();
+         return isTopic() == that.isTopic() && that.name == null;
       }
-      return this.name.equals(that.name) && isTopic() == that.isTopic();
+      return isTopic() == that.isTopic() && this.name.equals(that.name);
    }
 
+   //Cache the hashCode
+   private int hash;
+   
    public int hashCode()
    {
-      int code = 0;
-      if (name != null)
+      if (hash != 0)
       {
-         code = name.hashCode();
+         return hash;
       }
-      return code + (isTopic() ? 10 : 20);
+      else
+      {
+         int code = 0;
+         if (name != null)
+         {
+            code = name.hashCode();
+         }
+         return code + (isTopic() ? 37 : 71);
+      }           
    }
+   
+   public int getFullSize()
+   {
+      return fullSize;
+   }
+   
+   public int getPageSize()
+   {
+      return pageSize;
+   }
+   
+   public int getDownCacheSize()
+   {
+      return downCacheSize;
+   }
 
    // Package protected ---------------------------------------------
    

Modified: trunk/src/main/org/jboss/jms/destination/JBossQueue.java
===================================================================
--- trunk/src/main/org/jboss/jms/destination/JBossQueue.java	2006-08-30 09:26:13 UTC (rev 1236)
+++ trunk/src/main/org/jboss/jms/destination/JBossQueue.java	2006-08-30 18:36:36 UTC (rev 1237)
@@ -42,6 +42,11 @@
    
    // Constructors --------------------------------------------------
 
+   public JBossQueue(String name, int fullSize, int pageSize, int downCacheSize)
+   {
+      super(name, fullSize, pageSize, downCacheSize);
+   }
+   
    public JBossQueue(String name)
    {
       super(name);

Modified: trunk/src/main/org/jboss/jms/destination/JBossTemporaryTopic.java
===================================================================
--- trunk/src/main/org/jboss/jms/destination/JBossTemporaryTopic.java	2006-08-30 09:26:13 UTC (rev 1236)
+++ trunk/src/main/org/jboss/jms/destination/JBossTemporaryTopic.java	2006-08-30 18:36:36 UTC (rev 1237)
@@ -53,6 +53,11 @@
       this.delegate = delegate;
    }
    
+   public JBossTemporaryTopic(String name, int fullSize, int pageSize, int downCacheSize)
+   {
+      super(name, fullSize, pageSize, downCacheSize);
+   }
+   
    public JBossTemporaryTopic(String name)
    {
       super(name);

Modified: trunk/src/main/org/jboss/jms/destination/JBossTopic.java
===================================================================
--- trunk/src/main/org/jboss/jms/destination/JBossTopic.java	2006-08-30 09:26:13 UTC (rev 1236)
+++ trunk/src/main/org/jboss/jms/destination/JBossTopic.java	2006-08-30 18:36:36 UTC (rev 1237)
@@ -38,10 +38,15 @@
 
    // Static --------------------------------------------------------
    
-   // Attributes ----------------------------------------------------
+   // Attributes ----------------------------------------------------     
    
    // Constructors --------------------------------------------------
 
+   public JBossTopic(String name, int fullSize, int pageSize, int downCacheSize)
+   {
+      super(name, fullSize, pageSize, downCacheSize);
+   }
+   
    public JBossTopic(String name)
    {
       super(name);

Modified: trunk/src/main/org/jboss/jms/message/JBossTextMessage.java
===================================================================
--- trunk/src/main/org/jboss/jms/message/JBossTextMessage.java	2006-08-30 09:26:13 UTC (rev 1236)
+++ trunk/src/main/org/jboss/jms/message/JBossTextMessage.java	2006-08-30 18:36:36 UTC (rev 1237)
@@ -32,7 +32,7 @@
 import javax.jms.TextMessage;
 
 import org.jboss.jms.destination.JBossDestination;
-import org.jboss.jms.util.SafeUTF;
+import org.jboss.messaging.util.SafeUTF;
 
 /**
  * This class implements javax.jms.TextMessage ported from SpyTextMessage in JBossMQ.

Modified: trunk/src/main/org/jboss/jms/selector/Selector.java
===================================================================
--- trunk/src/main/org/jboss/jms/selector/Selector.java	2006-08-30 09:26:13 UTC (rev 1236)
+++ trunk/src/main/org/jboss/jms/selector/Selector.java	2006-08-30 18:36:36 UTC (rev 1237)
@@ -66,6 +66,14 @@
    public Object result;
    
    private Class resultType;
+   
+   /**
+    * Return the string representation of the selector
+    */
+   public String getFilterString()
+   {
+      return selector;
+   }
 
    /**
     * Get the class that implements the ISelectorParser interface to be used by

Modified: trunk/src/main/org/jboss/jms/server/ConnectionFactoryManager.java
===================================================================
--- trunk/src/main/org/jboss/jms/server/ConnectionFactoryManager.java	2006-08-30 09:26:13 UTC (rev 1236)
+++ trunk/src/main/org/jboss/jms/server/ConnectionFactoryManager.java	2006-08-30 18:36:36 UTC (rev 1237)
@@ -25,6 +25,7 @@
 
 /**
  * @author <a href="mailto:ovidiu at jboss.org">Ovidiu Feodorov</a>
+ * @author <a href="mailto:tim.fox at jboss.com">Tim Fox</a>
  * @version <tt>$Revision$</tt>
  *
  * $Id$

Modified: trunk/src/main/org/jboss/jms/server/DestinationJNDIMapper.java
===================================================================
--- trunk/src/main/org/jboss/jms/server/DestinationJNDIMapper.java	2006-08-30 09:26:13 UTC (rev 1236)
+++ trunk/src/main/org/jboss/jms/server/DestinationJNDIMapper.java	2006-08-30 18:36:36 UTC (rev 1237)
@@ -21,18 +21,18 @@
   */
 package org.jboss.jms.server;
 
-import java.util.Collections;
+import java.util.HashMap;
 import java.util.HashSet;
 import java.util.Iterator;
 import java.util.Map;
 import java.util.Set;
 
-import javax.jms.Destination;
 import javax.jms.InvalidDestinationException;
 import javax.naming.Context;
 import javax.naming.InitialContext;
 import javax.naming.NameNotFoundException;
 
+import org.jboss.jms.destination.JBossDestination;
 import org.jboss.jms.destination.JBossQueue;
 import org.jboss.jms.destination.JBossTopic;
 import org.jboss.jms.util.JNDIUtil;
@@ -40,12 +40,12 @@
 import org.jboss.logging.Logger;
 import org.w3c.dom.Element;
 
-import EDU.oswego.cs.dl.util.concurrent.ConcurrentReaderHashMap;
-
 /**
- * Manages JNDI mapping for JMS destinations
+ * Keeps track of destinations - including temporary destinations
+ * Also manages the mapping of non temporary destinations to JNDI context
  *
  * @author <a href="mailto:ovidiu at jboss.org">Ovidiu Feodorov</a>
+ * @author <a href="mailto:tim.fox at jboss.com">Tim Fox</a>
  * @version <tt>$Revision$</tt>
  *
  * $Id$
@@ -63,141 +63,160 @@
    protected ServerPeer serverPeer;
    protected Context initialContext;
 
-   // <name - JNDI name>
-   protected Map queueNameToJNDI;
-   protected Map topicNameToJNDI;
-
+   // Map <name , destination holder>
+   protected Map queueMap;
+   protected Map topicMap;
+      
    // Constructors --------------------------------------------------
 
    public DestinationJNDIMapper(ServerPeer serverPeer) throws Exception
    {
       this.serverPeer = serverPeer;
-      queueNameToJNDI = new ConcurrentReaderHashMap();
-      topicNameToJNDI = new ConcurrentReaderHashMap();
+      queueMap = new HashMap();
+      topicMap = new HashMap();
    }
    
    // DestinationManager implementation -----------------------------
    
-   public String registerDestination(boolean isQueue, String name, String jndiName,
-                                     Element securityConfiguration) throws Exception
+   public synchronized String registerDestination(JBossDestination destination, String jndiName,
+                                                  Element securityConfiguration) throws Exception
    {            
-      String parentContext;
-      String jndiNameInContext;
-
-      if (jndiName == null)
+      if (!destination.isTemporary())
       {
-         parentContext = isQueue ?
-            serverPeer.getDefaultQueueJNDIContext() : serverPeer.getDefaultTopicJNDIContext();
-
-         jndiNameInContext = name;
-         jndiName = parentContext + "/" + jndiNameInContext;
-      }
-      else
-      {
-         // TODO more solid parsing + test cases
-         int sepIndex = jndiName.lastIndexOf('/');
-         if (sepIndex == -1)
+         String parentContext;
+         String jndiNameInContext;
+   
+         if (jndiName == null)
          {
-            parentContext = "";
+            parentContext = destination.isQueue() ?
+               serverPeer.getDefaultQueueJNDIContext() : serverPeer.getDefaultTopicJNDIContext();
+   
+            jndiNameInContext = destination.getName();
+            jndiName = parentContext + "/" + jndiNameInContext;
          }
          else
          {
-            parentContext = jndiName.substring(0, sepIndex);
+            // TODO more solid parsing + test cases
+            int sepIndex = jndiName.lastIndexOf('/');
+            if (sepIndex == -1)
+            {
+               parentContext = "";
+            }
+            else
+            {
+               parentContext = jndiName.substring(0, sepIndex);
+            }
+            jndiNameInContext = jndiName.substring(sepIndex + 1);
          }
-         jndiNameInContext = jndiName.substring(sepIndex + 1);
-      }
+   
+         try
+         {
+            initialContext.lookup(jndiName);
+            throw new InvalidDestinationException("Destination " + destination.getName() + " already exists");
+         }
+         catch(NameNotFoundException e)
+         {
+            // OK
+         }      
 
-      try
-      {
-         initialContext.lookup(jndiName);
-         throw new InvalidDestinationException("Destination " + name + " already exists");
+         Context c = JNDIUtil.createContext(initialContext, parentContext);
+         
+         c.rebind(jndiNameInContext, destination);
+         
+         //if the destination has no security configuration, then the security manager will always
+         // use its current default security configuration when requested to authorize requests for
+         // that destination
+         if (securityConfiguration != null)
+         {
+            serverPeer.getSecurityManager().setSecurityConfig(destination.isQueue(),
+                                                              destination.getName(),
+                                                              securityConfiguration);
+         }
       }
-      catch(NameNotFoundException e)
+            
+      if (destination.isQueue())
       {
-         // OK
+         queueMap.put(destination.getName(), new DestinationHolder(destination, jndiName));
       }
-
-      Destination jmsDestination =
-         isQueue ? (Destination) new JBossQueue(name) : (Destination) new JBossTopic(name);
-
-      Context c = JNDIUtil.createContext(initialContext, parentContext);
-      c.rebind(jndiNameInContext, jmsDestination);
-      if (isQueue)
-      {
-         queueNameToJNDI.put(name, jndiName);
-      }
       else
       {
-         topicNameToJNDI.put(name, jndiName);
-      }
-
-      // if the destination has no security configuration, then the security manager will always
-      // use its current default security configuration when requested to authorize requests for
-      // that destination
-      if (securityConfiguration != null)
-      {
-         serverPeer.getSecurityManager().setSecurityConfig(isQueue, name, securityConfiguration);
-      }
-
-      log.debug((isQueue ? "queue" : "topic") + " " + name +
-                " registered and bound in JNDI as " + jndiName );
-
+         topicMap.put(destination.getName(), new DestinationHolder(destination, jndiName));
+      }      
+      
+      log.debug((destination.isQueue() ? "queue" : "topic") + " " + destination.getName() + " registered ");
+      log.debug((destination.isQueue() ? "queue" : "topic") + " bound in JNDI as " + jndiName);
+      
       return jndiName;
    }
 
-   public void unregisterDestination(boolean isQueue, String name) throws Exception
+   public synchronized void unregisterDestination(JBossDestination destination) throws Exception
    {
       String jndiName = null;
-      if (isQueue)
+      if (destination.isQueue())
       {
-         jndiName = (String)queueNameToJNDI.remove(name);
+         DestinationHolder holder = (DestinationHolder)queueMap.remove(destination.getName());
+         if (holder != null)
+         {
+            jndiName = holder.jndiName;
+         }
       }
       else
       {
-         jndiName = (String)topicNameToJNDI.remove(name);
+         DestinationHolder holder = (DestinationHolder)topicMap.remove(destination.getName());
+         if (holder != null)
+         {
+            jndiName = holder.jndiName;
+         }
       }
       if (jndiName == null)
       {
          return;
       }
 
-      initialContext.unbind(jndiName);      
-
-      serverPeer.getSecurityManager().clearSecurityConfig(isQueue, name);
-
-      log.debug("unregistered " + (isQueue ? "queue " : "topic ") + name);
+      if (!destination.isTemporary())
+      {
+         initialContext.unbind(jndiName);      
+   
+         serverPeer.getSecurityManager().clearSecurityConfig(destination.isQueue(), destination.getName());
+      }
+      
+      log.debug("unregistered " + (destination.isQueue() ? "queue " : "topic ") + destination.getName());
    }
-
-   // Public --------------------------------------------------------
-
-   public boolean isDeployed(boolean isQueue, String name)
+   
+   public synchronized boolean destinationExists(JBossDestination dest)
    {
-      return isQueue ? queueNameToJNDI.containsKey(name) : topicNameToJNDI.containsKey(name);
+      return getDestination(dest) != null;
    }
-
-   public Set getDestinations()
+   
+   public synchronized JBossDestination getDestination(JBossDestination dest)
    {
-      Set destinations = Collections.EMPTY_SET;
-
-      for(Iterator i = queueNameToJNDI.keySet().iterator(); i.hasNext(); )
+      Map m = dest.isTopic() ? topicMap : queueMap;
+      
+      DestinationHolder holder = (DestinationHolder)m.get(dest.getName());
+      
+      return holder == null ? null : holder.destination;
+   }
+   
+   public synchronized Set getDestinations()
+   {
+      Set destinations = new HashSet();
+      
+      for(Iterator i = queueMap.values().iterator(); i.hasNext(); )
       {
-         if (destinations == Collections.EMPTY_SET)
-         {
-            destinations = new HashSet();
-         }
-         destinations.add(new JBossQueue((String)i.next()));
+         DestinationHolder holder = (DestinationHolder)i.next();
+         destinations.add(holder.destination);
       }
-      for(Iterator i = topicNameToJNDI.keySet().iterator(); i.hasNext(); )
+      for(Iterator i = topicMap.values().iterator(); i.hasNext(); )
       {
-         if (destinations == Collections.EMPTY_SET)
-         {
-            destinations = new HashSet();
-         }
-         destinations.add(new JBossTopic((String)i.next()));
+         DestinationHolder holder = (DestinationHolder)i.next();
+         destinations.add(holder.destination);
       }
       return destinations;
    }
+   
 
+   // Public --------------------------------------------------------
+
    // Package protected ---------------------------------------------
 
    void start() throws Exception
@@ -211,15 +230,19 @@
 
    void stop() throws Exception
    {
+      Set queues = new HashSet(queueMap.keySet());
+      
+      Set topics = new HashSet(topicMap.keySet());
+      
       // remove all destinations from JNDI
-      for(Iterator i = queueNameToJNDI.keySet().iterator(); i.hasNext(); )
+      for(Iterator i = queues.iterator(); i.hasNext(); )
       {
-         unregisterDestination(true, (String)i.next());         
+         unregisterDestination(new JBossQueue((String)i.next()));         
       }
 
-      for(Iterator i = topicNameToJNDI.keySet().iterator(); i.hasNext(); )
+      for(Iterator i = topics.iterator(); i.hasNext(); )
       {
-         unregisterDestination(false, (String)i.next());
+         unregisterDestination(new JBossTopic((String)i.next()));
       }
 
       initialContext.unbind(serverPeer.getDefaultQueueJNDIContext());
@@ -254,4 +277,17 @@
    }
 
    // Inner classes -------------------------------------------------
+   
+   private class DestinationHolder
+   {
+      DestinationHolder(JBossDestination destination, String jndiName)
+      {
+         this.destination = destination;
+         this.jndiName = jndiName;
+      }
+      
+      JBossDestination destination;
+      
+      String jndiName;
+   }
 }

Modified: trunk/src/main/org/jboss/jms/server/DestinationManager.java
===================================================================
--- trunk/src/main/org/jboss/jms/server/DestinationManager.java	2006-08-30 09:26:13 UTC (rev 1236)
+++ trunk/src/main/org/jboss/jms/server/DestinationManager.java	2006-08-30 18:36:36 UTC (rev 1237)
@@ -21,10 +21,14 @@
   */
 package org.jboss.jms.server;
 
+import java.util.Set;
+
+import org.jboss.jms.destination.JBossDestination;
 import org.w3c.dom.Element;
 
 /**
  * @author <a href="mailto:ovidiu at jboss.org">Ovidiu Feodorov</a>
+ * @author <a href="mailto:tim.fox at jboss.com">Tim Fox</a>
  * @version <tt>$Revision$</tt>
  *
  * $Id$
@@ -38,13 +42,19 @@
     *
     * @return the name under which the destination was bound in JNDI.
     */
-   String registerDestination(boolean isQueue, String name, String jndiName, Element securityConfig)
-      throws Exception;
+   String registerDestination(JBossDestination destination,
+                              String jndiName, Element securityConfig) throws Exception;
 
    /**
     * Method called by a destination service to unregister itself from the server peer. The server
     * peer is supposed to clean up the state maintained on behalf of the unregistered destination.
     */
-   void unregisterDestination(boolean isQueue, String name) throws Exception;
-
+   void unregisterDestination(JBossDestination destination) throws Exception;
+   
+   boolean destinationExists(JBossDestination destination);
+   
+   //TODO There is probably a better way of doing this
+   JBossDestination getDestination(JBossDestination dest);
+   
+   Set getDestinations();   
 }

Deleted: trunk/src/main/org/jboss/jms/server/DurableSubscriptionHolder.java
===================================================================
--- trunk/src/main/org/jboss/jms/server/DurableSubscriptionHolder.java	2006-08-30 09:26:13 UTC (rev 1236)
+++ trunk/src/main/org/jboss/jms/server/DurableSubscriptionHolder.java	2006-08-30 18:36:36 UTC (rev 1237)
@@ -1,117 +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.jms.server;
-
-import java.io.Serializable;
-
-import org.jboss.messaging.core.local.Queue;
-import org.jboss.messaging.core.local.Topic;
-
-/**
- * 
- * Holds state for a DurableSubscription
- *
- * @author <a href="tim.fox at jboss.com">Tim Fox/a>
- * @version $Revision$
- *
- * $Id$
- */
-public class DurableSubscriptionHolder implements Serializable
-{
-   // Constants -----------------------------------------------------
-   
-   private static final long serialVersionUID = 6572385758103922254L;
-   
-   // Attributes ----------------------------------------------------
-   
-   private String name;
-   private Queue queue;
-   private Topic topic;
-   private String selector;
-
-   // Static --------------------------------------------------------
-   
-   // Constructors --------------------------------------------------
-   
-   public DurableSubscriptionHolder(String name, Topic topic, Queue queue, String selector)
-   {
-      this.name = name;
-      this.queue = queue;
-      this.topic = topic;
-      this.selector = selector;
-   }
-
-   // Public --------------------------------------------------------
-   
-
-   public Queue getQueue()
-   {
-      return queue;
-   }
-   
-   public Topic getTopic()
-   {
-      return topic;
-   }
-   
-   public String getName()
-   {
-      return name;
-   }
-   
-   public String getSelector()
-   {
-      return selector;
-   }
-   
-
-   // Interface XXX implementation ----------------------------------
-   
-   // Object overrides -------------------------------------------
-   
-   public boolean equals(Object other)
-   {
-      if (this == other) return true;
-      
-      if (!(other instanceof DurableSubscriptionHolder)) return false;
-      
-      DurableSubscriptionHolder dOther = (DurableSubscriptionHolder)other;
-      
-      if (dOther.name == null || this.name == null) return false;
-      
-      return dOther.name.equals(this.name);
-   }
-   
-   public int hashCode()
-   {
-      return name.hashCode();
-   }
-
-   // Protected -----------------------------------------------------
-
-   // Package Private -----------------------------------------------
-
-   // Private -------------------------------------------------------
-   
-   // Inner Classes -------------------------------------------------
-     
-}

Modified: trunk/src/main/org/jboss/jms/server/ServerPeer.java
===================================================================
--- trunk/src/main/org/jboss/jms/server/ServerPeer.java	2006-08-30 09:26:13 UTC (rev 1236)
+++ trunk/src/main/org/jboss/jms/server/ServerPeer.java	2006-08-30 18:36:36 UTC (rev 1237)
@@ -39,7 +39,7 @@
 import org.jboss.jms.server.connectionmanager.SimpleConnectionManager;
 import org.jboss.jms.server.connectormanager.SimpleConnectorManager;
 import org.jboss.jms.server.endpoint.ServerConsumerEndpoint;
-import org.jboss.jms.server.plugin.contract.ChannelMapper;
+import org.jboss.jms.server.plugin.contract.JMSUserManager;
 import org.jboss.jms.server.remoting.JMSServerInvocationHandler;
 import org.jboss.jms.server.remoting.JMSWireFormat;
 import org.jboss.jms.server.security.SecurityMetadataStore;
@@ -48,8 +48,12 @@
 import org.jboss.messaging.core.memory.MemoryManager;
 import org.jboss.messaging.core.memory.SimpleMemoryManager;
 import org.jboss.messaging.core.plugin.IdManager;
+import org.jboss.messaging.core.plugin.SimpleMessageStore;
+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.exchange.DirectExchange;
 import org.jboss.messaging.core.tx.TransactionRepository;
 import org.jboss.messaging.util.Util;
 import org.jboss.mx.loading.UnifiedClassLoader3;
@@ -87,41 +91,46 @@
 
    // Attributes ----------------------------------------------------
 
-   protected String serverPeerID;
-   protected byte[] clientAOPConfig;
+   private String serverPeerID;
+   private byte[] clientAOPConfig;
    private Version version;
 
-   protected String defaultQueueJNDIContext;
-   protected String defaultTopicJNDIContext;
+   private String defaultQueueJNDIContext;
+   private String defaultTopicJNDIContext;
    
-   protected int queuedExecutorPoolSize = 200;
+   private int queuedExecutorPoolSize = 200;
 
-   protected boolean started;
+   private boolean started;
 
-   protected int objectIDSequence = Integer.MIN_VALUE + 1;
+   private int objectIDSequence = Integer.MIN_VALUE + 1;
 
    // wired components
 
-   protected DestinationJNDIMapper destinationJNDIMapper;
-   protected SecurityMetadataStore securityStore;
-   protected ConnectionFactoryJNDIMapper connFactoryJNDIMapper;
-   protected TransactionRepository txRepository;
-   protected ConnectionManager connectionManager;
-   protected ConnectorManager connectorManager;
-   protected IdManager messageIdManager;
-   protected MemoryManager memoryManager;
-   protected QueuedExecutorPool queuedExecutorPool;
+   private DestinationJNDIMapper destinationJNDIMapper;
+   private SecurityMetadataStore securityStore;
+   private ConnectionFactoryJNDIMapper connFactoryJNDIMapper;
+   private TransactionRepository txRepository;
+   private ConnectionManager connectionManager;
+   private ConnectorManager connectorManager;
+   private IdManager messageIdManager;
+   private IdManager channelIdManager;
+   private IdManager transactionIdManager;
+   private MemoryManager memoryManager;
+   private QueuedExecutorPool queuedExecutorPool;
+   private MessageStore messageStore;   
 
    // plugins
 
    protected ObjectName persistenceManagerObjectName;
    protected PersistenceManager persistenceManagerDelegate;
-   protected ObjectName messageStoreObjectName;
-   protected MessageStore messageStoreDelegate;
-   protected ObjectName channelMapperObjectName;
-   protected ChannelMapper channelMapper;
+   protected ObjectName directExchangeObjectName;
+   protected ObjectName topicExchangeObjectName;
+   protected Exchange directExchangeDelegate;
+   protected Exchange topicExchangeDelegate;
+   protected ObjectName JMSUserManagerObjectName;
+   protected JMSUserManager JMSUserManagerDelegate;
 
-   protected JMSServerInvocationHandler handler;
+   private JMSServerInvocationHandler handler;
 
    // We keep a map of consumers to prevent us to recurse through the attached session in order to
    // find the ServerConsumerDelegate so we can acknowledge the message. Originally, this map was
@@ -149,6 +158,7 @@
       connectionManager = new SimpleConnectionManager();
       connectorManager = new SimpleConnectorManager();
       memoryManager = new SimpleMemoryManager();
+      messageStore = new SimpleMessageStore();
 
       consumers = new ConcurrentReaderHashMap();
 
@@ -169,6 +179,13 @@
          }
    
          log.debug(this + " starting");
+         
+         if (queuedExecutorPoolSize < 1)
+         {
+            throw new IllegalArgumentException("queuedExecutorPoolSize must be > 0");
+         }
+         queuedExecutorPool = new QueuedExecutorPool(queuedExecutorPoolSize);
+         
    
          loadClientAOPConfig();
    
@@ -180,42 +197,48 @@
          // circumventing the MBeanServer. However, they are installed as services to take advantage
          // of their automatically-creating management interface.
    
+         //FIXME - Why are these called xxxDelegate ??
+         //They're not delegates - this is confusing
          persistenceManagerDelegate =
             (PersistenceManager)mbeanServer.getAttribute(persistenceManagerObjectName, "Instance");
    
-         // TODO: is should be possible to share this with other peers
-         messageStoreDelegate =
-            (MessageStore)mbeanServer.getAttribute(messageStoreObjectName, "Instance");
-   
-         channelMapper = (ChannelMapper)mbeanServer.
-            getAttribute(channelMapperObjectName, "Instance");
+         directExchangeDelegate = (Exchange)mbeanServer.
+            getAttribute(directExchangeObjectName, "Instance");
          
-         if (queuedExecutorPoolSize < 1)
-         {
-            throw new IllegalArgumentException("queuedExecutorPoolSize must be > 0");
-         }
-         queuedExecutorPool = new QueuedExecutorPool(queuedExecutorPoolSize);
-   
-   
-         // TODO: Shouldn't this go into ChannelMapper's dependencies? Since it's a plug in,
-         //       we shouldn't inject their dependencies externally, but they should take care
-         ///      of them themselves.
-         channelMapper.setPersistenceManager(persistenceManagerDelegate);
+         topicExchangeDelegate = (Exchange)mbeanServer.
+            getAttribute(topicExchangeObjectName, "Instance");
          
-         channelMapper.setQueuedExecutorPool(queuedExecutorPool);
-   
+         JMSUserManagerDelegate = (JMSUserManager)mbeanServer.
+            getAttribute(JMSUserManagerObjectName, "Instance");
+                  
+         //TODO Make block size configurable
+         messageIdManager = new IdManager("MESSAGE_ID", 8192, persistenceManagerDelegate);
+         channelIdManager = new IdManager("CHANNEL_ID", 10, persistenceManagerDelegate);
+         transactionIdManager = new IdManager("TRANSACTION_ID", 4096, persistenceManagerDelegate);
+         
+         //Inject attributes
+         
+         ((DirectExchange)directExchangeDelegate).injectAttributes("Direct", serverPeerID,
+                                                                    messageStore,
+                                                                    channelIdManager,
+                                                                    queuedExecutorPool);
+                           
+         ((ClusteredTopicExchange)topicExchangeDelegate).injectAttributes(null, null, null, "Topic", serverPeerID,
+                                                                   messageStore, 
+                                                                   channelIdManager,
+                                                                   queuedExecutorPool,
+                                                                   txRepository,
+                                                                   persistenceManagerDelegate);
+         
+         txRepository.injectAttributes(persistenceManagerDelegate, transactionIdManager);
+         
          // start the rest of the internal components
    
          memoryManager.start();
          destinationJNDIMapper.start();
          securityStore.start();
-         connFactoryJNDIMapper.start();
-         txRepository.start(persistenceManagerDelegate);
-         txRepository.loadPreparedTransactions();
-         
-         //TODO Make block size configurable
-         messageIdManager = new IdManager("MESSAGE_ID", 8192, persistenceManagerDelegate);
-   
+         connFactoryJNDIMapper.start();   
+
          initializeRemoting(mbeanServer);
    
          createRecoverable();
@@ -248,7 +271,6 @@
    
          // stop the internal components
          memoryManager.stop();
-         txRepository.stop();
          txRepository = null;
          securityStore.stop();
          securityStore = null;
@@ -282,25 +304,35 @@
    {
       persistenceManagerObjectName = on;
    }
-
-   public ObjectName getMessageStore()
+   
+   public ObjectName getDirectExchange()
    {
-      return messageStoreObjectName;
+      return directExchangeObjectName;
    }
 
-   public void setMessageStore(ObjectName on)
+   public void setDirectExchange(ObjectName on)
    {
-      messageStoreObjectName = on;
+      directExchangeObjectName = on;
    }
+   
+   public ObjectName getTopicExchange()
+   {
+      return topicExchangeObjectName;
+   }
 
-   public ObjectName getChannelMapper()
+   public void setTopicExchange(ObjectName on)
    {
-      return channelMapperObjectName;
+      topicExchangeObjectName = on;
    }
+   
+   public ObjectName getJMSUserManager()
+   {
+      return JMSUserManagerObjectName;
+   }
 
-   public void setChannelMapper(ObjectName on)
+   public void setJMSUserManager(ObjectName on)
    {
-      channelMapperObjectName = on;
+      JMSUserManagerObjectName = on;
    }
 
    public Object getInstance()
@@ -382,6 +414,11 @@
    {
       return messageIdManager;
    }
+   
+   public IdManager getChannelIdManager()
+   {
+      return channelIdManager;
+   }
 
    public ServerInvocationHandler getInvocationHandler()
    {
@@ -484,18 +521,8 @@
       } 
    }
 
-   // Public --------------------------------------------------------
+   // Public --------------------------------------------------------     
 
-   public boolean isDeployed(boolean isQueue, String name)
-   {
-      return destinationJNDIMapper.isDeployed(isQueue, name);
-   }
-
-   public ChannelMapper getChannelMapperDelegate()
-   {
-      return channelMapper;
-   }
-
    public TransactionRepository getTxRepository()
    {
       return txRepository;
@@ -542,6 +569,16 @@
    {
       return connectorManager;
    }
+   
+   public MessageStore getMessageStore()
+   {
+      return messageStore;
+   }
+   
+   public MemoryManager getMemoryManager()
+   {
+      return memoryManager;
+   }
 
    // access to plugin references
 
@@ -549,16 +586,23 @@
    {
       return persistenceManagerDelegate;
    }
-
-   public MessageStore getMessageStoreDelegate()
+   
+   public JMSUserManager getJMSUserManagerDelegate()
    {
-      return messageStoreDelegate;
+      return JMSUserManagerDelegate;
    }
    
-   public MemoryManager getMemoryManager()
+   public Exchange getDirectExchangeDelegate()
    {
-      return memoryManager;
+      return directExchangeDelegate;
    }
+   
+   public Exchange getTopicExchangeDelegate()
+   {
+      return topicExchangeDelegate;
+   }
+   
+   
 
    public synchronized int getNextObjectID()
    {

Modified: trunk/src/main/org/jboss/jms/server/Version.java
===================================================================
--- trunk/src/main/org/jboss/jms/server/Version.java	2006-08-30 09:26:13 UTC (rev 1236)
+++ trunk/src/main/org/jboss/jms/server/Version.java	2006-08-30 18:36:36 UTC (rev 1237)
@@ -14,6 +14,7 @@
 
 /**
  * @author <a href="mailto:ovidiu at jboss.org">Ovidiu Feodorov</a>
+ * @author <a href="mailto:tim.fox at jboss.com">Tim Fox</a>
  * @version <tt>$Revision$</tt>
  *
  * $Id$

Modified: trunk/src/main/org/jboss/jms/server/connectionfactory/ConnectionFactory.java
===================================================================
--- trunk/src/main/org/jboss/jms/server/connectionfactory/ConnectionFactory.java	2006-08-30 09:26:13 UTC (rev 1236)
+++ trunk/src/main/org/jboss/jms/server/connectionfactory/ConnectionFactory.java	2006-08-30 18:36:36 UTC (rev 1237)
@@ -21,6 +21,7 @@
  * A deployable JBoss Messaging connection factory.
  *
  * @author <a href="mailto:ovidiu at jboss.org">Ovidiu Feodorov</a>
+ * @author <a href="mailto:tim.fox at jboss.com">Tim Fox</a>
  * @version <tt>$Revision$</tt>
  *
  * $Id$

Modified: trunk/src/main/org/jboss/jms/server/destination/DestinationServiceSupport.java
===================================================================
--- trunk/src/main/org/jboss/jms/server/destination/DestinationServiceSupport.java	2006-08-30 09:26:13 UTC (rev 1236)
+++ trunk/src/main/org/jboss/jms/server/destination/DestinationServiceSupport.java	2006-08-30 18:36:36 UTC (rev 1237)
@@ -10,10 +10,8 @@
 
 import org.jboss.jms.server.DestinationManager;
 import org.jboss.jms.server.SecurityManager;
-import org.jboss.jms.server.ServerPeer;
-import org.jboss.jms.server.plugin.contract.ChannelMapper;
 import org.jboss.jms.util.ExceptionUtil;
-import org.jboss.jms.util.XMLUtil;
+import org.jboss.messaging.core.plugin.contract.Exchange;
 import org.jboss.system.ServiceMBeanSupport;
 import org.w3c.dom.Element;
 
@@ -64,8 +62,8 @@
 
    protected ObjectName serverPeerObjectName;
    protected DestinationManager dm;
-   protected ChannelMapper cm;
    protected SecurityManager sm;
+   protected Exchange exchange;
    protected Element securityConfig;
 
    protected String name;
@@ -76,14 +74,14 @@
    
    // The following 3 attributes can only be changed when service is stopped.
 
-   // In memory message number limit
-   private int fullSize = FULL_SIZE;
+   // Default in memory message number limit
+   protected int fullSize = FULL_SIZE;
 
-   // Paging size
-   private int pageSize = PAGE_SIZE;
+   // Default paging size
+   protected int pageSize = PAGE_SIZE;
 
-   // Down-cache size
-   private int downCacheSize = DOWN_CACHE_SIZE;
+   // Default down-cache size
+   protected int downCacheSize = DOWN_CACHE_SIZE;
 
    // Constructors --------------------------------------------------
 
@@ -92,69 +90,6 @@
       this.createdProgrammatically = createdProgrammatically;
    }
 
-   // ServiceMBeanSupport overrides ---------------------------------
-
-   public synchronized void startService() throws Exception
-   {
-      try
-      {
-         started = true;
-   
-         if (serviceName != null)
-         {
-            name = serviceName.getKeyProperty("name");
-         }
-   
-         if (name == null || name.length() == 0)
-         {
-            throw new IllegalStateException( "The " + (isQueue() ? "queue" : "topic") + " " +
-                                             "name was not properly set in the service's" +
-                                             "ObjectName");
-         }
-   
-         ServerPeer serverPeer = (ServerPeer)server.getAttribute(serverPeerObjectName, "Instance");
-
-         dm = serverPeer.getDestinationManager();
-         sm = serverPeer.getSecurityManager();
-         cm = serverPeer.getChannelMapperDelegate();
-         
-         //Core destination MUST be deployed before destination is registered in JNDI
-         //otherwise the user could get a reference to the destination and use it
-         //while it is still being loaded
-         
-         cm.deployCoreDestination(isQueue(), name, serverPeer.getMessageStoreDelegate(),
-               serverPeer.getPersistenceManagerDelegate(),
-               serverPeer.getMemoryManager(),
-               fullSize, pageSize, downCacheSize);
-   
-         jndiName = dm.registerDestination(isQueue(), name, jndiName, securityConfig);
-        
-         log.debug(this + " security configuration: " + (securityConfig == null ?
-            "null" : "\n" + XMLUtil.elementToString(securityConfig)));
-
-         log.info(this + " started, fullSize=" + fullSize + ", pageSize=" + pageSize + ", downCacheSize=" + downCacheSize);
-      }
-      catch (Throwable t)
-      {
-         ExceptionUtil.handleJMXInvocation(t, this + " startService");
-      }
-   }
-
-   public void stopService() throws Exception
-   {
-      try
-      {
-         dm.unregisterDestination(isQueue(), name);
-         cm.undeployCoreDestination(isQueue(), name);
-         started = false;
-         log.info(this + " stopped");
-      }
-      catch (Throwable t)
-      {
-         ExceptionUtil.handleJMXInvocation(t, this + " stopService");
-      }
-   }
-
    // JMX managed attributes ----------------------------------------
 
    public String getJNDIName()

Modified: trunk/src/main/org/jboss/jms/server/destination/Queue.java
===================================================================
--- trunk/src/main/org/jboss/jms/server/destination/Queue.java	2006-08-30 09:26:13 UTC (rev 1236)
+++ trunk/src/main/org/jboss/jms/server/destination/Queue.java	2006-08-30 18:36:36 UTC (rev 1237)
@@ -14,7 +14,14 @@
 
 import org.jboss.jms.destination.JBossQueue;
 import org.jboss.jms.selector.Selector;
+import org.jboss.jms.server.ServerPeer;
 import org.jboss.jms.util.ExceptionUtil;
+import org.jboss.jms.util.XMLUtil;
+import org.jboss.messaging.core.local.MessageQueue;
+import org.jboss.messaging.core.memory.MemoryManager;
+import org.jboss.messaging.core.plugin.contract.MessageStore;
+import org.jboss.messaging.core.plugin.contract.PersistenceManager;
+import org.jboss.messaging.core.plugin.exchange.Binding;
 
 /**
  * A deployable JBoss Messaging queue.
@@ -57,10 +64,17 @@
             log.warn("Queue is stopped.");
             return 0;
          }
+         
+         Binding binding = (Binding)exchange.listBindingsForWildcard(name).get(0);
+         
+         if (binding == null)
+         {
+            throw new IllegalStateException("Cannot find binding for queue:" + name);
+         }
+         
+         MessageQueue queue = binding.getQueue();
    
-         JBossQueue jbq = new JBossQueue(name);
-         org.jboss.messaging.core.local.Queue q = (org.jboss.messaging.core.local.Queue)cm.getCoreDestination(jbq);
-   	   return q.getMessageCount();
+   	   return queue.messageCount();
       }
       catch (Throwable t)
       {
@@ -70,6 +84,84 @@
 
    // JMX managed operations ----------------------------------------
    
+   public synchronized void startService() throws Exception
+   {
+      try
+      {
+         started = true;
+   
+         if (serviceName != null)
+         {
+            name = serviceName.getKeyProperty("name");
+         }
+   
+         if (name == null || name.length() == 0)
+         {
+            throw new IllegalStateException( "The " + (isQueue() ? "queue" : "topic") + " " +
+                                             "name was not properly set in the service's" +
+                                             "ObjectName");
+         }
+   
+         ServerPeer serverPeer = (ServerPeer)server.getAttribute(serverPeerObjectName, "Instance");
+
+         dm = serverPeer.getDestinationManager();
+         sm = serverPeer.getSecurityManager();         
+         exchange = serverPeer.getDirectExchangeDelegate();
+         
+         //Binding must be added before destination is registered in JNDI
+         //otherwise the user could get a reference to the destination and use it
+         //while it is still being loaded
+         
+         MessageStore ms = serverPeer.getMessageStore();
+         PersistenceManager pm = serverPeer.getPersistenceManagerDelegate(); 
+         //Binding might already exist
+         Binding binding = exchange.getBindingForName(name);
+         
+         if (binding != null)
+         {
+            //Reload the queue for the binding
+            exchange.reloadQueues(name, ms, pm, fullSize, pageSize, downCacheSize);
+         }
+         else
+         {         
+            //Make a binding for this queue
+            exchange.bindQueue(name, name, null, false, true, ms, pm, fullSize, pageSize, downCacheSize);
+         }
+         
+         JBossQueue q = new JBossQueue(name, fullSize, pageSize, downCacheSize);
+         
+         jndiName = dm.registerDestination(q, jndiName, securityConfig);
+        
+         log.debug(this + " security configuration: " + (securityConfig == null ?
+            "null" : "\n" + XMLUtil.elementToString(securityConfig)));
+
+         log.info(this + " started, fullSize=" + fullSize + ", pageSize=" + pageSize + ", downCacheSize=" + downCacheSize);
+      }
+      catch (Throwable t)
+      {
+         ExceptionUtil.handleJMXInvocation(t, this + " startService");
+      }
+   }
+
+   public void stopService() throws Exception
+   {
+      try
+      {
+         dm.unregisterDestination(new JBossQueue(name));
+         
+         //We undeploy the queue from memory - this also deactivates the binding
+         exchange.unloadQueues(name);
+         
+         started = false;
+         
+         log.info(this + " stopped");
+      }
+      catch (Throwable t)
+      {
+         ExceptionUtil.handleJMXInvocation(t, this + " stopService");
+      }
+   }
+   
    public void removeAllMessages() throws Exception
    {
       try
@@ -79,10 +171,17 @@
             log.warn("Queue is stopped.");
             return;
          }
+         
+         Binding binding = (Binding)exchange.listBindingsForWildcard(name).get(0);
+         
+         if (binding == null)
+         {
+            throw new IllegalStateException("Cannot find binding for queue:" + name);
+         }
+         
+         MessageQueue queue = binding.getQueue();
    
-         JBossQueue jbq = new JBossQueue(name);
-         org.jboss.messaging.core.local.Queue q = (org.jboss.messaging.core.local.Queue)cm.getCoreDestination(jbq);
-         q.removeAllReferences();
+         queue.removeAllReferences();
       }
       catch (Throwable t)
       {
@@ -108,19 +207,26 @@
                selector = null;
             }
          }
+         
+         Binding binding = (Binding)exchange.listBindingsForWildcard(name).get(0);
+         
+         if (binding == null)
+         {
+            throw new IllegalStateException("Cannot find binding for queue:" + name);
+         }
+         
+         MessageQueue queue = binding.getQueue();
    
-         JBossQueue jbq = new JBossQueue(name);
-         org.jboss.messaging.core.local.Queue q = (org.jboss.messaging.core.local.Queue)cm.getCoreDestination(jbq);
          try 
          {
             List msgs;
             if (selector == null)
             {
-               msgs = q.browse();
+               msgs = queue.browse();
             }
             else
             {
-               msgs = q.browse(new Selector(selector));
+               msgs = queue.browse(new Selector(selector));
             }
             return msgs;
          }

Modified: trunk/src/main/org/jboss/jms/server/destination/Topic.java
===================================================================
--- trunk/src/main/org/jboss/jms/server/destination/Topic.java	2006-08-30 09:26:13 UTC (rev 1236)
+++ trunk/src/main/org/jboss/jms/server/destination/Topic.java	2006-08-30 18:36:36 UTC (rev 1237)
@@ -15,9 +15,15 @@
 
 import org.jboss.jms.destination.JBossTopic;
 import org.jboss.jms.selector.Selector;
-import org.jboss.jms.server.subscription.DurableSubscription;
-import org.jboss.jms.server.subscription.Subscription;
+import org.jboss.jms.server.ServerPeer;
 import org.jboss.jms.util.ExceptionUtil;
+import org.jboss.jms.util.MessageQueueNameHelper;
+import org.jboss.jms.util.XMLUtil;
+import org.jboss.messaging.core.local.MessageQueue;
+import org.jboss.messaging.core.memory.MemoryManager;
+import org.jboss.messaging.core.plugin.contract.MessageStore;
+import org.jboss.messaging.core.plugin.contract.PersistenceManager;
+import org.jboss.messaging.core.plugin.exchange.Binding;
 
 
 /**
@@ -53,7 +59,90 @@
    // JMX managed attributes ----------------------------------------
 
    // JMX managed operations ----------------------------------------
+   
+   public synchronized void startService() throws Exception
+   {
+      try
+      {
+         started = true;
+   
+         if (serviceName != null)
+         {
+            name = serviceName.getKeyProperty("name");
+         }
+   
+         if (name == null || name.length() == 0)
+         {
+            throw new IllegalStateException( "The " + (isQueue() ? "queue" : "topic") + " " +
+                                             "name was not properly set in the service's" +
+                                             "ObjectName");
+         }
+   
+         ServerPeer serverPeer = (ServerPeer)server.getAttribute(serverPeerObjectName, "Instance");
 
+         dm = serverPeer.getDestinationManager();
+         sm = serverPeer.getSecurityManager();
+         exchange = serverPeer.getTopicExchangeDelegate();
+         
+         MessageStore ms = serverPeer.getMessageStore();
+         PersistenceManager pm = serverPeer.getPersistenceManagerDelegate();
+        
+         //We deploy any queues corresponding to pre-existing durable subscriptions
+         exchange.reloadQueues(name, ms, pm, fullSize, pageSize, downCacheSize);
+                  
+         JBossTopic t = new JBossTopic(name, fullSize, pageSize, downCacheSize);
+         
+         jndiName = dm.registerDestination(t, jndiName, securityConfig);
+         
+         log.debug(this + " security configuration: " + (securityConfig == null ?
+            "null" : "\n" + XMLUtil.elementToString(securityConfig)));
+
+         log.info(this + " started, fullSize=" + fullSize + ", pageSize=" + pageSize + ", downCacheSize=" + downCacheSize);
+      }
+      catch (Throwable t)
+      {
+         ExceptionUtil.handleJMXInvocation(t, this + " startService");
+      }
+   }
+
+   public void stopService() throws Exception
+   {
+      try
+      {
+         dm.unregisterDestination(new JBossTopic(name));
+         
+         //When undeploying a topic, any non durable subscriptions will be removed
+         //Any durable subscriptions will survive in persistent storage, but be removed
+         //from memory
+         
+         //First we remove any data for a non durable sub - a non durable sub might have data in the
+         //database since it might have paged
+         
+         List bindings = exchange.listBindingsForWildcard(name);
+         
+         Iterator iter = bindings.iterator();
+         while (iter.hasNext())            
+         {
+            Binding binding = (Binding)iter.next();
+            
+            if (!binding.isDurable())
+            {
+               binding.getQueue().removeAllReferences();
+            }
+         }
+          
+         //We undeploy the queues for the subscriptions - this also unbinds the bindings
+         exchange.unloadQueues(name);
+         
+         started = false;
+         log.info(this + " stopped");
+      }
+      catch (Throwable t)
+      {
+         ExceptionUtil.handleJMXInvocation(t, this + " stopService");
+      }
+   }
+
    /**
     * Remove all messages from subscription's storage.
     */
@@ -66,15 +155,16 @@
             log.warn("Topic is stopped.");
             return;
          }
-         JBossTopic jbt = new JBossTopic(name);
-         org.jboss.messaging.core.local.Topic t = (org.jboss.messaging.core.local.Topic)cm.getCoreDestination(jbt);
          
+         List subs = exchange.listBindingsForWildcard(name);
+         
          //XXX How to lock down all subscriptions?
-         Iterator iter = t.iterator();
+         Iterator iter = subs.iterator();
          while (iter.hasNext())
          {
-            Object sub = iter.next();
-            ((Subscription)sub).removeAllReferences();
+            Binding binding = (Binding)iter.next();
+            MessageQueue queue = binding.getQueue();
+            queue.removeAllReferences();
          }
       }
       catch (Throwable t)
@@ -98,17 +188,9 @@
             return 0;
          }
    
-         JBossTopic jbt = new JBossTopic(name);
-         org.jboss.messaging.core.local.Topic t = (org.jboss.messaging.core.local.Topic)cm.getCoreDestination(jbt);
-        
-         int count = 0;
-         Iterator iter = t.iterator();
-         while (iter.hasNext())
-         {
-            count++;
-            iter.next();
-         }
-         return count;
+         List subs = exchange.listBindingsForWildcard(name);
+         
+         return subs.size();         
       }
       catch (Throwable t)
       {
@@ -132,20 +214,23 @@
             log.warn("Topic is stopped.");
             return 0;
          }
-   
-         JBossTopic jbt = new JBossTopic(name);
-         org.jboss.messaging.core.local.Topic t = (org.jboss.messaging.core.local.Topic)cm.getCoreDestination(jbt);
          
+         List subs = exchange.listBindingsForWildcard(name);
+         
+         Iterator iter = subs.iterator();
+         
          int count = 0;
-         Iterator iter = t.iterator();
+         
          while (iter.hasNext())
          {
-            Subscription sub = (Subscription)iter.next();
-            if (sub.isRecoverable() ^ !durable)
+            Binding binding = (Binding)iter.next();
+            
+            if ((binding.isDurable() && durable) || (!binding.isDurable() && !durable))
             {
                count++;
             }
          }
+   
          return count;
       }
       catch (Throwable t)
@@ -184,9 +269,9 @@
             return "";
          }
    
-         JBossTopic jbt = new JBossTopic(name);
-         org.jboss.messaging.core.local.Topic t = (org.jboss.messaging.core.local.Topic)cm.getCoreDestination(jbt);
-         return getSubscriptionsAsText(t, true) + getSubscriptionsAsText(t, false);
+         List subs = exchange.listBindingsForWildcard(name);
+         
+         return getSubscriptionsAsText(subs, true) + getSubscriptionsAsText(subs, false);
       }
       catch (Throwable t)
       {
@@ -212,9 +297,9 @@
             return "";
          }
    
-         JBossTopic jbt = new JBossTopic(name);
-         org.jboss.messaging.core.local.Topic t = (org.jboss.messaging.core.local.Topic)cm.getCoreDestination(jbt);
-         return getSubscriptionsAsText(t, durable);
+         List subs = exchange.listBindingsForWildcard(name);
+         
+         return getSubscriptionsAsText(subs, durable);
       }
       catch (Throwable t)
       {
@@ -263,14 +348,14 @@
    
    /**
     * Get messages from a durable subscription.
-    * @param name Subscription name.
+    * @param subName Subscription name.
     * @param clientID Client ID.
     * @param selector Filter expression.
     * @return list of javax.jms.Message
     * @throws JMSException
     * @see ManageableTopic#getMessagesFromDurableSub(String, String, String)
     */
-   public List listMessagesDurableSub(String name, String clientID, String selector)
+   public List listMessagesDurableSub(String subName, String clientID, String selector)
       throws Exception
    {
       try
@@ -281,9 +366,9 @@
             return new ArrayList();
          }
    
-         JBossTopic jbt = new JBossTopic(this.name);
-         org.jboss.messaging.core.local.Topic t = (org.jboss.messaging.core.local.Topic)cm.getCoreDestination(jbt);
-         return getMessagesFromDurableSub(t, name, clientID, trimSelector(selector));
+         List subs = exchange.listBindingsForWildcard(name);
+         
+         return getMessagesFromDurableSub(subs, subName, clientID, trimSelector(selector));
       }
       catch (Throwable t)
       {
@@ -310,9 +395,9 @@
             return new ArrayList();
          }
          
-         JBossTopic jbt = new JBossTopic(this.name);
-         org.jboss.messaging.core.local.Topic t = (org.jboss.messaging.core.local.Topic)cm.getCoreDestination(jbt);
-         return getMessagesFromNonDurableSub(t, channelID, trimSelector(selector));
+         List subs = exchange.listBindingsForWildcard(name);
+         
+         return getMessagesFromNonDurableSub(subs, channelID, trimSelector(selector));
       }
       catch (Throwable t)
       {
@@ -364,51 +449,57 @@
       return false;
    }
    
-   protected String getSubscriptionsAsText(org.jboss.messaging.core.local.Topic t, boolean durable)
+   protected String getSubscriptionsAsText(List bindings, boolean durable)
    {
       StringBuffer sb = new StringBuffer();
-      Iterator iter = t.iterator();
+      Iterator iter = bindings.iterator();
       while (iter.hasNext())
       {
-         Subscription sub = (Subscription)iter.next();
-         if (durable && sub.isRecoverable())
-         {            
-            DurableSubscription ds = (DurableSubscription)sub;
+         Binding binding = (Binding)iter.next();
+                  
+         if (durable && binding.isDurable())
+         {                      
+            MessageQueueNameHelper helper = MessageQueueNameHelper.createHelper(binding.getQueueName());
+            
             sb.append("Durable, subscriptionID=\"");
-            sb.append(sub.getChannelID());    
+            sb.append(binding.getChannelId());    
             sb.append("\", name=\"");
-            sb.append(ds.getName());
+            sb.append(helper.getSubName());
             sb.append("\", clientID=\"");
-            sb.append(ds.getClientID());
+            sb.append(helper.getClientId());
             sb.append("\", selector=\"");
-            sb.append(ds.getSelector());
+            sb.append(binding.getSelector());
             sb.append("\", noLocal=\"");
-            sb.append(ds.isNoLocal());
+            sb.append(binding.isNoLocal());
             sb.append("\"\n");
          }
-         else if (!durable && !sub.isRecoverable())
+         else if (!durable && !binding.isDurable())
          {            
             sb.append("Non-durable, subscriptionID=\"");
-            sb.append(sub.getChannelID());
+            sb.append(binding.getChannelId());
             sb.append("\", selector=\"");
-            sb.append(sub.getSelector());
+            sb.append(binding.getSelector());
             sb.append("\", noLocal=\"");
-            sb.append(sub.isNoLocal());
+            sb.append(binding.isNoLocal());
             sb.append("\"\n");
          }
       }
       return sb.toString();
    }
    
-   protected List getMessagesFromDurableSub(org.jboss.messaging.core.local.Topic t, String name, String clientID, String selector) throws InvalidSelectorException
+   protected List getMessagesFromDurableSub(List bindings, String name,
+                                            String clientID, String selector) throws InvalidSelectorException
    {
-      Iterator iter = t.iterator();
+      Iterator iter = bindings.iterator();
       while (iter.hasNext())
       {
-         Subscription sub = (Subscription)iter.next();
+         Binding binding = (Binding)iter.next();
          // If subID matches, then get message list from the subscription
-         if (matchDurableSubscription(name, clientID, sub))
-            return sub.browse(null == selector ? null : new Selector(selector));
+         if (matchDurableSubscription(name, clientID, binding))
+         {
+            MessageQueue queue = binding.getQueue();
+            return queue.browse(null == selector ? null : new Selector(selector));
+         }
       }   
       // No match, return an empty list
       return new ArrayList();
@@ -417,50 +508,51 @@
    /**
     * @see ManageableTopic#getMessagesFromNonDurableSub(Long, String)
     */
-   public List getMessagesFromNonDurableSub(org.jboss.messaging.core.local.Topic t, long channelID, String selector) throws InvalidSelectorException
+   public List getMessagesFromNonDurableSub(List bindings, long channelID, String selector) throws InvalidSelectorException
    {
-      Iterator iter = t.iterator();
+      Iterator iter = bindings.iterator();
       while (iter.hasNext())
       {
-         Subscription sub = (Subscription)iter.next();
+         Binding binding = (Binding)iter.next();
          // If subID matches, then get message list from the subscription
-         if (matchNonDurableSubscription(channelID, sub))
-            return sub.browse(null == selector ? null : new Selector(selector));
+         if (matchNonDurableSubscription(channelID, binding))
+            return binding.getQueue().browse(null == selector ? null : new Selector(selector));
       }   
       // No match, return an empty list
       return new ArrayList();
    }
 
    // Test if the durable subscriptions match
-   private boolean matchDurableSubscription(String name, String clientID, Subscription sub)
+   private boolean matchDurableSubscription(String name, String clientID, Binding binding)
    {
       // Validate the name
       if (null == name)
          throw new IllegalArgumentException();
       // Must be durable
-      if (!sub.isRecoverable())
+      if (!binding.isDurable())
          return false;
+      
+      MessageQueueNameHelper helper = MessageQueueNameHelper.createHelper(binding.getQueueName());
 
-      DurableSubscription duraSub = (DurableSubscription)sub;
       // Subscription name check
-      if (!name.equals(duraSub.getName()))
+      if (!name.equals(helper.getSubName()))
          return false;
       // Client ID check: if no client ID specified, it's considered as matched 
       if (null == clientID || 0 == clientID.length())
          return true;
-      if (!clientID.equals(duraSub.getClientID()))
+      if (!clientID.equals(helper.getClientId()))
          return false;
       return true;
    }
    
    // Test if the non-durable subscriptions match
-   private boolean matchNonDurableSubscription(long channelID, Subscription sub)
+   private boolean matchNonDurableSubscription(long channelID, Binding binding)
    {
       // Must be non-durable
-      if (sub.isRecoverable())
+      if (binding.isDurable())
          return false;
       // Channel ID must be the same
-      if (channelID != sub.getChannelID())
+      if (channelID != binding.getChannelId())
          return false;
       return true;
    }

Modified: trunk/src/main/org/jboss/jms/server/endpoint/ServerBrowserEndpoint.java
===================================================================
--- trunk/src/main/org/jboss/jms/server/endpoint/ServerBrowserEndpoint.java	2006-08-30 09:26:13 UTC (rev 1236)
+++ trunk/src/main/org/jboss/jms/server/endpoint/ServerBrowserEndpoint.java	2006-08-30 18:36:36 UTC (rev 1237)
@@ -31,9 +31,9 @@
 import org.jboss.jms.selector.Selector;
 import org.jboss.jms.server.remoting.JMSDispatcher;
 import org.jboss.logging.Logger;
-import org.jboss.messaging.core.Channel;
 import org.jboss.messaging.core.Filter;
 import org.jboss.messaging.core.Routable;
+import org.jboss.messaging.core.local.MessageQueue;
 
 /**
  * Concrete implementation of BrowserEndpoint.
@@ -66,7 +66,7 @@
    // Constructors --------------------------------------------------
 
    protected ServerBrowserEndpoint(ServerSessionEndpoint session, int id,
-                                   Channel destination, String messageSelector)
+                                   MessageQueue destination, String messageSelector)
       throws JMSException
    {     
       this.session = session;

Modified: trunk/src/main/org/jboss/jms/server/endpoint/ServerConnectionEndpoint.java
===================================================================
--- trunk/src/main/org/jboss/jms/server/endpoint/ServerConnectionEndpoint.java	2006-08-30 09:26:13 UTC (rev 1236)
+++ trunk/src/main/org/jboss/jms/server/endpoint/ServerConnectionEndpoint.java	2006-08-30 18:36:36 UTC (rev 1237)
@@ -41,7 +41,6 @@
 import org.jboss.jms.server.SecurityManager;
 import org.jboss.jms.server.ServerPeer;
 import org.jboss.jms.server.endpoint.advised.SessionAdvised;
-import org.jboss.jms.server.plugin.contract.ChannelMapper;
 import org.jboss.jms.server.remoting.JMSDispatcher;
 import org.jboss.jms.server.remoting.JMSWireFormat;
 import org.jboss.jms.tx.AckInfo;
@@ -52,14 +51,12 @@
 import org.jboss.jms.util.MessagingTransactionRolledBackException;
 import org.jboss.jms.util.ToString;
 import org.jboss.logging.Logger;
-import org.jboss.messaging.core.Delivery;
-import org.jboss.messaging.core.Message;
 import org.jboss.messaging.core.MessageReference;
-import org.jboss.messaging.core.local.CoreDestination;
-import org.jboss.messaging.core.local.Queue;
+import org.jboss.messaging.core.plugin.contract.Exchange;
+import org.jboss.messaging.core.plugin.contract.MessageStore;
 import org.jboss.messaging.core.tx.Transaction;
 import org.jboss.messaging.core.tx.TransactionRepository;
-import org.jboss.messaging.core.util.ConcurrentReaderHashSet;
+import org.jboss.messaging.util.ConcurrentReaderHashSet;
 import org.jboss.remoting.Client;
 import org.jboss.util.id.GUID;
 
@@ -111,14 +108,18 @@
    private ServerPeer serverPeer;
 
    // access to server's extensions
-   private ChannelMapper channelMapper;
+   private Exchange directExchange;
    
+   private Exchange topicExchange;
+   
    private SecurityManager sm;
    
    private ConnectionManager cm;
    
    private TransactionRepository tr;
    
+   private MessageStore ms;
+   
    private Client callbackClient;
    
    private byte usingVersion;
@@ -140,11 +141,13 @@
                                       int defaultTempQueueDownCacheSize)
    {
       this.serverPeer = serverPeer;
-
-      channelMapper = serverPeer.getChannelMapperDelegate();
+      
       sm = serverPeer.getSecurityManager();
       tr = serverPeer.getTxRepository();
       cm = serverPeer.getConnectionManager();
+      ms = serverPeer.getMessageStore();
+      directExchange = serverPeer.getDirectExchangeDelegate();
+      topicExchange = serverPeer.getTopicExchangeDelegate();
 
       started = false;
 
@@ -303,14 +306,26 @@
          for(Iterator i = temporaryDestinations.iterator(); i.hasNext(); )
          {
             JBossDestination dest = (JBossDestination)i.next();
-            CoreDestination cd  = channelMapper.undeployTemporaryCoreDestination(dest.isQueue(), dest.getName());
+
             if (dest.isQueue())
             {
-               //If it's a temp queue then remove it's data-
-               //If it's a topic then the data in the consumers will have been removed when they were closed
-               Queue queue = (Queue)cd;
-               queue.removeAllReferences();
+//               //Unbind
+//               Binding binding = directExchange.unbind(dest.getName());
+//               
+//               //Remove all data for queue - even though it is a temporary queue it may have data in the
+//               //db since it might have gone into paging
+//               
+//               binding.getQueue().removeAllReferences();
+               
+               directExchange.unbindQueue(dest.getName());
+               
             }
+            else
+            {
+               //No need to unbind - this will already have happened, and all removeAllReferences
+               //will have already been called when the subscriptions were closed
+               //which always happens before the connection closed (depth first close)              
+            }
          }
          
          temporaryDestinations.clear();
@@ -631,96 +646,43 @@
       return jmsClientVMId;
    }
 
-   protected void sendMessage(JBossMessage jbm, Transaction tx) throws Exception
+   protected void sendMessage(JBossMessage msg, Transaction tx) throws Exception
    {
-      // The JMSDestination header must already have been set for each message
-      JBossDestination jbDest = (JBossDestination)jbm.getJMSDestination();
-
-      if (jbDest == null)
-      {
-         throw new IllegalStateException("JMSDestination header not set!");
-      }
-
-      CoreDestination coreDestination = channelMapper.getCoreDestination(jbDest);
+      JBossDestination dest = (JBossDestination)msg.getJMSDestination();
       
-      if (coreDestination == null)
-      {
-         throw new JMSException("Destination " + jbDest.getName() + " does not exist");
-      }
+      //We must reference the message *before* we send it the destination to be handled. This is
+      // so we can guarantee that the message doesn't disappear from the store before the
+      // handling is complete. Each channel then takes copies of the reference if they decide to
+      // maintain it internally
       
-      // This allows the no-local consumers to filter out the messages that come from the same
-      // connection
-      // TODO Do we want to set this for ALL messages. Optimisation is possible here.
-      jbm.setConnectionID(connectionID);
+      MessageReference ref = null; 
       
-      Message m = (Message)jbm;
-    
-      if (trace) { log.trace("sending " + jbm + (tx == null ? " non-transactionally" : " transactionally on " + tx + " to the core destination " + jbDest.getName())); }
-      
-      // If we are sending to a topic, then we *always* do the send in the context of a transaction,
-      // in order to ensure that the message is delivered to all durable subscriptions (if any)
-      // attached to the topic. Otherwise if the server crashed in mid send, we may end up with the
-      // message in some, but not all of the durable subscriptions, which would be in contravention
-      // of the spec. When there are many durable subs for the topic, this actually should give us
-      // a performance gain since all the inserts can be done in the same JDBC tx too.
-      
-      boolean internalTx = false;
-      if (m.isReliable() && tx == null && !coreDestination.isQueue())
-      {
-         tx = tr.createTransaction();
-         
-         internalTx = true;
-      }
-      
       try
       {         
-         // We must reference the message *before* we send it the destination to be handled. This is
-         // so we can guarantee that the message doesn't disappear from the store before the
-         // handling is complete. Each channel then takes copies of the reference if they decide to
-         // maintain it internally
+         ref = ms.reference(msg);
          
-         MessageReference ref = this.serverPeer.getMessageStoreDelegate().reference(m);
-         
-         Delivery d;
-         
-         try
-         {         
-            d = coreDestination.handle(null, ref, tx);         
-         }
-         finally
+         if (dest.isQueue())
          {
-            ref.releaseMemoryReference();
+            if (!directExchange.route(ref, dest.getName(), tx))
+            {
+               throw new JMSException("Failed to route message");
+            }
          }
-         
-         if (internalTx)
-         {
-            tx.commit();
+         else
+         {                                
+            topicExchange.route(ref, dest.getName(), tx);           
          }
-         
-         // The core destination is supposed to acknowledge immediately. If not, there's a problem.
-         if (d == null || !d.isDone())
-         {
-            String msg = "The message was not acknowledged by destination " + coreDestination;
-            log.error(msg);
-            throw new MessagingJMSException(msg);
-         }
       }
-      catch (Throwable t)
+      finally
       {
-         if (internalTx)
+         if (ref != null)
          {
-            try
-            {               
-               tx.rollback();
-            }
-            catch (Exception e)
-            {
-               log.error("Failed to rollback internal transaction", e);
-            }
+            ref.releaseMemoryReference();
          }
-         throw new MessagingJMSException("Failed to send message", t);
       }
-   }   
+         
+      if (trace) { log.trace("sent " + msg); }
+   }
 
    // Private -------------------------------------------------------
    
@@ -736,7 +698,7 @@
          started = s;
       }
    }   
-   
+    
    private void processTransaction(TxState txState, Transaction tx) throws Throwable
    {
       if (trace) { log.trace("processing transaction, there are " + txState.getMessages().size() + " messages and " + txState.getAcks().size() + " acks "); }
@@ -744,8 +706,8 @@
       for(Iterator i = txState.getMessages().iterator(); i.hasNext(); )
       {
          JBossMessage m = (JBossMessage)i.next();
+         
          sendMessage(m, tx);
-         if (trace) { log.trace("sent " + m); }
       }
       
       if (trace) { log.trace("done the sends"); }

Modified: trunk/src/main/org/jboss/jms/server/endpoint/ServerConnectionFactoryEndpoint.java
===================================================================
--- trunk/src/main/org/jboss/jms/server/endpoint/ServerConnectionFactoryEndpoint.java	2006-08-30 09:26:13 UTC (rev 1236)
+++ trunk/src/main/org/jboss/jms/server/endpoint/ServerConnectionFactoryEndpoint.java	2006-08-30 18:36:36 UTC (rev 1237)
@@ -108,8 +108,10 @@
          // see if there is a preconfigured client id for the user
          if (username != null)
          {
+            
+            
             String preconfClientID =
-               serverPeer.getChannelMapperDelegate().getPreConfiguredClientID(username);
+               serverPeer.getJMSUserManagerDelegate().getPreConfiguredClientID(username);
             
             if (preconfClientID != null)
             {

Modified: trunk/src/main/org/jboss/jms/server/endpoint/ServerConsumerEndpoint.java
===================================================================
--- trunk/src/main/org/jboss/jms/server/endpoint/ServerConsumerEndpoint.java	2006-08-30 09:26:13 UTC (rev 1236)
+++ trunk/src/main/org/jboss/jms/server/endpoint/ServerConsumerEndpoint.java	2006-08-30 18:36:36 UTC (rev 1237)
@@ -41,18 +41,17 @@
 import org.jboss.jms.server.QueuedExecutorPool;
 import org.jboss.jms.server.remoting.JMSDispatcher;
 import org.jboss.jms.server.remoting.MessagingMarshallable;
-import org.jboss.jms.server.subscription.Subscription;
 import org.jboss.jms.util.ExceptionUtil;
 import org.jboss.logging.Logger;
-import org.jboss.messaging.core.Channel;
 import org.jboss.messaging.core.Delivery;
 import org.jboss.messaging.core.DeliveryObserver;
-import org.jboss.messaging.core.Filter;
 import org.jboss.messaging.core.MessageReference;
 import org.jboss.messaging.core.Receiver;
 import org.jboss.messaging.core.Routable;
 import org.jboss.messaging.core.SimpleDelivery;
-import org.jboss.messaging.core.SingleReceiverDelivery;
+import org.jboss.messaging.core.local.MessageQueue;
+import org.jboss.messaging.core.plugin.contract.Exchange;
+import org.jboss.messaging.core.plugin.exchange.Binding;
 import org.jboss.messaging.core.tx.Transaction;
 import org.jboss.messaging.core.tx.TransactionException;
 import org.jboss.messaging.core.tx.TxCallback;
@@ -71,7 +70,7 @@
  *
  * $Id$
  */
-public class ServerConsumerEndpoint implements Receiver, Filter, ConsumerEndpoint
+public class ServerConsumerEndpoint implements Receiver, ConsumerEndpoint
 {
    // Constants -----------------------------------------------------
 
@@ -89,7 +88,9 @@
 
    private int id;
 
-   private Channel channel;
+   private MessageQueue messageQueue;
+   
+   private String queueName;
 
    private ServerSessionEndpoint sessionEndpoint;
 
@@ -123,10 +124,10 @@
    private Object lock;
 
    private Map deliveries;
-
+   
    // Constructors --------------------------------------------------
 
-   protected ServerConsumerEndpoint(int id, Channel channel,
+   protected ServerConsumerEndpoint(int id, MessageQueue messageQueue, String queueName,
                                     ServerSessionEndpoint sessionEndpoint,
                                     String selector, boolean noLocal, JBossDestination dest,
                                     int prefetchSize)
@@ -135,7 +136,8 @@
       if (trace) { log.trace("constructing consumer endpoint " + id); }
 
       this.id = id;
-      this.channel = channel;
+      this.messageQueue = messageQueue;
+      this.queueName = queueName;
       this.sessionEndpoint = sessionEndpoint;
       this.prefetchSize = prefetchSize;
 
@@ -149,7 +151,7 @@
       QueuedExecutorPool pool =
          sessionEndpoint.getConnectionEndpoint().getServerPeer().getQueuedExecutorPool();
 
-      this.executor = (QueuedExecutor)pool.get("consumer" + id);
+      this.executor = (QueuedExecutor)pool.get();
              
       // Note that using a PooledExecutor with a linked queue is not sufficient to ensure that
       // deliveries for the same consumer happen serially, since even if they are queued serially
@@ -188,11 +190,11 @@
             
       this.started = this.sessionEndpoint.getConnectionEndpoint().isStarted();
 
-      // adding the consumer to the channel
-      this.channel.add(this);
+      // adding the consumer to the queue
+      this.messageQueue.add(this);
       
       // prompt delivery
-      channel.deliver(false);
+      messageQueue.deliver(false);
       
       log.debug(this + " constructed");
    }
@@ -200,7 +202,7 @@
    // Receiver implementation ---------------------------------------
 
    /*
-    * The channel ensures that handle is never called concurrently by more than one thread.
+    * The queue ensures that handle is never called concurrently by more than one thread.
     */
    public Delivery handle(DeliveryObserver observer, Routable reference, Transaction tx)
    {
@@ -221,7 +223,7 @@
       synchronized (lock)
       {  
          // If the consumer is stopped then we don't accept the message, it should go back into the
-         // channel for delivery later.
+         // queue for delivery later.
          if (!started)
          {
             // this is a common programming error, make this visible in the debug logs
@@ -306,10 +308,12 @@
             int conId = ((JBossMessage)r).getConnectionID();
             if (trace) { log.trace("message connection id: " + conId); }
 
-            if (trace) { log.trace("current connection connection id: " + sessionEndpoint.getConnectionEndpoint().getConnectionID()); }
+            if (trace) { log.trace("current connection connection id: " + sessionEndpoint.getConnectionEndpoint().getConnectionID()); }   
+                 
             accept = conId != sessionEndpoint.getConnectionEndpoint().getConnectionID();
+            
             if (trace) { log.trace("accepting? " + accept); }
-
+            
          }
       }
       return accept;
@@ -338,11 +342,11 @@
       {
          synchronized (lock)
          { 
-            // On close we only disconnect the consumer from the Channel we don't actually remove
+            // On close we only disconnect the consumer from the queue we don't actually remove
             // it. This is because it may still contain deliveries that may well be acknowledged
             // after the consumer has closed. This is perfectly valid.
 
-            //FIXME - The deliveries should really be stored in the session endpoint, not here
+            //TODO - The deliveries should really be stored in the session endpoint, not here
             //that is their natural place, that would mean we wouldn't have to mess around with keeping
             //deliveries after this is closed
                   
@@ -350,24 +354,27 @@
             
             JMSDispatcher.instance.unregisterTarget(new Integer(id));
             
-            //If it's a subscription, remove it
-            if (channel instanceof Subscription)
+            //If this is a consumer of a non durable subscription
+            //then we want to unbind the subscription and delete all it's data
+            
+            if (destination.isTopic())
             {
-               Subscription sub = (Subscription)channel;
-               if (!sub.isRecoverable())
+               Exchange topicExchange = 
+                  sessionEndpoint.getConnectionEndpoint().getServerPeer().getTopicExchangeDelegate();
+               
+               Binding binding = topicExchange.getBindingForName(queueName);
+               
+               if (binding == null)
                {
-                  //We don't disconnect durable subs
-                  sub.disconnect();                  
-               }            
-            } 
-            
-            //If it's non recoverable, i.e. it's a non durable sub or a temporary queue
-            //then remove all it's references
-            if (!channel.isRecoverable())
-            {
-               channel.removeAllReferences();
+                  throw new IllegalStateException("Cannot find queue with name " + queueName);
+               }
+               
+               if (!binding.isDurable())
+               {                 
+                  topicExchange.unbindQueue(queueName);
+               }
             }
-            
+                        
             closed = true;
          }
       }
@@ -416,7 +423,7 @@
                   
          //Now we know the deliverer has delivered any outstanding messages to the client buffer
          
-         channel.deliver(false);
+         messageQueue.deliver(false);
       }
       catch (InterruptedException e)
       {
@@ -459,12 +466,12 @@
    {
       if (trace) { log.trace("acknowledging transactionally " + messageID); }
       
-      SingleReceiverDelivery d = null;
+      Delivery d = null;
                  
       // The actual removal of the deliveries from the delivery list is deferred until tx commit
       synchronized (lock)
       {
-         d = (SingleReceiverDelivery)deliveries.get(new Long(messageID));
+         d = (Delivery)deliveries.get(new Long(messageID));
       }
       
       DeliveryCallback deliveryCallback = (DeliveryCallback)tx.getKeyedCallback(this);
@@ -489,11 +496,11 @@
    protected void acknowledge(long messageID) throws Throwable
    {  
       // acknowledge a delivery   
-      SingleReceiverDelivery d;
+      Delivery d;
         
       synchronized (lock)
       {
-         d = (SingleReceiverDelivery)deliveries.remove(new Long(messageID));
+         d = (Delivery)deliveries.remove(new Long(messageID));
       }
       
       if (d != null)
@@ -514,13 +521,14 @@
     **/
    protected void remove() throws Throwable
    {         
-      if (trace) log.trace("attempting to remove receiver " + this + " from destination " + channel);
+      if (trace) log.trace("attempting to remove receiver " + this + " from destination " + messageQueue);
       
       boolean wereDeliveries = false;
       for(Iterator i = deliveries.values().iterator(); i.hasNext(); )
       {
-         SingleReceiverDelivery d = (SingleReceiverDelivery)i.next();
 
+         Delivery d = (Delivery)i.next();
+
          d.cancel();
          wereDeliveries = true;
       }
@@ -541,21 +549,21 @@
       
       if (wereDeliveries)
       {
-         //If we cancelled any deliveries we need to force a deliver on the channel
+         //If we cancelled any deliveries we need to force a deliver on the queue
          //This is because there may be other waiting competing consumers who need a chance to get
          //any of the cancelled messages
-         channel.deliver(false);
+         messageQueue.deliver(false);
       }
    }  
    
    protected void promptDelivery()
    {
-      channel.deliver(false);
+      messageQueue.deliver(false);
    }
    
    protected void cancelDelivery(Long messageID) throws Throwable
    {
-      SingleReceiverDelivery del = (SingleReceiverDelivery)deliveries.remove(messageID);
+      Delivery del = (Delivery)deliveries.remove(messageID);
       if (del != null)
       {  
           del.getReference().decrementDeliveryCount();    
@@ -586,7 +594,7 @@
       }
       
       // Prompt delivery
-      channel.deliver(false);
+      messageQueue.deliver(false);
    }
    
    protected void stop() throws Throwable
@@ -658,18 +666,18 @@
    // Private -------------------------------------------------------
    
    /**
-    * Disconnect this consumer from the Channel that feeds it. This method does not clear up
+    * Disconnect this consumer from the queue that feeds it. This method does not clear up
     * deliveries
     */
    private void disconnect()
    {
 
-      boolean removed = channel.remove(this);
+      boolean removed = messageQueue.remove(this);
       
       if (removed)
       {
          disconnected = true;
-         if (trace) { log.trace(this + " removed from the channel"); }
+         if (trace) { log.trace(this + " removed from the queue"); }
       }
    }
      

Modified: trunk/src/main/org/jboss/jms/server/endpoint/ServerSessionEndpoint.java
===================================================================
--- trunk/src/main/org/jboss/jms/server/endpoint/ServerSessionEndpoint.java	2006-08-30 09:26:13 UTC (rev 1236)
+++ trunk/src/main/org/jboss/jms/server/endpoint/ServerSessionEndpoint.java	2006-08-30 18:36:36 UTC (rev 1237)
@@ -38,25 +38,24 @@
 import org.jboss.jms.delegate.ConsumerDelegate;
 import org.jboss.jms.destination.JBossDestination;
 import org.jboss.jms.destination.JBossQueue;
+import org.jboss.jms.destination.JBossTemporaryTopic;
 import org.jboss.jms.destination.JBossTopic;
 import org.jboss.jms.message.JBossMessage;
+import org.jboss.jms.selector.Selector;
+import org.jboss.jms.server.DestinationManager;
 import org.jboss.jms.server.ServerPeer;
 import org.jboss.jms.server.endpoint.advised.BrowserAdvised;
 import org.jboss.jms.server.endpoint.advised.ConsumerAdvised;
-import org.jboss.jms.server.plugin.contract.ChannelMapper;
 import org.jboss.jms.server.remoting.JMSDispatcher;
-import org.jboss.jms.server.subscription.DurableSubscription;
-import org.jboss.jms.server.subscription.Subscription;
 import org.jboss.jms.tx.AckInfo;
 import org.jboss.jms.util.ExceptionUtil;
+import org.jboss.jms.util.MessageQueueNameHelper;
 import org.jboss.logging.Logger;
-import org.jboss.messaging.core.Channel;
-import org.jboss.messaging.core.local.CoreDestination;
-import org.jboss.messaging.core.local.CoreSubscription;
-import org.jboss.messaging.core.local.Queue;
-import org.jboss.messaging.core.memory.MemoryManager;
+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.Binding;
+import org.jboss.util.id.GUID;
 
 /**
  * Concrete implementation of SessionEndpoint.
@@ -88,11 +87,13 @@
    private Map consumers;
    private Map browsers;
 
-   private ChannelMapper cm;
    private PersistenceManager pm;
    private MessageStore ms;
-   private MemoryManager mm;
+   private DestinationManager dm;
+   private Exchange topicExchange;
+   private Exchange directExchange;
    
+   
    // Constructors --------------------------------------------------
 
    protected ServerSessionEndpoint(int sessionID, ServerConnectionEndpoint connectionEndpoint)
@@ -103,10 +104,11 @@
 
       ServerPeer sp = connectionEndpoint.getServerPeer();
 
-      cm = sp.getChannelMapperDelegate();
       pm = sp.getPersistenceManagerDelegate();
-      ms = sp.getMessageStoreDelegate();
-      mm = sp.getMemoryManager();
+      ms = sp.getMessageStore();
+      dm = sp.getDestinationManager();
+      topicExchange = sp.getTopicExchangeDelegate();
+      directExchange = sp.getDirectExchangeDelegate();
 
       consumers = new HashMap();
 		browsers = new HashMap();  
@@ -115,7 +117,7 @@
    // SessionDelegate implementation --------------------------------
 
 	public ConsumerDelegate createConsumerDelegate(JBossDestination jmsDestination,
-                                                  String selector,
+                                                  String selectorString,
                                                   boolean noLocal,
                                                   String subscriptionName,
                                                   boolean isCC) throws JMSException
@@ -127,13 +129,23 @@
             throw new IllegalStateException("Session is closed");
          }
          
-         if ("".equals(selector))
+         if ("".equals(selectorString))
          {
-            selector = null;
+            selectorString = null;
          }
          
-         log.debug("creating consumer for " + jmsDestination + ", selector " + selector + ", " + (noLocal ? "noLocal, " : "") + "subscription " + subscriptionName);
+         log.debug("creating consumer for " + jmsDestination + ", selector " + selectorString + ", " + (noLocal ? "noLocal, " : "") + "subscription " + subscriptionName);
    
+         //"Refresh" the destination - this will populate it with it's paging values
+         //TODO There's probably a better way of doing this
+         
+         if (!dm.destinationExists(jmsDestination))
+         {
+            throw new InvalidDestinationException("No such destination: " + jmsDestination);
+         } 
+         
+         jmsDestination = dm.getDestination(jmsDestination);
+         
          if (jmsDestination.isTemporary())
          {
             // Can only create a consumer for a temporary destination on the same connection
@@ -144,26 +156,33 @@
                             "to that which created the temporary destination";
                throw new IllegalStateException(msg);
             }
-         }
+         }          
+             
+         int consumerID = connectionEndpoint.getServerPeer().getNextObjectID();
+        
+         Binding binding = null;
          
-         CoreDestination coreDestination = cm.getCoreDestination(jmsDestination);
-         if (coreDestination == null)
+         //Always validate the selector first
+         Selector selector = null;
+         if (selectorString != null)
          {
-            throw new InvalidDestinationException("No such destination: " + jmsDestination);
+            selector = new Selector(selectorString);
          }
-             
-         int consumerID = connectionEndpoint.getServerPeer().getNextObjectID();
-        
-         Subscription subscription = null;
    
          if (jmsDestination.isTopic())
          {
             if (subscriptionName == null)
             {
                // non-durable subscription
-               if (log.isTraceEnabled()) { log.trace("creating new non-durable subscription on " + coreDestination); }
-               subscription =
-                  cm.createSubscription(jmsDestination.getName(), selector, noLocal, ms, pm, mm);
+               if (log.isTraceEnabled()) { log.trace("creating new non-durable subscription on " + jmsDestination); }
+                     
+               binding = topicExchange.bindQueue(new GUID().toString(), jmsDestination.getName(),
+                                                 selector, noLocal,
+                                                 false, ms, pm,
+                                                 jmsDestination.getFullSize(),
+                                                 jmsDestination.getPageSize(),
+                                                 jmsDestination.getDownCacheSize());
+               
             }
             else
             {
@@ -178,25 +197,34 @@
                {
                   throw new JMSException("Cannot create durable subscriber without a valid client ID");
                }
-   
-               subscription = cm.getDurableSubscription(clientID, subscriptionName, ms, pm, mm);
-   
-               if (subscription == null)
+               
+               //See if there any bindings with the same client_id.subscription_name name
+               
+               String name = MessageQueueNameHelper.createSubscriptionName(clientID, subscriptionName);
+               
+               binding = topicExchange.getBindingForName(name);
+                  
+               if (binding == null)
                {
-                  if (trace) { log.trace("creating new durable subscription on " + coreDestination); }
-                  subscription = cm.createDurableSubscription(jmsDestination.getName(),
-                                                              clientID,
-                                                              subscriptionName,
-                                                              selector,
-                                                              noLocal,
-                                                              ms,
-                                                              pm,
-                                                              mm);
+                  //Does not already exist
+                  
+                  if (trace) { log.trace("creating new durable subscription on " + jmsDestination); }
+                  
+                  //Create a new binding for the durable subscription
+
+                  binding = topicExchange.bindQueue(name, jmsDestination.getName(),
+                                                  selector, noLocal,
+                                                  true, ms, pm,
+                                                  jmsDestination.getFullSize(),
+                                                  jmsDestination.getPageSize(),
+                                                  jmsDestination.getDownCacheSize());
                }
                else
                {
+                  //Durable sub already exists
+                  
                   if (trace) { log.trace("subscription " + subscriptionName + " already exists"); }
-   
+                  
                   // From javax.jms.Session Javadoc (and also JMS 1.1 6.11.1):
                   // A client can change an existing durable subscription by creating a durable
                   // TopicSubscriber with the same name and a new topic and/or message selector.
@@ -204,67 +232,64 @@
                   // one and creating a new one.
    
                   boolean selectorChanged =
-                     (selector == null && subscription.getSelector() != null) ||
-                     (subscription.getSelector() == null && selector != null) ||
-                     (subscription.getSelector() != null && selector != null &&
-                     !subscription.getSelector().equals(selector));
+                     (selectorString == null && binding.getSelector() != null) ||
+                     (binding.getSelector() == null && selectorString != null) ||
+                     (binding.getSelector() != null && selectorString != null &&
+                     !binding.getSelector().equals(selectorString));
                   
                   if (trace) { log.trace("selector " + (selectorChanged ? "has" : "has NOT") + " changed"); }
    
-                  boolean topicChanged =  subscription.getTopic().getId() != coreDestination.getId();
+                  boolean topicChanged = !binding.getCondition().equals(jmsDestination.getName());
                   
                   if (log.isTraceEnabled()) { log.trace("topic " + (topicChanged ? "has" : "has NOT") + " changed"); }
                   
-                  boolean noLocalChanged = noLocal != subscription.isNoLocal();
+                  boolean noLocalChanged = noLocal != binding.isNoLocal();
    
                   if (selectorChanged || topicChanged || noLocalChanged)
-                  {
+                  {    
                      if (trace) { log.trace("topic or selector or noLocal changed so deleting old subscription"); }
    
-                     boolean removed =
-                        cm.removeDurableSubscription(connectionEndpoint.getClientID(), subscriptionName);
+                     // Unbind the durable subscription
+                     
+                     topicExchange.unbindQueue(name);
    
-                     if (!removed)
-                     {
-                        throw new InvalidDestinationException("Cannot find durable subscription " +
-                                                              subscriptionName + " to unsubscribe");
-                     }
-   
-                     //Remove data for the durable sub
-                     ((DurableSubscription)subscription).unsubscribe();
-   
                      // create a fresh new subscription
-                     subscription = cm.createDurableSubscription(jmsDestination.getName(),
-                                                                 clientID,
-                                                                 subscriptionName,
-                                                                 selector,
-                                                                 noLocal,
-                                                                 ms,
-                                                                 pm,
-                                                                 mm);
+                     
+                     binding = topicExchange.bindQueue(name, jmsDestination.getName(),
+                                                     selector, noLocal,
+                                                     true, ms, pm,
+                                                     jmsDestination.getFullSize(),
+                                                     jmsDestination.getPageSize(),
+                                                     jmsDestination.getDownCacheSize());
                   }               
                }
             }
          }
+         else
+         {
+            //Consumer on a jms queue
+            
+            //Let's find the binding
+            binding = directExchange.getBindingForName(jmsDestination.getName());
+            
+            if (binding == null)
+            {
+               throw new IllegalStateException("Cannot find binding for jms queue: " + jmsDestination.getName());
+            }
+         }
          
          int prefetchSize = connectionEndpoint.getPrefetchSize();
          
          ServerConsumerEndpoint ep =
-            new ServerConsumerEndpoint(consumerID,
-                                       subscription == null ? (Channel)coreDestination : subscription,
-                                       this, selector, noLocal, jmsDestination, prefetchSize);
+            new ServerConsumerEndpoint(consumerID, binding.getQueue(), binding.getQueueName(),
+                                       this, selectorString, noLocal, jmsDestination, prefetchSize);
           
          JMSDispatcher.instance.registerTarget(new Integer(consumerID), new ConsumerAdvised(ep));
-            
-         
+                     
          ClientConsumerDelegate stub = new ClientConsumerDelegate(consumerID, prefetchSize);
+                       
+         putConsumerEndpoint(consumerID, ep); // caching consumer locally
          
-         if (subscription != null)
-         {
-            subscription.connect();
-         }
-               
-         putConsumerEndpoint(consumerID, ep); // caching consumer locally
          connectionEndpoint.getServerPeer().putConsumerEndpoint(consumerID, ep); // cachin consumer in server peer
          
          log.debug("created and registered " + ep);
@@ -291,23 +316,23 @@
    	   {
    	      throw new InvalidDestinationException("null destination");
    	   }
+         
+         if (jmsDestination.isTopic())
+         {
+            throw new IllegalStateException("Cannot browse a topic");
+         }
    	   
-   	   CoreDestination destination = cm.getCoreDestination(jmsDestination);
-   	   
-   	   if (destination == null)
-   	   {
-   	      throw new InvalidDestinationException("No such destination: " + jmsDestination);
-   	   }
-   	   
-   	   if (!(destination instanceof Queue))
-   	   {
-   	      throw new IllegalStateException("Cannot browse a topic");
-   	   }
-   	   
+         if (!dm.destinationExists(jmsDestination))
+         {
+            throw new InvalidDestinationException("No such destination: " + jmsDestination);
+         }
+         
+         Binding binding = directExchange.getBindingForName(jmsDestination.getName());
+         
    	   int browserID = connectionEndpoint.getServerPeer().getNextObjectID();
    	   
    	   ServerBrowserEndpoint ep =
-   	      new ServerBrowserEndpoint(this, browserID, (Channel)destination, messageSelector);
+   	      new ServerBrowserEndpoint(this, browserID, binding.getQueue(), messageSelector);
    	   
    	   putBrowserDelegate(browserID, ep);
    	   
@@ -334,12 +359,10 @@
             throw new IllegalStateException("Session is closed");
          }
          
-         CoreDestination coreDestination = cm.getCoreDestination(new JBossQueue(name));
-   
-         if (coreDestination == null)
+         if (!dm.destinationExists(new JBossQueue(name)))
          {
             throw new JMSException("There is no administratively defined queue with name:" + name);
-         }
+         }        
    
          return new JBossQueue(name);
       }
@@ -358,12 +381,10 @@
             throw new IllegalStateException("Session is closed");
          }
          
-         CoreDestination coreDestination = cm.getCoreDestination(new JBossTopic(name));
-   
-         if (coreDestination == null)
+         if (!dm.destinationExists(new JBossTopic(name)))
          {
             throw new JMSException("There is no administratively defined topic with name:" + name);
-         }
+         } 
    
          return new JBossTopic(name);
       }
@@ -509,13 +530,30 @@
          }
          connectionEndpoint.addTemporaryDestination(dest);
          
-         //FIXME - Params should not be hardcoded
-         long id = connectionEndpoint.getServerPeer().getNextObjectID();
+         //Register with the destination manager
          
-         cm.deployTemporaryCoreDestination(dest.isQueue(), dest.getName(), id, ms, pm, mm,
-                                           connectionEndpoint.getDefaultTempQueueFullSize(),
-                                           connectionEndpoint.getDefaultTempQueuePageSize(),
-                                           connectionEndpoint.getDefaultTempQueueDownCacheSize());
+         if (dest.isTopic())
+         {
+            //TODO - we should find a better way of maintaining the paging params
+            dest = new JBossTemporaryTopic(dest.getName(),
+                     connectionEndpoint.getDefaultTempQueueFullSize(),
+                     connectionEndpoint.getDefaultTempQueuePageSize(),
+                     connectionEndpoint.getDefaultTempQueueDownCacheSize());
+         }
+         
+         dm.registerDestination(dest, null, null);
+         
+         if (dest.isQueue())
+         {
+            //Create a new binding
+
+            directExchange.bindQueue(dest.getName(), dest.getName(),
+                                     null, false,
+                                     false, ms, pm,
+                                     connectionEndpoint.getDefaultTempQueueFullSize(),
+                                     connectionEndpoint.getDefaultTempQueuePageSize(),
+                                     connectionEndpoint.getDefaultTempQueueDownCacheSize());        
+         }         
       }
       catch (Throwable t)
       {
@@ -537,35 +575,30 @@
             throw new InvalidDestinationException("Destination:" + dest + " is not a temporary destination");
          }
          
-         //It is illegal to delete a temporary destination if there any active consumers on it
-         CoreDestination destination = cm.getCoreDestination(dest);
-         
-         if (destination == null)
+         if (!dm.destinationExists(dest))
          {
-            throw new InvalidDestinationException("Destination:" + dest + " does not exist");         
+            throw new InvalidDestinationException("Destination:" + dest + " does not exist");      
          }
-         
-         if (dest instanceof JBossQueue)
+                  
+         if (dest.isQueue())
          {
-            if (destination.iterator().hasNext())
-            {
-               throw new IllegalStateException("Cannot delete temporary destination, since it has active consumer(s)");
-            }
+            //Unbind
+            directExchange.unbindQueue(dest.getName());
          }
-         else if (dest instanceof JBossTopic)
+         else
          {
-            Iterator iter = destination.iterator();
-            while (iter.hasNext())
+            //Topic
+            
+            List bindings = topicExchange.listBindingsForWildcard(dest.getName());
+            
+            if (!bindings.isEmpty())
             {
-               CoreSubscription sub = (CoreSubscription)iter.next();
-               if (sub.iterator().hasNext())
-               {
-                  throw new IllegalStateException("Cannot delete temporary destination, since it has active consumer(s)");
-               }
+               throw new IllegalStateException("Cannot delete temporary destination, since it has active consumer(s)");
             }
          }
          
-         cm.undeployTemporaryCoreDestination(dest.isQueue(), dest.getName());
+         dm.unregisterDestination(dest);         
+            
          connectionEndpoint.removeTemporaryDestination(dest);
       }
       catch (Throwable t)
@@ -593,25 +626,20 @@
          {
             throw new JMSException("null clientID on connection");
          }
-   
-         DurableSubscription subscription =
-            cm.getDurableSubscription(clientID, subscriptionName, ms, pm, mm);
-   
-         if (subscription == null)
+         
+         String queueName = MessageQueueNameHelper.createSubscriptionName(clientID, subscriptionName);
+         
+         Binding binding = topicExchange.getBindingForName(queueName);
+         
+         if (binding == null)
          {
             throw new InvalidDestinationException("Cannot find durable subscription with name " +
                                                   subscriptionName + " to unsubscribe");
          }
          
-         boolean removed =
-            cm.removeDurableSubscription(connectionEndpoint.getClientID(), subscriptionName);
-         
-         if (!removed)
-         {
-            throw new JMSException("Failed to remove durable subscription");
-         }
-         
-         subscription.unsubscribe();      
+         //Unbind it
+  
+         topicExchange.unbindQueue(queueName);
       }
       catch (Throwable t)
       {

Deleted: trunk/src/main/org/jboss/jms/server/plugin/JDBCChannelMapper.java
===================================================================
--- trunk/src/main/org/jboss/jms/server/plugin/JDBCChannelMapper.java	2006-08-30 09:26:13 UTC (rev 1236)
+++ trunk/src/main/org/jboss/jms/server/plugin/JDBCChannelMapper.java	2006-08-30 18:36:36 UTC (rev 1237)
@@ -1,1352 +0,0 @@
-/*
- * JBoss, the OpenSource J2EE webOS
- * 
- * Distributable under LGPL license.
- * See terms of license at gnu.org.
- */
-package org.jboss.jms.server.plugin;
-
-import java.io.ByteArrayInputStream;
-import java.io.ByteArrayOutputStream;
-import java.io.IOException;
-import java.sql.Connection;
-import java.sql.PreparedStatement;
-import java.sql.ResultSet;
-import java.sql.SQLException;
-import java.sql.Statement;
-import java.sql.Types;
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.HashSet;
-import java.util.Iterator;
-import java.util.List;
-import java.util.Map;
-import java.util.Properties;
-import java.util.Set;
-
-import javax.jms.JMSException;
-import javax.management.MBeanServerInvocationHandler;
-import javax.management.ObjectName;
-import javax.naming.InitialContext;
-import javax.sql.DataSource;
-import javax.transaction.Status;
-import javax.transaction.TransactionManager;
-
-import org.jboss.jms.destination.JBossDestination;
-import org.jboss.jms.destination.JBossQueue;
-import org.jboss.jms.destination.JBossTopic;
-import org.jboss.jms.selector.Selector;
-import org.jboss.jms.server.QueuedExecutorPool;
-import org.jboss.jms.server.plugin.contract.ChannelMapper;
-import org.jboss.jms.server.subscription.DurableSubscription;
-import org.jboss.jms.server.subscription.Subscription;
-import org.jboss.jms.util.ExceptionUtil;
-import org.jboss.jms.util.MessagingJMSException;
-import org.jboss.logging.Logger;
-import org.jboss.messaging.core.local.CoreDestination;
-import org.jboss.messaging.core.local.CoreSubscription;
-import org.jboss.messaging.core.local.Queue;
-import org.jboss.messaging.core.local.Topic;
-import org.jboss.messaging.core.memory.MemoryManager;
-import org.jboss.messaging.core.persistence.JDBCUtil;
-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.system.ServiceMBeanSupport;
-import org.jboss.tm.TransactionManagerServiceMBean;
-
-import EDU.oswego.cs.dl.util.concurrent.ConcurrentReaderHashMap;
-import EDU.oswego.cs.dl.util.concurrent.QueuedExecutor;
-
-/**
- * JDBC Implementation of ChannelMapper
- * @author <a href="mailto:tim.fox at jboss.com">Tim Fox</a>
- * @author <a href="mailto:ovidiu at jboss.org">Ovidiu Feodorov</a>
- * @author <a href="mailto:adrian at jboss.org">Adrian Brock</a>
- * @author <a href="mailto:ivelin at jboss.org">Ivelin Ivanov</a>
- *
- * JDBCChannelMapper.java,v 1.1 2006/03/01 09:15:09 timfox Exp
- */
-public class JDBCChannelMapper extends ServiceMBeanSupport implements ChannelMapper
-{
-   // Constants -----------------------------------------------------
-   
-   private static final Logger log = Logger.getLogger(JDBCChannelMapper.class);
-   
-   protected static final char TYPE_QUEUE = 'Q';
-   
-   protected static final char TYPE_TOPIC = 'T';
-   
-   protected static final char TYPE_DURABLE_SUB = 'D';
-   
-   //========================================
-   
-   //FIXME - user-role table management should be handled by a different service
-   //It doesn't belong here
-   
-   private String createUserTable =
-      "CREATE TABLE JMS_USER (USERID VARCHAR(32) NOT NULL, PASSWD VARCHAR(32) NOT NULL, CLIENTID VARCHAR(128),"
-      + " PRIMARY KEY(USERID))";
-   
-   private String createRoleTable = "CREATE TABLE JMS_ROLE (ROLEID VARCHAR(32) NOT NULL, USERID VARCHAR(32) NOT NULL,"
-      + " PRIMARY KEY(USERID, ROLEID))";
-   
-   private String selectPreConfClientId = 
-      "SELECT CLIENTID FROM JMS_USER WHERE USERID=?";
-   
-   
-   // =============================================================================
-   
-   private String createMappingTable = 
-      "CREATE TABLE JMS_CHANNEL_MAPPING (ID BIGINT, TYPE CHAR(1), " +
-      "JMS_DEST_NAME VARCHAR(1024), JMS_SUB_NAME VARCHAR(1024), " +
-      "CLIENT_ID VARCHAR(128), SELECTOR VARCHAR(1024), NO_LOCAL CHAR(1), PRIMARY KEY(ID))";
-   
-   private String insertMapping = 
-      "INSERT INTO JMS_CHANNEL_MAPPING (ID, TYPE, JMS_DEST_NAME, JMS_SUB_NAME, CLIENT_ID, SELECTOR, NO_LOCAL) " +
-      "VALUES (?, ?, ?, ?, ?, ?, ?)";
-   
-   private String deleteMapping =
-      "DELETE FROM JMS_CHANNEL_MAPPING WHERE ID = ?";
-   
-   private String selectIdForDestination = 
-      "SELECT ID FROM JMS_CHANNEL_MAPPING WHERE TYPE=? AND JMS_DEST_NAME=?";
-   
-   private String selectDurableSub = 
-      "SELECT JMS_DEST_NAME, ID, SELECTOR, NO_LOCAL FROM JMS_CHANNEL_MAPPING WHERE CLIENT_ID=? AND JMS_SUB_NAME=?";
-   
-   private String selectSubscriptionsForTopic = 
-      "SELECT ID, CLIENT_ID, JMS_SUB_NAME, SELECTOR, NO_LOCAL FROM JMS_CHANNEL_MAPPING WHERE TYPE='D' AND J" +
-      "MS_DEST_NAME=?";
-   
-   // Static --------------------------------------------------------
-   
-   // Attributes ----------------------------------------------------
-   
-   // Map<clientID - Map<subscriptionName - CoreDurableSubscription>>
-   protected Map subscriptions;
-   
-   // Map<name - Queue>
-   protected Map queues;
-   
-   // Map<name - Topic>
-   protected Map topics;
-   
-   // Map<id - JBossDestination>
-   protected Map idMap;
-   
-   protected String dataSourceJNDIName;
-   protected DataSource ds;
-   protected ObjectName tmObjectName;
-
-   protected IdManager channelIDManager;
-   
-   protected boolean createTablesOnStartup = true;
-   protected Properties sqlProperties;
-   protected List populateTables;
-   
-   protected QueuedExecutorPool queuedExecutorPool;
-
-   // Constructors --------------------------------------------------
-   
-   public JDBCChannelMapper()
-   {
-      subscriptions = new ConcurrentReaderHashMap();
-      
-      queues = new ConcurrentReaderHashMap();
-      
-      topics = new ConcurrentReaderHashMap();
-      
-      idMap = new ConcurrentReaderHashMap();
-      
-      sqlProperties = new Properties();
-      
-      populateTables = new ArrayList();
-   }
-   
-   /*
-    * Only to be used by tests to create an instance
-    */
-   public JDBCChannelMapper(DataSource ds, TransactionManager tm)
-   {
-      this();
-
-      this.ds = ds;
-
-      this.tm = tm;
-   }
-
-   //Injection
-   
-   //TODO
-   //Since channel mapper requires knowledge of the persistence manager anyway so it can get ids for new channels
-   //there seems to me no reason why channel mapper should handle it's own persistence
-   //IMHO all persistence should be handled by the pm
-   public void setPersistenceManager(PersistenceManager pm) throws Exception
-   {      
-      this.channelIDManager = new IdManager("CHANNEL_ID", 10, pm);
-   }
-   
-   public void setQueuedExecutorPool(QueuedExecutorPool pool) throws Exception
-   {
-      this.queuedExecutorPool = pool;
-   }
-   
-   // ServiceMBeanSupport overrides ---------------------------------
-   
-   protected void startService() throws Exception
-   {
-      try
-      {
-         if (ds == null)
-         {
-            InitialContext ic = new InitialContext();
-            ds = (DataSource)ic.lookup(dataSourceJNDIName);
-            ic.close();
-         }
-         
-         if (ds == null)
-         {
-            throw new IllegalStateException("No DataSource found. This service dependencies must " +
-            "have not been enforced correctly!");
-         }
-   
-         initSqlProperties();
-         
-         if (createTablesOnStartup)
-         {
-            createSchema();
-         }
-         
-         log.debug(this + " started");
-      }
-      catch (Throwable t)
-      {
-         throw ExceptionUtil.handleJMXInvocation(t, this + " startService");
-      } 
-   }
-   
-   protected void stopService() throws Exception
-   {
-      log.debug(this + " stopped");
-   }
-   
-   // DurableSubscriptionStore implementation ---------------
-   
-   public Object getInstance()
-   {
-      return this;
-   }
-   
-   public CoreDestination getCoreDestination(JBossDestination jbDest)
-   {
-      return getCoreDestinationInternal(jbDest.isQueue(), jbDest.getName());
-   }
-   
-   public JBossDestination getJBossDestination(long coreDestinationId)
-   {
-      return (JBossDestination)idMap.get(new Long(coreDestinationId));
-   }
-   
-   
-    
-   public void deployCoreDestination(boolean isQueue, 
-                                     String destName,
-                                     MessageStore ms, 
-                                     PersistenceManager pm,
-                                     MemoryManager mm,
-                                     int fullSize, 
-                                     int pageSize, 
-                                     int downCacheSize) throws Exception
-   {        
-      if (log.isTraceEnabled()) { log.trace("creating core destination for " + destName); }
-      
-      CoreDestination cd = getCoreDestinationInternal(isQueue, destName);
-      if (cd != null)
-      {
-         throw new JMSException("Destination " + destName + " already deployed");
-      }
-      
-      // Might already be in db
-      long id;
-      Long l = getIdForDestination(isQueue, destName);
-      if (l == null)
-      {
-         //Not in db - insert a new mapping row
-         id = this.getNextId();
-         
-         insertMappingRow(id, isQueue ? TYPE_QUEUE : TYPE_TOPIC,
-                          destName, null, null, null, null);
-      }
-      else
-      {
-         id = l.longValue();
-      }
-      
-      // TODO I am using LocalQueues for the time being, switch to distributed Queues
-      if (isQueue)
-      {
-         //We allocate an executor for the queue from the rotating pool
-         QueuedExecutor executor = (QueuedExecutor)queuedExecutorPool.get(destName);
-         
-         cd = new Queue(id, ms, pm, mm, true, fullSize, pageSize, downCacheSize, executor);
-         
-         try
-         {
-            // we load the queue with any state it might have in the db
-            ((Queue)cd).load();
-         }
-         catch (Exception e)
-         {
-            log.error("Failed to load queue state", e);
-            JMSException e2 = new JMSException("Failed to load queue state");
-            e2.setLinkedException(e);
-            throw e2;
-         }
-         
-         queues.put(destName, cd);
-      }
-      else
-      {
-         // TODO I am using LocalTopics for the time being, switch to distributed Topics
-         cd = new Topic(id, fullSize, pageSize, downCacheSize);
-         
-         topics.put(destName, cd);
-         
-         // TODO: The following piece of code may be better placed either in the Topic itself or in
-         //       the DurableSubscriptionStore - I'm not sure it really belongs here
-         
-         // Load any durable subscriptions for the Topic
-         List durableSubs = loadDurableSubscriptionsForTopic(destName, ms, pm, mm);
-         
-         Iterator iter = durableSubs.iterator();
-         while (iter.hasNext())
-         {
-            DurableSubscription sub = (DurableSubscription)iter.next();
-            //load the state of the dub
-            try
-            {
-               sub.load();
-            }
-            catch (Exception e)
-            {
-               log.error("Failed to load queue state", e);
-               JMSException e2 = new JMSException("Failed to load durable subscription state");
-               e2.setLinkedException(e);
-               throw e2;
-            }
-            //and connect it to the Topic
-            sub.connect();
-         }
-      }
-      
-      // Put in id map too
-      
-      JBossDestination jbd ;
-      
-      if (isQueue)
-      {
-         jbd = new JBossQueue(destName);
-      }
-      else
-      {
-         jbd =  new JBossTopic(destName);
-      }
-      
-      idMap.put(new Long(id), jbd);
-
-      log.debug("core destination " + cd + " (fullSize=" + fullSize + ", pageSize=" +
-                pageSize  + ", downCacheSize=" + downCacheSize + ") deployed");
-   }
-         
-   public CoreDestination undeployCoreDestination(boolean isQueue, String destName)
-      throws Exception
-   {
-      Map m = isQueue ? queues : topics;
-      
-      CoreDestination dest = (CoreDestination)m.remove(destName);
-      
-      if (dest != null)
-      {      
-         idMap.remove(new Long(dest.getId()));
-         
-         //If topic need to remove durable subs from map too
-         
-         if (!isQueue)
-         {
-            Topic topic = (Topic)dest;
-            
-            Iterator iter = topic.iterator();
-            
-            while (iter.hasNext())
-            {
-               CoreSubscription sub = (CoreSubscription)iter.next();
-               
-               if (sub.isRecoverable())
-               {
-                  DurableSubscription dursub = (DurableSubscription)sub;
-                  
-                  String clientID = dursub.getClientID();
-                  
-                  String name = dursub.getName();
-                  
-                  removeDurableSubscriptionInMemory(clientID, name);
-               }
-            }
-         }
-         
-      }
-      
-      return dest;
-   }
-   
-   
-   public void deployTemporaryCoreDestination(boolean isQueue, 
-            String destName,
-            long id,
-            MessageStore ms, 
-            PersistenceManager pm,
-            MemoryManager mm,
-            int fullSize, 
-            int pageSize, 
-            int downCacheSize) throws Exception
-   {        
-      if (log.isTraceEnabled()) { log.trace("creating temporary core destination for " + destName); }
-      
-      CoreDestination cd = getCoreDestinationInternal(isQueue, destName);
-      if (cd != null)
-      {
-         throw new JMSException("Destination " + destName + " already deployed");
-      }      
-      
-      if (isQueue)
-      {
-         //We allocate an executor for the queue from the rotating pool
-         QueuedExecutor executor = (QueuedExecutor)queuedExecutorPool.get(destName);
-         
-         cd = new Queue(id, ms, pm, mm, false, fullSize, pageSize, downCacheSize, executor);                 
-         
-         queues.put(destName, cd);
-      }
-      else
-      {
-         cd = new Topic(id, fullSize, pageSize, downCacheSize);
-         
-         topics.put(destName, cd);         
-      }
-      
-      //Put in id map too
-      
-      JBossDestination jbd ;
-      
-      if (isQueue)
-      {
-         jbd = new JBossQueue(destName);
-      }
-      else
-      {
-         jbd =  new JBossTopic(destName);
-      }
-      
-      idMap.put(new Long(id), jbd);
-      
-      log.debug("core destination " + cd + " (fullSize=" + fullSize + ", pageSize=" +
-               pageSize  + ", downCacheSize=" + downCacheSize + ") deployed");
-   }
-   
-   public CoreDestination undeployTemporaryCoreDestination(boolean isQueue, String destName)
-      throws Exception
-   {
-      Map m = isQueue ? queues : topics;
-      
-      CoreDestination dest = (CoreDestination)m.remove(destName);
-      
-      if (dest != null)
-      {      
-         idMap.remove(new Long(dest.getId())); 
-      }
-      
-      return dest;
-   }
-   
-   public DurableSubscription getDurableSubscription(String clientID,
-                                                     String subscriptionName,                                                         
-                                                     MessageStore ms,
-                                                     PersistenceManager pm,
-                                                     MemoryManager mm)
-      throws Exception
-   {
-      // Look in memory first
-      DurableSubscription sub = getDurableSubscription(clientID, subscriptionName);
-      
-      if (sub != null)
-      {
-         return sub;
-      }
-      
-      //Now look in the db        
-      Connection conn = null;
-      PreparedStatement ps  = null;
-      ResultSet rs = null;
-      TransactionWrapper wrap = new TransactionWrapper();
-      
-      try
-      {
-         conn = ds.getConnection();
-         
-         ps = conn.prepareStatement(selectDurableSub);
-         
-         ps.setString(1, clientID);
-         ps.setString(2, subscriptionName);
-         
-         boolean exists = false;
-         
-         try
-         {
-            rs = ps.executeQuery();
-            exists = rs.next();
-         }
-         finally
-         {
-            if (log.isTraceEnabled())
-            {
-               String s = JDBCUtil.statementToString(selectDurableSub, clientID, subscriptionName);
-               log.trace(s + (rs == null ? " failed!" : (exists ? " returned rows" : " did NOT return rows")));
-            }
-         }
-         
-         if (exists)
-         {
-            String topicName = rs.getString(1);
-            long id = rs.getLong(2);
-            String selector = rs.getString(3);
-            boolean noLocal = rs.getString(4).equals("Y");
-            
-            Selector sel = selector == null ? null : new Selector(selector);
-            
-            Map subs = (Map)subscriptions.get(clientID);
-            if (subs == null)
-            {
-               subs = new ConcurrentReaderHashMap();
-               subscriptions.put(clientID, subs);
-            }
-            
-            //The subscription might be in the database, but the Topic which owns the subscription
-            //might not be deployed.
-            //In this case the user needs to make sure the Topic is deployed
-            
-            Topic topic = (Topic)getCoreDestinationInternal(false, topicName);
-            
-            if (topic == null)
-            {
-               throw new MessagingJMSException("Unable to get subscription: " + subscriptionName
-                     + " for client-id: "
-                     + clientID + " which belongs to topic: " + topicName
-                     + " since this topic is not currently deployed. Please deploy the topic and try again");
-            }
-            
-            
-            // create in memory
-            sub = createDurableSubscriptionInternal(id, topicName, clientID, subscriptionName, sel,
-                                                    noLocal, ms, pm, mm);
-            
-            // load its state
-            sub.load();
-         }
-         
-         return sub;
-      }
-      finally
-      {
-         if (rs != null)
-         {
-            rs.close();
-         }
-         if (ps != null)
-         {
-            ps.close();
-         }
-         if (conn != null)
-         {
-            conn.close();
-         }
-         wrap.end();
-      }      
-   }
-     
-   public DurableSubscription createDurableSubscription(String topicName,
-                                                         String clientID,
-                                                         String subscriptionName, 
-                                                         String selector, 
-                                                         boolean noLocal,                                                            
-                                                         MessageStore ms,
-                                                         PersistenceManager pm,
-                                                         MemoryManager mm) throws Exception
-   {
-      Selector sel = selector == null ? null : new Selector(selector);
-      
-      long id;
-
-      //First insert a row in the db
-      id = this.getNextId();
-      
-      insertMappingRow(id, TYPE_DURABLE_SUB, topicName, subscriptionName, clientID,
-                       selector, new Boolean(noLocal));
-            
-      return createDurableSubscriptionInternal(id, topicName, clientID, subscriptionName, sel,
-                                               noLocal, ms, pm, mm);          
-   }
-
-   public Subscription createSubscription(String topicName, String selector, boolean noLocal,
-                                          MessageStore ms, PersistenceManager pm,
-                                          MemoryManager mm)
-      throws Exception
-   {
-      Selector sel = selector == null ? null : new Selector(selector);
-
-      long id = this.getNextId();
-      
-      Topic topic = (Topic)getCoreDestinationInternal(false, topicName);
-      
-      if (topic == null)
-      {
-         throw new javax.jms.IllegalStateException("Topic " + topicName + " is not loaded");
-      }
-
-      //We allocate an executor for the subscription from the rotating pool
-      //Currently all subscriptions for the same topic share the same executor
-      QueuedExecutor executor = (QueuedExecutor)queuedExecutorPool.get(topicName);
-               
-      return new Subscription(id, topic, ms, pm, mm,
-                              topic.getFullSize(), topic.getPageSize(),
-                              topic.getDownCacheSize(), executor, sel, noLocal);
-   }
-   
-   
-   
-   public boolean removeDurableSubscription(String clientID, String subscriptionName)
-      throws Exception
-   {
-      DurableSubscription removed = removeDurableSubscriptionInMemory(clientID, subscriptionName);
-      
-      if (removed != null)
-      {
-         //Now remove from db
-         deleteMappingRow(removed.getChannelID());
-         
-         return true;
-      }
-      else
-      {
-         return false;
-      }
-   }
-   
-   //FIXME - This doesn't belong here
-   public String getPreConfiguredClientID(String username) throws Exception
-   {
-      try
-      {
-         Connection conn = null;
-         PreparedStatement ps  = null;
-         ResultSet rs = null;
-         TransactionWrapper wrap = new TransactionWrapper();
-         
-         try
-         {
-            conn = ds.getConnection();
-            
-            ps = conn.prepareStatement(selectPreConfClientId);
-            
-            ps.setString(1, username);
-            
-            rs = ps.executeQuery();
-            
-            String clientID = null;
-            
-            if (rs.next())
-            {
-               clientID = rs.getString(1);
-            }
-            
-            return clientID;
-         }
-         catch (SQLException e)
-         {
-            wrap.exceptionOccurred();
-            throw e;
-         }
-         finally
-         {
-            if (rs != null)
-            {
-               rs.close();
-            }
-            if (ps != null)
-            {
-               ps.close();
-            }
-            if (conn != null)
-            {
-               conn.close();
-            }
-            wrap.end();
-         }
-      }
-      catch (Exception e)
-      {
-         final String msg = "Failed to get client id";
-         log.error(msg, e);
-         JMSException e2 = new JMSException(msg);
-         e2.setLinkedException(e);
-         throw e2;
-      }
-   }
-   
- 
-   
-   // MBean operations ----------------------------------------------
-   
-   public String getSqlProperties()
-   {
-      try
-      {
-         ByteArrayOutputStream boa = new ByteArrayOutputStream();
-         sqlProperties.store(boa, "");
-         return new String(boa.toByteArray());
-      }
-      catch (IOException shouldnothappen)
-      {
-         return "";
-      }
-   }
-   
-   public void setSqlProperties(String value)
-   {
-      try
-      {
-         
-         ByteArrayInputStream is = new ByteArrayInputStream(value.getBytes());
-         sqlProperties = new Properties();
-         sqlProperties.load(is);
-         
-      }
-      catch (IOException shouldnothappen)
-      {
-         log.error("Caught IOException", shouldnothappen);
-      }
-   }
-   
-   // Public --------------------------------------------------------
-   
-   /**
-    * Managed attribute.
-    */
-   public void setDataSource(String dataSourceJNDIName) throws Exception
-   {
-      this.dataSourceJNDIName = dataSourceJNDIName;
-   }
-   
-   /**
-    * Managed attribute.
-    */
-   public String getDataSource()
-   {
-      return dataSourceJNDIName;
-   }
-   
-   /**
-    * Managed attribute.
-    */
-   public void setTransactionManager(ObjectName tmObjectName) throws Exception
-   {
-      this.tmObjectName = tmObjectName;
-   }
-   
-   /**
-    * Managed attribute.
-    */
-   public ObjectName getTransactionManager()
-   {
-      return tmObjectName;
-   }
-
-   /**
-    * Managed attribute.
-    */
-   public boolean isCreateTablesOnStartup() throws Exception
-   {
-      return createTablesOnStartup;
-   }
-
-   /**
-    * Managed attribute.
-    */
-   public void setCreateTablesOnStartup(boolean b) throws Exception
-   {
-      createTablesOnStartup = b;
-   }
-   
-   /**
-    * @return a Set<String>. It may return an empty Set, but never null.
-    */
-   public Set getSubscriptions(String clientID)
-   {
-      Map m = (Map)subscriptions.get(clientID);
-      if (m == null)
-      {
-         return Collections.EMPTY_SET;
-      }
-      // concurrent keyset is not serializable
-      Set result = new HashSet();
-      result.addAll(m.keySet());
-      return result;
-   }
-   
-   public String toString()
-   {
-      return "JDBCChannelMapper[" + Integer.toHexString(hashCode()) + "]";
-   }
-   
-   // Package protected ---------------------------------------------
-   
-   // Protected -----------------------------------------------------
-   
-   protected DurableSubscription removeDurableSubscriptionInMemory(String clientID, String subscriptionName)
-      throws JMSException
-   {
-      if (log.isTraceEnabled()) { log.trace("removing durable subscription " + subscriptionName); }
-      
-      if (clientID == null)
-      {
-         throw new JMSException("Client ID must be set for connection!");
-      }
-   
-      Map subs = (Map)subscriptions.get(clientID);
-   
-      if (subs == null)
-      {
-         return null;
-      }
-   
-      if (log.isTraceEnabled()) { log.trace("removing durable subscription " + subscriptionName); }
-   
-      DurableSubscription removed = (DurableSubscription)subs.remove(subscriptionName);
-      
-      if (removed == null)
-      {
-         return null;
-      }
-   
-      if (subs.size() == 0)
-      {
-         subscriptions.remove(clientID);
-      }
-                  
-      return removed;
-   }
-   
-   protected List loadDurableSubscriptionsForTopic(String topicName,                                               
-                                                   MessageStore ms,
-                                                   PersistenceManager pm,
-                                                   MemoryManager mm) throws Exception
-   {              
-      List result = new ArrayList();
-      
-      Connection conn = null;
-      PreparedStatement ps  = null;
-      ResultSet rs = null;
-      TransactionWrapper wrap = new TransactionWrapper();
-      int rowCount = -1;
-      
-      try
-      {
-         conn = ds.getConnection();
-
-         ps = conn.prepareStatement(selectSubscriptionsForTopic);
-         
-         ps.setString(1, topicName);
-         
-         rs = ps.executeQuery();
-         
-         rowCount = 0;
-         
-         while (rs.next())
-         {
-            rowCount ++;
-            long id = rs.getLong(1);
-            String clientId = rs.getString(2);
-            String subName = rs.getString(3);
-            String selector = rs.getString(4);
-            boolean noLocal = rs.getString(5).equals("Y");
-            
-            Selector sel = selector == null ? null : new Selector(selector);
-                              
-            DurableSubscription sub = getDurableSubscription(clientId, subName);
-            
-            if (sub == null)
-            {
-               sub = createDurableSubscriptionInternal(id, topicName,
-                                                      clientId,
-                                                      subName,
-                                                      sel,
-                                                      noLocal,
-                                                      ms, pm, mm);
-               result.add(sub);
-            }                  
-         }
-      }
-      catch (SQLException e)
-      {
-         wrap.exceptionOccurred();
-         throw e;
-      }
-      finally
-      {
-         if (log.isTraceEnabled())
-         {
-            String s = JDBCUtil.statementToString(selectSubscriptionsForTopic, topicName);
-            log.trace(s + " returned " + rowCount + " rows");
-         }            
-         if (rs != null)
-         {
-            rs.close();
-         }
-         if (ps != null)
-         {
-            ps.close();
-         }
-         if (conn != null)
-         {
-            conn.close();
-         }
-         wrap.end();
-      }
-      
-      return result;
-   }
-
-   
-
-   protected void insertMappingRow(long id, char type, String jmsDestName, String jmsSubName, String clientID,
-                                   String selector, Boolean noLocal) throws Exception
-   {
-      Connection conn = null;
-      PreparedStatement ps  = null;
-      ResultSet rs = null;
-      TransactionWrapper wrap = new TransactionWrapper();
-      
-      boolean failed = true;
-      
-      try
-      {
-         conn = ds.getConnection();
-         
-         ps = conn.prepareStatement(insertMapping);
-         
-         ps.setLong(1, id);
-         
-         ps.setString(2, String.valueOf(type)); 
-         
-         ps.setString(3, jmsDestName);
-         
-         ps.setString(4, jmsSubName);
-         
-         ps.setString(5, clientID);
-         
-         ps.setString(6, selector);
-         
-         if (noLocal == null)
-         {
-            ps.setNull(7, Types.VARCHAR);
-         }
-         else
-         {
-            ps.setString(7, noLocal.booleanValue() ? "Y" : "N");
-         }
-                  
-         int rows = ps.executeUpdate();
-         
-         failed = rows != 1;
-          
-         ps.close();
-         
-         ps = null;        
-      }
-      finally
-      {
-         if (log.isTraceEnabled())
-         {
-            String s = JDBCUtil.
-            statementToString(insertMapping, null, String.valueOf(type), jmsDestName, jmsSubName,
-                  clientID, selector, noLocal);
-            log.trace(s + (failed ? " failed!" : " executed successfully"));
-         }
-         
-         if (rs != null)
-         {
-            try
-            {
-               rs.close();
-            }
-            catch (Throwable t)
-            {}
-         }
-         if (ps != null)
-         {
-            try
-            {
-               ps.close();
-            }
-            catch (Throwable t)
-            {}
-         }
-         if (conn != null)
-         {
-            try
-            {
-               conn.close();
-            }
-            catch (Throwable t)
-            {}
-         }
-         wrap.end();
-      }
-   }
-   
-   protected Long getIdForDestination(boolean isQueue, String destName) throws Exception
-   {
-      Connection conn = null;
-      PreparedStatement ps  = null;
-      ResultSet rs = null;
-      TransactionWrapper wrap = new TransactionWrapper();
-      
-      try
-      {
-         conn = ds.getConnection();
-         
-         ps = conn.prepareStatement(selectIdForDestination);
-         
-         ps.setString(1, String.valueOf(isQueue ? TYPE_QUEUE : TYPE_TOPIC));
-         
-         ps.setString(2, destName);
-        
-         rs = ps.executeQuery();  
-         
-         if (rs.next())
-         {
-            return new Long(rs.getLong(1));
-         }
-         else
-         {
-            return null;
-         }         
-      }
-      finally
-      {
-         if (rs != null)
-         {
-            try
-            {
-               rs.close();
-            }
-            catch (Throwable t)
-            {}
-         }
-         if (ps != null)
-         {
-            try
-            {
-               ps.close();
-            }
-            catch (Throwable t)
-            {}
-         }
-         if (conn != null)
-         {
-            try
-            {
-               conn.close();
-            }
-            catch (Throwable t)
-            {}
-         }
-         wrap.end();
-      }
-   }
-   
-   
-   protected boolean deleteMappingRow(long id) throws Exception
-   {
-      Connection conn = null;
-      PreparedStatement ps  = null;
-      TransactionWrapper wrap = new TransactionWrapper();
-      
-      boolean failed = true;
-      
-      try
-      {
-         conn = ds.getConnection();
-         
-         ps = conn.prepareStatement(deleteMapping);
-         
-         ps.setLong(1, id);
-        
-         failed = ps.executeUpdate() != -1;      
-         
-         return !failed;
-      }
-      finally
-      {
-         if (log.isTraceEnabled())
-         {
-            String s = JDBCUtil.statementToString(deleteMapping, new Long(id));
-            log.trace(s + (failed ? " failed!" : " executed successfully"));
-         }
-         if (ps != null)
-         {
-            try
-            {
-               ps.close();
-            }
-            catch (Throwable t)
-            {}
-         }
-         if (conn != null)
-         {
-            try
-            {
-               conn.close();
-            }
-            catch (Throwable t)
-            {}
-         }
-         wrap.end();
-      }
-   }
-   
-   protected DurableSubscription getDurableSubscription(String clientID,
-                                                        String subscriptionName) throws JMSException
-   {
-      Map subs = (Map)subscriptions.get(clientID);
-      return subs == null ? null : (DurableSubscription)subs.get(subscriptionName);
-   }
-
-
-   protected DurableSubscription createDurableSubscriptionInternal(long id, String topicName,
-                                                                   String clientID,
-                                                                   String subscriptionName,
-                                                                   Selector selector,
-                                                                   boolean noLocal,
-                                                                   MessageStore ms,
-                                                                   PersistenceManager pm,
-                                                                   MemoryManager mm)
-      throws JMSException
-   {
-      Map subs = (Map)subscriptions.get(clientID);
-      if (subs == null)
-      {
-         subs = new ConcurrentReaderHashMap();
-         subscriptions.put(clientID, subs);
-      }
-      
-      Topic topic = (Topic)getCoreDestinationInternal(false, topicName);
-      
-      if (topic == null)
-      {
-         throw new javax.jms.IllegalStateException("Topic " + topicName + " is not loaded");
-      }
-       
-      //We allocate an executor for the subscription from the rotating pool
-      //Currently all subscriptions for the same topic share the same executor
-      QueuedExecutor executor = (QueuedExecutor)queuedExecutorPool.get(topicName);
-             
-      DurableSubscription subscription =
-         new DurableSubscription(id, topic, ms, pm, mm,
-               topic.getFullSize(), topic.getPageSize(), topic.getDownCacheSize(),
-               executor, selector,
-               noLocal, subscriptionName, clientID);
-      
-      subs.put(subscriptionName, subscription);
-      
-      return subscription;
-   }   
-   
-   protected CoreDestination getCoreDestinationInternal(boolean isQueue, String destName)
-   {
-      Map m = isQueue ? queues : topics;
-      
-      return (CoreDestination)m.get(destName);
-   }
-   
-   protected void initSqlProperties()
-   {
-      createUserTable = sqlProperties.getProperty("CREATE_USER_TABLE", createUserTable);
-      createRoleTable = sqlProperties.getProperty("CREATE_ROLE_TABLE", createRoleTable);
-      selectPreConfClientId = sqlProperties.getProperty("SELECT_PRECONF_CLIENTID", selectPreConfClientId);      
-      createMappingTable = sqlProperties.getProperty("CREATE_MAPPING_TABLE", createMappingTable);
-      insertMapping = sqlProperties.getProperty("INSERT_MAPPING", insertMapping);
-      deleteMapping = sqlProperties.getProperty("DELETE_MAPPING", deleteMapping);
-      selectIdForDestination = sqlProperties.getProperty("SELECT_ID_FOR_DESTINATION", selectIdForDestination);
-      selectDurableSub = sqlProperties.getProperty("SELECT_DURABLE_SUB", selectDurableSub);
-      selectSubscriptionsForTopic = sqlProperties.getProperty("SELECT_SUBSCRIPTIONS_FOR_TOPIC", selectSubscriptionsForTopic);
-   
-      for (Iterator i = sqlProperties.entrySet().iterator(); i.hasNext();)
-      {
-         Map.Entry entry = (Map.Entry) i.next();
-         String key = (String) entry.getKey();
-         if (key.startsWith("POPULATE.TABLES."))
-            populateTables.add(entry.getValue());
-      }      
-   }
-   
-   protected void createSchema() throws Exception
-   {      
-      Connection conn = null;      
-      TransactionWrapper tx = new TransactionWrapper();
-      
-      try
-      {
-         conn = ds.getConnection();
-         
-         try
-         {
-            if (log.isTraceEnabled()) { log.trace("Creating JMS_USERS table"); }            
-            conn.createStatement().executeUpdate(createUserTable);
-         }
-         catch (SQLException e) 
-         {
-            log.debug("Failed to create users table: " + createUserTable, e);
-         }
-         
-         try
-         {
-            if (log.isTraceEnabled()) { log.trace("Creating JMS_ROLES table"); }
-            conn.createStatement().executeUpdate(createRoleTable);
-         }
-         catch (SQLException e) 
-         {
-            log.debug("Failed to create roles table: " + createRoleTable, e);
-         }
-         
-         try
-         {
-            if (log.isTraceEnabled()) { log.trace("Creating JMS_SUBSCRIPTIONS table"); }
-            conn.createStatement().
-            executeUpdate(createMappingTable);
-         }
-         catch (SQLException e) 
-         {
-            log.debug("Failed to create subscriptions table: " + createMappingTable, e);
-         }
-         
-         
-         //Insert user-role data
-         Iterator iter = populateTables.iterator();
-         String nextQry = null;
-         while (iter.hasNext())
-         {
-            Statement st = null;
-            try
-            {
-               nextQry = (String) iter.next();               
-               st = conn.createStatement();              
-               st.executeUpdate(nextQry);
-            }
-            catch (SQLException ignored)
-            {
-               log.debug("Error populating tables: " + nextQry, ignored);
-            }
-         }
-         
-      }
-      finally
-      {
-         if (conn != null)
-         {
-            try
-            {
-               conn.close();
-            }
-            catch (Throwable t)
-            {}
-         }
-         tx.end();
-      }
-      
-   }
-   
-   protected long getNextId() throws Exception
-   {
-      return channelIDManager.getId();
-   }
-   
-   // Private -------------------------------------------------------
-
-   // never access directly
-   private TransactionManager tm;
-
-   private TransactionManager getTransactionManagerReference()
-   {
-      // lazy initialization
-      if (tm == null)
-      {
-         TransactionManagerServiceMBean tms =
-            (TransactionManagerServiceMBean)MBeanServerInvocationHandler.
-            newProxyInstance(getServer(), tmObjectName, TransactionManagerServiceMBean.class, false);
-
-         tm = tms.getTransactionManager();
-      }
-
-      return tm;
-   }
-
-   // Inner classes -------------------------------------------------
-   
-   /*
-    * TODO This inner class is duplicated from HSQLPersistenceManager - need to avoid code duplication
-    */
-   class TransactionWrapper
-   {
-      private javax.transaction.Transaction oldTx;
-      
-      private TransactionWrapper() throws Exception
-      {
-         TransactionManager tm = getTransactionManagerReference();
-
-         oldTx = tm.suspend();
-         
-         tm.begin();
-      }
-      
-      private void end() throws Exception
-      {
-         TransactionManager tm = getTransactionManagerReference();
-
-         try
-         {
-            if (Status.STATUS_MARKED_ROLLBACK == tm.getStatus())
-            {
-               tm.rollback();
-            }
-            else
-            {
-               tm.commit();
-            }
-         }
-         finally
-         {
-            if (oldTx != null && tm != null)
-            {
-               tm.resume(oldTx);
-            }
-         }
-      }
-      
-      private void exceptionOccurred() throws Exception
-      {
-         getTransactionManagerReference().setRollbackOnly();
-      }
-   }
-   
-}

Added: trunk/src/main/org/jboss/jms/server/plugin/JDBCJMSUserManager.java
===================================================================
--- trunk/src/main/org/jboss/jms/server/plugin/JDBCJMSUserManager.java	2006-08-30 09:26:13 UTC (rev 1236)
+++ trunk/src/main/org/jboss/jms/server/plugin/JDBCJMSUserManager.java	2006-08-30 18:36:36 UTC (rev 1237)
@@ -0,0 +1,199 @@
+/*
+ * 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.jms.server.plugin;
+
+import java.sql.Connection;
+import java.sql.PreparedStatement;
+import java.sql.ResultSet;
+import java.sql.SQLException;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+
+import org.jboss.jms.server.plugin.contract.JMSUserManager;
+import org.jboss.logging.Logger;
+import org.jboss.messaging.core.plugin.JDBCServiceSupport;
+
+/**
+ * A JDBCJMSUserManager
+ * 
+ * Manages JMS user and role data - in particular the predefined client id (if any)
+ * for the user
+ *
+ * @author <a href="mailto:tim.fox at jboss.com">Tim Fox</a>
+ * @version <tt>$Revision: 1.1 $</tt>
+ *
+ * $Id$
+ *
+ */
+public class JDBCJMSUserManager extends JDBCServiceSupport implements JMSUserManager
+{
+   private static final Logger log = Logger.getLogger(JDBCJMSUserManager.class);
+      
+   // PersistentServiceSupport overrides ----------------------------
+   
+   protected Map getDefaultDMLStatements()
+   {                
+      Map map = new HashMap();
+      map.put("SELECT_PRECONF_CLIENTID", "SELECT CLIENTID FROM JMS_USER WHERE USERID=?");
+      return map;
+   }
+   
+   protected Map getDefaultDDLStatements()
+   {
+      Map map = new HashMap();
+      map.put("CREATE_USER_TABLE",
+              "CREATE TABLE JMS_USER (USERID VARCHAR(32) NOT NULL, PASSWD VARCHAR(32) NOT NULL, CLIENTID VARCHAR(128)," +
+              " PRIMARY KEY(USERID))");
+      map.put("CREATE_ROLE_TABLE",
+              "CREATE TABLE JMS_ROLE (ROLEID VARCHAR(32) NOT NULL, USERID VARCHAR(32) NOT NULL," +
+              " PRIMARY KEY(USERID, ROLEID))");
+      return map;
+   }
+   
+   // ServiceMBeanSupport overrides ---------------------------------
+   
+   protected void startService() throws Exception
+   {
+      super.startService();
+      
+      insertUserRoleData();
+   }
+
+   // MBean operations ----------------------------------------------
+   
+   // MBean attributes --------------------------------------------------------
+   
+   // JMSUserManager implementation -------------------------------------
+
+   //TODO There is no reason why this class should implement ClientIDRetriever
+   //the implementation should be moved out into a completely different service
+   public String getPreConfiguredClientID(String username) throws Exception
+   {
+      Connection conn = null;
+      PreparedStatement ps  = null;
+      ResultSet rs = null;
+      TransactionWrapper wrap = new TransactionWrapper();
+      
+      try
+      {
+         conn = ds.getConnection();
+         
+         ps = conn.prepareStatement(getSQLStatement("GET_PRECONF_CLIENTID"));
+         
+         ps.setString(1, username);
+         
+         rs = ps.executeQuery();
+         
+         String clientID = null;
+         
+         if (rs.next())
+         {
+            clientID = rs.getString(1);
+         }
+         
+         return clientID;
+      }
+      catch (SQLException e)
+      {
+         wrap.exceptionOccurred();
+         throw e;
+      }
+      finally
+      {
+         if (rs != null)
+         {
+            rs.close();
+         }
+         if (ps != null)
+         {
+            ps.close();
+         }
+         if (conn != null)
+         {
+            conn.close();
+         }
+         wrap.end();
+      }     
+   }
+   
+   private void insertUserRoleData() throws Exception
+   {
+      List populateTables = new ArrayList();
+      for (Iterator i = sqlProperties.entrySet().iterator(); i.hasNext();)
+      {
+         Map.Entry entry = (Map.Entry) i.next();
+         String key = (String) entry.getKey();
+         if (key.startsWith("POPULATE.TABLES."))
+         {
+            populateTables.add(entry.getValue());
+         }
+      }      
+      
+      if (!populateTables.isEmpty())
+      {         
+         Connection conn = null;      
+         TransactionWrapper tx = new TransactionWrapper();
+         
+         try
+         {
+            conn = ds.getConnection();
+            
+            Iterator iter = populateTables.iterator();
+            
+            while (iter.hasNext())
+            {
+               String statement = (String)iter.next();
+               
+               try
+               {
+                  if (log.isTraceEnabled()) { log.trace("Executing: " + statement); }
+                  
+                  conn.createStatement().executeUpdate(statement);
+               }
+               catch (SQLException e) 
+               {
+                  log.debug("Failed to execute: " + statement, e);
+               }  
+            }      
+         }
+         finally
+         {
+            if (conn != null)
+            {
+               try
+               {
+                  conn.close();
+               }
+               catch (Throwable t)
+               {}
+            }
+            tx.end();
+         }    
+      }
+   }
+   
+ 
+   // Inner classes -------------------------------------------------      
+}

Deleted: trunk/src/main/org/jboss/jms/server/plugin/contract/ChannelMapper.java
===================================================================
--- trunk/src/main/org/jboss/jms/server/plugin/contract/ChannelMapper.java	2006-08-30 09:26:13 UTC (rev 1236)
+++ trunk/src/main/org/jboss/jms/server/plugin/contract/ChannelMapper.java	2006-08-30 18:36:36 UTC (rev 1237)
@@ -1,103 +0,0 @@
-/**
- * JBoss, Home of Professional Open Source
- *
- * Distributable under LGPL license.
- * See terms of license at gnu.org.
- */
-package org.jboss.jms.server.plugin.contract;
-
-import java.util.Set;
-
-import javax.jms.JMSException;
-
-import org.jboss.jms.destination.JBossDestination;
-import org.jboss.jms.server.QueuedExecutorPool;
-import org.jboss.jms.server.subscription.DurableSubscription;
-import org.jboss.jms.server.subscription.Subscription;
-import org.jboss.messaging.core.local.CoreDestination;
-import org.jboss.messaging.core.memory.MemoryManager;
-import org.jboss.messaging.core.plugin.contract.MessageStore;
-import org.jboss.messaging.core.plugin.contract.PersistenceManager;
-import org.jboss.messaging.core.plugin.contract.ServerPlugin;
-
-/**
- * Handles mappings between Queues/Topics/Subscriptions and core channels
- * 
- * @author <a href="mailto:tim.fox at jboss.com">Tim Fox</a>
- * @author <a href="mailto:ovidiu at jboss.org">Ovidiu Feodorov</a>
- * @version <tt>1.1</tt>
- *
- * ChannelMapper.java,v 1.1 2006/02/28 16:48:13 timfox Exp
- */
-public interface ChannelMapper extends ServerPlugin
-{
-   /**
-    *  FIXME This doesn't belong here and should be moved out to a different service
-    * 
-    * @param username
-    * @return
-    * @throws JMSException
-    */
-   String getPreConfiguredClientID(String username) throws Exception;
-         
-   CoreDestination getCoreDestination(JBossDestination jbDest) throws Exception;
-   
-   JBossDestination getJBossDestination(long coreDestinationID);
-      
-   void deployCoreDestination(boolean isQueue, 
-                              String destName, 
-                              MessageStore ms, 
-                              PersistenceManager pm,
-                              MemoryManager mm,                              
-                              int fullSize, 
-                              int pageSize, 
-                              int downCacheSize) throws Exception;
-
-   CoreDestination undeployCoreDestination(boolean isQueue, String destName)
-      throws Exception;
-   
-   void deployTemporaryCoreDestination(boolean isQueue, 
-                                       String destName, 
-                                       long id,
-                                       MessageStore ms, 
-                                       PersistenceManager pm,
-                                       MemoryManager mm,                              
-                                       int fullSize, 
-                                       int pageSize, 
-                                       int downCacheSize) throws Exception;
-
-   CoreDestination undeployTemporaryCoreDestination(boolean isQueue, String destName)
-      throws Exception;
-   
-   DurableSubscription createDurableSubscription(String topicName,
-                                                  String clientID,
-                                                  String subscriptionName,
-                                                  String selector,
-                                                  boolean noLocal,
-                                                  MessageStore ms,
-                                                  PersistenceManager pm,
-                                                  MemoryManager mm) throws Exception;
-   
-   Subscription createSubscription(String topicName,
-                                   String selector,
-                                   boolean noLocal,
-                                   MessageStore ms,
-                                   PersistenceManager pm,
-                                   MemoryManager mm) throws Exception;
-   
-   DurableSubscription getDurableSubscription(String clientID,
-                                              String subscriptionName,
-                                              MessageStore ms,
-                                              PersistenceManager pm,
-                                              MemoryManager mm) throws Exception;
-
-   boolean removeDurableSubscription(String clientID, String subscriptionName) throws Exception;
-
-   Set getSubscriptions(String clientID);
-   
-   //TODO Handle this dependency properly
-   void setPersistenceManager(PersistenceManager pm) throws Exception;
-   
-   void setQueuedExecutorPool(QueuedExecutorPool pool) throws Exception;
-
-}

Added: trunk/src/main/org/jboss/jms/server/plugin/contract/JMSUserManager.java
===================================================================
--- trunk/src/main/org/jboss/jms/server/plugin/contract/JMSUserManager.java	2006-08-30 09:26:13 UTC (rev 1236)
+++ trunk/src/main/org/jboss/jms/server/plugin/contract/JMSUserManager.java	2006-08-30 18:36:36 UTC (rev 1237)
@@ -0,0 +1,37 @@
+/*
+ * 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.jms.server.plugin.contract;
+
+
+/**
+ * A JMSUserManager
+
+ * @author <a href="mailto:tim.fox at jboss.com">Tim Fox</a>
+ * @version <tt>$Revision: 1.1 $</tt>
+ *
+ * $Id$
+ *
+ */
+public interface JMSUserManager
+{
+   String getPreConfiguredClientID(String username) throws Exception;
+}

Deleted: trunk/src/main/org/jboss/jms/server/plugin/contract/LazyLoadingDelegate.java
===================================================================
--- trunk/src/main/org/jboss/jms/server/plugin/contract/LazyLoadingDelegate.java	2006-08-30 09:26:13 UTC (rev 1236)
+++ trunk/src/main/org/jboss/jms/server/plugin/contract/LazyLoadingDelegate.java	2006-08-30 18:36:36 UTC (rev 1237)
@@ -1,17 +0,0 @@
-/**
- * JBoss, Home of Professional Open Source
- *
- * Distributable under LGPL license.
- * See terms of license at gnu.org.
- */
-package org.jboss.jms.server.plugin.contract;
-
-/**
- * @author <a href="mailto:ovidiu at jboss.org">Ovidiu Feodorov</a>
- * @version <tt>$Revision$</tt>
- *
- * $Id$
- */
-public interface LazyLoadingDelegate
-{
-}

Modified: trunk/src/main/org/jboss/jms/tx/MessagingXAResource.java
===================================================================
--- trunk/src/main/org/jboss/jms/tx/MessagingXAResource.java	2006-08-30 09:26:13 UTC (rev 1236)
+++ trunk/src/main/org/jboss/jms/tx/MessagingXAResource.java	2006-08-30 18:36:36 UTC (rev 1237)
@@ -38,9 +38,6 @@
  * 
  * @author <a href="mailto:tim.fox at jboss.com">Tim Fox</a>
  * @author <a href="mailto:ovidiu at jboss.org">Ovidiu Feodorov</a>
- * 
- * Parts based on JBoss MQ XAResource implementation by:
- * 
  * @author Hiram Chirino (Cojonudo14 at hotmail.com)
  * @author <a href="mailto:adrian at jboss.org">Adrian Brock</a>
  * 
@@ -161,10 +158,7 @@
    public void rollback(Xid xid) throws XAException
    {
       if (trace) { log.trace(this + " rolling back " + xid); }
-
-      //TODO Hmmm on rollback should we also stop and start the consumers to remove any transient messages
-      //Like we do on local session rollback??
-      
+  
       rm.rollback(xid, connection);
    }
 

Modified: trunk/src/main/org/jboss/jms/tx/ResourceManager.java
===================================================================
--- trunk/src/main/org/jboss/jms/tx/ResourceManager.java	2006-08-30 09:26:13 UTC (rev 1236)
+++ trunk/src/main/org/jboss/jms/tx/ResourceManager.java	2006-08-30 18:36:36 UTC (rev 1237)
@@ -50,9 +50,6 @@
  * by ResourceManagerFactory.
  * 
  * @author <a href="mailto:tim.fox at jboss.com>Tim Fox</a>
- * 
- * Parts adapted from SpyXAResourceManager by:
- *
  * @author <a href="mailto:Cojonudo14 at hotmail.com">Hiram Chirino</a>
  * @author <a href="mailto:adrian at jboss.org">Adrian Brock</a>
  * @version $Revision$

Modified: trunk/src/main/org/jboss/jms/tx/TransactionRequest.java
===================================================================
--- trunk/src/main/org/jboss/jms/tx/TransactionRequest.java	2006-08-30 09:26:13 UTC (rev 1236)
+++ trunk/src/main/org/jboss/jms/tx/TransactionRequest.java	2006-08-30 18:36:36 UTC (rev 1237)
@@ -37,6 +37,7 @@
  * 
  * Partially based on JBossMQ version by:
  * 
+ * @author <a href="mailto:tim.fox at jboss.com">Tim Fox</a>
  * @author <a href="mailto:Cojonudo14 at hotmail.com">Hiram Chirino</a>
  * @author <a href="mailto:David.Maplesden at orion.co.nz">David Maplesden</a>
  * @author <a href="mailto:adrian at jboss.org">Adrian Brock</a>

Added: trunk/src/main/org/jboss/jms/util/MessageQueueNameHelper.java
===================================================================
--- trunk/src/main/org/jboss/jms/util/MessageQueueNameHelper.java	2006-08-30 09:26:13 UTC (rev 1236)
+++ trunk/src/main/org/jboss/jms/util/MessageQueueNameHelper.java	2006-08-30 18:36:36 UTC (rev 1237)
@@ -0,0 +1,110 @@
+/*
+ * 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.jms.util;
+
+import java.util.StringTokenizer;
+
+/**
+ * A JMSExchangeHelper
+ *
+ * By convention, we name durable topic message queue names in the following way:
+ * 
+ * <clientid>.<sub_name>
+ * 
+ * This is a helper class to aid in converting between the string form and the client id
+ * and subscription name and vice versa
+ * 
+ * @author <a href="mailto:tim.fox at jboss.com">Tim Fox</a>
+ * @version <tt>$Revision: 1.1 $</tt>
+ *
+ * $Id$
+ *
+ */
+public class MessageQueueNameHelper
+{
+   private String clientId;
+   
+   private String subName;
+   
+   private static String SEPARATOR = ".";
+   
+   private MessageQueueNameHelper(String messageQueueName)
+   {
+      if (messageQueueName == null)
+      {
+         throw new IllegalArgumentException("Message queue name is null");
+      }
+      
+      StringTokenizer tok = new StringTokenizer(messageQueueName, SEPARATOR);
+      
+      int count = 0;
+      
+      while (tok.hasMoreElements())
+      {
+         String token = (String)tok.nextElement();
+         
+         if (count == 0)
+         {
+            clientId = token;
+         }
+         else if (count == 1)
+         {
+            subName = token;
+         }
+         count++;   
+      }
+      
+      if (count != 2)
+      {
+         throw new IllegalArgumentException("Invalid message queue name: " + messageQueueName);
+      }
+   }
+
+   public String getClientId()
+   {
+      return clientId;
+   }
+   
+   public String getSubName()
+   {
+      return subName;
+   }
+   
+   public static MessageQueueNameHelper createHelper(String messageQueueName)
+   {
+      return new MessageQueueNameHelper(messageQueueName);
+   }
+   
+   public static String createSubscriptionName(String clientId, String subName)
+   {
+      if (clientId == null)
+      {
+         throw new IllegalArgumentException("clientId name is null");
+      }
+      if (subName == null)
+      {
+         throw new IllegalArgumentException("Subscription name is null");
+      }
+      
+      return clientId + SEPARATOR + subName;
+   }      
+}

Modified: trunk/src/main/org/jboss/jms/util/MessagingXAException.java
===================================================================
--- trunk/src/main/org/jboss/jms/util/MessagingXAException.java	2006-08-30 09:26:13 UTC (rev 1236)
+++ trunk/src/main/org/jboss/jms/util/MessagingXAException.java	2006-08-30 18:36:36 UTC (rev 1237)
@@ -23,6 +23,16 @@
 
 import javax.transaction.xa.XAException;
 
+/**
+ * 
+ * A MessagingXAException
+
+ * @author <a href="mailto:tim.fox at jboss.com">Tim Fox</a>
+ * @version <tt>$Revision: 1.1 $</tt>
+ *
+ * $Id$
+ *
+ */
 public class MessagingXAException extends XAException
 {
    private static final long serialVersionUID = 1144870736311098699L;

Deleted: trunk/src/main/org/jboss/jms/util/RendezVous.java
===================================================================
--- trunk/src/main/org/jboss/jms/util/RendezVous.java	2006-08-30 09:26:13 UTC (rev 1236)
+++ trunk/src/main/org/jboss/jms/util/RendezVous.java	2006-08-30 18:36:36 UTC (rev 1237)
@@ -1,124 +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.jms.util;
-
-import org.jboss.logging.Logger;
-
-/**
- * @author <a href="mailto:ovidiu at jboss.org">Ovidiu Feodorov</a>
- * @version <tt>$Revision$</tt>
- */
-public class RendezVous
-{
-   // Constants -----------------------------------------------------
-
-   public static final Logger log = Logger.getLogger(RendezVous.class);
-
-   // Static --------------------------------------------------------
-
-   // Attributes ----------------------------------------------------
-
-   private boolean threadWaiting = false;
-   private Object object;
-
-
-   // Constructors --------------------------------------------------
-
-   // Public --------------------------------------------------------
-
-   /**
-    * This method is used by the receiver thread, which registers with the redezvous and blocks
-    * until an object becomes available. Only one thread can be waiting, if the method is called
-    * by other threads while one is waiting, will throw unchecked exception.
-    *
-    * @param timeout - the timeout value in milliseconds. A zero timeout never expires, and the
-    *        call blocks indefinitely.
-    *
-    * @return the object or null if the timeout expires and no Object was put.
-    */
-   public Object get(long timeout)
-   {
-      synchronized(this)
-      {
-         if (threadWaiting)
-         {
-            throw new RuntimeException("Another thread waiting!");
-         }
-
-         threadWaiting = true;
-
-         try
-         {
-            wait(timeout);
-         }
-         catch(InterruptedException e)
-         {
-            log.warn(e);
-         }
-         finally
-         {
-            threadWaiting = false;
-            Object tmp = object;
-            object = null;
-            if (log.isTraceEnabled()) { log.trace("get() returns " + tmp); }
-            return tmp;
-         }
-      }
-   }
-
-   /**
-    * Method used by the sender thread, that only puts the object IF there is a receiver thread
-    * waiting.
-    *
-    * @return true if the object was transferred to the receiver thread, or false if there is
-    *         no receiver thread waiting.
-    */
-   public boolean put(Object o)
-   {
-      synchronized(this)
-      {
-         if (!threadWaiting || object != null)
-         {
-            return false;
-         }
-
-         object = o;
-         notifyAll();
-         if (log.isTraceEnabled()) { log.trace("put(" + o + ")"); }
-         return true;
-      }
-   }
-
-
-   public synchronized boolean isOccupied()
-   {
-      return threadWaiting;
-   }
-
-   // Package protected ---------------------------------------------
-
-   // Protected -----------------------------------------------------
-
-   // Private -------------------------------------------------------
-
-   // Inner classes -------------------------------------------------
-}

Deleted: trunk/src/main/org/jboss/jms/util/SafeUTF.java
===================================================================
--- trunk/src/main/org/jboss/jms/util/SafeUTF.java	2006-08-30 09:26:13 UTC (rev 1236)
+++ trunk/src/main/org/jboss/jms/util/SafeUTF.java	2006-08-30 18:36:36 UTC (rev 1237)
@@ -1,165 +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.jms.util;
-
-import java.io.IOException;
-import java.io.ObjectInput;
-import java.io.ObjectOutput;
-
-/**
- * 
- * A SafeUTF
- * 
- * @author <a href="tim.fox at jboss.com">Tim Fox</a>
- * @author <a href="mailto:adrian at jboss.org">Adrian Brock</a>
- * @version $Revision$
- *
- * $Id$
- * 
- * There is a "bug" in JDK1.4 / 1.5 DataOutputStream.writeUTF()
- * which means it does not work with Strings >= 64K serialized size.
- * See http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=4806007
- * 
- * We work around this by chunking larger strings into smaller pieces.
- * 
- * Note we only support TextMessage and ObjectMessage bodies with serialized length >= 64K
- * We DO NOT support Strings written to BytesMessages or StreamMessages or written as keys or values
- * in MapMessages, or as String properties or other String fields having serialized length >= 64K
- * This is for performance reasons since there is an overhead in coping with large
- * Strings
- * 
- */
-public class SafeUTF
-{      
-   //Default is 16K chunks
-   private static final int CHUNK_SIZE = 16 * 1024;
-   
-   private static final byte NULL = 0;
-   
-   private static final byte NOT_NULL = 1;
-   
-   public static SafeUTF instance = new SafeUTF(CHUNK_SIZE);
-   
-   private int chunkSize;
-   
-   private int lastReadBufferSize;
-   
-   public int getLastReadBufferSize()
-   {
-      return lastReadBufferSize;
-   }
-   
-   public SafeUTF(int chunkSize)
-   {
-      this.chunkSize = chunkSize;
-   }
-      
-   public void safeWriteUTF(ObjectOutput out, String str) throws IOException
-   {        
-      if (str == null)
-      {
-         out.writeByte(NULL);
-      }
-      else
-      {         
-         int len = str.length();
-          
-         short numChunks;
-         
-         if (len == 0)
-         {
-            numChunks = 0;
-         }
-         else
-         {
-            numChunks = (short)(((len - 1) / chunkSize) + 1);
-         }         
-         
-         out.writeByte(NOT_NULL);
-         
-         out.writeShort(numChunks);
-              
-         int i = 0;
-         while (len > 0)
-         {
-            int beginCopy = i * chunkSize;
-            
-            int endCopy = len <= chunkSize ? beginCopy + len : beginCopy + chunkSize;
-     
-            String theChunk = str.substring(beginCopy, endCopy);
-               
-            out.writeUTF(theChunk);
-            
-            len -= chunkSize;
-            
-            i++;
-         }
-      }
-   }
-   
-   public String safeReadUTF(ObjectInput in) throws IOException
-   {   
-      boolean isNull = in.readByte() == NULL;
-      
-      if (isNull)
-      {
-         return null;
-      }
-      
-      short numChunks = in.readShort();
-      
-      int bufferSize = chunkSize * numChunks;
-      
-      // special handling for single chunk
-      if (numChunks == 1)
-      {
-         // The text size is likely to be much smaller than the chunkSize
-         // so set bufferSize to the min of the input stream available
-         // and the maximum buffer size. Since the input stream
-         // available() can be <= 0 we check for that and default to
-         // a small msg size of 256 bytes.
-         
-         int inSize = in.available();
-               
-         if (inSize <= 0)
-         {
-            inSize = 256;
-         }
-
-         bufferSize = Math.min(inSize, bufferSize);
-         
-         lastReadBufferSize = bufferSize;
-      }
-        
-      StringBuffer buff = new StringBuffer(bufferSize);
-            
-      for (int i = 0; i < numChunks; i++)
-      {
-         String s = in.readUTF();
-
-         buff.append(s);
-      }
-      
-      return buff.toString();
-   }
-      
-}

Modified: trunk/src/main/org/jboss/messaging/core/ChannelSupport.java
===================================================================
--- trunk/src/main/org/jboss/messaging/core/ChannelSupport.java	2006-08-30 09:26:13 UTC (rev 1236)
+++ trunk/src/main/org/jboss/messaging/core/ChannelSupport.java	2006-08-30 18:36:36 UTC (rev 1237)
@@ -22,17 +22,14 @@
 package org.jboss.messaging.core;
 
 import java.util.ArrayList;
-import java.util.HashMap;
 import java.util.HashSet;
 import java.util.Iterator;
 import java.util.LinkedHashSet;
 import java.util.List;
 import java.util.ListIterator;
-import java.util.Map;
 import java.util.Set;
 
 import org.jboss.logging.Logger;
-import org.jboss.messaging.core.memory.MemoryManager;
 import org.jboss.messaging.core.plugin.contract.MessageStore;
 import org.jboss.messaging.core.plugin.contract.PersistenceManager;
 import org.jboss.messaging.core.refqueue.BasicPrioritizedDeque;
@@ -43,16 +40,23 @@
 import org.jboss.messaging.util.Future;
 
 import EDU.oswego.cs.dl.util.concurrent.QueuedExecutor;
-import EDU.oswego.cs.dl.util.concurrent.SynchronizedLong;
 
 /**
- * Channel implementation. It supports atomicity, isolation and recoverability of reliable messages.
- * The channel implementation here uses a "SEDA-type" approach, where requests to handle messages,
- * deliver to receivers or acknowledge messages are not executed concurrently but placed on an event
- * queue and executed serially by a single thread. This prevents lock contention since requests are
+ * 
+ * This class provides much of the functionality needed to implement a channel.
+ * 
+ * This partial implementation supports atomicity, isolation and recoverability of reliable messages.
+ * 
+ * It uses a "SEDA-type" approach, where requests to handle messages,
+ * and deliver to receivers are not executed concurrently but placed on an event
+ * queue and executed serially by a single thread.
+ * 
+ * This prevents lock contention since requests are
  * executed serially, resulting in better scalability and higher throughput at the expense of some
  * latency.
  * 
+ * Currently remoting does not support a non blocking API so a full SEDA approach is not possible at this stage.
+ * 
  * @author <a href="mailto:ovidiu at jboss.org">Ovidiu Feodorov</a>
  * @author <a href="mailto:tim.fox at jboss.com">Tim Fox</a>
  * @version <tt>$Revision$</tt> $Id: ChannelSupport.java,v 1.65
@@ -84,93 +88,39 @@
 
    protected Set deliveries;
 
-   protected List downCache;
-
    protected boolean acceptReliableMessages;
 
    protected boolean recoverable;
 
-   protected SynchronizedLong messageOrdering;
-
    protected PersistenceManager pm;
 
-   protected MemoryManager mm;
+   protected Object refLock;
 
-   protected int fullSize;
+   protected Object deliveryLock;
 
-   protected int pageSize;
-
-   protected int downCacheSize;
-
-   protected boolean paging;
-
-   protected int refsInStorage;
-
-   private Object refLock;
-
-   private Object deliveryLock;
-
-   // When we load refs from the channel we do so with values of ordering >=
-   // this value
-   private long loadFromOrderingValue;
-
    // Constructors --------------------------------------------------
 
-   /**
-    * @param acceptReliableMessages -
-    *           it only makes sense if tl is null. Otherwise ignored (a
-    *           recoverable channel always accepts reliable messages)
-    */
-
    protected ChannelSupport(long channelID, MessageStore ms,
-            PersistenceManager pm, MemoryManager mm,
-            boolean acceptReliableMessages, boolean recoverable, int fullSize,
-            int pageSize, int downCacheSize, QueuedExecutor executor)
+                            PersistenceManager pm,
+                            boolean acceptReliableMessages, boolean recoverable,
+                            QueuedExecutor executor)
    {
-      if (trace)
-      {
-         log.trace("creating "
-                  + (pm != null ? "recoverable " : "non-recoverable ")
-                  + "channel[" + channelID + "]");
-      }
+      if (trace) { log.trace("creating " + (pm != null ? "recoverable " : "non-recoverable ") + "channel[" + channelID + "]"); }
 
       if (ms == null)
       {
-         throw new IllegalArgumentException(
-                  "ChannelSupport requires a non-null message store");
+         throw new IllegalArgumentException("ChannelSupport requires a non-null message store");
       }
       if (pm == null)
       {
-         throw new IllegalArgumentException("ChannelSupport requires a "
-                  + "non-null persistence manager");
+         throw new IllegalArgumentException("ChannelSupport requires a " +
+                                            "non-null persistence manager");
       }
-      if (pageSize >= fullSize)
-      {
-         throw new IllegalArgumentException(
-                  "pageSize must be less than full size");
-      }
-      if (downCacheSize > pageSize)
-      {
-         throw new IllegalArgumentException(
-                  "pageSize cannot be smaller than downCacheSize");
-      }
-      if (pageSize <= 0)
-      {
-         throw new IllegalArgumentException(
-                  "pageSize must be greater than zero");
-      }
-      if (downCacheSize <= 0)
-      {
-         throw new IllegalArgumentException(
-                  "downCacheSize must be greater than zero");
-      }
 
       this.ms = ms;
 
       this.pm = pm;
 
-      this.mm = mm;
-
       this.channelID = channelID;
 
       this.executor = executor;
@@ -183,19 +133,9 @@
 
       deliveries = new LinkedHashSet();
 
-      downCache = new ArrayList();
-
-      this.fullSize = fullSize;
-
-      this.pageSize = pageSize;
-
-      this.downCacheSize = downCacheSize;
-
       refLock = new Object();
 
       deliveryLock = new Object();
-
-      messageOrdering = new SynchronizedLong(0);
    }
 
    // Receiver implementation ---------------------------------------
@@ -225,7 +165,7 @@
       }
       else
       {
-         return this.handleInternal(sender, r, tx);
+         return handleInternal(sender, r, tx);
       }
    }
       
@@ -233,34 +173,12 @@
 
    public void acknowledge(Delivery d, Transaction tx) throws Throwable
    {
-      if (trace)
-      {
-         log.trace("acknowledging "
-                  + d
-                  + (tx == null ? " non-transactionally"
-                           : " transactionally in " + tx));
-      }
+      if (trace) { log.trace("acknowledging " + d + (tx == null ? " non-transactionally" : " transactionally in " + tx)); }
 
       if (tx == null)
       {
          // acknowledge non transactionally
 
-         // we put the acknowledgement on the event queue
-
-         // try
-         // {
-         // Future result = new Future();
-         //
-         // this.executor.execute(new AcknowledgeRunnable(d, result));
-         //               
-         // //For now we wait for result, but this may not be necessary
-         // result.getResult();
-         // }
-         // catch (InterruptedException e)
-         // {
-         // log.warn("Thread interrupted", e);
-         // }
-
          // TODO We should consider also executing acks on the event queue
          acknowledgeInternal(d);
       }
@@ -268,8 +186,7 @@
       {
          this.getCallback(tx).addDelivery(d);
 
-         if (trace) { log.trace(this + " added " + d + " to memory on transaction " + tx);
-         }
+         if (trace) { log.trace(this + " added " + d + " to memory on transaction " + tx); }
 
          if (recoverable && d.getReference().isReliable())
          {
@@ -280,21 +197,6 @@
 
    public void cancel(Delivery d) throws Throwable
    {
-      // We put the cancellation on the event queue
-      // try
-      // {
-      // Future result = new Future();
-      //         
-      // this.executor.execute(new CancelRunnable(d, result));
-      //         
-      // //For now we wait for result, but this may not be necessary
-      // result.getResult();
-      // }
-      // catch (InterruptedException e)
-      // {
-      // log.warn("Thread interrupted", e);
-      // }
-
       // TODO We should also consider executing cancels on the event queue
       cancelInternal(d);   
    }
@@ -361,11 +263,7 @@
 
    public List browse(Filter filter)
    {
-      if (trace)
-      {
-         log.trace(this + " browse"
-                  + (filter == null ? "" : ", filter = " + filter));
-      }
+      if (trace) { log.trace(this + " browse" + (filter == null ? "" : ", filter = " + filter)); }
       
       synchronized (deliveryLock)
       {
@@ -374,6 +272,8 @@
             //FIXME - This is currently broken since it doesn't take into account
             // refs paged into persistent storage
             // Also is very inefficient since it makes a copy
+            // The way to implement this properly is to use the Prioritized deque iterator
+            // combined with an iterator over the refs in storage
             
             //TODO use the ref queue iterator
             List references = delivering(filter);
@@ -428,8 +328,7 @@
       {
          router.clear();
          router = null;
-      }
-      
+      }      
    }  
    
    /*
@@ -480,28 +379,6 @@
       }
    }
 
-   public void load() throws Exception
-   {
-      if (trace)
-      {
-         log.trace(this + " loading channel state");
-      }
-      synchronized (refLock)
-      {
-         // First we need to reset the loaded flag in the db to "N"
-         pm.resetLoadedStatus(channelID);
-
-         refsInStorage = pm.getNumberOfUnloadedReferences(channelID);
-
-         loadFromOrderingValue = pm.getMinOrdering(channelID);
-
-         if (refsInStorage > 0)
-         {
-            load(Math.min(refsInStorage, fullSize));
-         }
-      }
-   }
-
    public List delivering(Filter filter)
    {
       List delivering = new ArrayList();
@@ -523,11 +400,7 @@
             }
          }
       }
-      if (trace)
-      {
-         log.trace(this + ": the non-recoverable state has "
-                  + delivering.size() + " messages being delivered");
-      }
+      if (trace) { log.trace(this + ": the non-recoverable state has " + delivering.size() + " messages being delivered"); }
 
       return delivering;
    }
@@ -553,19 +426,11 @@
             }
             else
             {
-               if (trace)
-               {
-                  log.trace(this + ": " + r
-                           + " NOT accepted by filter so won't add to list");
-               }
+               if (trace) { log.trace(this + ": " + r + " NOT accepted by filter so won't add to list"); }
             }
          }
       }
-      if (trace)
-      {
-         log.trace(this + ": undelivered() returns a list of "
-                  + undelivered.size() + " undelivered memory messages");
-      }
+      if (trace) { log.trace(this + ": undelivered() returns a list of " + undelivered.size() + " undelivered memory messages"); }
 
       return undelivered;
    }
@@ -599,22 +464,6 @@
       }
    }
 
-   public int downCacheCount()
-   {
-      synchronized (refLock)
-      {
-         return downCache.size();
-      }
-   }
-
-   public boolean isPaging()
-   {
-      synchronized (refLock)
-      {
-         return paging;
-      }
-   }
-
    public String toString()
    {
       return "ChannelSupport[" + channelID + "]";
@@ -690,7 +539,7 @@
                   // Reference is not expired
 
                   // Attempt to push the ref to a receiver
-                  Delivery del = push(ref);
+                  Delivery del = router.handle(this, ref, null);
 
                   if (del == null)
                   {
@@ -801,7 +650,7 @@
       }
 
       if (trace) { log.trace(this + " handles " + r + (tx == null ? " non-transactionally" : " in transaction: " + tx)); }
-
+ 
       MessageReference ref = obtainReference(r);
 
       try
@@ -833,17 +682,13 @@
                         + " because the channel has a non-recoverable state!");
                return null;
             }
-
-            checkMemory();                        
-
-            ref.setOrdering(messageOrdering.increment());
-            
+        
             if (ref.isReliable() && recoverable)
             {
                // Reliable message in a recoverable state - also add to db
                if (trace) { log.trace(this + "adding " + ref + " to database non-transactionally"); }
 
-               pm.addReference(channelID, ref, null);               
+               pm.addReference(channelID, ref, null);        
             }
             
             addReferenceInMemory(ref);
@@ -860,8 +705,6 @@
          {
             if (trace) { log.trace(this + "adding " + ref + " to state " + (tx == null ? "non-transactionally" : "in transaction: " + tx)); }
 
-            checkMemory();
-
             if (ref.isReliable() && !acceptReliableMessages)
             {
                // this transaction has no chance to succeed, since a reliable
@@ -877,13 +720,8 @@
             else
             {
                // add to post commit callback
-               ref.setOrdering(messageOrdering.increment());
                this.getCallback(tx).addRef(ref);
-               if (trace)
-               {
-                  log.trace(this + " added transactionally " + ref
-                           + " in memory");
-               }
+               if (trace) { log.trace(this + " added transactionally " + ref + " in memory"); }
             }
 
             if (ref.isReliable() && recoverable)
@@ -923,92 +761,23 @@
       d.getReference().releaseMemoryReference();        
    }
 
-   protected void cancelInternal(Delivery del) throws Exception
+   protected boolean acknowledgeInMemory(Delivery d)
    {
-      if (trace)
+      if (d == null)
       {
-         log.trace(this + " cancelling " + del + " in memory");
+         throw new IllegalArgumentException("Can't acknowledge a null delivery");
       }
 
-      boolean removed;
+      boolean removed = deliveries.remove(d);
 
-      synchronized (deliveryLock)
-      {
-         removed = deliveries.remove(del);
-      }
+      // It's ok if the delivery couldn't be found - this might happen
+      // if the delivery is acked before the call to handle() has returned
 
-      if (!removed)
-      {
-         // This is ok
-         // This can happen if the message is cancelled before the result of
-         // ServerConsumerDelegate.handle
-         // has returned, in which case we won't have a record of the delivery
-         // in the Set
-
-         // In this case we don't want to add the message reference back into
-         // the state
-         // since it was never removed in the first place
-
-         if (trace)
-         {
-            log.trace(this + " can't find delivery " + del
-                     + " in state so not replacing messsage ref");
-         }
-
-      }
-      else
-      {
-         synchronized (refLock)
-         {
-            messageRefs.addFirst(del.getReference(), del.getReference()
-                     .getPriority());
-
-            if (paging)
-            {
-               // if paging we need to evict the end reference to storage to
-               // preserve the number of refs in the queue
-
-               MessageReference ref = (MessageReference) messageRefs
-                        .removeLast();
-
-               addToDownCache(ref);
-
-               refsInStorage++;
-            }
-         }
-
-         if (trace)
-         {
-            log.trace(this + " added " + del.getReference()
-                     + " back into state");
-         }
-      }
+      if (trace) { log.trace(this + " removed " + d + " from memory:" + removed); }
+      
+      return removed;
    }
-
-   protected MessageReference removeFirstInMemory() throws Exception
-   {
-      synchronized (refLock)
-      {
-         MessageReference result = (MessageReference) messageRefs.removeFirst();
-
-         if (refsInStorage > 0)
-         {
-            int numberLoadable = Math.min(refsInStorage, pageSize);
-
-            if (messageRefs.size() <= fullSize - numberLoadable)
-            {
-               load(numberLoadable);
-            }
-         }
-         else
-         {
-            paging = false;
-         }
-
-         return (MessageReference) result;
-      }
-   }
-
+   
    protected MessageReference obtainReference(Routable r)
    {
       MessageReference ref = null;
@@ -1041,394 +810,6 @@
       }
    }
 
-   protected void checkMemory()
-   {
-
-      // Disabled for now
-
-      // if (mm != null)
-      // {
-      // boolean isLow = mm.isMemoryLow();
-      //         
-      // if (isLow)
-      // {
-      //            
-      // synchronized (refLock)
-      // {
-      // if (!paging)
-      // {
-      // log.info("Memory is low:" + this);
-      //                  
-      // fullSize = messageRefs.size() + 1;
-      //                  
-      // //TODO Make this configurable
-      // pageSize = downCacheSize = Math.max(1, fullSize / 50);
-      //                  
-      // log.info("Turned paging on, fullSize=" + fullSize + " dc:" +
-      // downCacheSize + " ps: " + pageSize);
-      // }
-      // else
-      // {
-      // //log.info("already paging");
-      // }
-      //               
-      // }
-      // }
-      // }
-   }
-
-   protected void addReferenceInMemory(MessageReference ref) throws Exception
-   {
-      if (ref.isReliable() && !acceptReliableMessages)
-      {
-         throw new IllegalStateException("Reliable reference " + ref
-                  + " cannot be added to non-recoverable state");
-      }
-
-      synchronized (refLock)
-      {
-         if (paging)
-         {
-            addToDownCache(ref);
-
-            refsInStorage++;
-         }
-         else
-         {
-            messageRefs.addLast(ref, ref.getPriority());
-
-            if (trace)
-            {
-               log.trace(this + " added " + ref
-                        + " non-transactionally in memory");
-            }
-
-            if (messageRefs.size() == fullSize)
-            {
-               // We are full in memory - go into paging mode
-
-               if (trace)
-               {
-                  log.trace(this + " going into paging mode");
-               }
-
-               paging = true;
-            }
-         }
-      }
-   }
-
-   protected void addToDownCache(MessageReference ref) throws Exception
-   {
-      // If the down cache exists then refs are not spilled over immediately,
-      // but store in the cache
-      // and spilled over in one go when the next load is requested, or when it
-      // is full
-
-      // Both non reliable and reliable references can go in the down cache,
-      // however only non-reliable
-      // references actually get added to storage, reliable references instead
-      // get their LOADED column
-      // updated to "N".
-
-      downCache.add(ref);
-
-      if (trace)
-      {
-         log.trace(ref + " sent to downcache");
-      }
-
-      if (downCache.size() == downCacheSize)
-      {
-         if (trace)
-         {
-            log.trace(this + "'s downcache is full (" + downCache.size()
-                     + " messages)");
-         }
-         flushDownCache();
-      }
-   }
-
-   protected void flushDownCache() throws Exception
-   {
-      if (trace)
-      {
-         log.trace(this + " flushing " + downCache.size()
-                  + " refs from downcache");
-      }
-
-      // Non persistent refs won't
-      // already be in the db
-      // so they need to be inserted
-      // Persistent refs in a recoverable state will already be there so need to
-      // be updated
-
-      List toUpdate = new ArrayList();
-
-      List toAdd = new ArrayList();
-
-      Iterator iter = downCache.iterator();
-
-      long minOrdering = Long.MAX_VALUE;
-
-      while (iter.hasNext())
-      {
-         MessageReference ref = (MessageReference) iter.next();
-
-         minOrdering = Math.min(minOrdering, ref.getOrdering());
-
-         if (ref.isReliable() && recoverable)
-         {
-            toUpdate.add(ref);
-         }
-         else
-         {
-            toAdd.add(ref);
-         }
-      }
-
-      if (!toAdd.isEmpty())
-      {
-         pm.addReferences(channelID, toAdd, false);
-      }
-      if (!toUpdate.isEmpty())
-      {
-         pm.updateReferencesNotLoaded(channelID, toUpdate);
-      }
-
-      // Release in memory refs for the refs we just spilled
-      // Note! This must be done after the db inserts - to ensure message is
-      // still in memory
-      iter = downCache.iterator();
-
-      while (iter.hasNext())
-      {
-         MessageReference ref = (MessageReference) iter.next();
-
-         ref.releaseMemoryReference();
-      }
-
-      downCache.clear();
-
-      // when we select refs to load from the channel we load them with a value
-      // of ordering >= loadFromOrderingValue
-      if (this.loadFromOrderingValue == 0)
-      {
-         // First time paging
-         this.loadFromOrderingValue = minOrdering;
-      }
-      else
-      {
-         // It's possible that one of the refs that we're spilling to disk
-         // has a lower ordering value than the current loadFromOrderingValue
-         // value
-         // normally this will not be the case but it can be the case if
-         // messages are cancelled out of normal delivery order
-         // or with committing transactions since the ordering for refs in a
-         // transaction is determined when the refs are added to the tx, not
-         // at commit time.
-         // In these cases we need to adjust loadFromOrderingValue appropriately
-         if (minOrdering < loadFromOrderingValue)
-         {
-            loadFromOrderingValue = minOrdering;
-         }
-      }
-
-      if (trace)
-      {
-         log.trace(this + " cleared downcache");
-      }
-   }
-
-   protected boolean acknowledgeInMemory(Delivery d)
-   {
-      if (d == null)
-      {
-         throw new IllegalArgumentException("Can't acknowledge a null delivery");
-      }
-
-      boolean removed = deliveries.remove(d);
-
-      // It's ok if the delivery couldn't be found - this might happen
-      // if the delivery is acked before the call to handle() has returned
-
-      if (trace)
-      {
-         log.trace(this + " removed " + d + " from memory:" + removed);
-      }
-      
-      return removed;
-   }
-
-   protected void load(int number) throws Exception
-   {
-      if (trace)
-      {
-         log.trace(this + " Loading " + number + " refs from storage");
-      }
-
-      // Must flush the down cache first
-      flushDownCache();
-
-      List refInfos = pm.getReferenceInfos(channelID, loadFromOrderingValue,number);
-
-      // We may load less than desired due to "holes" - this is ok
-      int numberLoaded = refInfos.size();
-      
-      if (numberLoaded == 0)
-      {
-         throw new IllegalStateException(
-                  "Trying to page refs in from persitent storage - but can't find any!");
-      }
-
-      Map refMap = new HashMap(refInfos.size());
-
-      List msgIdsToLoad = new ArrayList(refInfos.size());
-
-      Iterator iter = refInfos.iterator();
-
-      // Put the refs that we already have messages for in a map
-      while (iter.hasNext())
-      {
-         PersistenceManager.ReferenceInfo info = (PersistenceManager.ReferenceInfo) iter.next();
-
-         long msgId = info.getMessageId();
-
-         MessageReference ref = ms.reference(msgId);
-
-         if (ref != null)
-         {
-            refMap.put(new Long(msgId), ref);
-         }
-         else
-         {
-            // Add id to list of msg ids to load
-            msgIdsToLoad.add(new Long(msgId));
-         }
-      }
-
-      // Load the messages (if any)
-      List messages = null;
-      if (!msgIdsToLoad.isEmpty())
-      {
-         messages = pm.getMessages(msgIdsToLoad);
-
-         if (messages.size() != msgIdsToLoad.size())
-         {
-            // Sanity check
-            throw new IllegalStateException(
-                     "Did not load correct number of messages, wanted:"
-                              + msgIdsToLoad.size() + " but got:"
-                              + messages.size());
-         }
-
-         // Create references for these messages and add them to the reference
-         // map
-         iter = messages.iterator();
-
-         while (iter.hasNext())
-         {
-            Message m = (Message) iter.next();
-
-            // Message might actually be know to the store since we did the
-            // first check
-            // since might have been added by different channel
-            // in intervening period, but this is ok - the store knows to only
-            // return a reference
-            // to the pre-existing message
-            MessageReference ref = ms.reference(m);
-            
-            refMap.put(new Long(m.getMessageID()), ref);
-         }
-      }
-
-      // Now we have all the messages loaded and refs created we need to put the
-      // refs in the right order
-      // in the channel
-
-      boolean loadedReliable = false;
-
-      long firstOrdering = -1;
-      long lastOrdering = -1;
-
-      List toRemove = new ArrayList();
-
-      iter = refInfos.iterator();
-      while (iter.hasNext())
-      {
-         PersistenceManager.ReferenceInfo info = (PersistenceManager.ReferenceInfo) iter
-                  .next();
-
-         if (firstOrdering == -1)
-         {
-            firstOrdering = info.getOrdering();
-         }
-         lastOrdering = info.getOrdering();
-
-         long msgId = info.getMessageId();
-
-         MessageReference ref = (MessageReference) refMap.get(new Long(msgId));
-
-         ref.setDeliveryCount(info.getDeliveryCount());
-
-         ref.setOrdering(info.getOrdering());
-         
-         //We ignore the reliable field from the message - this is because reliable might be true on the message
-         //but this is a non recoverable state
-         
-         //FIXME - Really the message shouldn't have a reliable field at all,
-         //Reliability is an attribute of the message reference, not the message
-         
-         ref.setReliable(info.isReliable());
-         
-         messageRefs.addLast(ref, ref.getPriority());
-
-         if (recoverable && ref.isReliable())
-         {
-            loadedReliable = true;
-         }
-         else
-         {
-            // We put the non reliable refs (or reliable in a non-recoverable
-            // store)
-            // in a list to be removed
-            toRemove.add(ref);
-         }
-      }
-
-      if (!toRemove.isEmpty())
-      {
-         // Now we remove the references we loaded (only the non persistent or
-         // persistent in a non-recoverable
-         // store)
-         pm.removeReferences(channelID, toRemove);
-      }
-
-      if (loadedReliable)
-      {
-         // If we loaded any reliable refs then we must mark them as loaded in
-         // the store
-         // otherwise they may get loaded again, the next time we do a load
-         // We can't delete them since they're reliable and haven't been acked
-         // yet
-         pm.updateReliableReferencesLoadedInRange(channelID, firstOrdering,
-                  lastOrdering);
-      }
-
-      refsInStorage -= numberLoaded;
-
-      loadFromOrderingValue = lastOrdering + 1;
-
-      if (refsInStorage != 0 || messageRefs.size() == fullSize)
-      {
-         paging = true;
-      }
-      else
-      {
-         paging = false;
-      }
-   }
-
    protected InMemoryCallback getCallback(Transaction tx)
    {
       InMemoryCallback callback = (InMemoryCallback) tx.getKeyedCallback(this);
@@ -1443,7 +824,12 @@
       return callback;
    }
    
-
+   protected abstract boolean cancelInternal(Delivery del) throws Exception;
+   
+   protected abstract MessageReference removeFirstInMemory() throws Exception;
+   
+   protected abstract void addReferenceInMemory(MessageReference ref) throws Exception;     
+   
    // Private -------------------------------------------------------
 
    // Inner classes -------------------------------------------------
@@ -1467,7 +853,7 @@
       {
          refsToAdd.add(ref);
 
-         minOrder = Math.min(minOrder, ref.getOrdering());
+         minOrder = Math.min(minOrder, ref.getPagingOrder());
       }
 
       private void addDelivery(Delivery del)
@@ -1562,7 +948,7 @@
          }
          catch (InterruptedException e)
          {
-            log.warn("Thread interrupted", e);
+            log.error("Thread interrupted", e);
          }
 
          // Wait for it to complete
@@ -1605,8 +991,7 @@
             }
             catch (Throwable t)
             {
-               // FIXME - Sort out this exception handling
-               log.error("Failed to add reference", t);
+               throw new TransactionException("Failed to add reference", t);
             }
          }
 
@@ -1618,10 +1003,7 @@
          {
             Delivery del = (Delivery) iter.next();
 
-            if (trace)
-            {
-               log.trace(this + " removing " + del + " after commit");
-            }
+            if (trace) { log.trace(this + " removing " + del + " after commit"); }
 
             del.getReference().releaseMemoryReference();
 
@@ -1655,8 +1037,8 @@
 
    /**
     * Give subclass a chance to process the message before storing it
-    * internally. Useful to get rid of the REMOTE_ROUTABLE header in a
-    * distributed case, for example.
+    * internally.
+    * TODO - Do we really need this?
     */
    protected void processMessageBeforeStorage(MessageReference reference)
    {
@@ -1664,39 +1046,7 @@
    }
 
    // Private -------------------------------------------------------
-
-   /**
-    * Pushes the reference to <i>a</i> receiver, as dictated by the routing
-    * policy
-    */
-   private Delivery push(MessageReference ref)
-   {
-      Delivery d = null;
-
-      Set deliveries = router.handle(this, ref, null);
-
-      if (deliveries.isEmpty())
-      {
-         return null;
-      }
-
-      // TODO
-      // Sanity check - we shouldn't get more then one delivery - the Channel
-      // can only cope with
-      // one delivery per message reference at any one time. Eventually this
-      // will be enforced in
-      // the design of the core classes but for now we just throw an Exception
-      if (deliveries.size() > 1)
-      {
-         throw new IllegalStateException(
-                  "More than one delivery returned from router!");
-      }
-
-      d = (Delivery) deliveries.iterator().next();
-
-      return d;
-   }
-   
+ 
    private void checkClosed()
    {
       if (router == null)

Modified: trunk/src/main/org/jboss/messaging/core/Delivery.java
===================================================================
--- trunk/src/main/org/jboss/messaging/core/Delivery.java	2006-08-30 09:26:13 UTC (rev 1236)
+++ trunk/src/main/org/jboss/messaging/core/Delivery.java	2006-08-30 18:36:36 UTC (rev 1237)
@@ -21,6 +21,8 @@
   */
 package org.jboss.messaging.core;
 
+import org.jboss.messaging.core.tx.Transaction;
+
 /**
  * A message delivery. It can be "done" or active.
  * 
@@ -46,5 +48,9 @@
    //      See http://jira.jboss.org/jira/browse/JBMESSAGING-275
 
    boolean isSelectorAccepted();
+   
+   void acknowledge(Transaction tx) throws Throwable;
 
+   void cancel() throws Throwable;
+
 }

Modified: trunk/src/main/org/jboss/messaging/core/Filter.java
===================================================================
--- trunk/src/main/org/jboss/messaging/core/Filter.java	2006-08-30 09:26:13 UTC (rev 1236)
+++ trunk/src/main/org/jboss/messaging/core/Filter.java	2006-08-30 18:36:36 UTC (rev 1237)
@@ -45,4 +45,6 @@
 	 * @return true if the Filter accepts the routable - i.e. let's it pass.
 	 */
 	boolean accept(Routable routable);
+   
+   String getFilterString();
 }

Modified: trunk/src/main/org/jboss/messaging/core/MessageReference.java
===================================================================
--- trunk/src/main/org/jboss/messaging/core/MessageReference.java	2006-08-30 09:26:13 UTC (rev 1236)
+++ trunk/src/main/org/jboss/messaging/core/MessageReference.java	2006-08-30 18:36:36 UTC (rev 1237)
@@ -21,7 +21,6 @@
   */
 package org.jboss.messaging.core;
 
-import java.io.Serializable;
 
 /**
  * A "lightweight" message representative.
@@ -34,13 +33,11 @@
  */
 public interface MessageReference extends Routable
 {
-   Serializable getStoreID();
-   
    int getInMemoryChannelCount();
 
-   long getOrdering();
+   long getPagingOrder();
    
-   void setOrdering(long ordering);   
+   void setPagingOrder(long order);   
    
    void releaseMemoryReference();
    

Added: trunk/src/main/org/jboss/messaging/core/PagingChannel.java
===================================================================
--- trunk/src/main/org/jboss/messaging/core/PagingChannel.java	2006-08-30 09:26:13 UTC (rev 1236)
+++ trunk/src/main/org/jboss/messaging/core/PagingChannel.java	2006-08-30 18:36:36 UTC (rev 1237)
@@ -0,0 +1,522 @@
+/*
+ * 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;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+
+import org.jboss.logging.Logger;
+import org.jboss.messaging.core.plugin.contract.MessageStore;
+import org.jboss.messaging.core.plugin.contract.PersistenceManager;
+import org.jboss.messaging.core.plugin.contract.PersistenceManager.InitialLoadInfo;
+import org.jboss.messaging.core.plugin.contract.PersistenceManager.ReferenceInfo;
+
+import EDU.oswego.cs.dl.util.concurrent.QueuedExecutor;
+
+/**
+ * A PagingChannel
+ * 
+ * This channel implementation automatically pages message references to and from storage to prevent more
+ * than a maximum number of references being stored in memory at once.
+ * 
+ * This allows us to support logical channels holding many millions of messages without running out of memory.
+ *
+ * @author <a href="mailto:tim.fox at jboss.com">Tim Fox</a>
+ * @version <tt>$Revision: 1.1 $</tt>
+ *
+ * $Id$
+ *
+ */
+public class PagingChannel extends ChannelSupport
+{
+   private static final Logger log = Logger.getLogger(PagingChannel.class);
+   
+   private boolean trace = log.isTraceEnabled();
+   
+   protected List downCache;
+   
+   /**
+    * The maximum number of references this channel will hold before going into paging mode
+    */
+   protected int fullSize;
+
+   /**
+    * The maximum number of references to load from storage in one go when unpaging
+    */
+   protected int pageSize;
+
+   /**
+    * The maximum number of references paged to storage in one operation
+    */
+   protected int downCacheSize;
+
+   /**
+    * Are we in paging mode?
+    */
+   protected boolean paging;
+
+   /**
+    * The page order value for the first reference paged in storage
+    */
+   protected long firstPagingOrder;
+   
+   /**
+    * The value of page order for the next reference to page
+    */
+   protected long nextPagingOrder;
+   
+   /**
+    * @param channelID
+    * @param ms
+    * @param pm
+    * @param mm
+    * @param acceptReliableMessages
+    * @param recoverable
+    * @param fullSize
+    * @param pageSize
+    * @param downCacheSize
+    * @param executor
+    */
+   public PagingChannel(long channelID, MessageStore ms, PersistenceManager pm, boolean acceptReliableMessages, boolean recoverable, int fullSize, int pageSize, int downCacheSize, QueuedExecutor executor)
+   {
+      super(channelID, ms, pm, acceptReliableMessages, recoverable, executor);
+      
+      if (pageSize >= fullSize)
+      {
+         throw new IllegalArgumentException("pageSize must be less than full size");
+      }
+      if (downCacheSize > pageSize)
+      {
+         throw new IllegalArgumentException("pageSize cannot be smaller than downCacheSize");
+      }
+      if (pageSize <= 0)
+      {
+         throw new IllegalArgumentException("pageSize must be greater than zero");
+      }
+      if (downCacheSize <= 0)
+      {
+         throw new IllegalArgumentException("downCacheSize must be greater than zero");
+      }
+      
+      downCache = new ArrayList(downCacheSize);
+
+      this.fullSize = fullSize;
+
+      this.pageSize = pageSize;
+
+      this.downCacheSize = downCacheSize;      
+   }
+   
+   // Channel implementation
+   // ---------------------------------------------------------------
+   
+   public void load() throws Exception
+   {
+      if (trace) { log.trace(this + " loading channel state"); }
+      
+      synchronized (refLock)
+      {
+         InitialLoadInfo ili = pm.getInitialReferenceInfos(channelID, fullSize);
+         
+         firstPagingOrder = ili.getMinPageOrdering();
+         
+         nextPagingOrder = ili.getMaxPageOrdering();
+         
+         Map refMap = processReferences(ili.getRefInfos());
+         
+         Iterator iter = ili.getRefInfos().iterator();
+         while (iter.hasNext())
+         {
+            ReferenceInfo info = (ReferenceInfo)iter.next();
+
+            addFromRefInfo(info, refMap);
+         }         
+      }
+   }      
+   
+   // Public --------------------------------------------------------
+
+   public int downCacheCount()
+   {
+      synchronized (refLock)
+      {
+         return downCache.size();
+      }
+   }
+
+   public boolean isPaging()
+   {
+      synchronized (refLock)
+      {
+         return paging;
+      }
+   }
+   
+   // Protected -------------------------------------------------------
+   
+   protected boolean cancelInternal(Delivery del) throws Exception
+   {
+      if (trace) { log.trace(this + " cancelling " + del + " in memory"); }
+
+      boolean removed;
+
+      synchronized (deliveryLock)
+      {
+         removed = deliveries.remove(del);
+      }
+
+      if (!removed)
+      {         
+         // This can happen if the message is cancelled before the result of
+         // ServerConsumerDelegate.handle has returned, in which case we won't have a record of the delivery
+         // In this case we don't want to add the message reference back into
+         // the state since it was never removed in the first place
+
+         if (trace) { log.trace(this + " can't find delivery " + del + " in state so not replacing messsage ref"); }
+      }
+      else
+      {
+         synchronized (refLock)
+         {
+            messageRefs.addFirst(del.getReference(), del.getReference().getPriority());
+
+            if (paging)
+            {
+               // if paging we need to evict the end reference to storage to
+               // preserve the number of refs in the queue
+
+               MessageReference ref = (MessageReference)messageRefs.removeLast();
+
+               addToDownCache(ref);
+            }
+         }
+
+         if (trace) { log.trace(this + " added " + del.getReference() + " back into state"); }
+      }
+      
+      return removed;
+   }
+   
+   protected MessageReference removeFirstInMemory() throws Exception
+   {
+      synchronized (refLock)
+      {
+         MessageReference result = (MessageReference) messageRefs.removeFirst();
+
+         long refNum = downCache.size() + nextPagingOrder - firstPagingOrder   ;
+         
+         if (refNum > 0)
+         {
+            long numberLoadable = Math.min(refNum, pageSize);
+
+            if (messageRefs.size() <= fullSize - numberLoadable)
+            {
+               //This will flush the down cache too
+               loadPagedReferences(numberLoadable);
+            }
+         }
+         else
+         {
+            paging = false;
+         }
+
+         return (MessageReference) result;
+      }
+   }
+   
+   protected void addReferenceInMemory(MessageReference ref) throws Exception
+   {
+      if (ref.isReliable() && !acceptReliableMessages)
+      {
+         throw new IllegalStateException("Reliable reference " + ref +
+                                         " cannot be added to non-recoverable state");
+      }
+
+      synchronized (refLock)
+      {
+         if (paging)
+         {
+            addToDownCache(ref);
+         }
+         else
+         {
+            messageRefs.addLast(ref, ref.getPriority());
+
+            if (trace){ log.trace(this + " added " + ref + " non-transactionally in memory"); }
+
+            if (messageRefs.size() == fullSize)
+            {
+               // We are full in memory - go into paging mode
+               if (trace) { log.trace(this + " going into paging mode"); }
+
+               paging = true;
+            }
+         }
+      }
+   }
+   
+   protected void addToDownCache(MessageReference ref) throws Exception
+   {
+      // If the down cache exists then refs are not spilled over immediately,
+      // but store in the cache and spilled over in one go when the next load is requested,
+      // or when it is full
+
+      // Both non reliable and reliable references can go in the down cache,
+      // however only non-reliable
+      // references actually get added to storage, reliable references instead
+      // just get their page ordering column updated since they will already be in storage
+
+      downCache.add(ref);
+
+      if (trace) { log.trace(ref + " sent to downcache"); }
+
+      if (downCache.size() == downCacheSize)
+      {
+         if (trace) { log.trace(this + "'s downcache is full (" + downCache.size() + " messages)"); }
+         
+         flushDownCache();
+      }
+   }
+
+   protected void flushDownCache() throws Exception
+   {
+      if (trace) { log.trace(this + " flushing " + downCache.size() + " refs from downcache"); }
+
+      // Non persistent refs won't already be in the db so they need to be inserted
+      // Persistent refs in a recoverable state will already be there so need to
+      // be updated
+
+      List toUpdate = new ArrayList();
+
+      List toAdd = new ArrayList();
+
+      Iterator iter = downCache.iterator();
+      
+      //It's important that we don't actually increment nextPagingOrder in the loop
+      //in case of failure
+      int count = 0;
+
+      while (iter.hasNext())
+      {
+         MessageReference ref = (MessageReference) iter.next();
+         
+         ref.setPagingOrder(nextPagingOrder + count++);
+
+         if (ref.isReliable() && recoverable)
+         {
+            toUpdate.add(ref);
+         }
+         else
+         {
+            toAdd.add(ref);
+         }
+      }
+
+      if (!toAdd.isEmpty())
+      {
+         pm.addReferences(channelID, toAdd);
+      }
+      if (!toUpdate.isEmpty())
+      {
+         pm.updatePageOrder(channelID, toUpdate);
+      }
+
+      // Release in memory refs for the refs we just spilled
+      // Note! This must be done after the db inserts - to ensure message is
+      // still in memory
+      iter = downCache.iterator();
+
+      while (iter.hasNext())
+      {
+         MessageReference ref = (MessageReference) iter.next();
+
+         ref.releaseMemoryReference();
+      }
+
+      downCache.clear();
+      
+      //If we get this far then the database operations succeeded so we can update nextPagingOrder
+      //We don't do this before the database updates since otherwise we will end up with gaps
+      //in page ordering in the database if the db temporarily fails then comes back to life without
+      //restarting the server.
+      
+      nextPagingOrder += count;      
+
+      if (trace) { log.trace(this + " cleared downcache"); }
+   }
+   
+   
+   
+   protected void loadPagedReferences(long number) throws Exception
+   {
+      if (trace) { log.trace(this + " Loading " + number + " paged references from storage"); }
+
+      // Must flush the down cache first
+      flushDownCache();
+      
+      List refInfos = pm.getPagedReferenceInfos(channelID, firstPagingOrder, number);
+      
+      Map refMap = processReferences(refInfos);
+
+      boolean loadedReliable = false;
+
+      List toRemove = new ArrayList();
+
+      Iterator iter = refInfos.iterator();
+      while (iter.hasNext())
+      {
+         ReferenceInfo info = (ReferenceInfo)iter.next();
+         
+         MessageReference ref = addFromRefInfo(info, refMap);
+         
+         if (recoverable && ref.isReliable())
+         {
+            loadedReliable = true;
+         }
+         else
+         {
+            // We put the non reliable refs (or reliable in a non-recoverable store)
+            // in a list to be removed
+            toRemove.add(ref);
+         }
+      }
+
+      if (!toRemove.isEmpty())
+      {
+         // Now we remove the references we loaded (only the non persistent or persistent in a non-recoverable store)
+         
+         pm.removeReferences(channelID, toRemove);
+      }
+
+      if (loadedReliable)
+      {
+         // If we loaded any reliable refs then we must set the page ordering to null in
+         // the store otherwise they may get loaded again, the next time we do a load
+         // We can't delete them since they're reliable and haven't been acked yet
+         
+         pm.updateReliableReferencesNotPagedInRange(channelID, firstPagingOrder, number);
+      }
+            
+      firstPagingOrder += number;
+      
+      if (firstPagingOrder == nextPagingOrder)
+      {
+         //No more refs in storage
+         firstPagingOrder = nextPagingOrder = 0;
+         
+         if (messageRefs.size() != fullSize)
+         {
+            paging = false;
+         }
+      }    
+   }
+   
+   // Private ------------------------------------------------------------------------------
+   
+   private MessageReference addFromRefInfo(ReferenceInfo info, Map refMap)
+   {
+      long msgId = info.getMessageId();
+
+      MessageReference ref = (MessageReference)refMap.get(new Long(msgId));
+
+      ref.setDeliveryCount(info.getDeliveryCount());
+
+      ref.setPagingOrder(-1);
+      
+      //We ignore the reliable field from the message - this is because reliable might be true on the message
+      //but this is a non recoverable state
+      
+      //TODO - Really the message shouldn't have a reliable field at all,
+      //Reliability is an attribute of the message reference, not the message
+      
+      ref.setReliable(info.isReliable());
+      
+      messageRefs.addLast(ref, ref.getPriority());
+      
+      return ref;
+   }
+   
+   private Map processReferences(List refInfos) throws Exception
+   {
+      Map refMap = new HashMap(refInfos.size());
+
+      List msgIdsToLoad = new ArrayList(refInfos.size());
+
+      Iterator iter = refInfos.iterator();
+
+      // Put the refs that we already have messages for in a map
+      while (iter.hasNext())
+      {
+         ReferenceInfo info = (ReferenceInfo) iter.next();
+
+         long msgId = info.getMessageId();
+
+         MessageReference ref = ms.reference(msgId);
+
+         if (ref != null)
+         {
+            refMap.put(new Long(msgId), ref);
+         }
+         else
+         {
+            // Add id to list of msg ids to load
+            msgIdsToLoad.add(new Long(msgId));
+         }
+      }
+
+      // Load the messages (if any)
+      List messages = null;
+      if (!msgIdsToLoad.isEmpty())
+      {
+         messages = pm.getMessages(msgIdsToLoad);
+
+         if (messages.size() != msgIdsToLoad.size())
+         {
+            // Sanity check
+            throw new IllegalStateException("Did not load correct number of messages, wanted:" +
+                                            msgIdsToLoad.size() + " but got:" +
+                                            messages.size());
+         }
+
+         // Create references for these messages and add them to the reference map
+         iter = messages.iterator();
+
+         while (iter.hasNext())
+         {
+            Message m = (Message)iter.next();
+
+            // Message might actually be know to the store since we did the
+            // first check since might have been added by different channel
+            // in intervening period, but this is ok - the store knows to only
+            // return a reference to the pre-existing message
+            MessageReference ref = ms.reference(m);
+            
+            refMap.put(new Long(m.getMessageID()), ref);
+         }
+      }
+      
+      return refMap;
+   }
+}

Modified: trunk/src/main/org/jboss/messaging/core/Router.java
===================================================================
--- trunk/src/main/org/jboss/messaging/core/Router.java	2006-08-30 09:26:13 UTC (rev 1236)
+++ trunk/src/main/org/jboss/messaging/core/Router.java	2006-08-30 18:36:36 UTC (rev 1237)
@@ -21,11 +21,12 @@
   */
 package org.jboss.messaging.core;
 
-import java.util.Set;
-
 import org.jboss.messaging.core.tx.Transaction;
 
 /**
+ * 
+ * Routes a routable to a maximum of one of the attached receivers
+ * 
  * @author <a href="mailto:ovidiu at jboss.org">Ovidiu Feodorov</a>
  * @author <a href="mailto:tim.fox at jboss.com">Tim Fox</a>
  * @version <tt>$Revision$</tt>
@@ -34,10 +35,5 @@
  */
 public interface Router extends Distributor
 {
-
-   /**
-    * Returns a set of Delivery instances.
-    */
-   Set handle(DeliveryObserver observer, Routable routable, Transaction transaction);
-
+   Delivery handle(DeliveryObserver observer, Routable routable, Transaction transaction);
 }

Deleted: trunk/src/main/org/jboss/messaging/core/RouterSupport.java
===================================================================
--- trunk/src/main/org/jboss/messaging/core/RouterSupport.java	2006-08-30 09:26:13 UTC (rev 1236)
+++ trunk/src/main/org/jboss/messaging/core/RouterSupport.java	2006-08-30 18:36:36 UTC (rev 1237)
@@ -1,174 +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;
-
-import org.jboss.logging.Logger;
-
-import java.util.Iterator;
-import java.util.Map;
-import java.util.HashMap;
-import java.util.Set;
-import java.util.HashSet;
-import java.io.Serializable;
-
-/**
- * Does Receiver management but it stops short of enforcing any routing policy, leaving it to
- * subclasses.
- *
- * @author <a href="mailto:ovidiu at jboss.org">Ovidiu Feodorov</a>
- * @version <tt>$Revision$</tt>
- */
-public abstract class RouterSupport implements Router
-{
-   // Attributes ----------------------------------------------------
-
-   /**
-    * <ReceiverID - Receiver> map
-    */
-   protected Map receivers;
-   protected Serializable id;
-   protected Logger log;
-
-   protected boolean passByReference;
-
-
-
-   // Constructors --------------------------------------------------
-
-   protected RouterSupport(Serializable id)
-   {
-      this.id = id;
-      receivers = new HashMap();
-
-      // by default a router passes by reference
-      passByReference = true;
-   }
-
-   // Public --------------------------------------------------------
-
-   // Router implementation -----------------------------------------
-
-   public Serializable getRouterID()
-   {
-      return id;
-   }
-
-   public Set handle(DeliveryObserver o, Routable r)
-   {
-      return handle(o, r);
-   }
-
-   public boolean isPassByReference()
-   {
-      return passByReference;
-   }
-
-   // Distributor implementation ------------------------------------
-
-   public boolean add(Receiver r)
-   {
-//      Serializable id = r.getReceiverID();
-//      synchronized(this)
-//      {
-//         if (receivers.containsKey(id)) {
-//            return false;
-//         }
-//         receivers.put(id, r);
-//         return true;
-//      }
-      return false;
-   }
-
-   public Receiver get(Serializable receiverID)
-   {
-      synchronized(this)
-      {
-         return (Receiver)receivers.get(receiverID);
-      }
-   }
-
-   public Receiver remove(Serializable receiverID)
-   {
-       synchronized(this)
-       {
-          Receiver removed = (Receiver)receivers.remove(receiverID);
-          return removed;
-       }
-   }
-
-   public boolean contains(Serializable receiverID)
-   {
-      synchronized(this)
-      {
-         return receivers.containsKey(receiverID);
-      }
-   }
-
-   public Iterator iterator()
-   {
-      synchronized(this)
-      {
-         return receivers.keySet().iterator();
-      }
-   }
-
-   public void clear()
-   {
-      synchronized(this)
-      {
-         receivers.clear();
-      }
-   }
-
-   // Protected  ----------------------------------------------------
-
-   /**
-    * @return the intersection between the current receiverID set and the given receiverID set.
-    */
-   protected Iterator iterator(Set receiverIDs)
-   {
-      if (receiverIDs == null)
-      {
-         return iterator();
-      }
-
-      Set result = new HashSet();
-      for(Iterator i = receiverIDs.iterator(); i.hasNext();)
-      {
-         Object o = i.next();
-         if (receivers.containsKey(o))
-         {
-            result.add(o);
-         }
-         else
-         {
-            log.warn("receiver " + o + "has disappeared; the message for it will be dropped");
-         }
-      }
-      return result.iterator();
-   }
-
-
-
-}
-
-

Modified: trunk/src/main/org/jboss/messaging/core/SimpleDelivery.java
===================================================================
--- trunk/src/main/org/jboss/messaging/core/SimpleDelivery.java	2006-08-30 09:26:13 UTC (rev 1236)
+++ trunk/src/main/org/jboss/messaging/core/SimpleDelivery.java	2006-08-30 18:36:36 UTC (rev 1237)
@@ -35,7 +35,7 @@
  * 
  * $Id$
  */
-public class SimpleDelivery implements SingleReceiverDelivery, Serializable
+public class SimpleDelivery implements Delivery, Serializable
 {
    // Constants -----------------------------------------------------
 

Deleted: trunk/src/main/org/jboss/messaging/core/SingleReceiverDelivery.java
===================================================================
--- trunk/src/main/org/jboss/messaging/core/SingleReceiverDelivery.java	2006-08-30 09:26:13 UTC (rev 1236)
+++ trunk/src/main/org/jboss/messaging/core/SingleReceiverDelivery.java	2006-08-30 18:36:36 UTC (rev 1237)
@@ -1,42 +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;
-
-import org.jboss.messaging.core.tx.Transaction;
-
-/**
- * A message delivery where the message has been delivered to only one receiver. It can be "done"
- * or active. This type of delivery is returned by a stateless receiver.
- *
- * @author <a href="mailto:ovidiu at jboss.org">Ovidiu Feodorov</a>
- * @author <a href="mailto:tim.fox at jboss.com">Tim Fox</a>
- * @version <tt>$Revision$</tt>
- *
- * $Id$
- */
-public interface SingleReceiverDelivery extends Delivery
-{
-   void acknowledge(Transaction tx) throws Throwable;
-
-   void cancel() throws Throwable;
-   
-}

Deleted: trunk/src/main/org/jboss/messaging/core/StatefulReceiverDelivery.java
===================================================================
--- trunk/src/main/org/jboss/messaging/core/StatefulReceiverDelivery.java	2006-08-30 09:26:13 UTC (rev 1236)
+++ trunk/src/main/org/jboss/messaging/core/StatefulReceiverDelivery.java	2006-08-30 18:36:36 UTC (rev 1237)
@@ -1,38 +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;
-
-import java.io.Serializable;
-
-/**
- * A message delivery where the message has been delivered to only one receiver. It can be "done" 
- * or active. This type of delivery is returned by a stateful receiver.
- * 
- * @author <a href="mailto:ovidiu at jboss.org">Ovidiu Feodorov</a>
- * @version <tt>$Revision$</tt>
- *
- * $Id$
- */
-public interface StatefulReceiverDelivery extends SingleReceiverDelivery
-{
-   Serializable getReceiverID();
-}

Deleted: trunk/src/main/org/jboss/messaging/core/local/CoreDestination.java
===================================================================
--- trunk/src/main/org/jboss/messaging/core/local/CoreDestination.java	2006-08-30 09:26:13 UTC (rev 1236)
+++ trunk/src/main/org/jboss/messaging/core/local/CoreDestination.java	2006-08-30 18:36:36 UTC (rev 1237)
@@ -1,51 +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.local;
-
-import org.jboss.messaging.core.Distributor;
-import org.jboss.messaging.core.Receiver;
-
-/**
- * Common type for a core destination (queue, topic)
- *
- * @author <a href="mailto:ovidiu at jboss.org">Ovidiu Feodorov</a>
- * @author <a href="mailto:tim.fox at jboss.com">Tim Fox</a>
- * @version <tt>$Revision$</tt>
- *
- * $Id$
- */
-public interface CoreDestination extends Distributor, Receiver
-{
-   long getId();     
-   
-   /**
-    * 
-    * @return true if the CoreDestination represents a Queue
-    */
-   boolean isQueue();
-   
-   int getFullSize();
-   
-   int getPageSize();
-   
-   int getDownCacheSize();
-}

Deleted: trunk/src/main/org/jboss/messaging/core/local/CoreSubscription.java
===================================================================
--- trunk/src/main/org/jboss/messaging/core/local/CoreSubscription.java	2006-08-30 09:26:13 UTC (rev 1236)
+++ trunk/src/main/org/jboss/messaging/core/local/CoreSubscription.java	2006-08-30 18:36:36 UTC (rev 1237)
@@ -1,133 +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.local;
-
-import org.jboss.logging.Logger;
-import org.jboss.messaging.core.Delivery;
-import org.jboss.messaging.core.DeliveryObserver;
-import org.jboss.messaging.core.Filter;
-import org.jboss.messaging.core.Routable;
-import org.jboss.messaging.core.memory.MemoryManager;
-import org.jboss.messaging.core.plugin.contract.MessageStore;
-import org.jboss.messaging.core.plugin.contract.PersistenceManager;
-import org.jboss.messaging.core.tx.Transaction;
-
-import EDU.oswego.cs.dl.util.concurrent.QueuedExecutor;
-
-/**
- * Represents a subscription to a destination (topic or queue).
- * 
- * @author <a href="mailto:tim.fox at jboss.com">Tim Fox</a>
- *
- * $Id$
- */
-public class CoreSubscription extends Pipe
-{
-   // Constants -----------------------------------------------------
-   
-   private static final Logger log;
-   
-   private static final boolean trace;
-   
-   private boolean connected;
-   
-   static
-   {
-      log = Logger.getLogger(CoreSubscription.class);
-      trace = log.isTraceEnabled();
-   }
-   // Static --------------------------------------------------------
-   
-   // Attributes ----------------------------------------------------
-   
-   protected Topic topic;
-
-   protected Filter filter;
-   
-   // Constructors --------------------------------------------------
- 
-   public CoreSubscription(long id, Topic topic, 
-                           MessageStore ms, PersistenceManager pm, MemoryManager mm,
-                           boolean recoverable,
-                           int fullSize, int pageSize, int downCacheSize,
-                           QueuedExecutor executor, Filter filter)
-                              
-   {
-      // A CoreSubscription must accept reliable messages
-      super(id, ms, pm, mm, true, recoverable, fullSize, pageSize, downCacheSize, executor);
-      this.topic = topic;
-      this.filter = filter;
-   }
-  
-   // Channel implementation ----------------------------------------
-   
-   public Delivery handle(DeliveryObserver sender, Routable r, Transaction tx)
-   { 
-      //If the subscription has a Filter we do not accept any Message references that do not
-      //match the Filter
-      if (filter != null && !filter.accept(r))
-      {
-         if (trace) { log.trace(this + " not accepting " + r); }
-         return null;
-      }
-      
-      return super.handle(sender, r, tx);
-   }
-
-   // Public --------------------------------------------------------
-   
-   public void connect()
-   {
-      if (!connected)
-      {
-         topic.add(this);
-         connected = true;
-      }
-   }
-   
-   public void disconnect()
-   {
-      if (connected)
-      {
-         topic.remove(this);
-         connected = false;
-      }
-   }
-      
-   public Topic getTopic()
-   {
-      return topic;
-   }
-        
-   public String toString()
-   {
-      return "CoreSubscription[" + getChannelID() + ", " + topic + "]";
-   }
-
-   // Package protected ---------------------------------------------
-   
-   // Protected -----------------------------------------------------
-   
-   // Private -------------------------------------------------------
-   
-   // Inner classes -------------------------------------------------   
-}

Modified: trunk/src/main/org/jboss/messaging/core/local/FirstReceiverPointToPointRouter.java
===================================================================
--- trunk/src/main/org/jboss/messaging/core/local/FirstReceiverPointToPointRouter.java	2006-08-30 09:26:13 UTC (rev 1236)
+++ trunk/src/main/org/jboss/messaging/core/local/FirstReceiverPointToPointRouter.java	2006-08-30 18:36:36 UTC (rev 1237)
@@ -22,10 +22,8 @@
 package org.jboss.messaging.core.local;
 
 import java.util.ArrayList;
-import java.util.HashSet;
 import java.util.Iterator;
 import java.util.List;
-import java.util.Set;
 
 import org.jboss.logging.Logger;
 import org.jboss.messaging.core.Delivery;
@@ -38,7 +36,6 @@
 
 /**
  * 
- * This router deliver the reference to a maximum of one of the router's receivers.
  * It will always favour the first receiver in the internal list of receivers, but will retry
  * the next one (and the next one...) if a previous one does not want to accept the message.
  * If the router has several receivers (e.g. the case of multiple consumers on a queue)
@@ -72,9 +69,9 @@
 
    // Router implementation -----------------------------------------
 
-   public Set handle(DeliveryObserver observer, Routable routable, Transaction tx)
+   public Delivery handle(DeliveryObserver observer, Routable routable, Transaction tx)
    {
-      Set deliveries = new HashSet();
+      Delivery del = null;
       
       boolean selectorRejected = false;
       
@@ -95,7 +92,8 @@
                   if (d.isSelectorAccepted())
                   {
                      // deliver to the first receiver that accepts
-                     deliveries.add(d);
+                     del = d;
+                     
                      break;
                   }
                   else
@@ -112,12 +110,12 @@
          }
       }
       
-      if (deliveries.isEmpty() && selectorRejected)
+      if (del == null && selectorRejected)
       {
-         deliveries.add(new SimpleDelivery(null, null, true, false));
+         del = new SimpleDelivery(null, null, true, false);
       }
 
-      return deliveries;
+      return del;
    }
 
    public boolean add(Receiver r)

Copied: trunk/src/main/org/jboss/messaging/core/local/MessageQueue.java (from rev 1223, trunk/src/main/org/jboss/messaging/core/local/CoreSubscription.java)
===================================================================
--- trunk/src/main/org/jboss/messaging/core/local/CoreSubscription.java	2006-08-10 19:04:47 UTC (rev 1223)
+++ trunk/src/main/org/jboss/messaging/core/local/MessageQueue.java	2006-08-30 18:36:36 UTC (rev 1237)
@@ -0,0 +1,120 @@
+/*
+  * 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.local;
+
+import org.jboss.logging.Logger;
+import org.jboss.messaging.core.Delivery;
+import org.jboss.messaging.core.DeliveryObserver;
+import org.jboss.messaging.core.Filter;
+import org.jboss.messaging.core.PagingChannel;
+import org.jboss.messaging.core.Routable;
+import org.jboss.messaging.core.plugin.contract.MessageStore;
+import org.jboss.messaging.core.plugin.contract.PersistenceManager;
+import org.jboss.messaging.core.tx.Transaction;
+
+import EDU.oswego.cs.dl.util.concurrent.QueuedExecutor;
+
+/**
+ * 
+ * A MessageQueue
+ * 
+ * Represents a generic message queue.
+ * 
+ * Can be used to implement a point to point queue, or a subscription fed from a topic
+ *
+ * @author <a href="mailto:ovidiu at jboss.org">Ovidiu Feodorov</a>
+ * @author <a href="mailto:tim.fox at jboss.com">Tim Fox</a>
+ * @version <tt>$Revision$</tt>
+ *
+ * $Id$
+ *
+ */
+public class MessageQueue extends PagingChannel
+{
+   // Constants -----------------------------------------------------
+   
+   private static final Logger log;
+   
+   private static final boolean trace;
+   
+   static
+   {
+      log = Logger.getLogger(MessageQueue.class);
+      trace = log.isTraceEnabled();
+   }
+
+   // Static --------------------------------------------------------
+   
+   // Attributes ----------------------------------------------------
+   
+   protected Filter filter;
+   
+   
+   // Constructors --------------------------------------------------
+
+   public MessageQueue(long id, MessageStore ms, PersistenceManager pm,             
+                       boolean acceptReliableMessages, boolean recoverable,
+                       int fullSize, int pageSize, int downCacheSize, QueuedExecutor executor,
+                       Filter filter)
+   {
+      super(id, ms, pm, acceptReliableMessages, recoverable, fullSize, pageSize, downCacheSize, executor);
+      
+      router = new RoundRobinPointToPointRouter();
+      
+      this.filter = filter;
+   }
+    
+   // Channel implementation ----------------------------------------
+   
+   public Delivery handle(DeliveryObserver sender, Routable r, Transaction tx)
+   { 
+      //If the queue has a Filter we do not accept any Message references that do not
+      //match the Filter
+      if (filter != null && !filter.accept(r))
+      {
+         if (trace) { log.trace(this + " not accepting " + r); }
+         return null;
+      }
+      
+      return super.handle(sender, r, tx);
+   }
+
+   // Public --------------------------------------------------------
+
+   public String toString()
+   {
+      return "Queue[" + getChannelID() + "]";
+   }
+   
+   public Filter getFilter()
+   {
+      return filter;
+   }
+
+   // Package protected ---------------------------------------------
+   
+   // Protected -----------------------------------------------------
+   
+   // Private -------------------------------------------------------
+   
+   // Inner classes -------------------------------------------------   
+}

Deleted: trunk/src/main/org/jboss/messaging/core/local/Pipe.java
===================================================================
--- trunk/src/main/org/jboss/messaging/core/local/Pipe.java	2006-08-30 09:26:13 UTC (rev 1236)
+++ trunk/src/main/org/jboss/messaging/core/local/Pipe.java	2006-08-30 18:36:36 UTC (rev 1237)
@@ -1,71 +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.local;
-
-import org.jboss.messaging.core.ChannelSupport;
-import org.jboss.messaging.core.memory.MemoryManager;
-import org.jboss.messaging.core.plugin.contract.MessageStore;
-import org.jboss.messaging.core.plugin.contract.PersistenceManager;
-
-import EDU.oswego.cs.dl.util.concurrent.QueuedExecutor;
-
-/**
- * @author <a href="mailto:ovidiu at jboss.org">Ovidiu Feodorov</a>
- * @author <a href="mailto:tim.fox at jboss.com">Tim Fox</a>
- * @version <tt>$Revision$</tt>
- * $Id$
- */
-public class Pipe extends ChannelSupport
-{
-   // Constants -----------------------------------------------------
-
-   // Static --------------------------------------------------------
-   
-   // Attributes ----------------------------------------------------
-   
-   // Constructors --------------------------------------------------
-
-   public Pipe(long id, MessageStore ms, PersistenceManager pm, MemoryManager mm,              
-               boolean acceptReliableMessages, boolean recoverable,
-               int fullSize, int pageSize, int downCacheSize, QueuedExecutor executor)
-   {
-      super(id, ms, pm, mm, acceptReliableMessages, recoverable, fullSize, pageSize, downCacheSize, executor);
-      router = new SingleDestinationRouter();
-   }
-    
-   // Channel implementation ----------------------------------------
-
-   // Public --------------------------------------------------------
-
-   public String toString()
-   {
-      return "CorePipe[" + getChannelID() + "]";
-   }
-
-   // Package protected ---------------------------------------------
-   
-   // Protected -----------------------------------------------------
-   
-   // Private -------------------------------------------------------
-   
-   // Inner classes -------------------------------------------------   
-}

Deleted: trunk/src/main/org/jboss/messaging/core/local/PointToMultipointRouter.java
===================================================================
--- trunk/src/main/org/jboss/messaging/core/local/PointToMultipointRouter.java	2006-08-30 09:26:13 UTC (rev 1236)
+++ trunk/src/main/org/jboss/messaging/core/local/PointToMultipointRouter.java	2006-08-30 18:36:36 UTC (rev 1237)
@@ -1,266 +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.local;
-
-import org.jboss.messaging.core.Router;
-import org.jboss.messaging.core.DeliveryObserver;
-import org.jboss.messaging.core.Routable;
-import org.jboss.messaging.core.Receiver;
-import org.jboss.messaging.core.Delivery;
-import org.jboss.messaging.core.tx.Transaction;
-import org.jboss.logging.Logger;
-
-import EDU.oswego.cs.dl.util.concurrent.ReadWriteLock;
-import EDU.oswego.cs.dl.util.concurrent.WriterPreferenceReadWriteLock;
-
-import java.util.List;
-import java.util.ArrayList;
-import java.util.Set;
-import java.util.HashSet;
-import java.util.Iterator;
-
-/**
- * @author <a href="mailto:ovidiu at jboss.org">Ovidiu Feodorov</a>
- * @version <tt>$Revision$</tt>
- * 
- * $Id$
- */
-public class PointToMultipointRouter implements Router
-{
-   // Constants -----------------------------------------------------
-
-   private static final Logger log = Logger.getLogger(PointToMultipointRouter.class);
-
-   // Static --------------------------------------------------------
-   
-   // Attributes ----------------------------------------------------
-   
-   private boolean trace = log.isTraceEnabled();
-
-   List receivers;
-   
-   ReadWriteLock lock;
-
-   // Constructors --------------------------------------------------
-
-   public PointToMultipointRouter()
-   {
-      receivers = new ArrayList();
-      
-      lock = new WriterPreferenceReadWriteLock();
-   }
-
-   // Router implementation -----------------------------------------
-   
-   public Set handle(DeliveryObserver observer, Routable routable, Transaction tx)
-   {
-      Set deliveries = new HashSet();
-
-      boolean acquired;
-      try
-      {
-         lock.readLock().acquire();
-         acquired = true;
-      }
-      catch (InterruptedException e)
-      {
-         throw new RuntimeException("Failed to obtain lock", e);
-      }
-      
-      try
-      {      
-         for(Iterator i = receivers.iterator(); i.hasNext(); )
-         {
-            Receiver receiver = (Receiver)i.next();
-
-            try
-            {
-               Delivery d = receiver.handle(observer, routable, tx);
-
-               if (trace) { log.trace("receiver " + receiver + " handled " + routable + " and returned " + d); }
-
-               if (d != null && !d.isCancelled())
-               {
-                  deliveries.add(d);
-               }
-            }
-            catch(Throwable t)
-            {
-               // broken receiver - log the exception and ignore it
-               log.error("The receiver " + receiver + " is broken", t);
-            }
-         }
-      }
-      finally
-      {
-         if (acquired)
-         {
-            lock.readLock().release();
-         }
-      }
-      
-      return deliveries;
-   }
-
-   public boolean add(Receiver r)
-   {
-      boolean acquired;
-      try
-      {
-         lock.writeLock().acquire();
-         acquired = true;
-      }
-      catch (InterruptedException e)
-      {
-         throw new RuntimeException("Failed to obtain lock", e);
-      }
-      try
-      {
-         if (receivers.contains(r))
-         {
-            return false;
-         }
-         receivers.add(r);
-      
-         return true;
-      }
-      finally
-      {
-         if (acquired)
-         {
-            lock.writeLock().release();
-         }
-      }
-   }
-
-
-   public boolean remove(Receiver r)
-   {
-      boolean acquired;
-      try
-      {
-         lock.writeLock().acquire();
-         acquired = true;
-      }
-      catch (InterruptedException e)
-      {
-         throw new RuntimeException("Failed to obtain lock", e);
-      }
-      try
-      {
-         return receivers.remove(r);
-      }
-      finally
-      {
-         if (acquired)
-         {
-            lock.writeLock().release();
-         }
-      }     
-   }
-
-   public void clear()
-   {
-      boolean acquired;
-      try
-      {
-         lock.writeLock().acquire();
-         acquired = true;
-      }
-      catch (InterruptedException e)
-      {
-         throw new RuntimeException("Failed to obtain lock", e);
-      }
-      try
-      {
-         receivers.clear();
-      }
-      finally
-      {
-         if (acquired)
-         {
-            lock.writeLock().release();
-         }
-      }
-   }
-
-   public boolean contains(Receiver r)
-   {
-      boolean acquired;
-      try
-      {
-         lock.writeLock().acquire();
-         acquired = true;
-      }
-      catch (InterruptedException e)
-      {
-         throw new RuntimeException("Failed to obtain lock", e);
-      }
-      try
-      {
-         return receivers.contains(r);      
-      }
-      finally
-      {
-         if (acquired)
-         {
-            lock.writeLock().release();
-         }
-      }
-   }
-
-   public Iterator iterator()
-   {
-      boolean acquired;
-      try
-      {
-         lock.writeLock().acquire();
-         acquired = true;
-      }
-      catch (InterruptedException e)
-      {
-         throw new RuntimeException("Failed to obtain lock", e);
-      }
-      try
-      {
-         return receivers.iterator();
-      }
-      finally
-      {
-         if (acquired)
-         {
-            lock.writeLock().release();
-         }
-      }
-   }
-
-
-   // Public --------------------------------------------------------
-
-   // Package protected ---------------------------------------------
-   
-   // Protected -----------------------------------------------------
-   
-   // Private -------------------------------------------------------
-   
-   // Inner classes -------------------------------------------------   
-}

Deleted: trunk/src/main/org/jboss/messaging/core/local/Queue.java
===================================================================
--- trunk/src/main/org/jboss/messaging/core/local/Queue.java	2006-08-30 09:26:13 UTC (rev 1236)
+++ trunk/src/main/org/jboss/messaging/core/local/Queue.java	2006-08-30 18:36:36 UTC (rev 1237)
@@ -1,118 +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.local;
-
-import org.jboss.messaging.core.ChannelSupport;
-import org.jboss.messaging.core.memory.MemoryManager;
-import org.jboss.messaging.core.plugin.contract.MessageStore;
-import org.jboss.messaging.core.plugin.contract.PersistenceManager;
-
-import EDU.oswego.cs.dl.util.concurrent.QueuedExecutor;
-
-/**
- * @author <a href="mailto:ovidiu at jboss.org">Ovidiu Feodorov</a>
- * @author <a href="mailto:tim.fox"jboss.com">Tim Fox</a>
- * @version <tt>$Revision$</tt>
- *
- * $Id$
- */
-public class Queue extends ChannelSupport implements CoreDestination
-{
-   // Constants -----------------------------------------------------
-
-   // Static --------------------------------------------------------
-   
-   // Attributes ----------------------------------------------------
-   
-   //TODO - Do we really need to cache these values here?
-   //Can't we just return the values from the corresponding ChannelState?
-   private int fullSize;
-   
-   private int pageSize;
-   
-   private int downCacheSize;
-
-   // Constructors --------------------------------------------------
-
-   public Queue(long id, MessageStore ms, PersistenceManager pm, MemoryManager mm,
-                boolean recoverable, int fullSize, int pageSize, int downCacheSize,
-                QueuedExecutor executor)
-   {      
-      super(id, ms, pm, mm, true, recoverable, fullSize, pageSize, downCacheSize, executor);
-      
-      //TODO make the policy configurable
-      //By default we use a router with a round robin policy for even distribution in the
-      //case of multiple consumers
-      router = new RoundRobinPointToPointRouter();
-      
-      this.fullSize = fullSize;
-      this.pageSize = pageSize;
-      this.downCacheSize = downCacheSize;
-   }
-
-   // Public --------------------------------------------------------
-
-   public String toString()
-   {
-      return "CoreQueue[" + getChannelID() + "]";
-   }
-   
-   public boolean isQueue()
-   {
-      return true;
-   }
-   
-   public int getMessageCount()
-   {
-      return messageCount();
-   }
-   
-   // CoreDestination implementation -------------------------------
-   
-   public long getId()
-   {
-      return channelID;
-   }
-   
-   public int getFullSize()
-   {
-      return fullSize;
-   }
-   
-   public int getPageSize()
-   {
-      return pageSize;
-   }
-   
-   public int getDownCacheSize()
-   {
-      return downCacheSize;
-   }
-
-   // Package protected ---------------------------------------------
-   
-   // Protected -----------------------------------------------------
-   
-   // Private -------------------------------------------------------
-   
-   // Inner classes -------------------------------------------------   
-}

Modified: trunk/src/main/org/jboss/messaging/core/local/RoundRobinPointToPointRouter.java
===================================================================
--- trunk/src/main/org/jboss/messaging/core/local/RoundRobinPointToPointRouter.java	2006-08-30 09:26:13 UTC (rev 1236)
+++ trunk/src/main/org/jboss/messaging/core/local/RoundRobinPointToPointRouter.java	2006-08-30 18:36:36 UTC (rev 1237)
@@ -22,10 +22,7 @@
 package org.jboss.messaging.core.local;
 
 import java.util.ArrayList;
-import java.util.HashSet;
 import java.util.Iterator;
-import java.util.Set;
-import java.util.Collections;
 
 import org.jboss.logging.Logger;
 import org.jboss.messaging.core.Delivery;
@@ -37,9 +34,7 @@
 import org.jboss.messaging.core.tx.Transaction;
 
 /**
- * 
- * This router deliver the reference to a maximum of one of the router's receivers.
- * 
+ *  
  * The router will always first try the next receiver in the list to the one it tried last time
  * This gives a more balanced distribution than the FirstReceiverPointToPointRouter and is
  * better suited when batching messages to consumers since we will end up with messages interleaved amongst
@@ -77,7 +72,7 @@
 
    // Router implementation -----------------------------------------
    
-   public Set handle(DeliveryObserver observer, Routable routable, Transaction tx)
+   public Delivery handle(DeliveryObserver observer, Routable routable, Transaction tx)
    {
       int initial, current;
       ArrayList receiversCopy;
@@ -86,7 +81,7 @@
       {
          if (receivers.isEmpty())
          {
-            return Collections.EMPTY_SET;
+            return null;
          }
 
          // try to release the lock as quickly as possible and make a copy of the receivers array
@@ -98,7 +93,7 @@
          current = initial;
       }
 
-      Set deliveries = new HashSet();;
+      Delivery del = null;
       boolean selectorRejected = false;
 
       while (true)
@@ -116,7 +111,7 @@
                if (d.isSelectorAccepted())
                {
                   // deliver to the first receiver that accepts
-                  deliveries.add(d);
+                  del = d;
                   shiftTarget(current);
                   break;
                }
@@ -141,12 +136,12 @@
          }
       }
 
-      if (deliveries.isEmpty() && selectorRejected)
+      if (del == null && selectorRejected)
       {
-         deliveries.add(new SimpleDelivery(null, null, true, false));
+         del = new SimpleDelivery(null, null, true, false);
       }
 
-      return deliveries;
+      return del;
    }
 
    public boolean add(Receiver r)

Deleted: trunk/src/main/org/jboss/messaging/core/local/SingleDestinationRouter.java
===================================================================
--- trunk/src/main/org/jboss/messaging/core/local/SingleDestinationRouter.java	2006-08-30 09:26:13 UTC (rev 1236)
+++ trunk/src/main/org/jboss/messaging/core/local/SingleDestinationRouter.java	2006-08-30 18:36:36 UTC (rev 1237)
@@ -1,147 +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.local;
-
-import org.jboss.messaging.core.Router;
-import org.jboss.messaging.core.Receiver;
-import org.jboss.messaging.core.DeliveryObserver;
-import org.jboss.messaging.core.Routable;
-import org.jboss.messaging.core.Delivery;
-import org.jboss.messaging.core.tx.Transaction;
-import org.jboss.logging.Logger;
-
-import java.util.Set;
-import java.util.Collections;
-import java.util.HashSet;
-import java.util.Iterator;
-import java.util.ArrayList;
-import java.util.List;
-
-/**
- * @author <a href="mailto:ovidiu at jboss.org">Ovidiu Feodorov</a>
- * @version <tt>$Revision$</tt>
- *
- * $Id$
- */
-public class SingleDestinationRouter implements Router
-{
-   // Constants -----------------------------------------------------
-
-   private static final Logger log = Logger.getLogger(SingleDestinationRouter.class);
-
-   // Static --------------------------------------------------------
-   
-   // Attributes ----------------------------------------------------
-
-   protected Receiver receiver;
-
-   // Constructors --------------------------------------------------
-
-   // Router implementation -----------------------------------------
-
-   public synchronized Set handle(DeliveryObserver observer, Routable routable, Transaction tx)
-   {
-      
-      
-      if (receiver == null)
-      {
-         return Collections.EMPTY_SET;
-      }
-
-      Set deliveries = new HashSet(1);
-      try
-      {
-         Delivery d = receiver.handle(observer, routable, tx);
-         
-         if (d != null && !d.isCancelled())
-         {
-            deliveries.add(d);
-         }
-      }
-      catch(Throwable t)
-      {
-         // broken receiver - log the exception and ignore it
-         log.error("The receiver " + receiver + " is broken" + t);
-      }
-      return deliveries;
-   }
-
-   public synchronized boolean add(Receiver r)
-   {
-      if (receiver == r)
-      {
-         return false;
-      }
-      receiver = r;
-      return true;
-   }
-
-
-   public synchronized boolean remove(Receiver r)
-   {
-      boolean result = false;
-      if (receiver == r)
-      {
-         result = true;
-         
-         //Only remove receiver if it is the same one
-         receiver = null;
-      }
-      
-      
-      return result;
-   }
-
-   public synchronized void clear()
-   {
-      receiver = null;
-   }
-
-   public synchronized boolean contains(Receiver r)
-   {
-      return receiver == r;
-   }
-
-   public synchronized Iterator iterator()
-   {
-      if (receiver == null)
-      {
-         return Collections.EMPTY_LIST.iterator();
-      }
-      List l = new ArrayList();
-      l.add(receiver);
-      return l.iterator(); 
-   }
-
-
-
-
-   // Public --------------------------------------------------------
-
-   // Package protected ---------------------------------------------
-   
-   // Protected -----------------------------------------------------
-   
-   // Private -------------------------------------------------------
-   
-   // Inner classes -------------------------------------------------   
-}

Deleted: trunk/src/main/org/jboss/messaging/core/local/Topic.java
===================================================================
--- trunk/src/main/org/jboss/messaging/core/local/Topic.java	2006-08-30 09:26:13 UTC (rev 1236)
+++ trunk/src/main/org/jboss/messaging/core/local/Topic.java	2006-08-30 18:36:36 UTC (rev 1237)
@@ -1,172 +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.local;
-
-import java.util.Iterator;
-import java.util.Set;
-
-import org.jboss.logging.Logger;
-import org.jboss.messaging.core.Delivery;
-import org.jboss.messaging.core.DeliveryObserver;
-import org.jboss.messaging.core.Receiver;
-import org.jboss.messaging.core.Routable;
-import org.jboss.messaging.core.Router;
-import org.jboss.messaging.core.SimpleDelivery;
-import org.jboss.messaging.core.tx.Transaction;
-
-/**
- * @author <a href="mailto:ovidiu at jboss.org">Ovidiu Feodorov</a>
- * @author <a href="mailto:tim.fox"jboss.com">Tim Fox</a>
- * @version <tt>$Revision$</tt>
- * 
- * $Id$
- */
-public class Topic implements CoreDestination
-{
-   // Constants -----------------------------------------------------
-
-   private static final Logger log = Logger.getLogger(Topic.class);
-
-   // Static --------------------------------------------------------
-   
-   // Attributes ----------------------------------------------------
-   
-   private int fullSize;
-   
-   private int pageSize;
-   
-   private int downCacheSize;
-   
-   private boolean trace = log.isTraceEnabled();
-   
-   protected Router router;
-   
-   protected long destinationId;
-   
-   // Constructors --------------------------------------------------
-   
-   public Topic(long id, int fullSize, int pageSize, int downCacheSize)
-   {
-      router = new PointToMultipointRouter();
-      
-      if (log.isTraceEnabled()) { log.trace(this + " created"); }
-      
-      this.destinationId = id;     
-      
-      this.fullSize = fullSize;
-      this.pageSize = pageSize;
-      this.downCacheSize = downCacheSize;
-   }
-
-   // Receiver implementation ---------------------------------------
-
-   public Delivery handle(DeliveryObserver sender, Routable r, Transaction tx)
-   {
-      if (trace){ log.trace(this + " handles " + r + (tx == null ? " non-transactionally" : " in transaction: " + tx) ); }
-
-      Set deliveries = router.handle(sender, r, tx);
-
-      // must insure that all deliveries are completed, otherwise we risk losing messages
-      for(Iterator i = deliveries.iterator(); i.hasNext(); )
-      {
-         Delivery d = (Delivery)i.next();
-         if (d == null || !d.isDone())
-         {
-            log.error("the point to multipoint delivery was not completed correctly: " + d);
-            throw new IllegalStateException("Incomplete delivery");
-         }
-      }
-      
-      return new SimpleDelivery(true);   
-   }
-
-   // Distributor implementation --------------------------------------
-
-   public boolean add(Receiver receiver)
-   {
-      return router.add(receiver);
-   }
-
-   public void clear()
-   {
-      router.clear();
-   }
-
-   public boolean contains(Receiver receiver)
-   {
-      return router.contains(receiver);
-   }
-
-   public Iterator iterator()
-   {
-      return router.iterator();
-   }
-
-   public boolean remove(Receiver receiver)
-   {
-      boolean removed = router.remove(receiver);
-      if (trace) { log.trace(this + (removed ? " removed " : " did NOT remove ") + receiver); }
-      return removed;
-   }
-   
-   // CoreDestination implementation -------------------------------
-   
-   public long getId()
-   {
-      return destinationId;
-   }
-
-   public boolean isQueue()
-   {
-      return false;
-   }
-   
-   public int getFullSize()
-   {
-      return fullSize;
-   }
-   
-   public int getPageSize()
-   {
-      return pageSize;
-   }
-   
-   public int getDownCacheSize()
-   {
-      return downCacheSize;
-   }
-   
-   // Public --------------------------------------------------------
-
-   public String toString()
-   {
-      return "CoreTopic[" + destinationId + "]";
-   }
-
-   // Package protected ---------------------------------------------
-   
-   // Protected -----------------------------------------------------
-   
-   // Private -------------------------------------------------------
-   
-   // Inner classes -------------------------------------------------   
-}

Modified: trunk/src/main/org/jboss/messaging/core/message/RoutableSupport.java
===================================================================
--- trunk/src/main/org/jboss/messaging/core/message/RoutableSupport.java	2006-08-30 09:26:13 UTC (rev 1236)
+++ trunk/src/main/org/jboss/messaging/core/message/RoutableSupport.java	2006-08-30 18:36:36 UTC (rev 1237)
@@ -33,9 +33,9 @@
 import java.util.Map;
 import java.util.Set;
 
-import org.jboss.jms.util.SafeUTF;
 import org.jboss.logging.Logger;
 import org.jboss.messaging.core.Routable;
+import org.jboss.messaging.util.SafeUTF;
 import org.jboss.util.Primitives;
 
 /**

Deleted: trunk/src/main/org/jboss/messaging/core/persistence/JDBCUtil.java
===================================================================
--- trunk/src/main/org/jboss/messaging/core/persistence/JDBCUtil.java	2006-08-30 09:26:13 UTC (rev 1236)
+++ trunk/src/main/org/jboss/messaging/core/persistence/JDBCUtil.java	2006-08-30 18:36:36 UTC (rev 1237)
@@ -1,115 +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.persistence;
-
-/**
- * @author <a href="mailto:ovidiu at jboss.org">Ovidiu Feodorov</a> 
- * @version <tt>$Revision$</tt>
- * $Id$
- */
-public class JDBCUtil
-{
-   // Constants -----------------------------------------------------
-
-   // Static --------------------------------------------------------
-
-   public static String statementToString(String sql)
-   {
-      return sql;
-   }
-
-   public static String statementToString(String sql, Object arg1)
-   {
-      return statementToString(sql, new Object[] { arg1 });
-   }
-
-   public static String statementToString(String sql, Object arg1, Object arg2)
-   {
-      return statementToString(sql, new Object[] { arg1, arg2 });
-   }
-
-   public static String statementToString(String sql, Object arg1, Object arg2, Object arg3)
-   {
-      return statementToString(sql, new Object[] { arg1, arg2, arg3 });
-   }
-
-   public static String statementToString(String sql, Object arg1, Object arg2, Object arg3,
-                                          Object arg4)
-   {
-      return statementToString(sql, new Object[] { arg1, arg2, arg3, arg4 });
-   }
-
-   public static String statementToString(String sql, Object arg1, Object arg2, Object arg3,
-                                          Object arg4, Object arg5)
-   {
-      return statementToString(sql, new Object[] { arg1, arg2, arg3, arg4, arg5 });
-   }
-   
-   public static String statementToString(String sql, Object arg1, Object arg2, Object arg3,
-         Object arg4, Object arg5, Object arg6)
-   {
-      return statementToString(sql, new Object[] { arg1, arg2, arg3, arg4, arg5, arg6 });
-   }
-   
-   public static String statementToString(String sql, Object arg1, Object arg2, Object arg3,
-         Object arg4, Object arg5, Object arg6, Object arg7)
-   {
-      return statementToString(sql, new Object[] { arg1, arg2, arg3, arg4, arg5, arg6, arg7 });
-   }
-
-   public static String statementToString(String sql, Object[] args)
-   {
-      StringBuffer statement = new StringBuffer();
-      int i = 0, pos = 0, cnt = 0;
-      while((i = sql.indexOf('?', pos)) != -1)
-      {
-         statement.append(sql.substring(pos, i));
-         Object s = "?";
-         if (cnt < args.length)
-         {
-            s = args[cnt++];
-            if ("".equals(s))
-            {
-               s = "''";
-            }
-         }
-         statement.append(s);
-         pos = i + 1;
-      }
-      statement.append(sql.substring(pos));
-      return statement.toString();
-   }
-
-   // Attributes ----------------------------------------------------
-   
-   // Constructors --------------------------------------------------
-   
-   // Public --------------------------------------------------------
-
-   // Package protected ---------------------------------------------
-   
-   // Protected -----------------------------------------------------
-   
-   // Private -------------------------------------------------------
-   
-   // Inner classes -------------------------------------------------   
-}

Modified: trunk/src/main/org/jboss/messaging/core/plugin/JDBCPersistenceManager.java
===================================================================
--- trunk/src/main/org/jboss/messaging/core/plugin/JDBCPersistenceManager.java	2006-08-30 09:26:13 UTC (rev 1236)
+++ trunk/src/main/org/jboss/messaging/core/plugin/JDBCPersistenceManager.java	2006-08-30 18:36:36 UTC (rev 1237)
@@ -24,7 +24,6 @@
 import java.io.BufferedInputStream;
 import java.io.ByteArrayInputStream;
 import java.io.ByteArrayOutputStream;
-import java.io.IOException;
 import java.io.InputStream;
 import java.sql.Connection;
 import java.sql.PreparedStatement;
@@ -39,41 +38,31 @@
 import java.util.Iterator;
 import java.util.List;
 import java.util.Map;
-import java.util.Properties;
 
-import javax.management.MBeanServer;
-import javax.management.MBeanServerInvocationHandler;
-import javax.management.ObjectName;
-import javax.naming.InitialContext;
 import javax.sql.DataSource;
-import javax.transaction.Status;
 import javax.transaction.TransactionManager;
 import javax.transaction.xa.Xid;
 
 import org.jboss.jms.destination.JBossDestination;
+import org.jboss.jms.destination.JBossQueue;
+import org.jboss.jms.destination.JBossTopic;
 import org.jboss.jms.message.JBossMessage;
-import org.jboss.jms.server.plugin.contract.ChannelMapper;
 import org.jboss.logging.Logger;
 import org.jboss.messaging.core.Message;
 import org.jboss.messaging.core.MessageReference;
-import org.jboss.messaging.core.local.CoreDestination;
 import org.jboss.messaging.core.message.CoreMessage;
 import org.jboss.messaging.core.message.MessageFactory;
 import org.jboss.messaging.core.message.MessageSupport;
 import org.jboss.messaging.core.message.RoutableSupport;
-import org.jboss.messaging.core.persistence.JDBCUtil;
 import org.jboss.messaging.core.plugin.contract.PersistenceManager;
 import org.jboss.messaging.core.tx.Transaction;
 import org.jboss.messaging.core.tx.TxCallback;
 import org.jboss.messaging.core.tx.XidImpl;
+import org.jboss.messaging.util.JDBCUtil;
 import org.jboss.messaging.util.Util;
 import org.jboss.serial.io.JBossObjectInputStream;
 import org.jboss.serial.io.JBossObjectOutputStream;
-import org.jboss.system.ServiceMBeanSupport;
-import org.jboss.tm.TransactionManagerServiceMBean;
 
-import EDU.oswego.cs.dl.util.concurrent.ConcurrentReaderHashMap;
-
 /**
  *  
  * JDBC implementation of PersistenceManager 
@@ -86,149 +75,18 @@
  *
  * JDBCPersistenceManager.java,v 1.1 2006/02/22 17:33:41 timfox Exp
  */
-public class JDBCPersistenceManager extends ServiceMBeanSupport implements PersistenceManager
+public class JDBCPersistenceManager extends JDBCServiceSupport implements PersistenceManager
 {
    // Constants -----------------------------------------------------
    
    private static final Logger log = Logger.getLogger(JDBCPersistenceManager.class); 
    
-   /* The default DML and DDL works with HSQLDB */
-   
-   //JMS_MESSAGE_REFERENCE
-   
-   protected String createMessageReference = "CREATE TABLE JMS_MESSAGE_REFERENCE (CHANNELID BIGINT, "
-   + "MESSAGEID BIGINT, TRANSACTIONID BIGINT, STATE CHAR(1), ORD BIGINT, "
-   + "DELIVERYCOUNT INTEGER, RELIABLE CHAR(1), LOADED CHAR(1), PRIMARY KEY(CHANNELID, MESSAGEID))";
-   
-   protected String createIdxMessageRefTx = "CREATE INDEX JMS_MESSAGE_REF_TX ON JMS_MESSAGE_REFERENCE (TRANSACTIONID)";
-   
-   protected String createIdxMessageRefOrd = "CREATE INDEX JMS_MESSAGE_REF_ORD ON JMS_MESSAGE_REFERENCE (ORD)";
-   
-   protected String createIdxMessageRefMessageId = "CREATE INDEX JMS_MESSAGE_REF_MESSAGEID ON JMS_MESSAGE_REFERENCE (MESSAGEID)";
-   
-   protected String createIdxMessageRefLoaded = "CREATE INDEX JMS_MESSAGE_REF_LOADED ON JMS_MESSAGE_REFERENCE (LOADED)";
-   
-   protected String createIdxMessageRefReliable = "CREATE INDEX JMS_MESSAGE_REF_RELIABLE ON JMS_MESSAGE_REFERENCE (RELIABLE)";
-   
-   protected String insertMessageRef = "INSERT INTO JMS_MESSAGE_REFERENCE (CHANNELID, MESSAGEID, TRANSACTIONID, STATE, ORD, DELIVERYCOUNT, RELIABLE, LOADED) "
-      + "VALUES (?, ?, ?, ?, ?, ?, ?, ?)";
-   
-   protected String deleteMessageRef = "DELETE FROM JMS_MESSAGE_REFERENCE WHERE MESSAGEID=? AND CHANNELID=? AND STATE='C'";
-   
-   protected String updateMessageRef = "UPDATE JMS_MESSAGE_REFERENCE SET TRANSACTIONID=?, STATE='-' "
-      + "WHERE MESSAGEID=? AND CHANNELID=? AND STATE='C'";
-   
-   protected String updateMessageRefNotLoaded = "UPDATE JMS_MESSAGE_REFERENCE SET LOADED='N' WHERE MESSAGEID=? AND CHANNELID=?";
-   
-   protected String commitMessageRef1 = "UPDATE JMS_MESSAGE_REFERENCE SET STATE='C', TRANSACTIONID = NULL WHERE TRANSACTIONID=? AND STATE='+'";
-   
-   protected String commitMessageRef2 = "DELETE FROM JMS_MESSAGE_REFERENCE WHERE TRANSACTIONID=? AND STATE='-'";
-   
-   protected String rollbackMessageRef1 = "DELETE FROM JMS_MESSAGE_REFERENCE WHERE TRANSACTIONID=? AND STATE='+'";
-   
-   protected String rollbackMessageRef2 = "UPDATE JMS_MESSAGE_REFERENCE SET STATE='C', TRANSACTIONID = NULL WHERE TRANSACTIONID=? AND STATE='-'";
-   
-   protected String loadReferenceInfo = 
-      "SELECT MESSAGEID, ORD, DELIVERYCOUNT, RELIABLE FROM JMS_MESSAGE_REFERENCE "
-      + "WHERE CHANNELID=? AND STATE <> '+' AND LOADED = 'N' AND "
-      + "ORD BETWEEN ? AND ? ORDER BY ORD";
-   
-   protected String selectMinOrdering = 
-      "SELECT MIN(ORD) FROM JMS_MESSAGE_REFERENCE WHERE "
-      + "CHANNELID=? AND STATE <> '+' AND LOADED = 'N'";
-   
-   protected String selectCountReferences = "SELECT COUNT(MESSAGEID) FROM JMS_MESSAGE_REFERENCE WHERE CHANNELID=? AND STATE <> '+' AND LOADED='N'";
-   
-   protected String updateReliableRefs = 
-      "UPDATE JMS_MESSAGE_REFERENCE SET LOADED='Y' WHERE ORD BETWEEN ? AND ? AND CHANNELID=? AND RELIABLE='Y' AND STATE <> '+'";
-    
-   protected String updateReliableRefsNotLoaded = "UPDATE JMS_MESSAGE_REFERENCE SET LOADED='N' WHERE CHANNELID=?";
-   
-   protected String deleteUnreliableRefs = 
-      "DELETE FROM JMS_MESSAGE_REFERENCE WHERE RELIABLE = 'N'";
-    
-   //JMS_MESSAGE
-   
-   protected String createMessage = "CREATE TABLE JMS_MESSAGE (MESSAGEID BIGINT, RELIABLE CHAR(1), "
-   + "EXPIRATION BIGINT, TIMESTAMP BIGINT, PRIORITY TINYINT, COREHEADERS LONGVARBINARY, "
-   + "PAYLOAD LONGVARBINARY, CHANNELCOUNT INTEGER, TYPE TINYINT, JMSTYPE VARCHAR(255), CORRELATIONID VARCHAR(255), "
-   + "CORRELATIONID_BYTES VARBINARY(254), DESTINATION_ID BIGINT, REPLYTO_ID BIGINT, "
-   + "JMSPROPERTIES LONGVARBINARY, "
-   + "PRIMARY KEY (MESSAGEID))";
-   
-   protected String loadMessages = "SELECT MESSAGEID, RELIABLE, EXPIRATION, TIMESTAMP, "
-   + "PRIORITY, COREHEADERS, PAYLOAD, CHANNELCOUNT, TYPE, JMSTYPE, CORRELATIONID, "
-   + "CORRELATIONID_BYTES, DESTINATION_ID, REPLYTO_ID, JMSPROPERTIES "
-   + "FROM JMS_MESSAGE";
-   
-   protected String insertMessage = "INSERT INTO JMS_MESSAGE (MESSAGEID, RELIABLE, EXPIRATION, "
-   + "TIMESTAMP, PRIORITY, COREHEADERS, PAYLOAD, CHANNELCOUNT, TYPE, JMSTYPE, CORRELATIONID, "
-   + "CORRELATIONID_BYTES, DESTINATION_ID, REPLYTO_ID, JMSPROPERTIES) "
-   + "VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)";
-   
-   protected String updateMessageChannelCount = 
-      "UPDATE JMS_MESSAGE SET CHANNELCOUNT=? WHERE MESSAGEID=?";
-   
-   protected String deleteMessage = "DELETE FROM JMS_MESSAGE WHERE MESSAGEID=?";
-   
-   protected String messageIdColumn = "MESSAGEID";
-   
-   protected String updateUnreliableChannelCount =
-      "UPDATE JMS_MESSAGE M SET M.CHANNELCOUNT = M.CHANNELCOUNT - 1 WHERE " +
-      "M.MESSAGEID IN (SELECT MR.MESSAGEID FROM JMS_MESSAGE_REFERENCE MR WHERE MR.RELIABLE = 'N' AND MR.CHANNELID = ?)";
-    
-   protected String deleteUnreffedMessages = 
-      "DELETE FROM JMS_MESSAGE WHERE CHANNELCOUNT = 0";
-   
-   
-   //JMS_TRANSACTION
-   
-   protected String createTransaction = "CREATE TABLE JMS_TRANSACTION ("
-      + "TRANSACTIONID BIGINT, BRANCH_QUAL VARBINARY(254), "
-      + "FORMAT_ID INTEGER, GLOBAL_TXID VARBINARY(254), PRIMARY KEY (TRANSACTIONID))";
-   
-   protected String insertTransaction = "INSERT INTO JMS_TRANSACTION (TRANSACTIONID, BRANCH_QUAL, FORMAT_ID, GLOBAL_TXID) "
-      + "VALUES(?, ?, ?, ?)";
-   
-   protected String deleteTransaction = "DELETE FROM JMS_TRANSACTION WHERE TRANSACTIONID = ?";
-   
-   protected String selectPreparedTransactions = "SELECT TRANSACTIONID, BRANCH_QUAL, FORMAT_ID, GLOBAL_TXID FROM JMS_TRANSACTION";
-   
-   //JMS_COUNTER
-   
-   protected String createCounter = "CREATE TABLE JMS_COUNTER (NAME VARCHAR(255), NEXT_ID BIGINT, PRIMARY KEY(NAME))";
-   
-   protected String updateCounter = "UPDATE JMS_COUNTER SET NEXT_ID = ? WHERE NAME=?";
-   
-   protected String selectCounter = "SELECT NEXT_ID FROM JMS_COUNTER WHERE NAME=?";
-   
-   protected String insertCounter = "INSERT INTO JMS_COUNTER (NAME, NEXT_ID) VALUES (?, ?)";
-   
-   //Other
-   
-   protected String selectAllChannels = "SELECT DISTINCT(CHANNELID) FROM JMS_MESSAGE_REFERENCE";
-   
-        
    // Static --------------------------------------------------------
    
    // Attributes ----------------------------------------------------
    
    private boolean trace = log.isTraceEnabled();
-   
-   protected String dataSourceJNDIName;
-   
-   protected DataSource ds;
-   
-   protected ObjectName tmObjectName;
-   
-   protected ObjectName cmObjectName;
-   
-   protected ChannelMapper cm;
-   
-   protected Properties sqlProperties;
-   
-   protected boolean createTablesOnStartup = true;
-   
+      
    protected boolean usingBatchUpdates = false;
    
    protected boolean usingBinaryStream = true;
@@ -237,62 +95,26 @@
    
    protected int minOrdering;
    
-   protected Map channelMultipliers;
-   
    // Constructors --------------------------------------------------
    
-   public JDBCPersistenceManager() throws Exception
+   public JDBCPersistenceManager()
    {
-      this(null, null, null);
    }
    
-   /**
-    * Only used for testing. In a real deployment, the data source and the transaction manager are
-    * injected as dependencies.
+   /*
+    * This constructor should only be used for testing
     */
-   public JDBCPersistenceManager(DataSource ds, TransactionManager tm) throws Exception
+   public JDBCPersistenceManager(DataSource ds, TransactionManager tm)
    {
-      this(ds, tm, null);
+      super(ds, tm);
    }
-
-   /**
-    * Only used for testing. In a real deployment, the data source and the transaction manager are
-    * injected as dependencies.
-    */
-   public JDBCPersistenceManager(DataSource ds, TransactionManager tm,
-                                 ChannelMapper cm) throws Exception
-   {
-      this.ds = ds;
-      this.tm = tm;
-      this.cm = cm;
-      sqlProperties = new Properties();
-      channelMultipliers = new ConcurrentReaderHashMap();
-   }
-
+      
    // ServiceMBeanSupport overrides ---------------------------------
    
    protected void startService() throws Exception
    {
-      if (ds == null)
-      {
-         InitialContext ic = new InitialContext();
-         ds = (DataSource) ic.lookup(dataSourceJNDIName);
-         ic.close();
-      }
-      
-      if (ds == null)
-      {
-         throw new Exception("No DataSource found. This service dependencies must "
-               + "have not been enforced correctly!");
-      }
+      super.startService();
 
-      if (cmObjectName != null)
-      {
-         MBeanServer server = getServer();
-         
-         cm = (ChannelMapper) server.getAttribute(cmObjectName, "Instance");
-      }
-      
       Connection conn = null;
       
       try
@@ -317,31 +139,17 @@
          conn.close();
       }
             
-      initSqlProperties();
-      
-      if (createTablesOnStartup)
-      {
-         createSchema();
-      }
-      
       removeUnreliableMessageData();
         
       log.debug(this + " started");
    }
    
-   protected void stopService() throws Exception
-   {
-      log.debug(this + " stopped");
-   }
-   
    // PersistenceManager implementation -------------------------
+
    
-   public Object getInstance()
-   {
-      return this;
-   }
+   // Related to counters
+   // ==================
    
-   
    public long reserveIDBlock(String counterName, int size) throws Exception
    {
       //TODO This will need locking (e.g. SELECT ... FOR UPDATE...) in the clustered case
@@ -365,7 +173,7 @@
       {
          conn = ds.getConnection();
          
-         ps = conn.prepareStatement(selectCounter);
+         ps = conn.prepareStatement(getSQLStatement("SELECT_COUNTER"));
          
          ps.setString(1, counterName);
          
@@ -378,7 +186,7 @@
             
             ps.close();
             
-            ps = conn.prepareStatement(insertCounter);
+            ps = conn.prepareStatement(getSQLStatement("INSERT_COUNTER"));
             
             ps.setString(1, counterName);
             
@@ -388,7 +196,7 @@
             
             if (trace)
             {
-               log.trace(JDBCUtil.statementToString(insertCounter, counterName)
+               log.trace(JDBCUtil.statementToString(getSQLStatement("INSERT_COUNTER"), counterName)
                      + " inserted " + rows + " rows");
             }  
             
@@ -400,7 +208,7 @@
          
          if (trace)
          {
-            log.trace(JDBCUtil.statementToString(selectCounter, counterName));
+            log.trace(JDBCUtil.statementToString(getSQLStatement("SELECT_COUNTER"), counterName));
          }
          
          long nextId = rs.getLong(1);
@@ -410,7 +218,7 @@
          
          ps.close();
          
-         ps = conn.prepareStatement(updateCounter);
+         ps = conn.prepareStatement(getSQLStatement("UPDATE_COUNTER"));
          
          ps.setLong(1, nextId + size);
          
@@ -420,7 +228,7 @@
          
          if (trace)
          {
-            log.trace(JDBCUtil.statementToString(updateCounter, new Long(nextId + size),
+            log.trace(JDBCUtil.statementToString(getSQLStatement("UPDATE_COUNTER"), new Long(nextId + size),
                   counterName)
                   + " updated " + rows + " rows");
          }        
@@ -457,13 +265,15 @@
          wrap.end();
       }     
    }
-   
+         
+   // Related to paging functionality
+   // ===============================
       
-   public void updateReliableReferencesLoadedInRange(long channelID, long orderStart, long orderEnd) throws Exception
+   public void updateReliableReferencesNotPagedInRange(long channelID, long orderStart, long number) throws Exception
    {
       if (trace)
       {
-         log.trace("Updating reliable references for channel " + channelID + " between " + orderStart + " and " + orderEnd);
+         log.trace("Updating reliable references for channel " + channelID + " between " + orderStart + " number " + number);
       }
       Connection conn = null;
       PreparedStatement ps = null;
@@ -475,11 +285,11 @@
       {
          conn = ds.getConnection();
          
-         ps = conn.prepareStatement(updateReliableRefs);
+         ps = conn.prepareStatement(getSQLStatement("UPDATE_RELIABLE_REFS_NOT_PAGED"));
          
          ps.setLong(1, orderStart);
          
-         ps.setLong(2, orderEnd);
+         ps.setLong(2, orderStart + number - 1);
          
          ps.setLong(3, channelID);
          
@@ -493,14 +303,21 @@
                
                if (trace)
                {
-                  log.trace(JDBCUtil.statementToString(updateReliableRefs, new Long(channelID),
-                        new Long(orderStart), new Long(orderEnd))
+                  log.trace(JDBCUtil.statementToString(getSQLStatement("UPDATE_RELIABLE_REFS_NOT_PAGED"), new Long(channelID),
+                        new Long(orderStart), new Long(orderStart + number - 1))
                         + " updated " + rows + " rows");
                }
                if (tries > 0)
                {
                   log.warn("Update worked after retry");
                }
+               
+               //Sanity check
+               if (rows != number)
+               {
+                  throw new IllegalStateException("Did not update correct number of rows");
+               }
+               
                break;
             }
             catch (SQLException e)
@@ -547,78 +364,8 @@
          }
          wrap.end();
       }
-   }
-         
-   public int getNumberOfUnloadedReferences(long channelID) throws Exception
-   {
-      if (trace) { log.trace("getting number of unloaded references for channel [" + channelID + "]"); }
-      
-      Connection conn = null;
-      PreparedStatement ps = null;
-      ResultSet rs = null;
-      TransactionWrapper wrap = new TransactionWrapper();
-          
-      try
-      {
-         conn = ds.getConnection();
-         
-         ps = conn.prepareStatement(selectCountReferences);
-         
-         ps.setLong(1, channelID);
-         
-         rs = ps.executeQuery();
-         
-         rs.next();
-         
-         int count = rs.getInt(1);
-         
-         if (trace) { log.trace("There are " + count + " unloaded references"); }
-         
-         return count;
-      }
-      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();
-      }
-   }
-   
-   
-   
+   }         
+        
    /*
     * Retrieve a List of messages corresponding to the specified List of message ids.
     * The implementation here for HSQLDB does this by using a PreparedStatment with an IN clause
@@ -667,8 +414,8 @@
                {
                   numParams = size % maxParams;
                }
-               StringBuffer buff = new StringBuffer(loadMessages);
-               buff.append(" WHERE ").append(messageIdColumn).append(" IN (");
+               StringBuffer buff = new StringBuffer(getSQLStatement("LOAD_MESSAGES"));
+               buff.append(" WHERE ").append(getSQLStatement("MESSAGEID_COLUMN")).append(" IN (");
                for (int i = 0; i < numParams; i++)
                {
                   buff.append("?");
@@ -723,18 +470,41 @@
                      String jmsType = rs.getString(10);
                      String correlationID = rs.getString(11);
                      byte[] correlationIDBytes = rs.getBytes(12);
-                     long destinationId = rs.getLong(13);
-                     long replyToId = rs.getLong(14);
-                     boolean replyToExists = rs.wasNull();
+                     String destination = rs.getString(13);
+                     String replyTo = rs.getString(14);
+                     boolean replyToExists = !rs.wasNull();
                      bytes = getBytes(rs, 15);
                      HashMap jmsProperties = bytesToMap(bytes);
-                     JBossDestination dest = cm.getJBossDestination(destinationId);
-                     JBossDestination replyTo = replyToExists ? cm.getJBossDestination(replyToId) : null;
                      
+                     JBossDestination dest;
+                     if (destination.charAt(0) == 'Q')
+                     {
+                        dest = new JBossQueue(destination.substring(1, destination.length()));
+                     }
+                     else
+                     {
+                        dest = new JBossTopic(destination.substring(1, destination.length()));
+                     }
+                     
+                     JBossDestination replyToDest = null;
+                     
+                     if (replyToExists)
+                     {
+                        if (replyTo.charAt(0) == 'Q')
+                        {
+                           replyToDest = new JBossQueue(replyTo.substring(1, replyTo.length()));
+                        }
+                        else
+                        {
+                           replyToDest = new JBossTopic(replyTo.substring(1, replyTo.length()));
+                        }
+                     }
+                         
                      m = MessageFactory.createJBossMessage(messageId, reliable, expiration, timestamp, priority,
-                           coreHeaders, payload, persistentChannelCount,
-                           type, jmsType, correlationID, correlationIDBytes, dest, replyTo,
-                           jmsProperties);
+                                                           coreHeaders, payload, persistentChannelCount,
+                                                           type, jmsType, correlationID, correlationIDBytes,
+                                                           dest, replyToDest,
+                                                           jmsProperties);
                   }
                   else
                   {
@@ -801,10 +571,8 @@
          wrap.end();
       }
    }  
-   
-         
-   
-   public void addReferences(long channelID, List references, boolean loaded) throws Exception
+               
+   public void addReferences(long channelID, List references) throws Exception
    {  
       Connection conn = null;
       PreparedStatement psInsertReference = null;  
@@ -831,9 +599,9 @@
          
          if (usingBatchUpdates)
          {
-            psInsertReference = conn.prepareStatement(insertMessageRef);
-            psInsertMessage = conn.prepareStatement(insertMessage);
-            psUpdateMessage = conn.prepareStatement(updateMessageChannelCount);
+            psInsertReference = conn.prepareStatement(getSQLStatement("INSERT_MESSAGE_REF"));
+            psInsertMessage = conn.prepareStatement(getSQLStatement("INSERT_MESSAGE"));
+            psUpdateMessage = conn.prepareStatement(getSQLStatement("UPDATE_MESSAGE_CHANNELCOUNT"));
          }
          
          while (iter.hasNext())
@@ -845,11 +613,11 @@
                            
             if (!usingBatchUpdates)
             {
-               psInsertReference = conn.prepareStatement(insertMessageRef);
+               psInsertReference = conn.prepareStatement(getSQLStatement("INSERT_MESSAGE_REF"));
             }
             
             //Now store the reference
-            addReference(channelID, ref, psInsertReference, loaded);
+            addReference(channelID, ref, psInsertReference);
                         
             if (usingBatchUpdates)
             {
@@ -870,8 +638,8 @@
             
             if (!usingBatchUpdates)
             {
-               psInsertMessage = conn.prepareStatement(insertMessage);
-               psUpdateMessage = conn.prepareStatement(updateMessageChannelCount);
+               psInsertMessage = conn.prepareStatement(getSQLStatement("INSERT_MESSAGE"));
+               psUpdateMessage = conn.prepareStatement(getSQLStatement("UPDATE_MESSAGE_CHANNELCOUNT"));
             }
                                                                                      
             //Maybe we need to persist the message itself
@@ -943,7 +711,7 @@
             
             if (trace)
             {
-               logBatchUpdate(insertMessageRef, rowsReference, "inserted");
+               logBatchUpdate(getSQLStatement("INSERT_MESSAGE_REF"), rowsReference, "inserted");
             }
             
             if (messageInsertsInBatch)
@@ -952,7 +720,7 @@
                
                if (trace)
                {
-                  logBatchUpdate(insertMessage, rowsMessage, "inserted");
+                  logBatchUpdate(getSQLStatement("INSERT_MESSAGE"), rowsMessage, "inserted");
                }
             }
             if (messageUpdatesInBatch)
@@ -961,7 +729,7 @@
                
                if (trace)
                {
-                  logBatchUpdate(updateMessageChannelCount, rowsMessage, "updated");
+                  logBatchUpdate(getSQLStatement("UPDATE_MESSAGE_CHANNELCOUNT"), rowsMessage, "updated");
                }
             }
             
@@ -1027,7 +795,7 @@
          }
          finally
          {            
-            if (wrap.failed)
+            if (wrap.isFailed())
             {
                //Reverse the incs
                this.decPersistentCounts(addsToReverse);
@@ -1068,9 +836,9 @@
          
          if (usingBatchUpdates)
          {
-            psDeleteReference = conn.prepareStatement(deleteMessageRef);
-            psDeleteMessage = conn.prepareStatement(deleteMessage);
-            psUpdateMessage = conn.prepareStatement(updateMessageChannelCount);
+            psDeleteReference = conn.prepareStatement(getSQLStatement("DELETE_MESSAGE_REF"));
+            psDeleteMessage = conn.prepareStatement(getSQLStatement("DELETE_MESSAGE"));
+            psUpdateMessage = conn.prepareStatement(getSQLStatement("UPDATE_MESSAGE_CHANNELCOUNT"));
          }
          
          while (iter.hasNext())
@@ -1079,7 +847,7 @@
                                                              
             if (!usingBatchUpdates)
             {
-               psDeleteReference = conn.prepareStatement(deleteMessageRef);
+               psDeleteReference = conn.prepareStatement(getSQLStatement("DELETE_MESSAGE_REF"));
             }
             
             removeReference(channelID, ref, psDeleteReference);
@@ -1103,8 +871,8 @@
             
             if (!usingBatchUpdates)
             {
-               psDeleteMessage = conn.prepareStatement(deleteMessage);
-               psUpdateMessage = conn.prepareStatement(updateMessageChannelCount);
+               psDeleteMessage = conn.prepareStatement(getSQLStatement("DELETE_MESSAGE"));
+               psUpdateMessage = conn.prepareStatement(getSQLStatement("UPDATE_MESSAGE_CHANNELCOUNT"));
             }
                
             Message m = ref.getMessage();
@@ -1177,7 +945,7 @@
             
             if (trace)
             {
-               logBatchUpdate(deleteMessageRef, rowsReference, "deleted");
+               logBatchUpdate(getSQLStatement("DELETE_MESSAGE_REF"), rowsReference, "deleted");
             }
             
             if (messageDeletionsInBatch)
@@ -1186,7 +954,7 @@
                
                if (trace)
                {
-                  logBatchUpdate(deleteMessage, rowsMessage, "deleted");
+                  logBatchUpdate(getSQLStatement("DELETE_MESSAGE"), rowsMessage, "deleted");
                }
             }
             if (messageUpdatesInBatch)
@@ -1195,7 +963,7 @@
                
                if (trace)
                {
-                  logBatchUpdate(updateMessageChannelCount, rowsMessage, "updated");
+                  logBatchUpdate(getSQLStatement("UPDATE_MESSAGE_CHANNELCOUNT"), rowsMessage, "updated");
                }
             }
             
@@ -1260,7 +1028,7 @@
          }
          finally
          {     
-            if (wrap.failed)
+            if (wrap.isFailed())
             {
                //Reverse the decs
                this.incPersistentCounts(removesToReverse);
@@ -1271,13 +1039,15 @@
          }         
       }      
    }
-   
-   public long getMinOrdering(long channelID) throws Exception
-   {           
+      
+   public List getPagedReferenceInfos(long channelID, long orderStart, long number) throws Exception
+   {
       if (trace)
       {
-         log.trace("Getting min ordering for channel " + channelID);
+         log.trace("loading message reference info for channel " + channelID + " from " + orderStart + " number " + number);
       }
+                    
+      List refs = new ArrayList();
       
       Connection conn = null;
       PreparedStatement ps = null;
@@ -1288,23 +1058,45 @@
       {
          conn = ds.getConnection();
          
-         //First get the min ordering
-         ps = conn.prepareStatement(selectMinOrdering);
+         ps = conn.prepareStatement(getSQLStatement("LOAD_PAGED_REFS"));
          
          ps.setLong(1, channelID);
          
+         ps.setLong(2, orderStart);
+         
+         ps.setLong(3, orderStart + number - 1);
+         
          rs = ps.executeQuery();
-                  
-         rs.next();
          
-         long minOrdering = rs.getLong(1);
+         long ord = orderStart;
          
-         if (rs.wasNull())
+         while (rs.next())
          {
-            minOrdering = 0;
+            long msgId = rs.getLong(1);     
+            int deliveryCount = rs.getInt(2);
+            int pageOrd = rs.getInt(3);
+            boolean reliable = rs.getString(4).equals("Y");
+            
+            //Sanity check
+            if (pageOrd != ord)
+            {
+               throw new IllegalStateException("Unexpected pageOrd: " + pageOrd + " expected: " + ord);
+            }
+            
+            ReferenceInfo ri = new ReferenceInfo(msgId, deliveryCount, reliable);
+            
+            refs.add(ri);
+            ord++;
          }
          
-         return minOrdering;      
+         //Sanity check
+         if (ord != orderStart + number)
+         {
+            throw new IllegalStateException("Didn't load expected number of references, loaded: " + (ord - orderStart) +
+                                            " expected: " + number);
+         }
+         
+         return refs;
       }
       catch (Exception e)
       {
@@ -1344,57 +1136,19 @@
             }
          }
          wrap.end();
-      }
-      
-   }      
-     
+      }      
+   }   
    
-   /*
-    * Load some refs from the channel.
-    * It is very difficult for the channel to maintain an absolute ordering of message references
-    * without holes, since messages can be acknowledged or cancelled in a different order to the 
-    * delivery order
-    * Consequently loading only the first x messages from the channel becomes difficult.
-    * A naive implementation might select all the refs in ordering order and only take the first x
-    * however for some databases this migh result in the entire resultset being prepared before being sent
-    * back to us.
-    * When there are many refs in the channel this could provide a performance problem.
-    * We take the following approach:
-    * We select references where ordering < min_ordering + x
-    * This might not select any references due to holes, in which case we double x and repeat until 
-    * we find refs.
-    * We store the multiplier for next time so it self adjusts
-    */      
-   public List getReferenceInfos(long channelID, long minOrdering, int number) throws Exception
-   {                          
+   public InitialLoadInfo getInitialReferenceInfos(long channelID, int fullSize) throws Exception
+   {
       if (trace)
       {
-         log.trace("loading message reference info for channel " + channelID + " for " + number + " refs");
+         log.trace("loading initial reference infos for channel " + channelID);
       }
                     
       List refs = new ArrayList();
+      List extraRefs = new ArrayList();
       
-      if (number == 0)
-      {
-         return refs;
-      }
-      
-      //Start with a reasonable multiplier
-      double multiplier = 1.15;
-      
-      Double d = (Double)channelMultipliers.get(new Long(channelID));
-      
-      if (d != null)
-      {
-         multiplier = d.doubleValue();
-      }
-           
-      final int MAX_TRIES = 20;
-      
-      final double SCALING = 2;
-            
-      double size = multiplier * number;
-      
       Connection conn = null;
       PreparedStatement ps = null;
       ResultSet rs = null;
@@ -1402,80 +1156,186 @@
       
       try
       {
+         conn = ds.getConnection();         
+         
+         //First we get the values for min() and max() page order
+         ps = conn.prepareStatement(getSQLStatement("SELECT_MIN_MAX_PAGE_ORD"));
+         
+         ps.setLong(1, channelID);
+         
+         rs = ps.executeQuery();
+                  
+         rs.next();
+         
+         long minOrdering = rs.getLong(1);
+         
+         if (rs.wasNull())
+         {
+            minOrdering = -1;
+         }
+         
+         long maxOrdering = rs.getLong(2);
+         
+         if (rs.wasNull())
+         {
+            maxOrdering = -1;
+         }
+         
+         //Must cope with the possibility that fullSize has changed for the channel since last
+         //restart
+         
          conn = ds.getConnection();
          
-         int tries = 0;
-
-         long lastOrdering = 0;
+         ps = conn.prepareStatement(getSQLStatement("LOAD_UNPAGED_REFS"));
          
-         do
-         {                 
+         ps.setLong(1, channelID);
+                 
+         rs = ps.executeQuery();
+         
+         int count = 0;
+         while (rs.next())
+         {
+            long msgId = rs.getLong(1);            
+            int deliveryCount = rs.getInt(2);
+            boolean reliable = rs.getString(3).equals("Y");
             
+            ReferenceInfo ri = new ReferenceInfo(msgId, deliveryCount, reliable);
             
-            ps = conn.prepareStatement(loadReferenceInfo);
+            if (count < fullSize)
+            {
+               refs.add(ri);
+            }
+            else
+            {
+               extraRefs.add(ri);
+            }
             
-            ps.setLong(1, channelID);
+            count++;
+         }
+                  
+         if (count != fullSize)
+         {                        
+            rs.close();
+            rs = null;
+            ps.close();
+            ps = null;            
             
-            ps.setLong(2, minOrdering);
-            
-            ps.setLong(3, minOrdering + (int)size - 1);
-            
-            rs = ps.executeQuery();
-            
-            int count = 0;
-            while (rs.next() && count < number)
+            if (count < fullSize)
             {
-               long msgId = rs.getLong(1);
-               long ordering = rs.getLong(2);
-               int deliveryCount = rs.getInt(3);
-               boolean reliable = rs.getString(4).equals("Y");
+               if (minOrdering != -1)
+               {
+                  //This means that fullSize is now greater and we have some paged refs
+                  //We need to convert some of the paged refs into non paged refs before loading               
+                  
+                  //We can do this by setting page_ord = null for the first x paged refs                  
+                  
+                  long numberPaged = 1 + maxOrdering - minOrdering;
+                  
+                  long numberToConvert = Math.min(numberPaged, fullSize - count);
+                                    
+                  ps = conn.prepareStatement(getSQLStatement("UPDATE_RELIABLE_REFS_NOT_PAGED"));
+                  
+                  ps.setLong(1, minOrdering);
+                  ps.setLong(2, minOrdering + numberToConvert - 1);
+                  ps.setLong(3, channelID);
+                  
+                  ps.executeUpdate();
+                  
+                  minOrdering += numberToConvert;      
+                  
+                  if (minOrdering == maxOrdering + 1)
+                  {
+                     minOrdering = maxOrdering = -1;
+                  }
+                  
+                  ps.close();
+                  ps = null;
+  
+                  //Need to reload
+                  
+                  ps = conn.prepareStatement(getSQLStatement("LOAD_UNPAGED_REFS"));
+                  
+                  ps.setLong(1, channelID);
+                          
+                  rs = ps.executeQuery();
+                  
+                  refs.clear();
+                  
+                  while (rs.next())
+                  {
+                     long msgId = rs.getLong(1);            
+                     int deliveryCount = rs.getInt(2);
+                     boolean reliable = rs.getString(3).equals("Y");                  
+                     ReferenceInfo ri = new ReferenceInfo(msgId, deliveryCount, reliable);
+                     refs.add(ri);                  
+                  }                                           
+               }
+               else
+               {
+                  //Not a problem nothing to do
+               }
+            }
+            else if (count > fullSize)
+            {         
+               //This means that fullSize is now smaller
+               //We need to convert some of the non paged refs into paged refs before loading
                
-               ReferenceInfo ri = new ReferenceInfo(msgId, ordering, deliveryCount, reliable);
+               int numberToConvert = count - fullSize;
                
-               refs.add(ri);        
+               //Shift any pre-existing paged refs up by this
                
-               count++;
+               ps = conn.prepareStatement(getSQLStatement("SHIFT_PAGE_ORDER"));
                
-               lastOrdering = ordering;
-            }
-
-            size *= SCALING;
-            
-            tries++;
-            
-            if (refs.size() < number)
-            {
-               //Query again
-               //We have to do the entire query each time, this is because we are at transaction
-               //isolation level READ_COMMITTED therefore we cannot guarantee repeatable reads
-               //so if a transaction is committed on the boundary of one execution and another
-               //we may get partial results
-               refs.clear();
-               if (trace)
+               ps.setLong(1, numberToConvert);
+               
+               ps.setLong(2, channelID);
+               
+               ps.executeUpdate();
+               
+               //Now we need to convert the last <numberToConvert> non paged refs to paged refs
+               ps.close();
+               ps = null;
+               
+               ps = conn.prepareStatement(getSQLStatement("UPDATE_PAGE_ORDER"));
+                                             
+               long c;
+               if (minOrdering == -1)
                {
-                  log.trace("Could not find sufficient refs in one query, trying again");
-               }              
-            }               
+                  c = 0;
+                  minOrdering = 0;
+               }
+               else
+               {
+                  c = minOrdering;
+               }
+               
+               if (maxOrdering == -1)
+               {
+                  maxOrdering = numberToConvert - 1;
+               }
+               else
+               {
+                  maxOrdering += numberToConvert;
+               }
+               
+               Iterator iter = extraRefs.iterator();
+               while (iter.hasNext())
+               {
+                  ReferenceInfo ri = (ReferenceInfo)iter.next();
+                  
+                  ps.setLong(1, c);
+                  ps.setLong(2, ri.getMessageId());
+                  ps.setLong(3, channelID);
+                  
+                  //TODO use batch updates
+                  ps.executeUpdate();
+                  
+                  c++;
+               }               
+            }
          }
-         while (refs.size() < number && tries < MAX_TRIES);
          
-         if (tries == MAX_TRIES)
-         {
-            //HIghly unlikely to happen
-            throw new IllegalStateException("Could not find sufficient references after trying " + tries + " times");
-         }          
-          
-         //We now adjust the multiplier so it 'learns' how many tries it needs which should aid performance         
-         long actSize = lastOrdering - minOrdering + 1;
-         
-         double idealMultiplier = (double)actSize / number;
-         
-         //Give 15% leeway
-         idealMultiplier *= 1.15;
-         
-         channelMultipliers.put(new Long(channelID), new Double(idealMultiplier));
-   
-         return refs;
+         return new InitialLoadInfo(minOrdering, maxOrdering, refs);
       }
       catch (Exception e)
       {
@@ -1515,10 +1375,10 @@
             }
          }
          wrap.end();
-      }
-   }
+      }      
+   }   
    
-   public void updateReferencesNotLoaded(long channelID, List references) throws Exception
+   public void updatePageOrder(long channelID, List references) throws Exception
    {
       Connection conn = null;
       PreparedStatement psUpdateReference = null;  
@@ -1526,7 +1386,7 @@
       
       if (trace)
       {
-         log.trace("Updating references to not loaded for channel:" + channelID);
+         log.trace("Updating page order for channel:" + channelID);
       }
         
       try
@@ -1537,7 +1397,7 @@
          
          if (usingBatchUpdates)
          {
-            psUpdateReference = conn.prepareStatement(updateMessageRefNotLoaded);
+            psUpdateReference = conn.prepareStatement(getSQLStatement("UPDATE_PAGE_ORDER"));
          }
          
          while (iter.hasNext())
@@ -1546,13 +1406,15 @@
                  
             if (!usingBatchUpdates)
             {
-               psUpdateReference = conn.prepareStatement(updateMessageRefNotLoaded);
+               psUpdateReference = conn.prepareStatement(getSQLStatement("UPDATE_PAGE_ORDER"));
             }
             
-            psUpdateReference.setLong(1, ref.getMessageID());
+            psUpdateReference.setLong(1, ref.getPagingOrder());
             
-            psUpdateReference.setLong(2, channelID);
+            psUpdateReference.setLong(2, ref.getMessageID());
             
+            psUpdateReference.setLong(3, channelID);
+            
             if (usingBatchUpdates)
             {
                psUpdateReference.addBatch();
@@ -1577,7 +1439,7 @@
             
             if (trace)
             {
-               logBatchUpdate(updateMessageRefNotLoaded, rowsReference, "updated");
+               logBatchUpdate(getSQLStatement("UPDATE_PAGE_ORDER"), rowsReference, "updated");
             }
                         
             psUpdateReference.close();
@@ -1615,6 +1477,9 @@
       }    
    }
    
+   // End of paging functionality
+   // ===========================
+   
    public void addReference(long channelID, MessageReference ref, Transaction tx) throws Exception
    {      
       if (tx != null)
@@ -1645,12 +1510,12 @@
             // Get lock on message
             LockMap.instance.obtainLock(m);
                                     
-            psReference = conn.prepareStatement(insertMessageRef);
+            psReference = conn.prepareStatement(getSQLStatement("INSERT_MESSAGE_REF"));
             
             // Add the reference
-            addReference(channelID, ref, psReference, true);
+            addReference(channelID, ref, psReference);
             
-            int rows = psReference.executeUpdate();
+            int rows = psReference.executeUpdate();            
             
             if (trace)
             {
@@ -1663,14 +1528,14 @@
             if (m.getPersistentChannelCount() == 1)
             {
                // First time so persist the message
-               psMessage = conn.prepareStatement(insertMessage);
+               psMessage = conn.prepareStatement(getSQLStatement("INSERT_MESSAGE"));
                
                storeMessage(m, psMessage);        
             }
             else
             {
                //Update the message's channel count
-               psMessage = conn.prepareStatement(updateMessageChannelCount);
+               psMessage = conn.prepareStatement(getSQLStatement("UPDATE_MESSAGE_CHANNELCOUNT"));
                
                updateMessageChannelCount(m, psMessage);
             }
@@ -1724,7 +1589,7 @@
             }
             finally
             {   
-               if (wrap.failed && incremented)
+               if (wrap.isFailed() && incremented)
                {
                   //reverse the inc                  
                   m.decPersistentChannelCount();                  
@@ -1767,13 +1632,18 @@
             //get lock on message
             LockMap.instance.obtainLock(m);
                               
-            psReference = conn.prepareStatement(deleteMessageRef);
+            psReference = conn.prepareStatement(getSQLStatement("DELETE_MESSAGE_REF"));
             
             //Remove the message reference
             removeReference(channelID, ref, psReference);
             
             int rows = psReference.executeUpdate();
             
+            if (rows != 1)
+            {
+               throw new IllegalStateException("Failed to remove row for: " + ref);
+            }
+            
             if (trace)
             {
                log.trace("Deleted " + rows + " rows");
@@ -1785,20 +1655,25 @@
             if (m.getPersistentChannelCount() == 0)
             {
                //No other channels have a reference so we can delete the message
-               psMessage = conn.prepareStatement(deleteMessage);
+               psMessage = conn.prepareStatement(getSQLStatement("DELETE_MESSAGE"));
                                  
                removeMessage(m, psMessage);
             }
             else
             {
                //Other channel(s) still have hold references so update the channel count
-               psMessage = conn.prepareStatement(updateMessageChannelCount);
+               psMessage = conn.prepareStatement(getSQLStatement("UPDATE_MESSAGE_CHANNELCOUNT"));
                
                updateMessageChannelCount(m, psMessage);
             }
                               
             rows = psMessage.executeUpdate();
             
+            if (rows != 1)
+            {
+               throw new IllegalStateException("Failed to update/delete message row for ref " + ref);
+            }
+            
             if (trace)
             {
                log.trace("Delete/updated " + rows + " rows");
@@ -1847,7 +1722,7 @@
             }
             finally
             {      
-               if (wrap.failed && decremented)
+               if (wrap.isFailed() && decremented)
                {
                   //Reverse decrement
                   m.incPersistentChannelCount();
@@ -1859,93 +1734,36 @@
       }
    }
    
-   public void resetLoadedStatus(long channelID) throws Exception
-   {
-      if (trace)
-      {
-         log.trace("resetting all channel data for channel " + channelID);
-      }
-      
-      Connection conn = null;
-      PreparedStatement ps = null;
-      TransactionWrapper wrap = new TransactionWrapper();
-      
-      log.trace("Resetting message data. This may take several minutes for large queues/subscriptions...");
-      
-      try
-      {
-         conn = ds.getConnection();
-         
-         log.debug("Updating all reliable references to not loaded");
-                  
-         ps = conn.prepareStatement(updateReliableRefsNotLoaded);
-         
-         ps.setLong(1, channelID);
-         
-         int rows = ps.executeUpdate();
-         
-         if (trace)
-         {
-            log.trace(JDBCUtil.statementToString(updateReliableRefsNotLoaded)
-                  + " updated " + rows + " rows");
-         }
-               
-         ps.close();
-         
-      }
-      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();
-      }
-   }
-     
-//   public void removeAllChannelData(long channelID) throws Exception
+//   public void resetPagedStatus(long channelID) throws Exception
 //   {
-//      if (trace)
-//      {
-//         log.trace("removing all references for channel " + channelID);
-//      }
+//      if (trace) { log.trace("resetting paged status for channel " + channelID); }
 //      
 //      Connection conn = null;
 //      PreparedStatement ps = null;
 //      TransactionWrapper wrap = new TransactionWrapper();
-//      boolean success = false;
 //      
+//      log.trace("Resetting paged status. This may take several minutes for large queues/subscriptions...");
+//      
 //      try
 //      {
 //         conn = ds.getConnection();
 //         
-//         ps = conn.prepareStatement(deleteChannelMessageRefs);
+//         log.debug("Updating all page ordering to null");
+//                  
+//         ps = conn.prepareStatement(getSQLStatement("RESET_PAGED_STATUS"));
 //         
 //         ps.setLong(1, channelID);
 //         
-//         ps.executeUpdate();
-//         success = true;
+//         int rows = ps.executeUpdate();
+//         
+//         if (trace)
+//         {
+//            log.trace(JDBCUtil.statementToString(getSQLStatement("RESET_PAGED_STATUS"))
+//                  + " updated " + rows + " rows");
+//         }
+//               
+//         ps.close();
+//         
 //      }
 //      catch (Exception e)
 //      {
@@ -1954,11 +1772,6 @@
 //      }
 //      finally
 //      {
-//         if (trace)
-//         {
-//            String s = JDBCUtil.statementToString(deleteChannelMessageRefs, new Long(channelID));
-//            log.trace(s + (success ? " successful" : "failed"));
-//         }
 //         if (ps != null)
 //         {
 //            try
@@ -1982,9 +1795,7 @@
 //         wrap.end();
 //      }
 //   }
-   
-   
-   
+     
    public List retrievePreparedTransactions() throws Exception
    {
       Connection conn = null;
@@ -1999,7 +1810,7 @@
          conn = ds.getConnection();
          
          st = conn.createStatement();
-         rs = st.executeQuery(selectPreparedTransactions);
+         rs = st.executeQuery(getSQLStatement("SELECT_PREPARED_TRANSACTIONS"));
          
          while (rs.next())
          {
@@ -2054,180 +1865,12 @@
          wrap.end();
       }
    }
-   
-   /*
-    
-    Reference counting code commented out until 1.2
-    
-    public int getMessageReferenceCount(Serializable messageID) throws Exception
-    {
-    Connection conn = null;
-    PreparedStatement ps = null;
-    ResultSet rs = null;
-    TransactionWrapper wrap = new TransactionWrapper();
-    
-    try
-    {
-    conn = ds.getConnection();
-    
-    ps = conn.prepareStatement(selectReferenceCount);
-    ps.setString(1, (String)messageID);
-    
-    rs = ps.executeQuery();
-    
-    int count = 0;
-    if (rs.next())
-    {
-    count = rs.getInt(1);
-    }
-    
-    if (trace) { log.trace(JDBCUtil.statementToString(selectReferenceCount, messageID) + " returned " + (count == 0 ? "no rows" : Integer.toString(count))); }
-    
-    return count;
-    }
-    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();
-    }
-    }
-    
-    */
-   
+  
    // Public --------------------------------------------------------
    
    /**
     * Managed attribute.
     */
-   public void setDataSource(String dataSourceJNDIName) throws Exception
-   {
-      this.dataSourceJNDIName = dataSourceJNDIName;
-   }
-   
-   /**
-    * Managed attribute.
-    */
-   public String getDataSource()
-   {
-      return dataSourceJNDIName;
-   }
-   
-   /**
-    * Managed attribute.
-    */
-   public void setTransactionManager(ObjectName tmObjectName) throws Exception
-   {
-      this.tmObjectName = tmObjectName;
-   }
-   
-   /**
-    * Managed attribute.
-    */
-   public ObjectName getTransactionManager()
-   {
-      return tmObjectName;
-   }
-   
-   /**
-    * Managed attribute.
-    */
-   public void setChannelMapper(ObjectName cmObjectName) throws Exception
-   {
-      this.cmObjectName = cmObjectName;
-   }
-   
-   /**
-    * Managed attribute.
-    */
-   public ObjectName getChannelMapper()
-   {
-      return cmObjectName;
-   }
-      
-   public String getSqlProperties()
-   {
-      try
-      {
-         ByteArrayOutputStream boa = new ByteArrayOutputStream();
-         sqlProperties.store(boa, "");
-         return new String(boa.toByteArray());
-      }
-      catch (IOException shouldnothappen)
-      {
-         log.error("Failed to get sql properties", shouldnothappen);
-         return null;
-      }
-   }
-   
-   public void setSqlProperties(String value)
-   {
-      try
-      {
-         ByteArrayInputStream is = new ByteArrayInputStream(value.getBytes());
-         sqlProperties = new Properties();
-         sqlProperties.load(is);
-      }
-      catch (IOException shouldnothappen)
-      {
-         log.error("Failed to set sql properties", shouldnothappen);
-      }
-   }
-   
-   public void setSqlProperties(Properties props)
-   {
-      sqlProperties = new Properties(props);
-   }
-   
-   /**
-    * Managed attribute.
-    */
-   public boolean isCreateTablesOnStartup() throws Exception
-   {
-      return createTablesOnStartup;
-   }
-   
-   /**
-    * Managed attribute.
-    */
-   public void setCreateTablesOnStartup(boolean b) throws Exception
-   {
-      createTablesOnStartup = b;
-   }
-   
-   /**
-    * Managed attribute.
-    */
    public boolean isUsingBatchUpdates() throws Exception
    {
       return usingBatchUpdates;
@@ -2256,202 +1899,12 @@
       return "JDBCPersistenceManager[" + Integer.toHexString(hashCode()) + "]";
    }
    
+   // Public --------------------------------------------------------
+   
    // Package protected ---------------------------------------------
    
    // Protected -----------------------------------------------------
-   
-   protected void createSchema() throws Exception
-   {
-      Connection conn = null;
-      TransactionWrapper tx = new TransactionWrapper();
       
-      try
-      {
-         conn = ds.getConnection();
-         
-         try
-         {
-            conn.createStatement().executeUpdate(createTransaction);
-            if (trace)
-            {
-               log.trace(createTransaction + " succeeded");
-            }
-         }
-         catch (SQLException e)
-         {
-            log.debug(createTransaction + " failed!", e);
-         }
-         
-         try
-         {
-            conn.createStatement().executeUpdate(createMessageReference);
-            if (trace)
-            {
-               log.trace(createMessageReference + " succeeded");
-            }
-         }
-         catch (SQLException e)
-         {
-            log.debug(createMessageReference + " failed!", e);
-         }
-         
-         try
-         {
-            conn.createStatement().executeUpdate(createIdxMessageRefTx);
-            if (trace)
-            {
-               log.trace(createIdxMessageRefTx + " succeeded");
-            }
-         }
-         catch (SQLException e)
-         {
-            log.debug(createIdxMessageRefTx + " failed!", e);
-         }
-         
-         try
-         {
-            conn.createStatement().executeUpdate(createIdxMessageRefOrd);
-            if (trace)
-            {
-               log.trace(createIdxMessageRefOrd + " succeeded");
-            }
-         }
-         catch (SQLException e)
-         {
-            log.debug(createIdxMessageRefOrd + " failed!", e);
-         }
-         
-         try
-         {
-            conn.createStatement().executeUpdate(createIdxMessageRefMessageId);
-            if (trace)
-            {
-               log.trace(createIdxMessageRefMessageId + " succeeded");
-            }
-         }
-         catch (SQLException e)
-         {
-            log.debug(createIdxMessageRefOrd + " failed!", e);
-         }
-         
-         try
-         {
-            conn.createStatement().executeUpdate(createIdxMessageRefLoaded);
-            if (trace)
-            {
-               log.trace(createIdxMessageRefLoaded + " succeeded");
-            }
-         }
-         catch (SQLException e)
-         {
-            log.debug(createIdxMessageRefLoaded + " failed!", e);
-         }
-         
-         try
-         {
-            conn.createStatement().executeUpdate(createIdxMessageRefReliable);
-            if (trace)
-            {
-               log.trace(createIdxMessageRefReliable + " succeeded");
-            }
-         }
-         catch (SQLException e)
-         {
-            log.debug(createIdxMessageRefReliable + " failed!", e);
-         }
-         
-         try
-         {
-            conn.createStatement().executeUpdate(createMessage);
-            if (trace)
-            {
-               log.trace(createMessage + " succeeded");
-            }
-         }
-         catch (SQLException e)
-         {
-            log.debug(createMessage + " failed!", e);
-         }                  
-         
-         try
-         {
-            conn.createStatement().executeUpdate(createCounter);
-            if (trace)
-            {
-               log.trace(createCounter + " succeeded");
-            }
-         }
-         catch (SQLException e)
-         {
-            log.debug(createCounter + " failed!", e);
-         }
-      }
-      finally
-      {
-         if (conn != null)
-         {
-            try
-            {
-               conn.close();
-            }
-            catch (Throwable t)
-            {
-            }
-         }
-         tx.end();
-      }
-   }
-   
-   protected void initSqlProperties()
-   { 
-      //Message Reference
-      createMessageReference = sqlProperties.getProperty("CREATE_MESSAGE_REF", createMessageReference);
-      createIdxMessageRefTx = sqlProperties.getProperty("CREATE_IDX_MESSAGE_REF_TX", createIdxMessageRefTx);
-      createIdxMessageRefOrd = sqlProperties.getProperty("CREATE_IDX_MESSAGE_REF_ORD", createIdxMessageRefOrd);
-      createIdxMessageRefMessageId = sqlProperties.getProperty("CREATE_IDX_MESSAGE_REF_MESSAGEID", createIdxMessageRefMessageId);
-      createIdxMessageRefLoaded = sqlProperties.getProperty("CREATE_IDX_MESSAGE_REF_LOADED", createIdxMessageRefLoaded); 
-      createIdxMessageRefReliable = sqlProperties.getProperty("CREATE_IDX_MESSAGE_REF_RELIABLE", createIdxMessageRefReliable);       
-      insertMessageRef = sqlProperties.getProperty("INSERT_MESSAGE_REF", insertMessageRef);
-      deleteMessageRef = sqlProperties.getProperty("DELETE_MESSAGE_REF", deleteMessageRef);      
-      updateMessageRef = sqlProperties.getProperty("UPDATE_MESSAGE_REF", updateMessageRef);
-      updateMessageRefNotLoaded = sqlProperties.getProperty("UPDATE_MESSAGE_REF_NOT_LOADED", updateMessageRefNotLoaded);  
-      commitMessageRef1 = sqlProperties.getProperty("COMMIT_MESSAGE_REF1", commitMessageRef1);
-      commitMessageRef2 = sqlProperties.getProperty("COMMIT_MESSAGE_REF2", commitMessageRef2);
-      rollbackMessageRef1 = sqlProperties.getProperty("ROLLBACK_MESSAGE_REF1", rollbackMessageRef1);
-      rollbackMessageRef2 = sqlProperties.getProperty("ROLLBACK_MESSAGE_REF2", rollbackMessageRef2);
-      loadReferenceInfo = sqlProperties.getProperty("LOAD_REF_INFO", loadReferenceInfo);
-      selectCountReferences = sqlProperties.getProperty("SELECT_COUNT_REFS", selectCountReferences);
-      updateReliableRefs = sqlProperties.getProperty("UPDATE_RELIABLE_REFS", updateReliableRefs);
-      updateReliableRefsNotLoaded = sqlProperties.getProperty("UPDATE_RELIABLE_REFS_NOT_LOADED", updateReliableRefsNotLoaded);
-      selectMinOrdering = sqlProperties.getProperty("SELECT_MIN_ORDERING", selectMinOrdering);
-      deleteUnreliableRefs = sqlProperties.getProperty("DELETE_UNRELIABLE_REFS", deleteUnreliableRefs);
-        
-      //Message
-      createMessage = sqlProperties.getProperty("CREATE_MESSAGE", createMessage);
-      loadMessages = sqlProperties.getProperty("LOAD_MESSAGES", loadMessages);
-      insertMessage = sqlProperties.getProperty("INSERT_MESSAGE", insertMessage);
-      updateMessageChannelCount = sqlProperties.getProperty("UPDATE_MESSAGE_CHANNELCOUNT", updateMessageChannelCount);
-      deleteMessage = sqlProperties.getProperty("DELETE_MESSAGE", deleteMessage);
-      messageIdColumn = sqlProperties.getProperty("MESSAGEID_COLUMN", messageIdColumn);
-      updateUnreliableChannelCount = sqlProperties.getProperty("UPDATE_UNRELIABLE_CHANNELCOUNT", updateUnreliableChannelCount);
-      deleteUnreffedMessages = sqlProperties.getProperty("DELETE_UNREFFED_MESSAGES", deleteUnreffedMessages);
-
-      //Transaction
-      createTransaction = sqlProperties.getProperty("CREATE_TRANSACTION", createTransaction);      
-      insertTransaction = sqlProperties.getProperty("INSERT_TRANSACTION", insertTransaction);
-      deleteTransaction = sqlProperties.getProperty("DELETE_TRANSACTION", deleteTransaction);
-      selectPreparedTransactions = sqlProperties.getProperty("SELECT_PREPARED_TRANSACTIONS", selectPreparedTransactions);
-
-      //Counter
-      createCounter = sqlProperties.getProperty("CREATE_COUNTER", createCounter);
-      updateCounter = sqlProperties.getProperty("UPDATE_COUNTER", updateCounter);
-      selectCounter = sqlProperties.getProperty("SELECT_COUNTER", selectCounter);
-      insertCounter = sqlProperties.getProperty("INSERT_COUNTER", insertCounter);      
-      
-      //Other
-      selectAllChannels = sqlProperties.getProperty("SELECT_ALL_CHANNELS", selectAllChannels);
-   }
-   
    protected TransactionCallback getCallback(Transaction tx)
    {
       TransactionCallback callback = (TransactionCallback) tx.getKeyedCallback(this);
@@ -2503,9 +1956,9 @@
       {
          conn = ds.getConnection();
          
-         psRes = conn.prepareStatement(selectAllChannels);
+         psRes = conn.prepareStatement(getSQLStatement("SELECT_ALL_CHANNELS"));
          
-         psUpdate = conn.prepareStatement(updateUnreliableChannelCount);
+         psUpdate = conn.prepareStatement(getSQLStatement("UPDATE_UNRELIABLE_CHANNELCOUNT"));
                           
          rs = psRes.executeQuery();
          
@@ -2519,31 +1972,30 @@
             
             if (trace)
             {
-               log.trace(JDBCUtil.statementToString(updateUnreliableChannelCount)
+               log.trace(JDBCUtil.statementToString(getSQLStatement("UPDATE_UNRELIABLE_CHANNELCOUNT"))
                      + " updated " + rows + " rows");
             }            
          }
          
-         psDeleteRefs = conn.prepareStatement(deleteUnreliableRefs);
+         psDeleteRefs = conn.prepareStatement(getSQLStatement("DELETE_UNRELIABLE_REFS"));
          
          int rows = psDeleteRefs.executeUpdate();
          
          if (trace)
          {
-            log.trace(JDBCUtil.statementToString(deleteUnreliableRefs)
+            log.trace(JDBCUtil.statementToString(getSQLStatement("DELETE_UNRELIABLE_REFS"))
                   + " deleted " + rows + " rows");
          }
                   
-         psDeleteMsgs = conn.prepareStatement(deleteUnreffedMessages);
+         psDeleteMsgs = conn.prepareStatement(getSQLStatement("DELETE_UNREFFED_MESSAGES"));
          
          rows = psDeleteMsgs.executeUpdate();
          
          if (trace)
          {
-            log.trace(JDBCUtil.statementToString(deleteUnreffedMessages)
+            log.trace(JDBCUtil.statementToString(getSQLStatement("DELETE_UNREFFED_MESSAGES"))
                   + " deleted " + rows + " rows");
-         }
-                   
+         }                   
       }
       catch (Exception e)
       {
@@ -2673,9 +2125,9 @@
          
          if (batch)
          {
-            psReference = conn.prepareStatement(insertMessageRef);
-            psInsertMessage = conn.prepareStatement(insertMessage);
-            psUpdateMessage = conn.prepareStatement(updateMessageChannelCount);
+            psReference = conn.prepareStatement(getSQLStatement("INSERT_MESSAGE_REF"));
+            psInsertMessage = conn.prepareStatement(getSQLStatement("INSERT_MESSAGE"));
+            psUpdateMessage = conn.prepareStatement(getSQLStatement("UPDATE_MESSAGE_CHANNELCOUNT"));
          }
          
          while (iter.hasNext())
@@ -2686,11 +2138,11 @@
                                                 
             if (!batch)
             {
-               psReference = conn.prepareStatement(insertMessageRef);
+               psReference = conn.prepareStatement(getSQLStatement("INSERT_MESSAGE_REF"));
             }
             
             //Now store the reference
-            addReference(pair.channelId, ref, psReference, true);
+            addReference(pair.channelId, ref, psReference);
               
             if (batch)
             {
@@ -2713,8 +2165,8 @@
             
             if (!batch)
             {
-               psInsertMessage = conn.prepareStatement(insertMessage);
-               psUpdateMessage = conn.prepareStatement(updateMessageChannelCount);
+               psInsertMessage = conn.prepareStatement(getSQLStatement("INSERT_MESSAGE"));
+               psUpdateMessage = conn.prepareStatement(getSQLStatement("UPDATE_MESSAGE_CHANNELCOUNT"));
             }
                          
             m.incPersistentChannelCount();
@@ -2782,7 +2234,7 @@
             
             if (trace)
             {
-               logBatchUpdate(insertMessageRef, rowsReference, "inserted");
+               logBatchUpdate(getSQLStatement("INSERT_MESSAGE_REF"), rowsReference, "inserted");
             }
             
             if (messageInsertsInBatch)
@@ -2791,7 +2243,7 @@
                
                if (trace)
                {
-                  logBatchUpdate(insertMessage, rowsMessage, "inserted");
+                  logBatchUpdate(getSQLStatement("INSERT_MESSAGE"), rowsMessage, "inserted");
                }
             }
             if (messageUpdatesInBatch)
@@ -2800,7 +2252,7 @@
                
                if (trace)
                {
-                  logBatchUpdate(updateMessageChannelCount, rowsMessage, "updated");
+                  logBatchUpdate(getSQLStatement("UPDATE_MESSAGE_CHANNELCOUNT"), rowsMessage, "updated");
                }
             }
             
@@ -2825,9 +2277,9 @@
          
          if (batch)
          {
-            psReference = conn.prepareStatement(deleteMessageRef);
-            psDeleteMessage = conn.prepareStatement(deleteMessage);
-            psUpdateMessage = conn.prepareStatement(updateMessageChannelCount);
+            psReference = conn.prepareStatement(getSQLStatement("DELETE_MESSAGE_REF"));
+            psDeleteMessage = conn.prepareStatement(getSQLStatement("DELETE_MESSAGE"));
+            psUpdateMessage = conn.prepareStatement(getSQLStatement("UPDATE_MESSAGE_CHANNELCOUNT"));
          }
          
          while (iter.hasNext())
@@ -2836,7 +2288,7 @@
             
             if (!batch)
             {
-               psReference = conn.prepareStatement(deleteMessageRef);
+               psReference = conn.prepareStatement(getSQLStatement("DELETE_MESSAGE_REF"));
             }
             
             removeReference(pair.channelId, pair.ref, psReference);
@@ -2860,8 +2312,8 @@
             
             if (!batch)
             {
-               psDeleteMessage = conn.prepareStatement(deleteMessage);
-               psUpdateMessage = conn.prepareStatement(updateMessageChannelCount);
+               psDeleteMessage = conn.prepareStatement(getSQLStatement("DELETE_MESSAGE"));
+               psUpdateMessage = conn.prepareStatement(getSQLStatement("UPDATE_MESSAGE_CHANNELCOUNT"));
             }
             
             Message m = pair.ref.getMessage();
@@ -2933,7 +2385,7 @@
             
             if (trace)
             {
-               logBatchUpdate(deleteMessageRef, rowsReference, "deleted");
+               logBatchUpdate(getSQLStatement("DELETE_MESSAGE_REF"), rowsReference, "deleted");
             }
             
             if (messageDeletionsInBatch)
@@ -2942,7 +2394,7 @@
                
                if (trace)
                {
-                  logBatchUpdate(deleteMessage, rowsMessage, "deleted");
+                  logBatchUpdate(getSQLStatement("DELETE_MESSAGE"), rowsMessage, "deleted");
                }
             }
             if (messageUpdatesInBatch)
@@ -2951,7 +2403,7 @@
                
                if (trace)
                {
-                  logBatchUpdate(updateMessageChannelCount, rowsMessage, "updated");
+                  logBatchUpdate(getSQLStatement("UPDATE_MESSAGE_CHANNELCOUNT"), rowsMessage, "updated");
                }
             }
             
@@ -3027,7 +2479,7 @@
          }
          finally
          {
-            if (wrap.failed)
+            if (wrap.isFailed())
             {
                //Reverse any incs and decs we made
                this.decPersistentCounts(addsToReverse);
@@ -3082,8 +2534,8 @@
       
          if (batch)
          {
-            psDeleteMessage = conn.prepareStatement(deleteMessage);
-            psUpdateMessage = conn.prepareStatement(updateMessageChannelCount);
+            psDeleteMessage = conn.prepareStatement(getSQLStatement("DELETE_MESSAGE"));
+            psUpdateMessage = conn.prepareStatement(getSQLStatement("UPDATE_MESSAGE_CHANNELCOUNT"));
          }
                   
          iter = refsToRemove.iterator();
@@ -3095,8 +2547,8 @@
             
             if (!batch)
             {
-               psDeleteMessage = conn.prepareStatement(deleteMessage);
-               psUpdateMessage = conn.prepareStatement(updateMessageChannelCount);
+               psDeleteMessage = conn.prepareStatement(getSQLStatement("DELETE_MESSAGE"));
+               psUpdateMessage = conn.prepareStatement(getSQLStatement("UPDATE_MESSAGE_CHANNELCOUNT"));
             }
             
             Message m = ref.getMessage();
@@ -3172,7 +2624,7 @@
                
                if (trace)
                {
-                  logBatchUpdate(deleteMessage, rows, "deleted");
+                  logBatchUpdate(getSQLStatement("DELETE_MESSAGE"), rows, "deleted");
                }
                
                psDeleteMessage.close();
@@ -3184,7 +2636,7 @@
                
                if (trace)
                {
-                  logBatchUpdate(updateMessageChannelCount, rows, "updated");
+                  logBatchUpdate(getSQLStatement("UPDATE_MESSAGE_CHANNELCOUNT"), rows, "updated");
                }
                
                psUpdateMessage.close();
@@ -3235,7 +2687,7 @@
          }
          finally
          {
-            if (wrap.failed)
+            if (wrap.isFailed())
             {
                //reverse any decs
                this.incPersistentCounts(removesToReverse);
@@ -3293,9 +2745,9 @@
          boolean messageUpdatesInBatch = false;
          if (batch)
          {
-            psReference = conn.prepareStatement(insertMessageRef);
-            psInsertMessage = conn.prepareStatement(insertMessage);
-            psUpdateMessage = conn.prepareStatement(updateMessageChannelCount);
+            psReference = conn.prepareStatement(getSQLStatement("INSERT_MESSAGE_REF"));
+            psInsertMessage = conn.prepareStatement(getSQLStatement("INSERT_MESSAGE"));
+            psUpdateMessage = conn.prepareStatement(getSQLStatement("UPDATE_MESSAGE_CHANNELCOUNT"));
          }
          
          while (iter.hasNext())
@@ -3304,7 +2756,7 @@
             
             if (!batch)
             {
-               psReference = conn.prepareStatement(insertMessageRef);
+               psReference = conn.prepareStatement(getSQLStatement("INSERT_MESSAGE_REF"));
             }
             
             prepareToAddReference(pair.channelId, pair.ref, tx, psReference);
@@ -3328,8 +2780,8 @@
             
             if (!batch)
             {
-               psInsertMessage = conn.prepareStatement(insertMessage);
-               psUpdateMessage = conn.prepareStatement(updateMessageChannelCount);
+               psInsertMessage = conn.prepareStatement(getSQLStatement("INSERT_MESSAGE"));
+               psUpdateMessage = conn.prepareStatement(getSQLStatement("UPDATE_MESSAGE_CHANNELCOUNT"));
             }
             
             Message m = pair.ref.getMessage();
@@ -3399,7 +2851,7 @@
             
             if (trace)
             {
-               logBatchUpdate(insertMessageRef, rowsReference, "inserted");
+               logBatchUpdate(getSQLStatement("INSERT_MESSAGE_REF"), rowsReference, "inserted");
             }
             
             if (messageInsertsInBatch)
@@ -3408,7 +2860,7 @@
                
                if (trace)
                {
-                  logBatchUpdate(insertMessage, rowsMessage, "inserted");
+                  logBatchUpdate(getSQLStatement("INSERT_MESSAGE"), rowsMessage, "inserted");
                }
             }
             if (messageUpdatesInBatch)
@@ -3417,7 +2869,7 @@
                
                if (trace)
                {
-                  logBatchUpdate(updateMessageChannelCount, rowsMessage, "updated");
+                  logBatchUpdate(getSQLStatement("UPDATE_MESSAGE_CHANNELCOUNT"), rowsMessage, "updated");
                }
             }
             
@@ -3436,7 +2888,7 @@
          batch = usingBatchUpdates && refsToRemove.size() > 1;
          if (batch)
          {
-            psReference = conn.prepareStatement(updateMessageRef);
+            psReference = conn.prepareStatement(getSQLStatement("UPDATE_MESSAGE_REF"));
          }
          
          while (iter.hasNext())
@@ -3445,7 +2897,7 @@
             
             if (!batch)
             {
-               psReference = conn.prepareStatement(updateMessageRef);
+               psReference = conn.prepareStatement(getSQLStatement("UPDATE_MESSAGE_REF"));
             }
             
             prepareToRemoveReference(pair.channelId, pair.ref, tx, psReference);
@@ -3474,7 +2926,7 @@
             
             if (trace)
             {
-               logBatchUpdate(updateMessageRef, rows, "updated");
+               logBatchUpdate(getSQLStatement("UPDATE_MESSAGE_REF"), rows, "updated");
             }
             
             psReference.close();
@@ -3534,7 +2986,7 @@
          }
          finally
          {
-            if (wrap.failed)
+            if (wrap.isFailed())
             {
                //reverse any incs
                this.decPersistentCounts(addsToReverse);
@@ -3586,8 +3038,8 @@
          boolean messageUpdatesInBatch = false;
          if (batch)
          {
-            psDeleteMessage = conn.prepareStatement(deleteMessage);
-            psUpdateMessage = conn.prepareStatement(updateMessageChannelCount);
+            psDeleteMessage = conn.prepareStatement(getSQLStatement("DELETE_MESSAGE"));
+            psUpdateMessage = conn.prepareStatement(getSQLStatement("UPDATE_MESSAGE_CHANNELCOUNT"));
          }
                                  
          while (iter.hasNext())
@@ -3596,8 +3048,8 @@
             
             if (!batch)
             {
-               psDeleteMessage = conn.prepareStatement(deleteMessage);
-               psUpdateMessage = conn.prepareStatement(updateMessageChannelCount);
+               psDeleteMessage = conn.prepareStatement(getSQLStatement("DELETE_MESSAGE"));
+               psUpdateMessage = conn.prepareStatement(getSQLStatement("UPDATE_MESSAGE_CHANNELCOUNT"));
             }
             
             Message m = pair.ref.getMessage();
@@ -3671,7 +3123,7 @@
                
                if (trace)
                {
-                  logBatchUpdate(deleteMessage, rows, "deleted");
+                  logBatchUpdate(getSQLStatement("DELETE_MESSAGE"), rows, "deleted");
                }
                
                psDeleteMessage.close();
@@ -3683,7 +3135,7 @@
                
                if (trace)
                {
-                  logBatchUpdate(updateMessageChannelCount, rows, "updated");
+                  logBatchUpdate(getSQLStatement("UPDATE_MESSAGE_CHANNELCOUNT"), rows, "updated");
                }
                
                psUpdateMessage.close();
@@ -3734,7 +3186,7 @@
          }
          finally
          {
-            if (wrap.failed)
+            if (wrap.isFailed())
             {
                //reverse any removes
                this.incPersistentCounts(removesToReverse);
@@ -3759,7 +3211,7 @@
       int formatID = -1;
       try
       {
-         statement = insertTransaction;
+         statement = getSQLStatement("INSERT_TRANSACTION");
          
          ps = conn.prepareStatement(statement);
          
@@ -3778,7 +3230,7 @@
       {
          if (trace)
          {
-            String s = JDBCUtil.statementToString(insertTransaction, new Long(tx.getId()), "<byte-array>",
+            String s = JDBCUtil.statementToString(statement, new Long(tx.getId()), "<byte-array>",
                   new Integer(formatID), "<byte-array>");
             log.trace(s + (rows == -1 ? " failed!" : " inserted " + rows + " row(s)"));
          }
@@ -3801,7 +3253,7 @@
       PreparedStatement ps = null;
       try
       {
-         ps = conn.prepareStatement(deleteTransaction);
+         ps = conn.prepareStatement(getSQLStatement("DELETE_TRANSACTION"));
          
          ps.setLong(1, tx.getId());
          
@@ -3809,7 +3261,7 @@
          
          if (trace)
          {
-            log.trace(JDBCUtil.statementToString(deleteTransaction, new Long(tx.getId())) + " removed " + rows + " row(s)");
+            log.trace(JDBCUtil.statementToString(getSQLStatement("DELETE_TRANSACTION"), new Long(tx.getId())) + " removed " + rows + " row(s)");
          }
       }
       finally
@@ -3828,21 +3280,27 @@
       }
    }  
    
-   protected void addReference(long channelID, MessageReference ref, PreparedStatement ps, boolean loaded) throws Exception
+   protected void addReference(long channelID, MessageReference ref, PreparedStatement ps) throws Exception
    {
       if (trace)
       {
          log.trace("adding " + ref + " to channel " + channelID);
       }
-
+      
       ps.setLong(1, channelID);
       ps.setLong(2, ref.getMessageID());
-      ps.setNull(3, java.sql.Types.BIGINT);
+      ps.setNull(3, Types.BIGINT);
       ps.setString(4, "C");
-      ps.setLong(5, ref.getOrdering());
+      if (ref.getPagingOrder() == -1)
+      {
+         ps.setNull(5, Types.BIGINT);
+      }
+      else
+      {
+         ps.setLong(5, ref.getPagingOrder());
+      }
       ps.setInt(6, ref.getDeliveryCount());
       ps.setString(7, ref.isReliable() ? "Y" : "N");
-      ps.setString(8, loaded ? "Y" : "N");
    }
    
    protected void removeReference(long channelID, MessageReference ref, PreparedStatement ps) throws Exception
@@ -3857,7 +3315,7 @@
    }
    
    protected void prepareToAddReference(long channelID, MessageReference ref, Transaction tx, PreparedStatement ps)
-   throws Exception
+     throws Exception
    {
       if (trace)
       {
@@ -3869,14 +3327,13 @@
       ps.setLong(2, ref.getMessageID());
       ps.setLong(3, tx.getId());
       ps.setString(4, "+");
-      ps.setLong(5, ref.getOrdering());
+      ps.setNull(5, Types.BIGINT);      
       ps.setInt(6, ref.getDeliveryCount());
       ps.setString(7, ref.isReliable() ? "Y" : "N");
-      ps.setString(8, "Y");
    }
    
    protected void prepareToRemoveReference(long channelID, MessageReference ref, Transaction tx, PreparedStatement ps)
-   throws Exception
+      throws Exception
    {
       if (trace)
       {
@@ -3895,7 +3352,7 @@
         
       try
       {
-         ps = conn.prepareStatement(commitMessageRef1);
+         ps = conn.prepareStatement(getSQLStatement("COMMIT_MESSAGE_REF1"));
          
          ps.setLong(1, tx.getId());        
          
@@ -3903,18 +3360,18 @@
          
          if (trace)
          {
-            log.trace(JDBCUtil.statementToString(commitMessageRef1, new Long(tx.getId())) + " removed " + rows + " row(s)");
+            log.trace(JDBCUtil.statementToString(getSQLStatement("COMMIT_MESSAGE_REF1"), new Long(tx.getId())) + " removed " + rows + " row(s)");
          }
          
          ps.close();
-         ps = conn.prepareStatement(commitMessageRef2);
+         ps = conn.prepareStatement(getSQLStatement("COMMIT_MESSAGE_REF2"));
          ps.setLong(1, tx.getId());         
          
          rows = ps.executeUpdate();
          
          if (trace)
          {
-            log.trace(JDBCUtil.statementToString(commitMessageRef2, null, new Long(tx.getId())) + " updated " + rows
+            log.trace(JDBCUtil.statementToString(getSQLStatement("COMMIT_MESSAGE_REF2"), null, new Long(tx.getId())) + " updated " + rows
                   + " row(s)");
          }
          
@@ -3941,7 +3398,7 @@
       
       try
       {
-         ps = conn.prepareStatement(rollbackMessageRef1);
+         ps = conn.prepareStatement(getSQLStatement("ROLLBACK_MESSAGE_REF1"));
          
          ps.setLong(1, tx.getId());         
          
@@ -3949,19 +3406,19 @@
          
          if (trace)
          {
-            log.trace(JDBCUtil.statementToString(rollbackMessageRef1, new Long(tx.getId())) + " removed " + rows + " row(s)");
+            log.trace(JDBCUtil.statementToString(getSQLStatement("ROLLBACK_MESSAGE_REF1"), new Long(tx.getId())) + " removed " + rows + " row(s)");
          }
          
          ps.close();
          
-         ps = conn.prepareStatement(rollbackMessageRef2);
+         ps = conn.prepareStatement(getSQLStatement("ROLLBACK_MESSAGE_REF2"));
          ps.setLong(1, tx.getId());
          
          rows = ps.executeUpdate();
          
          if (trace)
          {
-            log.trace(JDBCUtil.statementToString(rollbackMessageRef2, null, new Long(tx.getId())) + " updated " + rows
+            log.trace(JDBCUtil.statementToString(getSQLStatement("ROLLBACK_MESSAGE_REF2"), null, new Long(tx.getId())) + " updated " + rows
                   + " row(s)");
          }
          
@@ -4130,21 +3587,17 @@
          }
          
          JBossDestination jbd = (JBossDestination) jbm.getJMSDestination();
+        
+         ps.setString(13, (jbd.isQueue() ? "Q" : "T") + jbd);
          
-         CoreDestination dest = cm.getCoreDestination(jbd);
-         
-         long destId = dest.getId();
-         ps.setLong(13, destId);
-         
          JBossDestination replyTo = (JBossDestination) jbm.getJMSReplyTo();
          if (replyTo == null)
          {
             ps.setNull(14, Types.BIGINT);
          }
          else
-         {
-            long replyToId = cm.getCoreDestination(replyTo).getId();
-            ps.setLong(14, replyToId);
+         {            
+            ps.setString(14, (replyTo.isQueue() ? "Q" : "T") + replyTo);
          }
          
          bytes = mapToBytes(jbm.getJMSProperties());
@@ -4331,74 +3784,105 @@
       log.trace("Batch update " + name + ", " + action + " total of " + count + " rows");
    }
    
-   // Private -------------------------------------------------------
-
-   // never access directly
-   private TransactionManager tm;
-
-   private TransactionManager getTransactionManagerReference()
-   {
-      // lazy initialization
-      if (tm == null)
-      {
-         TransactionManagerServiceMBean tms = (TransactionManagerServiceMBean)
-            MBeanServerInvocationHandler.newProxyInstance(getServer(), tmObjectName,
-                                                          TransactionManagerServiceMBean.class, false);
-
-         tm = tms.getTransactionManager();
-      }
-
-      return tm;
-   }
+   //PersistentServiceSupport overrides ----------------------------
    
-   // Inner classes -------------------------------------------------
-   
-   private class TransactionWrapper
+   protected Map getDefaultDDLStatements()
    {
-      private javax.transaction.Transaction oldTx;
+      Map map = new HashMap();
+      //Message reference
+      map.put("CREATE_MESSAGE_REFERENCE",
+              "CREATE TABLE JMS_MESSAGE_REFERENCE (CHANNELID BIGINT, " +
+              "MESSAGEID BIGINT, TRANSACTIONID BIGINT, STATE CHAR(1), ORD BIGINT, PAGE_ORD BIGINT, " +
+              "DELIVERYCOUNT INTEGER, RELIABLE CHAR(1), PRIMARY KEY(CHANNELID, MESSAGEID))");
+      map.put("CREATE_IDX_MESSAGE_REF_TX", "CREATE INDEX JMS_MESSAGE_REF_TX ON JMS_MESSAGE_REFERENCE (TRANSACTIONID)");
+      map.put("CREATE_IDX_MESSAGE_REF_ORD", "CREATE INDEX JMS_MESSAGE_REF_ORD ON JMS_MESSAGE_REFERENCE (ORD)");
+      map.put("CREATE_IDX_MESSAGE_REF_PAGE_ORD", "CREATE INDEX JMS_MESSAGE_REF__PAGE_ORD ON JMS_MESSAGE_REFERENCE (PAGE_ORD)");
+      map.put("CREATE_IDX_MESSAGE_REF_MESSAGEID", "CREATE INDEX JMS_MESSAGE_REF_MESSAGEID ON JMS_MESSAGE_REFERENCE (MESSAGEID)");
+      map.put("CREATE_IDX_MESSAGE_REF_RELIABLE", "CREATE INDEX JMS_MESSAGE_REF_RELIABLE ON JMS_MESSAGE_REFERENCE (RELIABLE)");
+      //Message
+      map.put("CREATE_MESSAGE",
+              "CREATE TABLE JMS_MESSAGE (MESSAGEID BIGINT, RELIABLE CHAR(1), " +
+              "EXPIRATION BIGINT, TIMESTAMP BIGINT, PRIORITY TINYINT, COREHEADERS LONGVARBINARY, " +
+              "PAYLOAD LONGVARBINARY, CHANNELCOUNT INTEGER, TYPE TINYINT, JMSTYPE VARCHAR(255), CORRELATIONID VARCHAR(255), " +
+              "CORRELATIONID_BYTES VARBINARY(254), DESTINATION VARCHAR(255), REPLYTO VARCHAR(255), " +
+              "JMSPROPERTIES LONGVARBINARY, " +
+              "PRIMARY KEY (MESSAGEID))"); 
+      //Transaction
+      map.put("CREATE_TRANSACTION",
+              "CREATE TABLE JMS_TRANSACTION (" +
+              "TRANSACTIONID BIGINT, BRANCH_QUAL VARBINARY(254), " +
+              "FORMAT_ID INTEGER, GLOBAL_TXID VARBINARY(254), PRIMARY KEY (TRANSACTIONID))");
+      //Counter
+      map.put("CREATE_COUNTER",
+              "CREATE TABLE JMS_COUNTER (NAME VARCHAR(255), NEXT_ID BIGINT, PRIMARY KEY(NAME))");
+      //Sequences
+      map.put("CREATE_ORDERING_SEQUENCE", "CREATE SEQUENCE REF_ORD");
+      return map;
+   }
       
-      private boolean failed;
-      
-      private TransactionWrapper() throws Exception
-      {
-         TransactionManager tm = getTransactionManagerReference();
-
-         oldTx = tm.suspend();
-         
-         tm.begin();
-      }
-      
-      private void end() throws Exception
-      {
-         TransactionManager tm = getTransactionManagerReference();
-
-         try
-         {
-            if (Status.STATUS_MARKED_ROLLBACK == tm.getStatus())
-            {
-               failed = true;
-               tm.rollback();               
-            }
-            else
-            {
-               tm.commit();
-            }
-         }
-         finally
-         {
-            if (oldTx != null && tm != null)
-            {
-               tm.resume(oldTx);
-            }
-         }
-      }      
-      
-      private void exceptionOccurred() throws Exception
-      {
-         getTransactionManagerReference().setRollbackOnly();
-      }
+   protected Map getDefaultDMLStatements()
+   {                
+      Map map = new HashMap();
+      //Message reference
+      map.put("INSERT_MESSAGE_REF",
+              "INSERT INTO JMS_MESSAGE_REFERENCE (CHANNELID, MESSAGEID, TRANSACTIONID, STATE, ORD, PAGE_ORD, DELIVERYCOUNT, RELIABLE) " +
+              "VALUES (?, ?, ?, ?, NEXT VALUE FOR REF_ORD, ?, ?, ?)");
+      map.put("DELETE_MESSAGE_REF", "DELETE FROM JMS_MESSAGE_REFERENCE WHERE MESSAGEID=? AND CHANNELID=? AND STATE='C'");
+      map.put("UPDATE_MESSAGE_REF",
+              "UPDATE JMS_MESSAGE_REFERENCE SET TRANSACTIONID=?, STATE='-' " +
+              "WHERE MESSAGEID=? AND CHANNELID=? AND STATE='C'");
+      map.put("UPDATE_PAGE_ORDER", "UPDATE JMS_MESSAGE_REFERENCE SET PAGE_ORD = ? WHERE MESSAGEID=? AND CHANNELID=?");
+      map.put("COMMIT_MESSAGE_REF1", "UPDATE JMS_MESSAGE_REFERENCE SET STATE='C', TRANSACTIONID = NULL WHERE TRANSACTIONID=? AND STATE='+'");
+      map.put("COMMIT_MESSAGE_REF2", "DELETE FROM JMS_MESSAGE_REFERENCE WHERE TRANSACTIONID=? AND STATE='-'");
+      map.put("ROLLBACK_MESSAGE_REF1", "DELETE FROM JMS_MESSAGE_REFERENCE WHERE TRANSACTIONID=? AND STATE='+'");
+      map.put("ROLLBACK_MESSAGE_REF2", "UPDATE JMS_MESSAGE_REFERENCE SET STATE='C', TRANSACTIONID = NULL WHERE TRANSACTIONID=? AND STATE='-'");
+      map.put("LOAD_PAGED_REFS",
+              "SELECT MESSAGEID, DELIVERYCOUNT, PAGE_ORD, RELIABLE FROM JMS_MESSAGE_REFERENCE " +
+              "WHERE CHANNELID = ? AND PAGE_ORD BETWEEN ? AND ? ORDER BY PAGE_ORD");
+      map.put("LOAD_UNPAGED_REFS",
+              "SELECT MESSAGEID, DELIVERYCOUNT, RELIABLE FROM JMS_MESSAGE_REFERENCE " +
+              "WHERE PAGE_ORD IS NULL and CHANNELID = ? ORDER BY ORD");
+      map.put("UPDATE_RELIABLE_REFS_NOT_PAGED", "UPDATE JMS_MESSAGE_REFERENCE SET PAGE_ORD = NULL WHERE PAGE_ORD BETWEEN ? AND ? AND CHANNELID=?");   
+      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 = ?");
+      //Message
+      map.put("LOAD_MESSAGES",
+              "SELECT MESSAGEID, RELIABLE, EXPIRATION, TIMESTAMP, " +
+              "PRIORITY, COREHEADERS, PAYLOAD, CHANNELCOUNT, TYPE, JMSTYPE, CORRELATIONID, " +
+              "CORRELATIONID_BYTES, DESTINATION, REPLYTO, JMSPROPERTIES " +
+              "FROM JMS_MESSAGE");
+      map.put("INSERT_MESSAGE",
+              "INSERT INTO JMS_MESSAGE (MESSAGEID, RELIABLE, EXPIRATION, " +
+              "TIMESTAMP, PRIORITY, COREHEADERS, PAYLOAD, CHANNELCOUNT, TYPE, JMSTYPE, CORRELATIONID, " +
+              "CORRELATIONID_BYTES, DESTINATION, REPLYTO, JMSPROPERTIES) " +
+              "VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)" );
+      map.put("UPDATE_MESSAGE_CHANNELCOUNT", "UPDATE JMS_MESSAGE SET CHANNELCOUNT=? WHERE MESSAGEID=?");
+      map.put("DELETE_MESSAGE", "DELETE FROM JMS_MESSAGE WHERE MESSAGEID=?");
+      map.put("MESSAGEID_COLUMN", "MESSAGEID");
+      map.put("UPDATE_UNRELIABLE_CHANNELCOUNT",
+              "UPDATE JMS_MESSAGE M SET M.CHANNELCOUNT = M.CHANNELCOUNT - 1 WHERE " +
+              "M.MESSAGEID IN (SELECT MR.MESSAGEID FROM JMS_MESSAGE_REFERENCE MR WHERE MR.RELIABLE = 'N' AND MR.CHANNELID = ?)");
+      map.put("DELETE_UNREFFED_MESSAGES", "DELETE FROM JMS_MESSAGE WHERE CHANNELCOUNT = 0");
+      //Transaction
+      map.put("INSERT_TRANSACTION",
+              "INSERT INTO JMS_TRANSACTION (TRANSACTIONID, BRANCH_QUAL, FORMAT_ID, GLOBAL_TXID) " +
+              "VALUES(?, ?, ?, ?)");
+      map.put("DELETE_TRANSACTION", "DELETE FROM JMS_TRANSACTION WHERE TRANSACTIONID = ?");
+      map.put("SELECT_PREPARED_TRANSACTIONS", "SELECT TRANSACTIONID, BRANCH_QUAL, FORMAT_ID, GLOBAL_TXID FROM JMS_TRANSACTION");
+      //Counter
+      map.put("UPDATE_COUNTER", "UPDATE JMS_COUNTER SET NEXT_ID = ? WHERE NAME=?");
+      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");
+      return map;
    }
    
+   // Private -------------------------------------------------------
+
+   // Inner classes -------------------------------------------------
+        
    private static class ChannelRefPair
    {
       private long channelId;

Added: trunk/src/main/org/jboss/messaging/core/plugin/JDBCServiceSupport.java
===================================================================
--- trunk/src/main/org/jboss/messaging/core/plugin/JDBCServiceSupport.java	2006-08-30 09:26:13 UTC (rev 1236)
+++ trunk/src/main/org/jboss/messaging/core/plugin/JDBCServiceSupport.java	2006-08-30 18:36:36 UTC (rev 1237)
@@ -0,0 +1,395 @@
+/*
+ * 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.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+import java.sql.Connection;
+import java.sql.SQLException;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.Map;
+import java.util.Properties;
+
+import javax.management.MBeanServerInvocationHandler;
+import javax.management.ObjectName;
+import javax.naming.InitialContext;
+import javax.sql.DataSource;
+import javax.transaction.Status;
+import javax.transaction.TransactionManager;
+
+import org.jboss.jms.util.ExceptionUtil;
+import org.jboss.messaging.core.plugin.contract.ServerPlugin;
+import org.jboss.system.ServiceMBeanSupport;
+import org.jboss.tm.TransactionManagerServiceMBean;
+
+/**
+ * A JDBCServiceSupport
+ *
+ * Common functionality for any service that needs to access a database
+ *
+ * @author <a href="mailto:tim.fox at jboss.com">Tim Fox</a>
+ * @author <a href="mailto:ovidiu at jboss.org">Ovidiu Feodorov</a>
+ * @version <tt>$Revision: 1.1 $</tt>
+ *
+ * $Id$
+ *
+ */
+public abstract class JDBCServiceSupport extends ServiceMBeanSupport implements ServerPlugin
+{   
+   protected DataSource ds;
+   
+   protected Properties sqlProperties;
+         
+   // never access directly
+   private TransactionManager tm;
+    
+   private Map defaultDMLStatements;
+   
+   private Map defaultDDLStatements;
+   
+   private String dataSourceJNDIName;
+   
+   private boolean createTablesOnStartup = true;
+   
+   private ObjectName tmObjectName;
+   
+   
+   public JDBCServiceSupport()
+   {
+      defaultDMLStatements = new HashMap();
+      
+      defaultDDLStatements = new HashMap();
+      
+      sqlProperties = new Properties();
+   }
+   
+   /*
+    * This constructor should only be used for testing
+    */
+   public JDBCServiceSupport(DataSource ds, TransactionManager tm)
+   {
+      this();
+      
+      log.info(this + " being created, tx mgr is " + tm);
+      
+      this.ds = ds;
+      
+      this.tm = tm;
+   }
+   
+   
+   // ServerPlugin implementation ------------------------------------------
+   
+   public Object getInstance()
+   {
+      return this;
+   }
+   
+   // ServiceMBeanSupport overrides ---------------------------------
+   
+   protected void startService() throws Exception
+   {
+      log.info(this + " startService");
+      
+      try
+      {
+         if (ds == null)
+         {
+            InitialContext ic = new InitialContext();
+            ds = (DataSource)ic.lookup(dataSourceJNDIName);
+            ic.close();
+         }
+         
+         if (ds == null)
+         {
+            throw new IllegalStateException("No DataSource found. This service dependencies must " +
+            "have not been enforced correctly!");
+         }
+         
+         defaultDMLStatements.putAll(getDefaultDMLStatements());
+         
+         defaultDDLStatements.putAll(getDefaultDDLStatements());
+                  
+         //Validate the SQL properties
+         Iterator iter = this.sqlProperties.keySet().iterator();
+         
+         while (iter.hasNext())
+         {
+            String statementName = (String)iter.next();
+            
+            //This will throw an exception if there is no default for the statement specified in the
+            //sql properties
+            getSQLStatement(statementName);
+         }
+         
+         //Also we validate the other way - if there are any sql properties specified then there should be one for every
+         //default property
+         //This allows us to catch subtle errors in the persistence manager configuration
+         if (!sqlProperties.isEmpty())
+         {
+            iter = defaultDMLStatements.keySet().iterator();
+            
+            while (iter.hasNext())
+            {
+               String statementName = (String)iter.next();
+               
+               if (sqlProperties.get(statementName) == null)
+               {
+                  throw new IllegalStateException("SQL statement " + statementName + " is not specified in the persistence manager SQL properties");
+               }
+            }
+            
+            iter = defaultDDLStatements.keySet().iterator();
+            
+            while (iter.hasNext())
+            {
+               String statementName = (String)iter.next();
+               
+               if (sqlProperties.get(statementName) == null)
+               {
+                  throw new IllegalStateException("SQL statement " + statementName + " is not specified in the persistence manager SQL properties");
+               }
+            }
+         }
+         
+         if (createTablesOnStartup)
+         {
+            createSchema();
+         }
+         
+         log.debug(this + " started");
+      }
+      catch (Throwable t)
+      {
+         throw ExceptionUtil.handleJMXInvocation(t, this + " startService");
+      } 
+   }
+   
+   protected void stopService() throws Exception
+   {
+      log.debug(this + " stopped");
+   }
+  
+   // MBean attributes --------------------------------------------------------
+      
+   public String getSqlProperties()
+   {
+      try
+      {
+         ByteArrayOutputStream boa = new ByteArrayOutputStream();
+         sqlProperties.store(boa, "");
+         return new String(boa.toByteArray());
+      }
+      catch (IOException shouldnothappen)
+      {
+         return "";
+      }
+   }
+   
+   public void setSqlProperties(String value)
+   {
+      try
+      {         
+         ByteArrayInputStream is = new ByteArrayInputStream(value.getBytes());
+         sqlProperties = new Properties();
+         sqlProperties.load(is);         
+      }
+      catch (IOException shouldnothappen)
+      {
+         log.error("Caught IOException", shouldnothappen);
+      }
+   }
+      
+   public void setDataSource(String dataSourceJNDIName) throws Exception
+   {
+      this.dataSourceJNDIName = dataSourceJNDIName;
+   }
+   
+   public String getDataSource()
+   {
+      return dataSourceJNDIName;
+   }
+   
+   public void setTransactionManager(ObjectName tmObjectName) throws Exception
+   {
+      this.tmObjectName = tmObjectName;
+   }
+   
+   public ObjectName getTransactionManager()
+   {
+      return tmObjectName;
+   }
+
+   public boolean isCreateTablesOnStartup() throws Exception
+   {
+      return createTablesOnStartup;
+   }
+
+   public void setCreateTablesOnStartup(boolean b) throws Exception
+   {
+      createTablesOnStartup = b;
+   }
+   
+   // Protected ----------------------------------------------------------     
+   
+   protected String getSQLStatement(String statementName)
+   {
+      String defaultStatement = (String)defaultDMLStatements.get(statementName);
+      
+      if (defaultStatement == null)
+      {
+         defaultStatement = (String)defaultDDLStatements.get(statementName);
+      }
+      
+      if (defaultStatement == null)
+      {
+         throw new IllegalArgumentException("No such SQL statement: " + statementName);
+      }
+      
+      String statement = sqlProperties.getProperty(statementName, defaultStatement);
+      
+      return statement;
+   }
+   
+   protected abstract Map getDefaultDDLStatements();
+   
+   protected abstract Map getDefaultDMLStatements();
+   
+   
+   // Private ----------------------------------------------------------------
+   
+   private TransactionManager getTransactionManagerReference()
+   {
+      // lazy initialization
+      if (tm == null)
+      {
+         TransactionManagerServiceMBean tms =
+            (TransactionManagerServiceMBean)MBeanServerInvocationHandler.
+            newProxyInstance(getServer(), tmObjectName, TransactionManagerServiceMBean.class, false);
+
+         tm = tms.getTransactionManager();
+      }
+
+      return tm;
+   }
+           
+   private void createSchema() throws Exception
+   {      
+      Connection conn = null;      
+      TransactionWrapper tx = new TransactionWrapper();
+      
+      log.info(this + " createSchema");
+      
+      try
+      {
+         conn = ds.getConnection();
+         
+         Iterator iter = defaultDDLStatements.keySet().iterator();
+         
+         while (iter.hasNext())
+         {
+            String statementName = (String)iter.next();
+             
+            String statement = getSQLStatement(statementName);
+            
+            try
+            {
+               if (log.isTraceEnabled()) { log.trace("Executing: " + statement); }
+                   
+               conn.createStatement().executeUpdate(statement);
+            }
+            catch (SQLException e) 
+            {
+               log.debug("Failed to execute: " + statement, e);
+            }  
+         }      
+      }
+      finally
+      {
+         if (conn != null)
+         {
+            try
+            {
+               conn.close();
+            }
+            catch (Throwable t)
+            {}
+         }
+         tx.end();
+      }      
+   }      
+   
+   // Innner classes ---------------------------------------------------------
+   
+   protected class TransactionWrapper
+   {
+      private javax.transaction.Transaction oldTx;
+      
+      private boolean failed;
+      
+      public TransactionWrapper() throws Exception
+      {
+         TransactionManager tm = getTransactionManagerReference();
+
+         oldTx = tm.suspend();
+         
+         tm.begin();
+      }
+      
+      public void end() throws Exception
+      {
+         TransactionManager tm = getTransactionManagerReference();
+
+         try
+         {
+            if (Status.STATUS_MARKED_ROLLBACK == tm.getStatus())
+            {
+               failed = true;
+               tm.rollback();               
+            }
+            else
+            {
+               tm.commit();
+            }
+         }
+         finally
+         {
+            if (oldTx != null && tm != null)
+            {
+               tm.resume(oldTx);
+            }
+         }
+      }      
+      
+      public void exceptionOccurred() throws Exception
+      {
+         getTransactionManagerReference().setRollbackOnly();
+      }
+      
+      public boolean isFailed()
+      {
+         return failed;
+      }
+   }
+}

Modified: trunk/src/main/org/jboss/messaging/core/plugin/SimpleMessageReference.java
===================================================================
--- trunk/src/main/org/jboss/messaging/core/plugin/SimpleMessageReference.java	2006-08-30 09:26:13 UTC (rev 1236)
+++ trunk/src/main/org/jboss/messaging/core/plugin/SimpleMessageReference.java	2006-08-30 18:36:36 UTC (rev 1237)
@@ -21,7 +21,6 @@
   */
 package org.jboss.messaging.core.plugin;
 
-import java.io.Serializable;
 import java.util.Map;
 
 import org.jboss.logging.Logger;
@@ -56,10 +55,8 @@
    
    private MessageHolder holder;
    
-   //private int deliveryCount;
+   private long pagingOrder = -1;
    
-   private long ordering;
-   
    private boolean released;
    
    // Constructors --------------------------------------------------
@@ -117,11 +114,6 @@
    }
 
    // MessageReference implementation -------------------------------
-
-   public Serializable getStoreID()
-   {
-      return ms.getStoreID();
-   }
    
    public Message getMessage()
    {
@@ -148,14 +140,14 @@
       return holder.getInMemoryChannelCount();
    }
   
-   public long getOrdering()
+   public long getPagingOrder()
    {
-      return ordering;
+      return pagingOrder;
    }
    
-   public void setOrdering(long ordering)
+   public void setPagingOrder(long order)
    {
-      this.ordering = ordering;
+      this.pagingOrder = order;
    }
    
    public MessageReference copy()

Modified: trunk/src/main/org/jboss/messaging/core/plugin/SimpleMessageStore.java
===================================================================
--- trunk/src/main/org/jboss/messaging/core/plugin/SimpleMessageStore.java	2006-08-30 09:26:13 UTC (rev 1236)
+++ trunk/src/main/org/jboss/messaging/core/plugin/SimpleMessageStore.java	2006-08-30 18:36:36 UTC (rev 1237)
@@ -21,7 +21,6 @@
   */
 package org.jboss.messaging.core.plugin;
 
-import java.io.Serializable;
 import java.util.ArrayList;
 import java.util.HashMap;
 import java.util.List;
@@ -31,8 +30,6 @@
 import org.jboss.messaging.core.Message;
 import org.jboss.messaging.core.MessageReference;
 import org.jboss.messaging.core.plugin.contract.MessageStore;
-import org.jboss.messaging.util.Util;
-import org.jboss.system.ServiceMBeanSupport;
 
 /**
  * A MessageStore implementation.
@@ -43,7 +40,7 @@
  *
  * $Id$
  */
-public class SimpleMessageStore extends ServiceMBeanSupport implements MessageStore
+public class SimpleMessageStore implements MessageStore
 {
    // Constants -----------------------------------------------------
 
@@ -54,52 +51,19 @@
    // Attributes ----------------------------------------------------
    
    private boolean trace = log.isTraceEnabled();
-
-   private Serializable storeID;
-   
-   private boolean acceptReliableMessages;
-
+ 
    // <messageID - MessageHolder>
    private Map messages;
 
    // Constructors --------------------------------------------------
 
-   /**
-    * @param storeID - if more than one message store is to be used in a distributed messaging
-    *        configuration, each store must have an unique store ID.
-    */
-   public SimpleMessageStore(String storeID)
-   {
-      this(storeID, true);
-   }
-
-   /**
-    * @param storeID - if more than one message store is to be used in a distributed messaging
-    *        configuration, each store must have an unique store ID.
-    */
-   public SimpleMessageStore(String storeID, boolean acceptReliableMessages)
-   {
-      this.storeID = storeID;
-      
-      this.acceptReliableMessages = acceptReliableMessages;
-      
+   public SimpleMessageStore()
+   {  
       messages = new HashMap();
 
       log.debug(this + " initialized");
    }
 
-   // ServiceMBeanSupport overrides ---------------------------------
-
-   protected void startService() throws Exception
-   {
-      log.debug(this + " started");
-   }
-
-   protected void stopService() throws Exception
-   {
-      log.debug(this + " stopped");
-   }
-
    // MessageStore implementation ---------------------------
 
    public Object getInstance()
@@ -107,33 +71,14 @@
       return this;
    }
 
-   public Serializable getStoreID()
-   {
-      return storeID;
-   }
-
-   public boolean isRecoverable()
-   {
-      return false;
-   }
-
-   public boolean acceptReliableMessages()
-   {
-      return acceptReliableMessages;
-   }
-
    // TODO If we can assume that the message is not known to the store before
    // (true when sending messages)
    // Then we can avoid synchronizing on this and use a ConcurrentHashmap
    // Which will give us much better concurrency for many threads
    public MessageReference reference(Message m)
    {
-      if (m.isReliable() && !acceptReliableMessages)
-      {
-         throw new IllegalStateException(this + " does not accept reliable messages (" + m + ")");
-      }
-      
       MessageHolder holder;
+      
       synchronized (this)
       {         
          holder = (MessageHolder)messages.get(new Long(m.getMessageID()));
@@ -145,9 +90,10 @@
       }
       holder.incrementInMemoryChannelCount();
       
-
       MessageReference ref = new SimpleMessageReference(holder, this);
+      
       if (trace) { log.trace(this + " generated " + ref + " for " + m); }
+      
       return ref;
    }
 
@@ -166,6 +112,7 @@
       }
        
       MessageReference ref = new SimpleMessageReference(holder, this);
+      
       if (trace) { log.trace(this + " generates " + ref + " for " + messageID); }
       
       holder.incrementInMemoryChannelCount();
@@ -191,14 +138,9 @@
 
    // Public --------------------------------------------------------
    
-   public void setStoreID(String storeID)
-   {
-      this.storeID = storeID;
-   }
-
    public String toString()
    {
-      return "MemoryStore[" + Util.guidToString(storeID) + "]";
+      return "MemoryStore[" + System.identityHashCode(this) + "]";
    }
 
    // Package protected ---------------------------------------------

Added: trunk/src/main/org/jboss/messaging/core/plugin/contract/Exchange.java
===================================================================
--- trunk/src/main/org/jboss/messaging/core/plugin/contract/Exchange.java	2006-08-30 09:26:13 UTC (rev 1236)
+++ trunk/src/main/org/jboss/messaging/core/plugin/contract/Exchange.java	2006-08-30 18:36:36 UTC (rev 1237)
@@ -0,0 +1,142 @@
+/*
+ * 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;
+
+import java.util.List;
+
+import org.jboss.messaging.core.Filter;
+import org.jboss.messaging.core.MessageReference;
+import org.jboss.messaging.core.memory.MemoryManager;
+import org.jboss.messaging.core.plugin.exchange.Binding;
+import org.jboss.messaging.core.tx.Transaction;
+
+/**
+ * 
+ * An Exchange
+ * 
+ * It is the responsibility of the exchange to maintain bindings between names and queues, and handle
+ * message routing to queues.
+ * 
+ * For a standard point to point queue, the Queue would be bound to a name that represents the name
+ * of the queue, e.g. "MyQueue".
+ * 
+ * If the Queue represents a publish-subscribe subscription then it might be bound to the name
+ * "MyTopic.subscription123".
+ * 
+ * Then we handling the message, a routing key is specified.
+ * 
+ * The routing key might be a simple name like "MyQueue" in which case the message would get sent to MyQueue
+ * or it might be a wildcard expression e.g. "MyTopic.*" - in which case the message would get sent to any 
+ * Queues bound to any names that start with "MyTopic."
+ * 
+ * In such a way we can provide the semantics of JMS Queues and Topics without having to create separate Queue
+ * and Topic constructs which vastly simplifies the code.
+ * 
+ * It also acts as a placeholder for much more complex routing policies in the future.
+ * 
+ * Finally, it makes clustering simpler, since we only have to worry about clustering the Queue.
+ * 
+ * For now we only support one binding per queue.
+ * 
+ * If we are to support full blown AMQP style message exchanges then we would
+ * need to support more than one binding per queue.
+ * 
+ * @author <a href="mailto:tim.fox at jboss.com">Tim Fox</a>
+ * @version <tt>$Revision: 1.1 $</tt>
+ *
+ * $Id$
+ *
+ */
+public interface Exchange extends ServerPlugin
+{   
+   /**
+    * Creates a new MessageQueue and binds it to the exchange
+    * If a binding with the queueName already exist an exception is thrown
+    * @param queueName
+    * @param condition
+    * @param selector
+    * @param noLocal
+    * @param durable
+    * @return The binding
+    * @throws Exception
+    */
+   Binding bindQueue(String queueName, String condition, Filter filter, boolean noLocal, boolean durable,
+                     MessageStore ms, PersistenceManager pm,
+                     int fullSize, int pageSize, int downCacheSize) throws Exception;
+   
+   /**
+    * Removes the queue and all its data and unbinds it from the exchange
+    * @param queueName
+    * @return
+    * @throws Exception
+    */
+   Binding unbindQueue(String queueName) throws Throwable;
+   
+   /**
+    * Reloads any message queues whose condition matches the wildcard.
+    * @param wildcard
+    * @param ms
+    * @param pm
+    * @param mm
+    * @param fullSize
+    * @param pageSize
+    * @param downCacheSize
+    * @throws Exception
+    */
+   void reloadQueues(String wildcard,
+                     MessageStore ms, PersistenceManager pm,
+                     int fullSize, int pageSize, int downCacheSize) throws Exception;
+   
+   /**
+    * Unloads any queues for any bindings whose condition matches the wildcard
+    * @param wildcard
+    * @throws Exception
+    */
+   void unloadQueues(String wildcard) throws Exception;
+   
+   /**
+    * List all bindings whose condition matches the wildcard
+    * @param wildcard
+    * @return
+    * @throws Exception
+    */
+   List listBindingsForWildcard(String wildcard) throws Exception;
+   
+   
+   /**
+    * Returns binding that matches the name
+    * @param queueName
+    * @return
+    * @throws Exception
+    */
+   Binding getBindingForName(String queueName) throws Exception;
+   
+   /**
+    * Route a message
+    * @param message
+    * @param routingKey
+    * @param tx
+    * @return
+    * @throws Exception
+    */
+   boolean route(MessageReference ref, String routingKey, Transaction tx) throws Exception;   
+}

Modified: trunk/src/main/org/jboss/messaging/core/plugin/contract/MessageStore.java
===================================================================
--- trunk/src/main/org/jboss/messaging/core/plugin/contract/MessageStore.java	2006-08-30 09:26:13 UTC (rev 1236)
+++ trunk/src/main/org/jboss/messaging/core/plugin/contract/MessageStore.java	2006-08-30 18:36:36 UTC (rev 1237)
@@ -6,8 +6,6 @@
  */
 package org.jboss.messaging.core.plugin.contract;
 
-import java.io.Serializable;
-
 import org.jboss.messaging.core.Message;
 import org.jboss.messaging.core.MessageReference;
 
@@ -20,26 +18,9 @@
  *
  * $Id$
  */
-public interface MessageStore extends ServerPlugin
+public interface MessageStore
 {
-   Serializable getStoreID();
-
-   boolean isRecoverable();
-
    /**
-    * A non-recoverable message store cannot guarantee recoverability for reliable messages so by
-    * default it won't accept reliable messages. If specifically configured to do so, it must
-    * unequivocally indicates that it accepts reliable messages by returning true as result of this
-    * method.
-    *
-    * A recoverable message store must always accept reliable messages, so this method must always
-    * return true for a recoverable message store.
-    *
-    * @return false if the channel doesn't accept reliable messages.
-    */
-   public boolean acceptReliableMessages();
-
-   /**
     * Message m is stored in the store if it is not already known to the store, then
     * a new MessageReference is returned for the Message
     *
@@ -61,6 +42,5 @@
     * @param messageID
     * @return
     */
-   public boolean forgetMessage(long messageID);
-   
+   public boolean forgetMessage(long messageID);   
 }

Modified: trunk/src/main/org/jboss/messaging/core/plugin/contract/PersistenceManager.java
===================================================================
--- trunk/src/main/org/jboss/messaging/core/plugin/contract/PersistenceManager.java	2006-08-30 09:26:13 UTC (rev 1236)
+++ trunk/src/main/org/jboss/messaging/core/plugin/contract/PersistenceManager.java	2006-08-30 18:36:36 UTC (rev 1237)
@@ -37,39 +37,35 @@
  */
 public interface PersistenceManager extends ServerPlugin
 {
-   /*
-    * Currently unused but will be used for XA recovery
-    */
-   List retrievePreparedTransactions() throws Exception;
-      
-   void resetLoadedStatus(long channelID) throws Exception;
-      
    void addReference(long channelID, MessageReference ref, Transaction tx) throws Exception;
 
    void removeReference(long channelID, MessageReference ref, Transaction tx) throws Exception;
+    
+   // XA Recovery functionality
+   
+   List retrievePreparedTransactions() throws Exception;
       
-
-   void addReferences(long channelID, List references, boolean loaded) throws Exception;
+   // Paging functionality - TODO we should split this out into its own interface
    
+   void addReferences(long channelID, List references) throws Exception;
+   
    void removeReferences(long channelID, List refs) throws Exception;
+    
+   void updatePageOrder(long channelID, List references) throws Exception;
    
-   long getMinOrdering(long channelID) throws Exception;
-   
-   
-   void updateReferencesNotLoaded(long channelID, List references) throws Exception;
-   
-   void updateReliableReferencesLoadedInRange(long channelID, long orderStart, long orderEnd) throws Exception;
+   void updateReliableReferencesNotPagedInRange(long channelID, long orderStart, long orderEnd) throws Exception;
             
-   int getNumberOfUnloadedReferences(long channelID) throws Exception;
+   List getPagedReferenceInfos(long channelID, long orderStart, long number) throws Exception;
    
-   List getReferenceInfos(long channelID, long minOrdering, int number) throws Exception;
-   
+   InitialLoadInfo getInitialReferenceInfos(long channelID, int fullSize) throws Exception;
+      
    List getMessages(List messageIds) throws Exception;
+         
+   //Counter related functionality - TODO we should split this out into its own interface
    
    long reserveIDBlock(String counterName, int size) throws Exception;
    
-   
-   
+      
    // Interface value classes
    //---------------------------------------------------------------
    
@@ -77,18 +73,14 @@
    {
       private long messageId;
       
-      private long ordering;
-      
       private int deliveryCount;
       
       private boolean reliable;
       
-      public ReferenceInfo(long msgId, long ordering, int deliveryCount, boolean reliable)
+      public ReferenceInfo(long msgId, int deliveryCount, boolean reliable)
       {
          this.messageId = msgId;
          
-         this.ordering = ordering;
-         
          this.deliveryCount = deliveryCount;
          
          this.reliable = reliable;
@@ -98,12 +90,7 @@
       {
          return messageId;
       }
-      
-      public long getOrdering()
-      {
-         return ordering;
-      }
-      
+ 
       public int getDeliveryCount()
       {
          return deliveryCount;
@@ -115,4 +102,35 @@
       }
    }
    
+   class InitialLoadInfo
+   {
+      private long minPageOrdering;
+      
+      private long maxPageOrdering;
+      
+      private List refInfos;
+
+      public InitialLoadInfo(long minPageOrdering, long maxPageOrdering, List refInfos)
+      {
+         this.minPageOrdering = minPageOrdering;
+         this.maxPageOrdering = maxPageOrdering;
+         this.refInfos = refInfos;
+      }
+
+      public long getMaxPageOrdering()
+      {
+         return maxPageOrdering;
+      }
+
+      public long getMinPageOrdering()
+      {
+         return minPageOrdering;
+      }
+      
+      public List getRefInfos()
+      {
+         return refInfos;
+      }
+   }
+   
 }

Added: trunk/src/main/org/jboss/messaging/core/plugin/contract/ib/BalancePolicy.java
===================================================================
--- trunk/src/main/org/jboss/messaging/core/plugin/contract/ib/BalancePolicy.java	2006-08-30 09:26:13 UTC (rev 1236)
+++ trunk/src/main/org/jboss/messaging/core/plugin/contract/ib/BalancePolicy.java	2006-08-30 18:36:36 UTC (rev 1237)
@@ -0,0 +1,43 @@
+/*
+ * 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.ib;
+
+import java.util.List;
+
+/**
+ * A BalancePolicy
+
+ * @author <a href="mailto:tim.fox at jboss.com">Tim Fox</a>
+ * @version <tt>$Revision: 1.1 $</tt>
+ *
+ * $Id$
+ *
+ */
+public interface BalancePolicy
+{
+   /**
+    * Given a list of statistics from different nodes, calculate a list of instructions
+    * @param statistics
+    * @return
+    */
+   List calculateInstructions(List statistics);
+}

Added: trunk/src/main/org/jboss/messaging/core/plugin/contract/ib/Balanceable.java
===================================================================
--- trunk/src/main/org/jboss/messaging/core/plugin/contract/ib/Balanceable.java	2006-08-30 09:26:13 UTC (rev 1236)
+++ trunk/src/main/org/jboss/messaging/core/plugin/contract/ib/Balanceable.java	2006-08-30 18:36:36 UTC (rev 1237)
@@ -0,0 +1,40 @@
+/*
+ * 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.ib;
+
+import java.util.List;
+
+/**
+ * A Balanceable
+
+ * @author <a href="mailto:tim.fox at jboss.com">Tim Fox</a>
+ * @version <tt>$Revision: 1.1 $</tt>
+ *
+ * $Id$
+ *
+ */
+public interface Balanceable
+{
+   List getStatistics() throws Exception;
+   
+   void instruct(Instruction instruction) throws Exception;
+}

Added: trunk/src/main/org/jboss/messaging/core/plugin/contract/ib/Instruction.java
===================================================================
--- trunk/src/main/org/jboss/messaging/core/plugin/contract/ib/Instruction.java	2006-08-30 09:26:13 UTC (rev 1236)
+++ trunk/src/main/org/jboss/messaging/core/plugin/contract/ib/Instruction.java	2006-08-30 18:36:36 UTC (rev 1237)
@@ -0,0 +1,36 @@
+/*
+ * 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.ib;
+
+/**
+ * A Instruction
+
+ * @author <a href="mailto:tim.fox at jboss.com">Tim Fox</a>
+ * @version <tt>$Revision: 1.1 $</tt>
+ *
+ * $Id$
+ *
+ */
+public interface Instruction
+{
+   
+}

Added: trunk/src/main/org/jboss/messaging/core/plugin/contract/ib/IntelligentBalancer.java
===================================================================
--- trunk/src/main/org/jboss/messaging/core/plugin/contract/ib/IntelligentBalancer.java	2006-08-30 09:26:13 UTC (rev 1236)
+++ trunk/src/main/org/jboss/messaging/core/plugin/contract/ib/IntelligentBalancer.java	2006-08-30 18:36:36 UTC (rev 1237)
@@ -0,0 +1,36 @@
+/*
+ * 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.ib;
+
+/**
+ * A IntelligentBalancer
+
+ * @author <a href="mailto:tim.fox at jboss.com">Tim Fox</a>
+ * @version <tt>$Revision: 1.1 $</tt>
+ *
+ * $Id$
+ *
+ */
+public interface IntelligentBalancer
+{
+
+}

Added: trunk/src/main/org/jboss/messaging/core/plugin/contract/ib/Statistic.java
===================================================================
--- trunk/src/main/org/jboss/messaging/core/plugin/contract/ib/Statistic.java	2006-08-30 09:26:13 UTC (rev 1236)
+++ trunk/src/main/org/jboss/messaging/core/plugin/contract/ib/Statistic.java	2006-08-30 18:36:36 UTC (rev 1237)
@@ -0,0 +1,36 @@
+/*
+ * 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.ib;
+
+/**
+ * A Statistic
+
+ * @author <a href="mailto:tim.fox at jboss.com">Tim Fox</a>
+ * @version <tt>$Revision: 1.1 $</tt>
+ *
+ * $Id$
+ *
+ */
+public interface Statistic
+{
+   
+}

Added: trunk/src/main/org/jboss/messaging/core/plugin/exchange/Binding.java
===================================================================
--- trunk/src/main/org/jboss/messaging/core/plugin/exchange/Binding.java	2006-08-30 09:26:13 UTC (rev 1236)
+++ trunk/src/main/org/jboss/messaging/core/plugin/exchange/Binding.java	2006-08-30 18:36:36 UTC (rev 1237)
@@ -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;
+
+import org.jboss.messaging.core.local.MessageQueue;
+
+/**
+ * A Binding
+
+ * @author <a href="mailto:tim.fox at jboss.com">Tim Fox</a>
+ * @version <tt>$Revision: 1.1 $</tt>
+ *
+ * $Id$
+ *
+ */
+public interface Binding
+{
+   String getNodeId();
+   
+   String getQueueName();
+   
+   String getCondition();
+   
+   MessageQueue getQueue();
+   
+   String getSelector();
+     
+   long getChannelId();
+   
+   boolean isDurable();
+   
+   boolean isNoLocal();
+   
+   boolean isActive();
+   
+   void activate();
+   
+   void deactivate();
+   
+   void setQueue(MessageQueue queue);
+
+}

Added: trunk/src/main/org/jboss/messaging/core/plugin/exchange/ClusteredExchangeSupport.java
===================================================================
--- trunk/src/main/org/jboss/messaging/core/plugin/exchange/ClusteredExchangeSupport.java	2006-08-30 09:26:13 UTC (rev 1236)
+++ trunk/src/main/org/jboss/messaging/core/plugin/exchange/ClusteredExchangeSupport.java	2006-08-30 18:36:36 UTC (rev 1237)
@@ -0,0 +1,606 @@
+/*
+ * 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 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.UnbindRequest;
+import org.jgroups.Address;
+import org.jgroups.Channel;
+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 RequestHandler requestHandler;
+   
+   private Object setStateLock = new Object();
+   
+   private boolean stateSet;
+   
+   private String groupName;
+   
+   //protected boolean clustered;
+   
+   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;
+      
+      //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.controlMessageDispatcher = new MessageDispatcher(controlChannel, controlMessageListener,
+                                                            null, requestHandler, true);      
+      this.dataReceiver = new DataMessageListener();
+      
+      dataChannel.setReceiver(dataReceiver);
+   }
+   
+   // ServiceMBeanSupport overrides ---------------------------------
+   
+   protected void startService() throws Exception
+   {
+      controlChannel.connect(groupName);
+      log.info("Connected to control channel");
+      
+      dataChannel.connect(groupName);
+      log.info("Connected to data channel");
+      
+      super.startService();            
+   }
+   
+   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);
+      
+      log.info(this + " load bindings, isState=" + isState);
+                            
+      if (!isState)
+      {       
+         //Must be first member in group or non clustered- we load the state ourself from the database
+         log.info("loading bindings from db");
+         super.loadBindings();      
+         log.info("loaded bindings from db");
+      }
+      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)
+            {
+               log.info("Waiting for state to arrive");
+               setStateLock.wait();
+            } 
+         }
+      }
+      
+      log.info(this + " loadBindings complete");
+   }
+   
+   // 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();
+      
+      log.info("node " + this.nodeId + " received request to add binding from node " + nodeId);
+      
+      try
+      {         
+         // 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("Binding already exists for node Id " + nodeId + " queue name " + queueName);
+         }
+         
+         binding = new SimpleBinding(nodeId, queueName, condition, filterString,
+                                     noLocal, channelID, durable); 
+         
+         log.info("Created binding");
+         
+         binding.activate();
+         
+         addBinding(binding);         
+         
+         log.info("Added it");
+      }
+      finally
+      {
+         lock.writeLock().release();
+      }
+   }
+   
+   /*
+    * Called when another node removes a binding
+    */
+   private void removeBindingFromCluster(String nodeId, String queueName) throws Exception
+   {
+      lock.writeLock().acquire();
+      
+      try
+      {         
+         // 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.remove(queueName);
+         }
+         
+         if (binding == null)
+         {
+            throw new IllegalArgumentException("Cannot find binding with node Id " + nodeId + " queue name: " + queueName);
+         }
+         
+      }
+      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
+      
+   }
+   
+   //TODO - Sort out serialization properly
+   
+   private byte[] getBindingListAsBytes() 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());
+         }
+      }
+      
+      byte[] bytes = Util.objectToByteBuffer(bindings);
+      
+      return bytes;
+   }
+   
+   private void processBindingListBytes(byte[] bytes) throws Exception
+   {
+      nameMaps.clear();
+      
+      conditionMap.clear();
+      
+      List bindings = (List)Util.objectFromByteBuffer(bytes);
+      
+      Iterator iter = bindings.iterator();
+      
+      while (iter.hasNext())
+      {
+         Binding binding = (Binding)iter.next();
+         
+         addBinding(binding);
+      }
+   }
+   
+   // Inner classes -------------------------------------------------------------------
+    
+   /*
+    * This class is used to manage state on the control channel
+    */
+   private class ControlMessageListener implements MessageListener
+   {
+      public byte[] getState()
+      {
+         //TODO should we propagate the exceptions up??
+         
+         log.info(this + " getState called");
+         try
+         {
+            lock.writeLock().acquire();
+         }
+         catch (InterruptedException e)
+         {
+            log.error("Thread Interrupted", e);
+         }
+         try
+         {
+            return getBindingListAsBytes();
+         }
+         catch (Exception e)
+         {
+            log.error("Failed to get state", e);
+            return null;
+         }     
+         finally
+         {
+            lock.writeLock().release();
+         }
+      }
+      
+      public void receive(Message message)
+      {         
+         log.info("Received message on control channel: " + message);
+      }
+      
+      public void setState(byte[] bytes)
+      {
+         // TODO should we propagate the exceptions up??
+         
+         log.info(this + " setState called");
+         log.info("state is: " + bytes);
+         
+         if (bytes != null)
+         {
+            
+            try
+            {
+               lock.writeLock().acquire();         
+            }
+            catch (InterruptedException e)
+            {
+               log.error("Thread interrupted", e);
+            }
+            try
+            {
+               processBindingListBytes(bytes);               
+            }
+            catch (Exception e)
+            {
+               log.error("Failed to deserialize", e);
+            }
+            finally
+            {
+               lock.writeLock().release();
+            }
+         }
+         
+         log.info("Set the state");
+         
+         synchronized (setStateLock)
+         {
+            stateSet = true;
+            setStateLock.notify();
+         }
+         
+         log.info("Notified");
+         
+      }      
+   }
+   
+   
+   /*
+    * This class is used to listen for messages on the data channel
+    */
+   private class DataMessageListener 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
+         {
+            log.info("Received message:" + message);
+            
+            //TODO handle deserialization more efficiently
+            
+            Object object = message.getObject();
+            
+            log.info("Object is: " + object);
+            
+            if (object instanceof MessageRequest)
+            {
+               MessageRequest request = (MessageRequest)object;
+               
+               //Need to reference the message
+               MessageReference ref = null;
+               try
+               {
+                  ref = ms.reference(request.getMessage());
+                  
+                  log.info("Routing it internally");
+                  routeFromCluster(ref, request.getRoutingKey());
+               }
+               finally
+               {
+                  if (ref != null)
+                  {
+                     ref.releaseMemoryReference();
+                  }
+               }
+            }
+         }
+         catch (Exception e)
+         {
+            log.error("Failed to route from cluster", e);
+            //TODO should we propagate exceptions up?
+         }
+         
+      }
+      
+      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 should we propagate the exceptions up??
+         
+         //TODO handle deserialization more efficiently
+         
+         Object request = message.getObject();
+         
+         log.info("Received request: " + request);
+         
+         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)
+            {
+               log.error("Failed to add binding from cluster", e);
+            }
+         }
+         else if (request instanceof UnbindRequest)
+         {
+            UnbindRequest ubr = (UnbindRequest)request;
+            
+            try
+            {
+               removeBindingFromCluster(ubr.getNodeId(), ubr.getQueueName());
+            }
+            catch (Exception e)
+            {
+               log.error("Failed to remove binding from cluster", e);
+            }
+         }
+         else
+         {
+            throw new IllegalArgumentException("Invalid request: " + request);
+         }
+            
+         return null;
+      }
+      
+   }   
+}
\ No newline at end of file

Added: trunk/src/main/org/jboss/messaging/core/plugin/exchange/ClusteredTopicExchange.java
===================================================================
--- trunk/src/main/org/jboss/messaging/core/plugin/exchange/ClusteredTopicExchange.java	2006-08-30 09:26:13 UTC (rev 1236)
+++ trunk/src/main/org/jboss/messaging/core/plugin/exchange/ClusteredTopicExchange.java	2006-08-30 18:36:36 UTC (rev 1237)
@@ -0,0 +1,364 @@
+/*
+ * 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);
+                  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, so we route the message as an unreliable message
+                     //to prevent it being persisted again
+                     if (ref.isReliable() && binding.isDurable())
+                     {
+                        ref.setReliable(false);
+                     }
+                     
+                     //It's a local binding so we pass the message on to the subscription
+                     MessageQueue subscription = binding.getQueue();
+                  
+                     subscription.handle(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;
+      
+      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/DirectExchange.java
===================================================================
--- trunk/src/main/org/jboss/messaging/core/plugin/exchange/DirectExchange.java	2006-08-30 09:26:13 UTC (rev 1236)
+++ trunk/src/main/org/jboss/messaging/core/plugin/exchange/DirectExchange.java	2006-08-30 18:36:36 UTC (rev 1237)
@@ -0,0 +1,137 @@
+/*
+ * 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.Map;
+
+import javax.sql.DataSource;
+import javax.transaction.TransactionManager;
+
+import org.jboss.jms.server.QueuedExecutorPool;
+import org.jboss.messaging.core.Delivery;
+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.tx.Transaction;
+
+/**
+ * A DirectExchange
+ * 
+ * A direct exchange routes messages directly to a queue if the routing key matches the
+ * queue name
+ * 
+ * This type of exchange is used for routing to point to point queues.
+ * 
+ * @author <a href="mailto:tim.fox at jboss.com">Tim Fox</a>
+ * @version <tt>$Revision: 1.1 $</tt>
+ *
+ * $Id$
+ *
+ */
+public class DirectExchange extends ExchangeSupport
+{
+   //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;
+   
+   public DirectExchange() throws Exception
+   {      
+   }
+   
+   /*
+    * This constructor should only be used for testing
+    */
+   public DirectExchange(DataSource ds, TransactionManager tm)
+   {
+      super(ds, tm);
+   }
+      
+   /*
+    * Direct exchanges aren't clustered
+    *
+    */
+   public void injectAttributes(String exchangeName, String nodeID,
+                                MessageStore ms, IdManager im, QueuedExecutorPool pool) throws Exception
+   {
+      super.injectAttributes(exchangeName, nodeID, ms, im, pool);
+   }
+   
+   public boolean route(MessageReference ref, String routingKey, Transaction tx) throws Exception
+   {    
+      if (ref == null)
+      {
+         throw new IllegalArgumentException("Reference is null");
+      }
+      
+      if (routingKey == null)
+      {
+         throw new IllegalArgumentException("Routing key is null");
+      }
+      
+      lock.readLock().acquire();
+      
+      try
+      {         
+         //We just route based on the name
+         if (shortcutNameMap == null)
+         {
+            shortcutNameMap = (Map)nameMaps.get(nodeId);
+         }
+         
+         Binding binding = null;
+                  
+         if (shortcutNameMap != null)
+         {
+            binding = (Binding)shortcutNameMap.get(routingKey);
+         }
+         
+         if (binding == null)
+         {
+            //No mapping
+            return false;
+         }
+         
+         Delivery del = null;
+         
+         if (binding.isActive())
+         {         
+            MessageQueue queue = binding.getQueue();            
+         
+            del = queue.handle(null, ref, tx);
+         }
+         
+         if (del == null || !del.isDone())
+         {
+            return false;
+         }
+         else
+         {
+            return true;
+         }
+      }
+      finally
+      {
+         lock.readLock().release();
+      }
+   }
+}

Added: trunk/src/main/org/jboss/messaging/core/plugin/exchange/ExchangeSupport.java
===================================================================
--- trunk/src/main/org/jboss/messaging/core/plugin/exchange/ExchangeSupport.java	2006-08-30 09:26:13 UTC (rev 1236)
+++ trunk/src/main/org/jboss/messaging/core/plugin/exchange/ExchangeSupport.java	2006-08-30 18:36:36 UTC (rev 1237)
@@ -0,0 +1,685 @@
+/*
+ * 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.sql.Connection;
+import java.sql.PreparedStatement;
+import java.sql.ResultSet;
+import java.util.ArrayList;
+import java.util.Collections;
+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.selector.Selector;
+import org.jboss.jms.server.QueuedExecutorPool;
+import org.jboss.logging.Logger;
+import org.jboss.messaging.core.Filter;
+import org.jboss.messaging.core.local.MessageQueue;
+import org.jboss.messaging.core.plugin.IdManager;
+import org.jboss.messaging.core.plugin.JDBCServiceSupport;
+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 EDU.oswego.cs.dl.util.concurrent.QueuedExecutor;
+import EDU.oswego.cs.dl.util.concurrent.ReadWriteLock;
+import EDU.oswego.cs.dl.util.concurrent.WriterPreferenceReadWriteLock;
+
+/**
+ * 
+ * A ExchangeSupport
+
+ * @author <a href="mailto:tim.fox at jboss.com">Tim Fox</a>
+ * @version <tt>$Revision: 1.1 $</tt>
+ *
+ * $Id$
+ *
+ */
+public abstract class ExchangeSupport extends JDBCServiceSupport implements Exchange
+{
+   private static final Logger log = Logger.getLogger(ExchangeSupport.class);
+           
+   private String exchangeName;
+   
+   private QueuedExecutorPool queuedExecutorPool;
+   
+   private IdManager idManager;
+   
+   protected ReadWriteLock lock;
+   
+   protected MessageStore ms;     
+   
+   protected String nodeId;
+   
+   //Map <node id, Map < queue name, binding > >
+   protected Map nameMaps;
+   
+   //Map <condition, List <binding> >
+   protected Map conditionMap;
+   
+   public ExchangeSupport() throws Exception
+   { 
+      init();
+   }     
+   
+   /*
+    * This constructor should only be used for testing
+    */
+   protected ExchangeSupport(DataSource ds, TransactionManager tm)
+   {
+      super(ds, tm);  
+      
+      init();
+   }
+   
+   protected void injectAttributes(String exchangeName, String nodeID,
+                                   MessageStore ms, IdManager im, QueuedExecutorPool pool)
+      throws Exception
+   {
+            
+      this.exchangeName = exchangeName;
+      
+      this.nodeId = nodeID;
+      
+      this.ms = ms;
+      
+      this.idManager = im;
+      
+      this.queuedExecutorPool = pool;            
+   }
+   
+   // ServiceMBeanSupport overrides ---------------------------------
+   
+   protected void startService() throws Exception
+   {
+      super.startService();
+      
+      log.info(this + " starting");
+      
+      loadBindings();
+   }
+   
+   // 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
+   {
+
+      if (queueName == null)
+      {
+         throw new IllegalArgumentException("Queue name is null");
+      }
+      
+      if (condition == null)
+      {
+         throw new IllegalArgumentException("Condition is null");
+      }
+      
+      lock.writeLock().acquire();
+      
+      try
+      {         
+         //We currently only allow one binding per name per node
+         Map nameMap = (Map)nameMaps.get(this.nodeId);
+         
+         Binding binding = null;
+         
+         if (nameMap != null)
+         {
+            binding = (Binding)nameMap.get(queueName);
+         }
+         
+         if (binding != null)
+         {
+            throw new Exception("Binding already exists for name " + queueName);
+         }
+         
+         long id = idManager.getId();         
+         
+         //Create the message queue
+         MessageQueue queue = new MessageQueue(id, ms, pm, 
+                                               true, durable,
+                                               fullSize, pageSize, downCacheSize,
+                                               (QueuedExecutor)queuedExecutorPool.get(),
+                                               filter);
+            
+         binding = new SimpleBinding(nodeId, queueName, condition, filter == null ? null : filter.getFilterString(),
+                                     noLocal, queue.getChannelID(), durable);         
+         
+         binding.setQueue(queue);
+         
+         binding.activate();
+         
+         if (durable)
+         {
+            queue.load();
+         }
+         
+         addBinding(binding);
+               
+         if (durable)
+         {
+            //Need to write the binding to the db
+            
+            insertBinding(binding);            
+         }
+                           
+         return binding;   
+      }
+      finally
+      {
+         lock.writeLock().release();
+      }
+   }
+      
+   public Binding unbindQueue(String queueName) throws Throwable
+   {
+      if (queueName == null)
+      {
+         throw new IllegalArgumentException("Queue name is null");
+      }
+      
+      lock.writeLock().acquire();
+      
+      try
+      {         
+         Map nameMap = (Map)nameMaps.get(this.nodeId);
+         
+         Binding binding = null;
+         
+         if (nameMap != null)
+         {
+            binding = (Binding)nameMap.remove(queueName);
+         }
+         
+         if (binding == null)
+         {
+            throw new IllegalStateException("Name map does not contain binding for " + queueName);
+         }
+         
+         if (binding.getQueue() == null)
+         {
+            throw new IllegalStateException("Need to reload the queue before unbinding");
+         }
+         
+         List bindings = (List)conditionMap.get(binding.getCondition());
+         
+         if (bindings == null)
+         {
+            throw new IllegalStateException("Cannot find condition bindings for " + binding.getCondition());
+         }
+         
+         boolean removed = bindings.remove(binding);
+         
+         if (!removed)
+         {
+            throw new IllegalStateException("Cannot find binding in condition binding list");
+         }
+         
+         if (binding == null)
+         {
+            throw new IllegalStateException("Channel id map does not contain binding for " + binding.getChannelId());
+         }
+         
+         if (!removed)
+         {
+            throw new IllegalStateException("Cannot find binding in condition binding list");
+         }
+         
+         if (bindings.isEmpty())
+         {
+            conditionMap.remove(binding.getCondition());
+         }
+      
+         if (binding.isDurable())
+         {
+            //Need to remove from db too
+            
+            deleteBinding(binding.getQueueName());                        
+         }
+         
+         binding.getQueue().removeAllReferences();
+         
+         return binding;     
+      }
+      finally
+      {
+         lock.writeLock().release();
+      }
+   }
+   
+   
+   public void reloadQueues(String wildcard,
+                            MessageStore ms, PersistenceManager pm,
+                            int fullSize, int pageSize, int downCacheSize) throws Exception
+   {
+      if (wildcard == null)
+      {
+         throw new IllegalArgumentException("Wildcard is null");
+      }
+        
+      lock.writeLock().acquire();
+      
+      try
+      {
+         //We deploy the queues of any bindings whose condition matches the wildcard
+         //And we activate the bindings
+         
+         List matches = listMatchingBindings(wildcard);
+         
+         Iterator iter = matches.iterator();
+         
+         while (iter.hasNext())
+         {           
+            Binding binding = (Binding)iter.next();
+            
+            if (binding.isActive())
+            {
+               //Already active - do nothing
+            }
+            else
+            {
+               long id = binding.getChannelId();
+                              
+               QueuedExecutor executor = (QueuedExecutor)queuedExecutorPool.get();
+               
+               Filter filter = createFilter(binding.getSelector());
+               
+               //Now create the queue
+               MessageQueue queue = new MessageQueue(id, ms, pm, true, binding.isDurable(),
+                                                     fullSize, pageSize, downCacheSize, executor, filter);
+               
+               if (binding.isDurable())
+               {
+                  queue.load();
+               }
+               
+               binding.setQueue(queue);    
+               
+               //Activate it
+               binding.activate();               
+            }            
+         }      
+      }
+      finally
+      {
+         lock.writeLock().release();
+      }      
+   }
+        
+   public void unloadQueues(String wildcard) throws Exception
+   {
+      if (wildcard == null)
+      {
+         throw new IllegalArgumentException("Wildcard is null");
+      }
+      
+      lock.writeLock().acquire();
+      
+      try
+      {
+         List matches = listMatchingBindings(wildcard);
+         
+         //We undeploy the queues of any bindings whose condition matches the wildcard    
+         //And also deactivate the binding
+         Iterator iter = matches.iterator();
+         
+         while (iter.hasNext())
+         {
+            Binding binding = (Binding)iter.next();
+               
+            if (binding.isActive())
+            {
+               //deactivate it
+               binding.deactivate();
+               
+               //unload the queue from memory
+               binding.setQueue(null);              
+            }
+            else
+            {
+               //Already deactivated - do nothing
+            }            
+         }      
+      }
+      finally
+      {
+         lock.writeLock().release();
+      }      
+   }
+   
+   
+   public List listBindingsForWildcard(String wildcard) throws Exception
+   {
+      if (wildcard == null)
+      {
+         throw new IllegalArgumentException("Wildcard is null");
+      }
+      
+      lock.writeLock().acquire();
+      
+      try
+      {
+         return listMatchingBindings(wildcard);
+      }
+      finally
+      {
+         lock.writeLock().release();
+      }
+   }
+   
+   public Binding getBindingForName(String queueName) throws Exception
+   {    
+      if (queueName == null)
+      {
+         throw new IllegalArgumentException("Queue name is null");
+      }
+      
+      lock.writeLock().acquire();
+      
+      try
+      {
+         Map nameMap = (Map)nameMaps.get(this.nodeId);
+         
+         Binding binding = null;
+         
+         if (nameMap != null)
+         {
+            binding = (Binding)nameMap.get(queueName);
+         }
+         
+         return binding;
+      }
+      finally
+      {
+         lock.writeLock().release();
+      }
+   }
+     
+   // Protected -----------------------------------------------------
+   
+   protected void loadBindings() throws Exception
+   {
+      lock.writeLock().acquire();
+      
+      try
+      {
+         List list = getBindings();
+         
+         Iterator iter = list.iterator();
+         
+         while (iter.hasNext())
+         {
+            Binding binding = (Binding)iter.next();
+            
+            addBinding(binding);                        
+         }
+      }
+      finally
+      {
+         lock.writeLock().release();
+      }
+   }
+   
+   
+   
+   protected void insertBinding(Binding binding) throws Exception
+   {
+      Connection conn = null;
+      PreparedStatement ps  = null;     
+      TransactionWrapper wrap = new TransactionWrapper();
+      
+      try
+      {
+         conn = ds.getConnection();
+         
+         ps = conn.prepareStatement(getSQLStatement("INSERT_BINDING"));
+          
+         ps.setString(1, this.exchangeName);
+         ps.setString(2, this.nodeId);
+         ps.setString(3, binding.getQueueName());
+         ps.setString(4, binding.getCondition());         
+         ps.setString(5, binding.getSelector());
+         ps.setString(6, binding.isNoLocal() ? "Y" : "N");
+         ps.setLong(7, binding.getChannelId());
+
+         ps.executeUpdate();;
+      }
+      finally
+      {
+         if (ps != null)
+         {
+            ps.close();
+         }
+         if (conn != null)
+         {
+            conn.close();
+         }
+         wrap.end();
+      }     
+   }
+   
+   protected boolean deleteBinding(String queueName) throws Exception
+   {
+      Connection conn = null;
+      PreparedStatement ps  = null;
+      TransactionWrapper wrap = new TransactionWrapper();
+      
+      try
+      {
+         conn = ds.getConnection();
+
+         ps = conn.prepareStatement(getSQLStatement("DELETE_BINDING"));
+         
+         ps.setString(1, this.exchangeName);
+         ps.setString(2, this.nodeId);
+         ps.setString(3, queueName);
+
+         int rows = ps.executeUpdate();
+         
+         return rows == 1;
+      }
+      finally
+      {
+         if (ps != null)
+         {
+            ps.close();
+         }
+         if (conn != null)
+         {
+            conn.close();
+         }
+         wrap.end();
+      }     
+   }
+
+   /*
+    * Note that we get all bindings irrespective of which node this represents.
+    * This is because persistent messages are always persisted in durable subscriptions on
+    * 
+    */
+   protected List getBindings() throws Exception
+   {
+      Connection conn = null;
+      PreparedStatement ps  = null;
+      ResultSet rs = null;
+      TransactionWrapper wrap = new TransactionWrapper();
+      
+      List list = new ArrayList();
+      
+      try
+      {
+         conn = ds.getConnection();
+         
+         ps = conn.prepareStatement(this.getSQLStatement("LOAD_BINDINGS"));
+         
+         ps.setString(1, this.exchangeName);
+
+         rs = ps.executeQuery();
+              
+         while (rs.next())
+         {
+            String nodeId = rs.getString(1);
+            
+            String queueName = rs.getString(2);
+            
+            String condition = rs.getString(3);
+            
+            String selector = rs.getString(4);
+            
+            boolean noLocal = rs.getString(5).equals("Y");
+            
+            long channelId = rs.getLong(6);
+              
+            //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);
+            
+            list.add(binding);
+         }
+             
+         return list;
+      }
+      finally
+      {
+         if (rs != null)
+         {
+            rs.close();
+         }
+         if (ps != null)
+         {
+            ps.close();
+         }
+         if (conn != null)
+         {
+            conn.close();
+         }
+         wrap.end();
+      }     
+   }
+   
+   protected void addBinding(Binding binding)
+   {
+      Map nameMap = (Map)nameMaps.get(this.nodeId);
+      
+      if (nameMap == null)
+      {
+         nameMap = new HashMap();
+         
+         nameMaps.put(this.nodeId, nameMap);
+      }
+      
+      nameMap.put(binding.getQueueName(), binding);
+      
+      String condition = binding.getCondition();
+            
+      List bindings = (List)conditionMap.get(condition);
+      
+      if (bindings == null)
+      {
+         bindings = new ArrayList();
+         
+         conditionMap.put(condition, bindings);
+      }
+      
+      bindings.add(binding);
+   }   
+   
+   // PersistentServiceSupport overrides ----------------------------
+   
+   protected Map getDefaultDMLStatements()
+   {                
+      Map map = new HashMap();
+      map.put("INSERT_BINDING",
+               "INSERT INTO JMS_EXCHANGE_BINDING (EXCHANGE_NAME, NODE_ID, QUEUE_NAME, CONDITION, SELECTOR, NOLOCAL, CHANNEL_ID) " +
+               "VALUES (?, ?, ?, ?, ?, ?, ?)");
+      map.put("DELETE_BINDING",
+              "DELETE FROM JMS_EXCHANGE_BINDING WHERE EXCHANGE_NAME=? AND NODE_ID=? AND QUEUE_NAME=?");
+      map.put("LOAD_BINDINGS",
+              "SELECT NODE_ID, QUEUE_NAME, CONDITION, SELECTOR, NOLOCAL, CHANNEL_ID FROM JMS_EXCHANGE_BINDING " +
+              "WHERE EXCHANGE_NAME  = ?");
+      return map;
+   }
+   
+   protected Map getDefaultDDLStatements()
+   {
+      Map map = new HashMap();
+      map.put("CREATE_BINDING_TABLE",
+              "CREATE TABLE JMS_EXCHANGE_BINDING (EXCHANGE_NAME VARCHAR(256), NODE_ID VARCHAR(256)," +
+              "QUEUE_NAME VARCHAR(1024), CONDITION VARCHAR(1024), " +
+              "SELECTOR VARCHAR(1024), NOLOCAL CHAR(1), CHANNEL_ID BIGINT)");
+      return map;
+   }
+          
+   // Private -------------------------------------------------------
+              
+   private Filter createFilter(String selector) throws Exception
+   {
+      //We should abstract this somehow so we don't have this dependency on the jms selector
+      
+      if (selector == null)
+      {
+         return null;
+      }
+      else
+      {
+         return new Selector(selector);
+      }
+   }
+   
+   /*
+    * List all bindings whose condition matches the wildcard
+    * Initially we just do an exact match - when we support topic hierarchies this
+    * will change
+    */
+   private List listMatchingBindings(String wildcard)
+   {      
+      List list = (List)conditionMap.get(wildcard);
+      
+      if (list == null)
+      {
+         return Collections.EMPTY_LIST;
+      }
+      else
+      {
+         return list;
+      }
+   }
+   
+   private void init()
+   {
+      lock = new WriterPreferenceReadWriteLock();
+      
+      nameMaps = new HashMap();
+       
+      conditionMap = new HashMap();   
+   }
+                  
+   // Inner classes -------------------------------------------------            
+}

Added: trunk/src/main/org/jboss/messaging/core/plugin/exchange/SimpleBinding.java
===================================================================
--- trunk/src/main/org/jboss/messaging/core/plugin/exchange/SimpleBinding.java	2006-08-30 09:26:13 UTC (rev 1236)
+++ trunk/src/main/org/jboss/messaging/core/plugin/exchange/SimpleBinding.java	2006-08-30 18:36:36 UTC (rev 1237)
@@ -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 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();
+      }
+   }
+   
+}

Added: trunk/src/main/org/jboss/messaging/core/plugin/exchange/TopicExchange.java
===================================================================
--- trunk/src/main/org/jboss/messaging/core/plugin/exchange/TopicExchange.java	2006-08-30 09:26:13 UTC (rev 1236)
+++ trunk/src/main/org/jboss/messaging/core/plugin/exchange/TopicExchange.java	2006-08-30 18:36:36 UTC (rev 1237)
@@ -0,0 +1,134 @@
+/*
+ * 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.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.tx.Transaction;
+import org.jboss.messaging.core.tx.TransactionRepository;
+
+/**
+ * A non-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 TopicExchange extends ExchangeSupport
+{
+   private static final Logger log = Logger.getLogger(ClusteredTopicExchange.class);
+   
+   protected TransactionRepository tr;   
+      
+   public TopicExchange() throws Exception
+   { 
+   }      
+   
+   /*
+    * This constructor should only be used for testing
+    */
+   public TopicExchange(DataSource ds, TransactionManager tm)
+   {
+      super(ds, tm);
+   }
+   
+   /*
+    * Clustered Topic exchange
+    */
+   public void injectAttributes(String exchangeName, String nodeID,
+                                MessageStore ms, IdManager im, QueuedExecutorPool pool,
+                                TransactionRepository tr) throws Exception
+   {
+      super.injectAttributes(exchangeName, nodeID, ms, im, pool);
+      
+      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
+      {                 
+         log.info("Routing message with key: " + routingKey);
+         
+         //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() && 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);                  
+               }               
+            }                        
+         }
+      }
+      finally
+      {                  
+         lock.readLock().release();
+      }
+         
+      // We don't care if the individual subscriptions accepted the reference
+      return true; 
+   }      
+}

Added: trunk/src/main/org/jboss/messaging/core/plugin/exchange/request/BindRequest.java
===================================================================
--- trunk/src/main/org/jboss/messaging/core/plugin/exchange/request/BindRequest.java	2006-08-30 09:26:13 UTC (rev 1236)
+++ trunk/src/main/org/jboss/messaging/core/plugin/exchange/request/BindRequest.java	2006-08-30 18:36:36 UTC (rev 1237)
@@ -0,0 +1,93 @@
+/*
+ * 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.request;
+
+import java.io.Serializable;
+
+/**
+ * A BindRequest
+ *
+ * @author <a href="mailto:tim.fox at jboss.com">Tim Fox</a>
+ * @version <tt>$Revision: 1.1 $</tt>
+ *
+ * $Id$
+ *
+ */
+public class BindRequest implements Serializable
+{
+   private static final long serialVersionUID = 6567558817192367353L;
+
+   private String nodeId;   
+   private String queueName;   
+   private String condition;   
+   private String filterString;   
+   private boolean noLocal;   
+   private long channelId;   
+   private boolean durable;
+   
+   public 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 String getCondition()
+   {
+      return condition;
+   }
+
+   public boolean isDurable()
+   {
+      return durable;
+   }
+
+   public String getFilterString()
+   {
+      return filterString;
+   }
+
+   public String getNodeId()
+   {
+      return nodeId;
+   }
+
+   public boolean isNoLocal()
+   {
+      return noLocal;
+   }
+
+   public String getQueueName()
+   {
+      return queueName;
+   }
+   
+   public long getChannelId()
+   {
+      return channelId;
+   }
+}

Added: trunk/src/main/org/jboss/messaging/core/plugin/exchange/request/MessageRequest.java
===================================================================
--- trunk/src/main/org/jboss/messaging/core/plugin/exchange/request/MessageRequest.java	2006-08-30 09:26:13 UTC (rev 1236)
+++ trunk/src/main/org/jboss/messaging/core/plugin/exchange/request/MessageRequest.java	2006-08-30 18:36:36 UTC (rev 1237)
@@ -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.request;
+
+import java.io.Serializable;
+
+import org.jboss.messaging.core.Message;
+
+/**
+ * A MessageRequest
+ *
+ * @author <a href="mailto:tim.fox at jboss.com">Tim Fox</a>
+ * @version <tt>$Revision: 1.1 $</tt>
+ *
+ * $Id$
+ *
+ */
+public class MessageRequest implements Serializable
+{
+   private static final long serialVersionUID = 644500948910063649L;
+
+   private String routingKey;   
+   private Message message;
+   
+   public MessageRequest(String routingKey, Message message)
+   {
+      this.routingKey = routingKey;
+      
+      this.message = message;
+   }
+   
+   public String getRoutingKey()
+   {
+      return routingKey;
+   }
+   
+   public Message getMessage()
+   {
+      return message;
+   }
+
+}

Added: trunk/src/main/org/jboss/messaging/core/plugin/exchange/request/UnbindRequest.java
===================================================================
--- trunk/src/main/org/jboss/messaging/core/plugin/exchange/request/UnbindRequest.java	2006-08-30 09:26:13 UTC (rev 1236)
+++ trunk/src/main/org/jboss/messaging/core/plugin/exchange/request/UnbindRequest.java	2006-08-30 18:36:36 UTC (rev 1237)
@@ -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.request;
+
+import java.io.Serializable;
+
+/**
+ * A UnbindRequest
+ *
+ * @author <a href="mailto:tim.fox at jboss.com">Tim Fox</a>
+ * @version <tt>$Revision: 1.1 $</tt>
+ *
+ * $Id$
+ *
+ */
+public class UnbindRequest implements Serializable
+{
+   private static final long serialVersionUID = 6597644036507360965L;
+
+   private String nodeId;   
+   private String queueName;
+
+   public UnbindRequest(String nodeId, String queueName)
+   {
+      this.nodeId = nodeId;
+      this.queueName = queueName;
+   }
+
+   public String getNodeId()
+   {
+      return nodeId;
+   }
+
+   public String getQueueName()
+   {
+      return queueName;
+   }      
+}

Modified: trunk/src/main/org/jboss/messaging/core/tx/TransactionRepository.java
===================================================================
--- trunk/src/main/org/jboss/messaging/core/tx/TransactionRepository.java	2006-08-30 09:26:13 UTC (rev 1236)
+++ trunk/src/main/org/jboss/messaging/core/tx/TransactionRepository.java	2006-08-30 18:36:36 UTC (rev 1237)
@@ -69,19 +69,14 @@
    }
    
    // Public --------------------------------------------------------
-
-   public void start(PersistenceManager persistenceManager) throws Exception
+   
+   public void injectAttributes(PersistenceManager persistenceManager, IdManager idManager)
    {
       this.persistenceManager = persistenceManager;
       
-      //TODO make this configurable
-      idManager = new IdManager("TRANSACTION_ID", 4096, persistenceManager);
+      this.idManager = idManager;
    }
 
-   public void stop() throws Exception
-   {
-   }
-
    public List getPreparedTransactions()
    {
       ArrayList prepared = new ArrayList();

Modified: trunk/src/main/org/jboss/messaging/core/tx/XidImpl.java
===================================================================
--- trunk/src/main/org/jboss/messaging/core/tx/XidImpl.java	2006-08-30 09:26:13 UTC (rev 1236)
+++ trunk/src/main/org/jboss/messaging/core/tx/XidImpl.java	2006-08-30 18:36:36 UTC (rev 1237)
@@ -29,6 +29,7 @@
  * 
  * Xid implementation
  * 
+ * @author <a href="mailto:adrian at jboss.org>Adrian Brock</a>
  * @author <a href="mailto:tim.fox at jboss.com">Tim Fox</a>
  * 
  * @version $Revision 1.1 $

Deleted: trunk/src/main/org/jboss/messaging/core/util/ConcurrentHashSet.java
===================================================================
--- trunk/src/main/org/jboss/messaging/core/util/ConcurrentHashSet.java	2006-08-30 09:26:13 UTC (rev 1236)
+++ trunk/src/main/org/jboss/messaging/core/util/ConcurrentHashSet.java	2006-08-30 18:36:36 UTC (rev 1237)
@@ -1,87 +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.util;
-
-import java.util.AbstractSet;
-import java.util.Iterator;
-import java.util.Map;
-
-import EDU.oswego.cs.dl.util.concurrent.ConcurrentHashMap;
-
-/**
- * 
- * A ConcurrentHashSet.
- * 
- * Offers same concurrency as ConcurrentHashMap but for a Set
- * 
- * @author <a href="tim.fox at jboss.com">Tim Fox</a>
- * @version $Revision$
- *
- * $Id$
- */
-public class ConcurrentHashSet extends AbstractSet
-{
-   private Map theMap;
-   
-   private static Object dummy = new Object();
-   
-   public ConcurrentHashSet()
-   {
-      theMap = new ConcurrentHashMap();
-   }
-   
-   public int size()
-   {
-      return theMap.size();
-   }
-   
-   public Iterator iterator()
-   {
-      return theMap.keySet().iterator();
-   }
-   
-   public boolean isEmpty()
-   {
-      return theMap.isEmpty();
-   }
-   
-   public boolean add(Object o)
-   {
-      return theMap.put(o, dummy) == dummy;
-   }
-   
-   public boolean contains(Object o)
-   {
-      return theMap.containsKey(o);
-   }
-   
-   public void clear()
-   {
-      theMap.clear();
-   }
-   
-   public boolean remove(Object o)
-   {
-      return theMap.remove(o) == dummy;
-   }
-
-}

Deleted: trunk/src/main/org/jboss/messaging/core/util/ConcurrentReaderHashSet.java
===================================================================
--- trunk/src/main/org/jboss/messaging/core/util/ConcurrentReaderHashSet.java	2006-08-30 09:26:13 UTC (rev 1236)
+++ trunk/src/main/org/jboss/messaging/core/util/ConcurrentReaderHashSet.java	2006-08-30 18:36:36 UTC (rev 1237)
@@ -1,87 +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.util;
-
-import java.util.AbstractSet;
-import java.util.Iterator;
-import java.util.Map;
-
-import EDU.oswego.cs.dl.util.concurrent.ConcurrentReaderHashMap;
-
-/**
- * 
- * A ConcurrentReaderHashSet.
- * 
- * Offers same concurrency as ConcurrentHashMap but for a Set
- * 
- * @author <a href="tim.fox at jboss.com">Tim Fox</a>
- * @version 1.1
- *
- * ConcurrentReaderHashSet.java,v 1.1 2006/04/20 20:42:27 timfox Exp
- */
-public class ConcurrentReaderHashSet extends AbstractSet
-{
-   private Map theMap;
-   
-   private static Object dummy = new Object();
-   
-   public ConcurrentReaderHashSet()
-   {
-      theMap = new ConcurrentReaderHashMap();
-   }
-   
-   public int size()
-   {
-      return theMap.size();
-   }
-   
-   public Iterator iterator()
-   {
-      return theMap.keySet().iterator();
-   }
-   
-   public boolean isEmpty()
-   {
-      return theMap.isEmpty();
-   }
-   
-   public boolean add(Object o)
-   {
-      return theMap.put(o, dummy) == dummy;
-   }
-   
-   public boolean contains(Object o)
-   {
-      return theMap.containsKey(o);
-   }
-   
-   public void clear()
-   {
-      theMap.clear();
-   }
-   
-   public boolean remove(Object o)
-   {
-      return theMap.remove(o) == dummy;
-   }
-
-}

Deleted: trunk/src/main/org/jboss/messaging/core/util/Lockable.java
===================================================================
--- trunk/src/main/org/jboss/messaging/core/util/Lockable.java	2006-08-30 09:26:13 UTC (rev 1236)
+++ trunk/src/main/org/jboss/messaging/core/util/Lockable.java	2006-08-30 18:36:36 UTC (rev 1237)
@@ -1,109 +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.util;
-
-import EDU.oswego.cs.dl.util.concurrent.ReentrantLock;
-import org.jboss.logging.Logger;
-
-/**
- * A simple wrapper around a ReentrantLock that provides a locking mechanism to subclasses.
- *
- * @author <a href="mailto:ovidiu at jboss.org">Ovidiu Feodorov</a>
- * @version <tt>$Revision$</tt>
- */
-public class Lockable
-{
-   // Constants -----------------------------------------------------
-
-   private static final Logger log = Logger.getLogger(Lockable.class);
-
-   // Static --------------------------------------------------------
-   
-   // Attributes ----------------------------------------------------
-   
-   private ReentrantLock lock = new ReentrantLock();
-
-   // Constructors --------------------------------------------------
-
-   // Public --------------------------------------------------------
-
-   // Package protected ---------------------------------------------
-   
-   // Protected -----------------------------------------------------
-
-   /**
-    * The thread calling this method acquires a reentrant lock on the current instance. The method
-    * can wait forever if the lock is being hold by another thread and not released.
-    */
-   public final void lock()
-   {
-      while(true)
-      {
-         try
-         {
-            lock.acquire();
-            if (log.isTraceEnabled()) { log.trace("locked " + this); }
-            return;
-         }
-         catch(InterruptedException e)
-         {
-            log.warn("failed to acquire " + this + "'s lock", e);
-         }
-      }
-   }
-
-   /**
-    * The thread calling attempts to acquire the reentrant lock for the specified time.
-    * @return true if succesful.
-    */
-   public final boolean lock(long millisecs)
-   {
-      long t1 = System.currentTimeMillis();
-      while(true)
-      {
-         try
-         {
-            boolean locked = lock.attempt(millisecs - System.currentTimeMillis() + t1);
-            if (log.isTraceEnabled()) { log.trace((locked ? "locked " : "could not acquire lock on ") + this); }
-            return locked;
-         }
-         catch(InterruptedException e)
-         {
-            log.warn(e);
-         }
-      }
-   }
-
-
-   /**
-    * The thread calling it gives up the lock on the current instance, if any.
-    */
-   public final void unlock()
-   {
-      lock.release();
-      if (log.isTraceEnabled()) { log.trace("unlocked " + this); }
-   }
-
-   // Private -------------------------------------------------------
-   
-   // Inner classes -------------------------------------------------   
-}

Copied: trunk/src/main/org/jboss/messaging/util/ConcurrentHashSet.java (from rev 1223, trunk/src/main/org/jboss/messaging/core/util/ConcurrentHashSet.java)
===================================================================
--- trunk/src/main/org/jboss/messaging/core/util/ConcurrentHashSet.java	2006-08-10 19:04:47 UTC (rev 1223)
+++ trunk/src/main/org/jboss/messaging/util/ConcurrentHashSet.java	2006-08-30 18:36:36 UTC (rev 1237)
@@ -0,0 +1,87 @@
+/*
+  * 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.util;
+
+import java.util.AbstractSet;
+import java.util.Iterator;
+import java.util.Map;
+
+import EDU.oswego.cs.dl.util.concurrent.ConcurrentHashMap;
+
+/**
+ * 
+ * A ConcurrentHashSet.
+ * 
+ * Offers same concurrency as ConcurrentHashMap but for a Set
+ * 
+ * @author <a href="tim.fox at jboss.com">Tim Fox</a>
+ * @version $Revision$
+ *
+ * $Id$
+ */
+public class ConcurrentHashSet extends AbstractSet
+{
+   private Map theMap;
+   
+   private static Object dummy = new Object();
+   
+   public ConcurrentHashSet()
+   {
+      theMap = new ConcurrentHashMap();
+   }
+   
+   public int size()
+   {
+      return theMap.size();
+   }
+   
+   public Iterator iterator()
+   {
+      return theMap.keySet().iterator();
+   }
+   
+   public boolean isEmpty()
+   {
+      return theMap.isEmpty();
+   }
+   
+   public boolean add(Object o)
+   {
+      return theMap.put(o, dummy) == dummy;
+   }
+   
+   public boolean contains(Object o)
+   {
+      return theMap.containsKey(o);
+   }
+   
+   public void clear()
+   {
+      theMap.clear();
+   }
+   
+   public boolean remove(Object o)
+   {
+      return theMap.remove(o) == dummy;
+   }
+
+}

Copied: trunk/src/main/org/jboss/messaging/util/ConcurrentReaderHashSet.java (from rev 1223, trunk/src/main/org/jboss/messaging/core/util/ConcurrentReaderHashSet.java)
===================================================================
--- trunk/src/main/org/jboss/messaging/core/util/ConcurrentReaderHashSet.java	2006-08-10 19:04:47 UTC (rev 1223)
+++ trunk/src/main/org/jboss/messaging/util/ConcurrentReaderHashSet.java	2006-08-30 18:36:36 UTC (rev 1237)
@@ -0,0 +1,87 @@
+/*
+  * 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.util;
+
+import java.util.AbstractSet;
+import java.util.Iterator;
+import java.util.Map;
+
+import EDU.oswego.cs.dl.util.concurrent.ConcurrentReaderHashMap;
+
+/**
+ * 
+ * A ConcurrentReaderHashSet.
+ * 
+ * Offers same concurrency as ConcurrentHashMap but for a Set
+ * 
+ * @author <a href="tim.fox at jboss.com">Tim Fox</a>
+ * @version 1.1
+ *
+ * ConcurrentReaderHashSet.java,v 1.1 2006/04/20 20:42:27 timfox Exp
+ */
+public class ConcurrentReaderHashSet extends AbstractSet
+{
+   private Map theMap;
+   
+   private static Object dummy = new Object();
+   
+   public ConcurrentReaderHashSet()
+   {
+      theMap = new ConcurrentReaderHashMap();
+   }
+   
+   public int size()
+   {
+      return theMap.size();
+   }
+   
+   public Iterator iterator()
+   {
+      return theMap.keySet().iterator();
+   }
+   
+   public boolean isEmpty()
+   {
+      return theMap.isEmpty();
+   }
+   
+   public boolean add(Object o)
+   {
+      return theMap.put(o, dummy) == dummy;
+   }
+   
+   public boolean contains(Object o)
+   {
+      return theMap.containsKey(o);
+   }
+   
+   public void clear()
+   {
+      theMap.clear();
+   }
+   
+   public boolean remove(Object o)
+   {
+      return theMap.remove(o) == dummy;
+   }
+
+}

Copied: trunk/src/main/org/jboss/messaging/util/JDBCUtil.java (from rev 1223, trunk/src/main/org/jboss/messaging/core/persistence/JDBCUtil.java)
===================================================================
--- trunk/src/main/org/jboss/messaging/core/persistence/JDBCUtil.java	2006-08-10 19:04:47 UTC (rev 1223)
+++ trunk/src/main/org/jboss/messaging/util/JDBCUtil.java	2006-08-30 18:36:36 UTC (rev 1237)
@@ -0,0 +1,115 @@
+/*
+  * 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.util;
+
+/**
+ * @author <a href="mailto:ovidiu at jboss.org">Ovidiu Feodorov</a> 
+ * @version <tt>$Revision$</tt>
+ * $Id$
+ */
+public class JDBCUtil
+{
+   // Constants -----------------------------------------------------
+
+   // Static --------------------------------------------------------
+
+   public static String statementToString(String sql)
+   {
+      return sql;
+   }
+
+   public static String statementToString(String sql, Object arg1)
+   {
+      return statementToString(sql, new Object[] { arg1 });
+   }
+
+   public static String statementToString(String sql, Object arg1, Object arg2)
+   {
+      return statementToString(sql, new Object[] { arg1, arg2 });
+   }
+
+   public static String statementToString(String sql, Object arg1, Object arg2, Object arg3)
+   {
+      return statementToString(sql, new Object[] { arg1, arg2, arg3 });
+   }
+
+   public static String statementToString(String sql, Object arg1, Object arg2, Object arg3,
+                                          Object arg4)
+   {
+      return statementToString(sql, new Object[] { arg1, arg2, arg3, arg4 });
+   }
+
+   public static String statementToString(String sql, Object arg1, Object arg2, Object arg3,
+                                          Object arg4, Object arg5)
+   {
+      return statementToString(sql, new Object[] { arg1, arg2, arg3, arg4, arg5 });
+   }
+   
+   public static String statementToString(String sql, Object arg1, Object arg2, Object arg3,
+         Object arg4, Object arg5, Object arg6)
+   {
+      return statementToString(sql, new Object[] { arg1, arg2, arg3, arg4, arg5, arg6 });
+   }
+   
+   public static String statementToString(String sql, Object arg1, Object arg2, Object arg3,
+         Object arg4, Object arg5, Object arg6, Object arg7)
+   {
+      return statementToString(sql, new Object[] { arg1, arg2, arg3, arg4, arg5, arg6, arg7 });
+   }
+
+   public static String statementToString(String sql, Object[] args)
+   {
+      StringBuffer statement = new StringBuffer();
+      int i = 0, pos = 0, cnt = 0;
+      while((i = sql.indexOf('?', pos)) != -1)
+      {
+         statement.append(sql.substring(pos, i));
+         Object s = "?";
+         if (cnt < args.length)
+         {
+            s = args[cnt++];
+            if ("".equals(s))
+            {
+               s = "''";
+            }
+         }
+         statement.append(s);
+         pos = i + 1;
+      }
+      statement.append(sql.substring(pos));
+      return statement.toString();
+   }
+
+   // Attributes ----------------------------------------------------
+   
+   // Constructors --------------------------------------------------
+   
+   // Public --------------------------------------------------------
+
+   // Package protected ---------------------------------------------
+   
+   // Protected -----------------------------------------------------
+   
+   // Private -------------------------------------------------------
+   
+   // Inner classes -------------------------------------------------   
+}

Copied: trunk/src/main/org/jboss/messaging/util/Lockable.java (from rev 1223, trunk/src/main/org/jboss/messaging/core/util/Lockable.java)
===================================================================
--- trunk/src/main/org/jboss/messaging/core/util/Lockable.java	2006-08-10 19:04:47 UTC (rev 1223)
+++ trunk/src/main/org/jboss/messaging/util/Lockable.java	2006-08-30 18:36:36 UTC (rev 1237)
@@ -0,0 +1,109 @@
+/*
+  * 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.util;
+
+import EDU.oswego.cs.dl.util.concurrent.ReentrantLock;
+import org.jboss.logging.Logger;
+
+/**
+ * A simple wrapper around a ReentrantLock that provides a locking mechanism to subclasses.
+ *
+ * @author <a href="mailto:ovidiu at jboss.org">Ovidiu Feodorov</a>
+ * @version <tt>$Revision$</tt>
+ */
+public class Lockable
+{
+   // Constants -----------------------------------------------------
+
+   private static final Logger log = Logger.getLogger(Lockable.class);
+
+   // Static --------------------------------------------------------
+   
+   // Attributes ----------------------------------------------------
+   
+   private ReentrantLock lock = new ReentrantLock();
+
+   // Constructors --------------------------------------------------
+
+   // Public --------------------------------------------------------
+
+   // Package protected ---------------------------------------------
+   
+   // Protected -----------------------------------------------------
+
+   /**
+    * The thread calling this method acquires a reentrant lock on the current instance. The method
+    * can wait forever if the lock is being hold by another thread and not released.
+    */
+   public final void lock()
+   {
+      while(true)
+      {
+         try
+         {
+            lock.acquire();
+            if (log.isTraceEnabled()) { log.trace("locked " + this); }
+            return;
+         }
+         catch(InterruptedException e)
+         {
+            log.warn("failed to acquire " + this + "'s lock", e);
+         }
+      }
+   }
+
+   /**
+    * The thread calling attempts to acquire the reentrant lock for the specified time.
+    * @return true if succesful.
+    */
+   public final boolean lock(long millisecs)
+   {
+      long t1 = System.currentTimeMillis();
+      while(true)
+      {
+         try
+         {
+            boolean locked = lock.attempt(millisecs - System.currentTimeMillis() + t1);
+            if (log.isTraceEnabled()) { log.trace((locked ? "locked " : "could not acquire lock on ") + this); }
+            return locked;
+         }
+         catch(InterruptedException e)
+         {
+            log.warn(e);
+         }
+      }
+   }
+
+
+   /**
+    * The thread calling it gives up the lock on the current instance, if any.
+    */
+   public final void unlock()
+   {
+      lock.release();
+      if (log.isTraceEnabled()) { log.trace("unlocked " + this); }
+   }
+
+   // Private -------------------------------------------------------
+   
+   // Inner classes -------------------------------------------------   
+}

Modified: trunk/src/main/org/jboss/messaging/util/RotatingPool.java
===================================================================
--- trunk/src/main/org/jboss/messaging/util/RotatingPool.java	2006-08-30 09:26:13 UTC (rev 1236)
+++ trunk/src/main/org/jboss/messaging/util/RotatingPool.java	2006-08-30 18:36:36 UTC (rev 1237)
@@ -21,11 +21,7 @@
  */
 package org.jboss.messaging.util;
 
-import java.util.HashMap;
-import java.util.Map;
 
-import org.jboss.logging.Logger;
-
 /**
  * A RotatingPool
  * 
@@ -41,57 +37,40 @@
  */
 public abstract class RotatingPool
 {
-   private static final Logger log = Logger.getLogger(RotatingPool.class);
-   
    protected int maxSize;
    
    protected int pos;
    
    protected Object[] entries;
    
-   protected Map keyMappings;
-   
    public RotatingPool(int maxSize)
    { 
       this.maxSize = maxSize;
       
       this.entries = new Object[maxSize];
-      
-      this.keyMappings = new HashMap();
    }
    
-   public synchronized Object get(Object key)
+   public synchronized Object get()
    {    
-      //Does the mapping already exist?
-      Object entry = keyMappings.get(key);
+      Object entry = entries[pos];
       
       if (entry == null)
       {
-         //Create a new entry allocating from the rotating pool
-         entry = entries[pos];
+         entry = createEntry();
          
-         if (entry == null)
-         {
-            entry = createEntry();
-            
-            entries[pos] = entry;
-         }
-         
-         keyMappings.put(key, entry);
-         
-         pos++;
-         
-         if (pos == maxSize)
-         {
-            pos = 0;
-         }
+         entries[pos] = entry;
       }
+       
+      pos++;
       
+      if (pos == maxSize)
+      {
+         pos = 0;
+      }
+            
       return entry;
    }
    
-   
-   
-   protected abstract Object createEntry();
-   
+
+   protected abstract Object createEntry();   
 }

Added: trunk/src/main/org/jboss/messaging/util/SafeUTF.java
===================================================================
--- trunk/src/main/org/jboss/messaging/util/SafeUTF.java	2006-08-30 09:26:13 UTC (rev 1236)
+++ trunk/src/main/org/jboss/messaging/util/SafeUTF.java	2006-08-30 18:36:36 UTC (rev 1237)
@@ -0,0 +1,165 @@
+/*
+  * 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.util;
+
+import java.io.IOException;
+import java.io.ObjectInput;
+import java.io.ObjectOutput;
+
+/**
+ * 
+ * A SafeUTF
+ * 
+ * @author <a href="tim.fox at jboss.com">Tim Fox</a>
+ * @author <a href="mailto:adrian at jboss.org">Adrian Brock</a>
+ * @version $Revision: 1174 $
+ *
+ * $Id: SafeUTF.java 1174 2006-08-02 14:14:32Z timfox $
+ * 
+ * There is a "bug" in JDK1.4 / 1.5 DataOutputStream.writeUTF()
+ * which means it does not work with Strings >= 64K serialized size.
+ * See http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=4806007
+ * 
+ * We work around this by chunking larger strings into smaller pieces.
+ * 
+ * Note we only support TextMessage and ObjectMessage bodies with serialized length >= 64K
+ * We DO NOT support Strings written to BytesMessages or StreamMessages or written as keys or values
+ * in MapMessages, or as String properties or other String fields having serialized length >= 64K
+ * This is for performance reasons since there is an overhead in coping with large
+ * Strings
+ * 
+ */
+public class SafeUTF
+{      
+   //Default is 16K chunks
+   private static final int CHUNK_SIZE = 16 * 1024;
+   
+   private static final byte NULL = 0;
+   
+   private static final byte NOT_NULL = 1;
+   
+   public static SafeUTF instance = new SafeUTF(CHUNK_SIZE);
+   
+   private int chunkSize;
+   
+   private int lastReadBufferSize;
+   
+   public int getLastReadBufferSize()
+   {
+      return lastReadBufferSize;
+   }
+   
+   public SafeUTF(int chunkSize)
+   {
+      this.chunkSize = chunkSize;
+   }
+      
+   public void safeWriteUTF(ObjectOutput out, String str) throws IOException
+   {        
+      if (str == null)
+      {
+         out.writeByte(NULL);
+      }
+      else
+      {         
+         int len = str.length();
+          
+         short numChunks;
+         
+         if (len == 0)
+         {
+            numChunks = 0;
+         }
+         else
+         {
+            numChunks = (short)(((len - 1) / chunkSize) + 1);
+         }         
+         
+         out.writeByte(NOT_NULL);
+         
+         out.writeShort(numChunks);
+              
+         int i = 0;
+         while (len > 0)
+         {
+            int beginCopy = i * chunkSize;
+            
+            int endCopy = len <= chunkSize ? beginCopy + len : beginCopy + chunkSize;
+     
+            String theChunk = str.substring(beginCopy, endCopy);
+               
+            out.writeUTF(theChunk);
+            
+            len -= chunkSize;
+            
+            i++;
+         }
+      }
+   }
+   
+   public String safeReadUTF(ObjectInput in) throws IOException
+   {   
+      boolean isNull = in.readByte() == NULL;
+      
+      if (isNull)
+      {
+         return null;
+      }
+      
+      short numChunks = in.readShort();
+      
+      int bufferSize = chunkSize * numChunks;
+      
+      // special handling for single chunk
+      if (numChunks == 1)
+      {
+         // The text size is likely to be much smaller than the chunkSize
+         // so set bufferSize to the min of the input stream available
+         // and the maximum buffer size. Since the input stream
+         // available() can be <= 0 we check for that and default to
+         // a small msg size of 256 bytes.
+         
+         int inSize = in.available();
+               
+         if (inSize <= 0)
+         {
+            inSize = 256;
+         }
+
+         bufferSize = Math.min(inSize, bufferSize);
+         
+         lastReadBufferSize = bufferSize;
+      }
+        
+      StringBuffer buff = new StringBuffer(bufferSize);
+            
+      for (int i = 0; i < numChunks; i++)
+      {
+         String s = in.readUTF();
+
+         buff.append(s);
+      }
+      
+      return buff.toString();
+   }
+      
+}

Modified: trunk/tests/build.xml
===================================================================
--- trunk/tests/build.xml	2006-08-30 09:26:13 UTC (rev 1236)
+++ trunk/tests/build.xml	2006-08-30 18:36:36 UTC (rev 1237)
@@ -175,6 +175,8 @@
       <path refid="jboss.mbeans.classpath"/>
       <path refid="jboss.naming.classpath"/>
       <path refid="jboss.jbossxb.classpath"/>
+      <path refid="jgroups.jgroups.classpath"/>
+      <path refid="apache.logging.classpath"/>
       <path refid="mysql.jdbc.driver.classpath"/>
       <path refid="oracle.jdbc.driver.classpath"/>
       <path refid="postgres.jdbc.driver.classpath"/>

Modified: trunk/tests/src/org/jboss/test/messaging/MessagingTestCase.java
===================================================================
--- trunk/tests/src/org/jboss/test/messaging/MessagingTestCase.java	2006-08-30 09:26:13 UTC (rev 1236)
+++ trunk/tests/src/org/jboss/test/messaging/MessagingTestCase.java	2006-08-30 18:36:36 UTC (rev 1237)
@@ -29,16 +29,17 @@
 import javax.jms.Session;
 import javax.jms.Topic;
 
+import junit.framework.TestCase;
+
 import org.jboss.logging.Logger;
 import org.jboss.test.messaging.tools.ServerManagement;
 
-import junit.framework.TestCase;
-
 /**
  * The base case for messaging tests.
  *
  * @author <a href="mailto:adrian at jboss.org">Adrian Brock</a>
  * @author <a href="mailto:ovidiu at jboss.org">Ovidiu Feodorov</a>
+ * @author <a href="mailto:tim.fox at jboss.org">Tim Fox</a>
  * @version <tt>$Revision$</tt>
  * $Id$
  */

Deleted: trunk/tests/src/org/jboss/test/messaging/core/ChannelSupportTest.java
===================================================================
--- trunk/tests/src/org/jboss/test/messaging/core/ChannelSupportTest.java	2006-08-30 09:26:13 UTC (rev 1236)
+++ trunk/tests/src/org/jboss/test/messaging/core/ChannelSupportTest.java	2006-08-30 18:36:36 UTC (rev 1237)
@@ -1,633 +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.core;
-
-import org.jboss.test.messaging.MessagingTestCase;
-
-/**
- * @author <a href="mailto:ovidiu at jboss.org">Ovidiu Feodorov</a>
- * @version <tt>$Revision$</tt>
- */
-public class ChannelSupportTest extends MessagingTestCase
-{
-//   // Attributes ----------------------------------------------------
-//
-//   protected Channel channel;
-//   protected ReceiverImpl receiverOne;
-//
-   // Constructors --------------------------------------------------
-
-   public ChannelSupportTest(String name)
-   {
-      super(name);
-   }
-
-//   //
-//   // Test synchronous - asynchronous switch
-//   //
-//
-//   public void testSwitchFromAsynchToSynchWhenChannelNotEmpty()
-//   {
-//      if(skip()) { return; }
-//
-//      receiverOne.setState(ReceiverImpl.NACKING);
-//      assertTrue(channel.setSynchronous(false));
-//      assertTrue(channel.handle(new RoutableSupport("routableID")));
-//      assertTrue(channel.hasMessages());
-//      assertFalse(channel.setSynchronous(true));
-//      assertFalse(channel.isSynchronous());
-//   }
-//
-//   //
-//   // Test handle() on synchronous channel
-//   //
-//
-//   public void testSuccessfulSynchronousDeliverOnSynchronousChannel()
-//   {
-//      if(skip()) { return; }
-//
-//      receiverOne.setState(ReceiverImpl.HANDLING);
-//      assertTrue(channel.setSynchronous(true));
-//      assertTrue(channel.handle(new RoutableSupport("routableID")));
-//      assertFalse(channel.hasMessages());
-//      List l = receiverOne.getMessages();
-//      assertEquals(1, l.size());
-//      assertEquals("routableID", ((RoutableSupport)receiverOne.iterator().next()).getMessageID());
-//   }
-//
-//   public void testDenyingReceiverOnSynchronousChannel()
-//   {
-//      if(skip()) { return; }
-//
-//      receiverOne.setState(ReceiverImpl.NACKING);
-//      assertTrue(channel.setSynchronous(true));
-//      assertFalse(channel.handle(new RoutableSupport("routableID")));
-//      assertFalse(channel.hasMessages());
-//      List l = receiverOne.getMessages();
-//      assertEquals(0, l.size());
-//   }
-//
-//   public void testBrokenReceiverOnSynchronousChannel()
-//   {
-//      if(skip()) { return; }
-//
-//      receiverOne.setState(ReceiverImpl.BROKEN);
-//      assertTrue(channel.setSynchronous(true));
-//      assertFalse(channel.handle(new RoutableSupport("routableID")));
-//      assertFalse(channel.hasMessages());
-//      List l = receiverOne.getMessages();
-//      assertEquals(0, l.size());
-//   }
-//
-//
-//
-//   //
-//   // Test handle() on asynchronous channel - unreliable routable
-//   //
-//
-//   public void testSuccessfulSynchronousDeliverOnAsynchronousChannel_UnreliableRoutable()
-//         throws Exception
-//   {
-//      if(skip()) { return; }
-//
-//      receiverOne.setState(ReceiverImpl.HANDLING);
-//      assertTrue(channel.setSynchronous(false));
-//
-//      assertTrue(channel.handle(new RoutableSupport("routableID", false)));
-//
-//      // wait for the acknowledgment to arrive and store to clear - if it doesn't, the test will timeout
-//      while(channel.hasMessages())
-//      {
-//         Thread.sleep(500);
-//      }
-//
-//      List l = receiverOne.getMessages();
-//      assertEquals(1, l.size());
-//      assertEquals("routableID", ((RoutableSupport)receiverOne.iterator().next()).getMessageID());
-//   }
-//
-//   public void testNackingReceiverOnAsynchronousChannel_UnreliableRoutable()
-//   {
-//      if(skip()) { return; }
-//
-//      receiverOne.setState(ReceiverImpl.NACKING);
-//      assertTrue(channel.setSynchronous(false));
-//
-//      assertTrue(channel.handle(new RoutableSupport("routableID", false)));
-//      assertTrue(channel.hasMessages());
-//      List l = receiverOne.getMessages();
-//      assertEquals(0, l.size());
-//   }
-//
-//   public void testBrokenReceiverOnAsynchronousChannel_UnreliableRoutable()
-//   {
-//      if(skip()) { return; }
-//
-//      receiverOne.setState(ReceiverImpl.BROKEN);
-//      assertTrue(channel.setSynchronous(false));
-//
-//      assertTrue(channel.handle(new RoutableSupport("routableID", false)));
-//      if (channel.isStoringUndeliverableMessages())
-//      {
-//         assertTrue(channel.hasMessages());
-//      }
-//      else
-//      {
-//         assertFalse(channel.hasMessages());
-//      }
-//      List l = receiverOne.getMessages();
-//      assertEquals(0, l.size());
-//   }
-//
-//   //
-//   // Test handle() on asynchronous channel - reliable routable
-//   //
-//
-//   public void testSuccessfulSynchronousDeliverOnAsynchronousChannel_ReliableRoutable()
-//         throws Exception
-//   {
-//      if(skip()) { return; }
-//
-//      receiverOne.setState(ReceiverImpl.HANDLING);
-//      channel.setAcknowledgmentStore(new TestAcknowledgmentStore("ACKStoreID"));
-//      channel.setMessageStore(new MessageStoreImpl("MessageStoreID"));
-//      assertTrue(channel.setSynchronous(false));
-//
-//      assertTrue(channel.handle(new RoutableSupport("routableID", true)));
-//
-//      // wait for the acknowledgment to arrive and store to clear - if it doesn't, the test will timeout
-//      while(channel.hasMessages())
-//      {
-//         Thread.sleep(500);
-//      }
-//
-//      assertFalse(channel.hasMessages());
-//      List l = receiverOne.getMessages();
-//      assertEquals(1, l.size());
-//      assertEquals("routableID", ((RoutableSupport)receiverOne.iterator().next()).getMessageID());
-//   }
-//
-//
-//   public void testDenyingReceiverOnAsynchronousChannel()
-//   {
-//      if(skip()) { return; }
-//
-//      internalTestReceiverOnAsynchronousChannel_ReliableRoutable(ReceiverImpl.NACKING);
-//   }
-//
-//   public void testBrokenReceiverOnAsynchronousChannel()
-//   {
-//      if(skip()) { return; }
-//
-//      internalTestReceiverOnAsynchronousChannel_ReliableRoutable(ReceiverImpl.BROKEN);
-//   }
-//
-//   // Private --------------------------------------------------------
-//
-//   private void internalTestReceiverOnAsynchronousChannel_ReliableRoutable(String receiverState)
-//   {
-//      receiverOne.setState(receiverState);
-//      assertTrue(channel.setSynchronous(false));
-//
-//
-//
-//      // no message store, no acknowledgment store
-//      channel.setMessageStore(null);
-//      channel.setAcknowledgmentStore(null);
-//
-//      // send a reliable message
-//
-//      boolean ack = channel.handle(new MessageSupport("messageID", true));
-//
-//      if (receiverState == ReceiverImpl.BROKEN && !channel.isStoringUndeliverableMessages())
-//      {
-//         assertTrue(ack);
-//      }
-//      else
-//      {
-//         assertFalse(ack);
-//      }
-//      assertFalse(channel.hasMessages());
-//      List l = receiverOne.getMessages();
-//      assertEquals(0, l.size());
-//
-//      // send a reliable reference
-//
-//      ack = channel.handle(new MessageReferenceSupport("messageID", true, 0, "someStoreID"));
-//      if (receiverState == ReceiverImpl.BROKEN && !channel.isStoringUndeliverableMessages())
-//      {
-//          assertTrue(ack);
-//      }
-//      else
-//      {
-//          assertFalse(ack);
-//      }
-//
-//      assertFalse(channel.hasMessages());
-//      l = receiverOne.getMessages();
-//      assertEquals(0, l.size());
-//
-//
-//
-//
-//      // install a broken acknowledgment store, but not a message store yet
-//      channel.setAcknowledgmentStore(new TestAcknowledgmentStore("ACKStoreID",
-//                                                                 TestAcknowledgmentStore.BROKEN));
-//
-//      // send a reliable message
-//
-//      ack = channel.handle(new MessageSupport("messageID", true));
-//      if (receiverState == ReceiverImpl.BROKEN && !channel.isStoringUndeliverableMessages())
-//      {
-//          assertTrue(ack);
-//      }
-//      else
-//      {
-//          assertFalse(ack);
-//      }
-//      assertFalse(channel.hasMessages());
-//      l = receiverOne.getMessages();
-//      assertEquals(0, l.size());
-//
-//      // send a reliable reference
-//
-//      ack = channel.handle(new MessageReferenceSupport("messageID", true, 0, "someStoreID"));
-//      if (receiverState == ReceiverImpl.BROKEN && !channel.isStoringUndeliverableMessages())
-//      {
-//          assertTrue(ack);
-//      }
-//      else
-//      {
-//          assertFalse(ack);
-//      }
-//      assertFalse(channel.hasMessages());
-//      l = receiverOne.getMessages();
-//      assertEquals(0, l.size());
-//
-//
-//
-//
-//      // install a valid acknowledgment store, but not a message store yet
-//      channel.setAcknowledgmentStore(new TestAcknowledgmentStore("ACKStoreID"));
-//
-//      // send a reliable message
-//
-//      ack = channel.handle(new MessageSupport("messageID", true));
-//      if (receiverState == ReceiverImpl.BROKEN && !channel.isStoringUndeliverableMessages())
-//      {
-//          assertTrue(ack);
-//      }
-//      else
-//      {
-//          assertFalse(ack);
-//      }
-//      assertFalse(channel.hasMessages());
-//      l = receiverOne.getMessages();
-//      assertEquals(0, l.size());
-//
-//      // send a reliable reference
-//
-//      assertTrue(channel.handle(new MessageReferenceSupport("messageID", true, Long.MAX_VALUE, "someStoreID")));
-//
-//      if (receiverState == ReceiverImpl.NACKING ||
-//          receiverState == ReceiverImpl.BROKEN && channel.isStoringUndeliverableMessages())
-//      {
-//         assertTrue(channel.hasMessages());
-//      }
-//      else
-//      {
-//         assertFalse(channel.hasMessages());
-//      }
-//
-//      l = receiverOne.getMessages();
-//      assertEquals(0, l.size());
-//
-//      // "fix" the receiver store and get rid of the nacked message
-//      String s = receiverOne.getState();
-//      receiverOne.setState(ReceiverImpl.HANDLING);
-//      assertTrue(channel.deliver());
-//      assertFalse(channel.hasMessages());
-//      // "break" the receiver again
-//      receiverOne.setState(s);
-//      receiverOne.clear();
-//
-//
-//
-//      // install a broken message store
-//      channel.setMessageStore(new MessageStoreImpl("MessageStoreID",
-//                                                   MessageStoreImpl.BROKEN));
-//
-//      // send a reliable message
-//
-//      ack = channel.handle(new MessageSupport("messageID", true));
-//      if (receiverState == ReceiverImpl.BROKEN && !channel.isStoringUndeliverableMessages())
-//      {
-//          assertTrue(ack);
-//      }
-//      else
-//      {
-//          assertFalse(ack);
-//      }
-//      assertFalse(channel.hasMessages());
-//      l = receiverOne.getMessages();
-//      assertEquals(0, l.size());
-//
-//      // send a reliable reference
-//
-//      assertTrue(channel.handle(new MessageReferenceSupport("messageID", true, Long.MAX_VALUE, "someStoreID")));
-//
-//      if (receiverState == ReceiverImpl.NACKING ||
-//          receiverState == ReceiverImpl.BROKEN && channel.isStoringUndeliverableMessages())
-//      {
-//         assertTrue(channel.hasMessages());
-//      }
-//      else
-//      {
-//         assertFalse(channel.hasMessages());
-//      }
-//
-//      l = receiverOne.getMessages();
-//      assertEquals(0, l.size());
-//      // "fix" the receiver store and get rid of the nacked message
-//      s = receiverOne.getState();
-//      receiverOne.setState(ReceiverImpl.HANDLING);
-//      assertTrue(channel.deliver());
-//      assertFalse(channel.hasMessages());
-//      // "break" the receiver again
-//      receiverOne.setState(s);
-//      receiverOne.clear();
-//
-//
-//
-//
-//      // finally install a valid message store - all should work now
-//      channel.setMessageStore(new MessageStoreImpl("MessageStoreID"));
-//
-//      // send a reliable message
-//
-//      assertTrue(channel.handle(new MessageSupport("messageID", true)));
-//      if (receiverState == ReceiverImpl.NACKING ||
-//          receiverState == ReceiverImpl.BROKEN && channel.isStoringUndeliverableMessages())
-//      {
-//         assertTrue(channel.hasMessages());
-//      }
-//      else
-//      {
-//         assertFalse(channel.hasMessages());
-//      }
-//      l = receiverOne.getMessages();
-//      assertEquals(0, l.size());
-//
-//      // "fix" the receiver store and get rid of the nacked message
-//      s = receiverOne.getState();
-//      receiverOne.setState(ReceiverImpl.HANDLING);
-//      assertTrue(channel.deliver());
-//      assertFalse(channel.hasMessages());
-//      // "break" the receiver again
-//      receiverOne.setState(s);
-//      receiverOne.clear();
-//
-//      // send a reliable reference
-//
-//      assertTrue(channel.handle(new MessageReferenceSupport("messageID", true, Long.MAX_VALUE, "someStoreID")));
-//      if (receiverState == ReceiverImpl.NACKING ||
-//          receiverState == ReceiverImpl.BROKEN && channel.isStoringUndeliverableMessages())
-//      {
-//         assertTrue(channel.hasMessages());
-//      }
-//      else
-//      {
-//         assertFalse(channel.hasMessages());
-//      }
-//      l = receiverOne.getMessages();
-//      assertEquals(0, l.size());
-//
-//      // "fix" the receiver store and get rid of the nacked message
-//      s = receiverOne.getState();
-//      receiverOne.setState(ReceiverImpl.HANDLING);
-//      assertTrue(channel.deliver());
-//      assertFalse(channel.hasMessages());
-//      // "break" the receiver again
-//      receiverOne.setState(s);
-//      receiverOne.clear();
-//   }
-//
-//
-//   //
-//   // Test deliver()
-//   //
-//
-//   public void testDeliver()
-//   {
-//      if(skip()) { return; }
-//
-//      // deliver none
-//
-//      receiverOne.setState(ReceiverImpl.NACKING);
-//      assertTrue(channel.setSynchronous(false));
-//      assertTrue(channel.handle(new RoutableSupport("routableID1")));
-//      assertTrue(channel.hasMessages());
-//
-//      receiverOne.setState(ReceiverImpl.HANDLING);
-//      assertTrue(channel.deliver());
-//
-//      assertEquals(1, receiverOne.getMessages().size());
-//      assertTrue(receiverOne.contains("routableID1"));
-//   }
-//
-//
-//   public void testDeliverMultiple()
-//   {
-//      if(skip()) { return; }
-//
-//      // deliver none
-//
-//      receiverOne.setState(ReceiverImpl.NACKING);
-//      assertTrue(channel.setSynchronous(false));
-//      assertTrue(channel.handle(new RoutableSupport("routableID1")));
-//      assertTrue(channel.handle(new RoutableSupport("routableID2")));
-//      assertTrue(channel.handle(new RoutableSupport("routableID3")));
-//      assertTrue(channel.hasMessages());
-//
-//      assertFalse(channel.deliver());
-//
-//      receiverOne.setState(ReceiverImpl.BROKEN);
-//      assertFalse(channel.deliver());
-//
-//      // deliver all
-//
-//      receiverOne.setState(ReceiverImpl.HANDLING);
-//      assertTrue(channel.deliver());
-//
-//      assertEquals(3, receiverOne.getMessages().size());
-//      assertTrue(receiverOne.contains("routableID1"));
-//      assertTrue(receiverOne.contains("routableID2"));
-//      assertTrue(receiverOne.contains("routableID3"));
-//
-//   }
-//
-//   public void testDeliverPartiallyandSwitchToDenying()
-//   {
-//      if(skip()) { return; }
-//
-//      receiverOne.setState(ReceiverImpl.NACKING);
-//      assertTrue(channel.setSynchronous(false));
-//
-//      assertTrue(channel.handle(new RoutableSupport("routableID1", false)));
-//      assertTrue(channel.handle(new RoutableSupport("routableID2", false)));
-//      assertTrue(channel.handle(new RoutableSupport("routableID3", false)));
-//      assertTrue(channel.hasMessages());
-//
-//      receiverOne.setState(ReceiverImpl.HANDLING);
-//      receiverOne.setState(ReceiverImpl.NACKING, 2);
-//
-//      assertFalse(channel.deliver());
-//
-//      Set unacked = channel.getUndelivered();
-//      assertEquals(1, unacked.size());
-//
-//      receiverOne.setState(ReceiverImpl.HANDLING);
-//
-//      assertTrue(channel.deliver());
-//
-//      assertEquals(3, receiverOne.getMessages().size());
-//      assertTrue(receiverOne.contains("routableID1"));
-//      assertTrue(receiverOne.contains("routableID2"));
-//      assertTrue(receiverOne.contains("routableID3"));
-//   }
-//
-//   public void testDeliverPartiallyandSwitchToBroken()
-//   {
-//      if(skip()) { return; }
-//
-//      receiverOne.setState(ReceiverImpl.NACKING);
-//      assertTrue(channel.setSynchronous(false));
-//
-//      assertTrue(channel.handle(new RoutableSupport("routableID1", false)));
-//      assertTrue(channel.handle(new RoutableSupport("routableID2", false)));
-//      assertTrue(channel.handle(new RoutableSupport("routableID3")));
-//      assertTrue(channel.hasMessages());
-//
-//      receiverOne.setState(ReceiverImpl.HANDLING);
-//      receiverOne.setState(ReceiverImpl.BROKEN, 2);
-//
-//      assertFalse(channel.deliver());
-//
-//      Set unacked = channel.getUndelivered();
-//      assertEquals(1, unacked.size());
-//
-//      receiverOne.setState(ReceiverImpl.HANDLING);
-//
-//      assertTrue(channel.deliver());
-//
-//      assertEquals(3, receiverOne.getMessages().size());
-//      assertTrue(receiverOne.contains("routableID1"));
-//      assertTrue(receiverOne.contains("routableID2"));
-//      assertTrue(receiverOne.contains("routableID3"));
-//   }
-//
-//   public void testMessageExpiration() throws Exception
-//   {
-//      if(skip()) { return; }
-//
-//      channel.setSynchronous(false);
-//      receiverOne.setState(ReceiverImpl.NACKING);
-//
-//      assertTrue(channel.handle(new RoutableSupport("routableID1", false, 1000))); // this should expire
-//      assertTrue(channel.handle(new RoutableSupport("routableID2", false, 100000)));
-//
-//      assertEquals(2, channel.getUndelivered().size());
-//
-//      Thread.sleep(2000);
-//
-//      receiverOne.setState(ReceiverImpl.HANDLING);
-//
-//      assertTrue(channel.deliver());
-//
-//      assertEquals(1, receiverOne.getMessages().size());
-//      assertTrue(receiverOne.contains("routableID2"));
-//   }
-//
-//
-//   //
-//   // Asynchronous ACK tests
-//   //
-//   public void testInvalidAsynchronousACK() throws Exception
-//   {
-//      if(skip()) { return; }
-//
-//      receiverOne.setState(ReceiverImpl.NACKING);
-//      assertTrue(channel.setSynchronous(false));
-//
-//      assertTrue(channel.handle(new RoutableSupport("routableID1", false)));
-//      assertTrue(channel.handle(new RoutableSupport("routableID2", false)));
-//
-//      channel.acknowledge("inexistentMessageID", receiverOne.getReceiverID());
-//
-//      assertTrue(channel.hasMessages());
-//      Set stillNaked = channel.getUndelivered();
-//      assertEquals(2, stillNaked.size());
-//      assertTrue(stillNaked.contains("routableID1"));
-//      assertTrue(stillNaked.contains("routableID2"));
-//
-//      channel.acknowledge("routableID1", "inexistentReceiver");
-//
-//      assertTrue(channel.hasMessages());
-//      stillNaked = channel.getUndelivered();
-//      assertEquals(2, stillNaked.size());
-//      assertTrue(stillNaked.contains("routableID1"));
-//      assertTrue(stillNaked.contains("routableID2"));
-//   }
-//
-//   public void testAsynchronousACK() throws Exception
-//   {
-//      if(skip()) { return; }
-//
-//      receiverOne.setState(ReceiverImpl.NACKING);
-//      assertTrue(channel.setSynchronous(false));
-//
-//      assertTrue(channel.handle(new RoutableSupport("routableID1", false)));
-//      assertTrue(channel.handle(new RoutableSupport("routableID2", false)));
-//
-//      channel.acknowledge("routableID1", receiverOne.getReceiverID());
-//
-//      assertTrue(channel.hasMessages());
-//      Set stillNaked = channel.getUndelivered();
-//      assertEquals(1, stillNaked.size());
-//      assertTrue(stillNaked.contains("routableID2"));
-//
-//      channel.acknowledge("routableID2", receiverOne.getReceiverID());
-//
-//      assertFalse(channel.hasMessages());
-//   }
-//
-//
-//   private boolean skip()
-//   {
-//      return channel == null;
-//   }
-
-   public void testNoop()
-   {
-
-   }
-}
\ No newline at end of file

Deleted: trunk/tests/src/org/jboss/test/messaging/core/DistributorTest.java
===================================================================
--- trunk/tests/src/org/jboss/test/messaging/core/DistributorTest.java	2006-08-30 09:26:13 UTC (rev 1236)
+++ trunk/tests/src/org/jboss/test/messaging/core/DistributorTest.java	2006-08-30 18:36:36 UTC (rev 1237)
@@ -1,145 +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.core;
-
-import org.jboss.test.messaging.MessagingTestCase;
-
-
-/**
- * @author <a href="mailto:ovidiu at jboss.org">Ovidiu Feodorov</a>
- * @version <tt>$Revision$</tt>
- */
-public class DistributorTest extends MessagingTestCase
-{
-//   // Attributes ----------------------------------------------------
-//
-//   protected Distributor distributor;
-
-   // Constructors --------------------------------------------------
-
-   public DistributorTest(String name)
-   {
-      super(name);
-   }
-
-//   //
-//   // Distributor tests
-//   //
-//
-//   public void testAddOneReceiver()
-//   {
-//      if (distributor == null) { return; }
-//
-//      Receiver r = new ReceiverImpl("ReceiverID1", ReceiverImpl.HANDLING);
-//      assertTrue(distributor.add(r));
-//      assertFalse(distributor.add(r));
-//      assertTrue(distributor.contains("ReceiverID1"));
-//      assertTrue(r == distributor.get("ReceiverID1"));
-//      Iterator i = distributor.iterator();
-//      assertEquals("ReceiverID1", i.next());
-//      assertFalse(i.hasNext());
-//      distributor.clear();
-//      i = distributor.iterator();
-//      assertFalse(i.hasNext());
-//
-//   }
-//
-//   public void testAddMultipleReceivers()
-//   {
-//      if (distributor == null) { return; }
-//
-//      Receiver r1 = new ReceiverImpl("ReceiverID1", ReceiverImpl.HANDLING);
-//      Receiver r2 = new ReceiverImpl("ReceiverID2", ReceiverImpl.HANDLING);
-//      assertTrue(distributor.add(r1));
-//      assertTrue(distributor.add(r2));
-//      assertTrue(distributor.contains("ReceiverID1"));
-//      assertTrue(distributor.contains("ReceiverID2"));
-//      assertTrue(r1 == distributor.get("ReceiverID1"));
-//      assertTrue(r2 == distributor.get("ReceiverID2"));
-//      distributor.clear();
-//      Iterator i = distributor.iterator();
-//      assertFalse(i.hasNext());
-//   }
-//
-//   public void testRemoveInexistentRouter()
-//   {
-//      if (distributor == null) { return; }
-//
-//      assertNull(distributor.remove("NoSuchId"));
-//
-//   }
-//
-//   public void testVariousAdds()
-//   {
-//      if (distributor == null) { return; }
-//
-//      assertFalse(distributor.iterator().hasNext());
-//
-//      ReceiverImpl r = new ReceiverImpl();
-//      assertTrue(distributor.add(r));
-//
-//      if (distributor instanceof Receiver)
-//      {
-//         boolean result = ((Receiver)distributor).handle(new MessageSupport(""));
-//         assertTrue(result);
-//      }
-//      else if (distributor instanceof Router)
-//      {
-//         Set acks = ((Router)distributor).handle(new MessageSupport(""));
-//         assertEquals(1, acks.size());
-//         assertTrue(((Acknowledgment)acks.iterator().next()).isPositive());
-//      }
-//
-//      assertFalse(distributor.add(r));
-//   }
-//
-//
-//   /**
-//    * This method assumes the router has no associates receivers.
-//    */
-//   public void testVariousRemoves()
-//   {
-//      if (distributor == null) { return; }
-//
-//      assertFalse(distributor.iterator().hasNext());
-//
-//      ReceiverImpl r = new ReceiverImpl();
-//      assertTrue(distributor.add(r));
-//      Iterator i = distributor.iterator();
-//      assertEquals(r.getReceiverID(), i.next());
-//      assertFalse(i.hasNext());
-//
-//      assertTrue(r == distributor.remove(r.getReceiverID()));
-//
-//      // make sure that removing an inexistent Receiver returns false
-//      assertNull(distributor.remove(r.getReceiverID()));
-//
-//      i = distributor.iterator();
-//      assertFalse(i.hasNext());
-//   }
-
-   public void testNoop()
-   {
-   }
-}
-
-

Deleted: trunk/tests/src/org/jboss/test/messaging/core/LocalPipeAsChannelTest.java
===================================================================
--- trunk/tests/src/org/jboss/test/messaging/core/LocalPipeAsChannelTest.java	2006-08-30 09:26:13 UTC (rev 1236)
+++ trunk/tests/src/org/jboss/test/messaging/core/LocalPipeAsChannelTest.java	2006-08-30 18:36:36 UTC (rev 1237)
@@ -1,92 +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.core;
-
-
-/**
- * @author <a href="mailto:ovidiu at jboss.org">Ovidiu Feodorov</a>
- * @version <tt>$Revision$</tt>
- */
-public class LocalPipeAsChannelTest extends SingleOutputChannelSupportTest
-{
-   // Constructors --------------------------------------------------
-
-   public LocalPipeAsChannelTest(String name)
-   {
-      super(name);
-   }
-
-//   public void setUp() throws Exception
-//   {
-//      // Create a receiver and a LocalPipe to be testes by the superclass tests
-//
-//      receiverOne = new ReceiverImpl("ReceiverOne", ReceiverImpl.HANDLING);
-//      channel = new LocalPipe("LocalPipeID", receiverOne);
-//
-//      // important, I need the channel set at this point
-//      super.setUp();
-//   }
-//
-//   public void tearDown()throws Exception
-//   {
-//      ((LocalPipe)channel).setReceiver(null);
-//      channel = null;
-//      receiverOne = null;
-//      super.tearDown();
-//   }
-//
-//   //
-//   // This test also runs all ChannelSupportTest's tests
-//   //
-//
-//   public void testDefaultSynchronous()
-//   {
-//      assertTrue(channel.isSynchronous());
-//   }
-//
-//   public void testDeliveryAttemptTriggeredByAddingReceiver()
-//   {
-//      LocalPipe pipe = (LocalPipe)channel;
-//      pipe.setReceiver(null);
-//      assertTrue(pipe.setSynchronous(false));
-//
-//      assertTrue(pipe.handle(new RoutableSupport("routableID1", false)));
-//      assertTrue(pipe.handle(new RoutableSupport("routableID2", false)));
-//      assertTrue(pipe.handle(new RoutableSupport("routableID3", false)));
-//
-//      assertEquals(3, pipe.getUndelivered().size());
-//
-//      assertFalse(pipe.deliver());
-//      assertEquals(3, pipe.getUndelivered().size());
-//
-//      // this should trigger asynchronous delivery attempt
-//      pipe.setReceiver(receiverOne);
-//
-//      assertFalse(pipe.hasMessages());
-//
-//      assertEquals(3, receiverOne.getMessages().size());
-//      assertTrue(receiverOne.contains("routableID1"));
-//      assertTrue(receiverOne.contains("routableID2"));
-//      assertTrue(receiverOne.contains("routableID3"));
-//   }
-
-}

Deleted: trunk/tests/src/org/jboss/test/messaging/core/LocalQueueAsChannelTest.java
===================================================================
--- trunk/tests/src/org/jboss/test/messaging/core/LocalQueueAsChannelTest.java	2006-08-30 09:26:13 UTC (rev 1236)
+++ trunk/tests/src/org/jboss/test/messaging/core/LocalQueueAsChannelTest.java	2006-08-30 18:36:36 UTC (rev 1237)
@@ -1,246 +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.core;
-
-
-
-/**
- * @author <a href="mailto:ovidiu at jboss.org">Ovidiu Feodorov</a>
- * @version <tt>$Revision$</tt>
- */
-public class LocalQueueAsChannelTest extends TransactionalChannelSupportTest
-{
-   // Constructors --------------------------------------------------
-
-   public LocalQueueAsChannelTest(String name)
-   {
-      super(name);
-   }
-
-//   public void setUp() throws Exception
-//   {
-//      // Create a LocalQueue to be tested by the superclass tests
-//      channel = new LocalQueue("LocalQueueID");
-//      receiverOne = new ReceiverImpl("ReceiverOne", ReceiverImpl.HANDLING);
-//      ((LocalQueue)channel).add(receiverOne);
-//
-//      super.setUp();
-//   }
-//
-//   public void tearDown()throws Exception
-//   {
-//      ((LocalQueue)channel).clear();
-//      channel = null;
-//      receiverOne = null;
-//
-//      super.tearDown();
-//   }
-//
-//   //
-//   // This test also runs all ChannelSupportTest's tests
-//   //
-//
-//   public void testDefaultAsynchronous()
-//   {
-//      assertFalse(channel.isSynchronous());
-//   }
-//
-//   public void testQueue() throws Exception
-//   {
-//      LocalQueue queue = new LocalQueue("");
-//
-//      // send without a receiver
-//
-//      Routable m = new MessageSupport("");
-//      assertTrue(queue.handle(m));
-//
-//      // attach a receiver
-//
-//      ReceiverImpl rOne = new ReceiverImpl("ReceiverONE", ReceiverImpl.HANDLING);
-//      assertTrue(queue.add(rOne));
-//
-//      // verify if the receiver got the message; by default the queue is configured to pass by
-//      // reference
-//
-//      Iterator i = rOne.iterator();
-//      assertTrue(m == i.next());
-//      assertFalse(i.hasNext());
-//
-//      rOne.clear();
-//
-//      // send with one receiver
-//
-//      m = new MessageSupport("");
-//      assertTrue(queue.handle(m));
-//
-//      i = rOne.iterator();
-//      assertTrue(m == i.next());
-//      assertFalse(i.hasNext());
-//
-//      rOne.clear();
-//
-//      // send with two receivers
-//
-//      ReceiverImpl rTwo = new ReceiverImpl("ReceiverTWO", ReceiverImpl.HANDLING);
-//      assertTrue(queue.add(rTwo));
-//
-//      m = new MessageSupport("");
-//      assertTrue(queue.handle(m));
-//
-//      Iterator iOne = rOne.iterator(), iTwo = rTwo.iterator();
-//      if (iOne.hasNext())
-//      {
-//         // then rOne got the message
-//         assertTrue(m == iOne.next());
-//         assertFalse(iOne.hasNext());
-//         assertFalse(iTwo.hasNext());
-//      }
-//      else
-//      {
-//         // otherwise rTwo got the message
-//         assertTrue(m == iTwo.next());
-//         assertFalse(iTwo.hasNext());
-//         assertFalse(iOne.hasNext());
-//      }
-//   }
-//
-//
-//   /**
-//    * Tests the behaviour of a "nacking" receiver (whose handle() returns false). However, the
-//    * test doesn't deal with the case when the receiver "heals" (starts accepting messages). See
-//    * testNackingReceiverThatStartsAccepting() for that.
-//    */
-//   public void testNackingReceiver() throws Exception
-//   {
-//      LocalQueue queue = new LocalQueue("");
-//
-//      ReceiverImpl nacking = new ReceiverImpl("NackingReceiverID", ReceiverImpl.NACKING);
-//      assertTrue(queue.add(nacking));
-//
-//      Routable m = new MessageSupport("");
-//      assertTrue(queue.handle(m));
-//
-//      Iterator i = nacking.iterator();
-//      assertFalse(i.hasNext());
-//
-//      // the queue holds a NACK for the nacking receiver, so it cannot deliver the message
-//      // until either the nacking receiver ACKs or the message expires, otherwise the queue
-//      // will deliver the same message to two receivers.
-//
-//      ReceiverImpl handling = new ReceiverImpl("HandlingReceiverID", ReceiverImpl.HANDLING);
-//      assertTrue(queue.add(handling));
-//
-//      // there should be an unsuccessful delivery attempt
-//
-//      assertTrue(queue.hasMessages());
-//
-//      // an explicit delivery attempt should faile
-//      assertFalse(queue.deliver());
-//
-//      i = nacking.iterator();
-//      assertFalse(i.hasNext());
-//
-//      i = handling.iterator();
-//      assertFalse(i.hasNext());
-//   }
-//
-//   public void testNackingReceiverThatStartsAccepting() throws Exception
-//   {
-//      LocalQueue queue = new LocalQueue("");
-//
-//      ReceiverImpl nacking = new ReceiverImpl(ReceiverImpl.NACKING);
-//      assertTrue(queue.add(nacking));
-//
-//      Routable m = new MessageSupport("");
-//      assertTrue(queue.handle(m));
-//
-//      Iterator i = nacking.iterator();
-//      assertFalse(i.hasNext());
-//
-//      assertTrue(queue.hasMessages());
-//
-//      // "heal" the receiver and attempt re-delivery
-//      nacking.setState(ReceiverImpl.HANDLING);
-//
-//      assertTrue(queue.deliver());
-//      assertFalse(queue.hasMessages());
-//
-//      i = nacking.iterator();
-//      assertTrue(m == i.next());
-//      assertFalse(i.hasNext());
-//   }
-//
-//
-//   /**
-//    * Tests the behaviour of a "broken" receiver (whose handle() throws unchecked exceptions).
-//    * However, the test don't deal with the case when the receiver "heals" (starts accepting
-//    * messages). See testBrokenReceiverThatHeals()
-//    */
-//   public void testBrokenReceiver() throws Exception
-//   {
-//      LocalQueue queue = new LocalQueue("");
-//
-//      ReceiverImpl broken = new ReceiverImpl("BrokenReceiverID", ReceiverImpl.BROKEN);
-//      assertTrue(queue.add(broken));
-//
-//      Routable m = new MessageSupport("");
-//      assertTrue(queue.handle(m));
-//
-//      Iterator i = broken.iterator();
-//      assertFalse(i.hasNext());
-//
-//      ReceiverImpl handling = new ReceiverImpl("HandlingReceiverID", ReceiverImpl.HANDLING);
-//      assertTrue(queue.add(handling));
-//
-//      // the delivery should have taken place already
-//
-//      i = broken.iterator();
-//      assertFalse(i.hasNext());
-//
-//      i = handling.iterator();
-//      assertTrue(m == i.next());
-//      assertFalse(i.hasNext());
-//   }
-//
-//   public void testBrokenReceiverThatHeals() throws Exception
-//   {
-//      LocalQueue queue = new LocalQueue("");
-//
-//      ReceiverImpl broken = new ReceiverImpl(ReceiverImpl.BROKEN);
-//      assertTrue(queue.add(broken));
-//
-//      Routable m = new MessageSupport("");
-//      assertTrue(queue.handle(m));
-//
-//      Iterator i = broken.iterator();
-//      assertFalse(i.hasNext());
-//      assertTrue(queue.hasMessages());
-//
-//      // "heal" the receiver and attempt re-delivery
-//      broken.setState(ReceiverImpl.HANDLING);
-//      assertTrue(queue.deliver());
-//      assertFalse(queue.hasMessages());
-//      i = broken.iterator();
-//      assertTrue(m == i.next());
-//      assertFalse(i.hasNext());
-//   }
-}

Deleted: trunk/tests/src/org/jboss/test/messaging/core/LocalQueueAsDistributorTest.java
===================================================================
--- trunk/tests/src/org/jboss/test/messaging/core/LocalQueueAsDistributorTest.java	2006-08-30 09:26:13 UTC (rev 1236)
+++ trunk/tests/src/org/jboss/test/messaging/core/LocalQueueAsDistributorTest.java	2006-08-30 18:36:36 UTC (rev 1237)
@@ -1,59 +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.core;
-
-
-
-
-/**
- * @author <a href="mailto:ovidiu at jboss.org">Ovidiu Feodorov</a>
- * @version <tt>$Revision$</tt>
- */
-public class LocalQueueAsDistributorTest extends DistributorTest
-{
-   // Constructors --------------------------------------------------
-
-   public LocalQueueAsDistributorTest(String name)
-   {
-      super(name);
-   }
-//
-//   public void setUp() throws Exception
-//   {
-//      super.setUp();
-//
-//      // Create a LocalQueue to be tested by the superclass tests
-//      distributor = new LocalQueue("LocalQueueID");
-//   }
-//
-//   public void tearDown()throws Exception
-//   {
-//      distributor.clear();
-//      distributor = null;
-//      super.tearDown();
-//   }
-//
-//   //
-//   // This test also runs all DistributorTest's tests
-//   //
-
-}

Deleted: trunk/tests/src/org/jboss/test/messaging/core/LocalTopicAsChannelTest.java
===================================================================
--- trunk/tests/src/org/jboss/test/messaging/core/LocalTopicAsChannelTest.java	2006-08-30 09:26:13 UTC (rev 1236)
+++ trunk/tests/src/org/jboss/test/messaging/core/LocalTopicAsChannelTest.java	2006-08-30 18:36:36 UTC (rev 1237)
@@ -1,209 +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.core;
-
-
-/**
- * @author <a href="mailto:ovidiu at jboss.org">Ovidiu Feodorov</a>
- * @version <tt>$Revision$</tt>
- */
-public class LocalTopicAsChannelTest extends TransactionalChannelSupportTest
-{
-   // Constructors --------------------------------------------------
-
-   public LocalTopicAsChannelTest(String name)
-   {
-      super(name);
-   }
-//
-//   public void setUp() throws Exception
-//   {
-//      // Create a LocalTopic to be tested by the superclass tests
-//      channel = new LocalTopic("LocalTopicID");
-//      receiverOne = new ReceiverImpl("ReceiverOne", ReceiverImpl.HANDLING);
-//      ((LocalTopic)channel).add(receiverOne);
-//
-//      super.setUp();
-//   }
-//
-//   public void tearDown()throws Exception
-//   {
-//      ((LocalTopic)channel).clear();
-//      channel = null;
-//      receiverOne = null;
-//      super.tearDown();
-//   }
-//
-//   //
-//   // This test also runs all ChannelSupportTest's tests
-//   //
-//
-//   public void testDefaultAsynchronous()
-//   {
-//      assertTrue(!channel.isSynchronous());
-//   }
-//
-//
-//   public void testTopicOneReceiver() throws Exception
-//   {
-//      LocalTopic topic = new LocalTopic("");
-//
-//      // send without a receiver
-//
-//      Routable r = new MessageSupport("");
-//      assertTrue(topic.handle(r));
-//
-//      // send with one receiver
-//
-//      ReceiverImpl rOne = new ReceiverImpl("ReceiverONE", ReceiverImpl.HANDLING);
-//      assertTrue(topic.add(rOne));
-//
-//      r = new MessageSupport("");
-//      assertTrue(topic.handle(r));
-//
-//      Iterator i = rOne.iterator();
-//      assertTrue(r == i.next());
-//      assertFalse(i.hasNext());
-//   }
-//
-//   public void testTopicTwoReceivers() throws Exception
-//   {
-//      LocalTopic topic = new LocalTopic("");
-//
-//      ReceiverImpl rOne = new ReceiverImpl("ReceiverONE", ReceiverImpl.HANDLING);
-//      assertTrue(topic.add(rOne));
-//
-//      ReceiverImpl rTwo = new ReceiverImpl("ReceiverTWO", ReceiverImpl.HANDLING);
-//      assertTrue(topic.add(rTwo));
-//
-//      Routable r = new MessageSupport("");
-//      assertTrue(topic.handle(r));
-//
-//      Iterator iOne = rOne.iterator();
-//      assertTrue(r == iOne.next());
-//      assertFalse(iOne.hasNext());
-//
-//      Iterator iTwo = rTwo.iterator();
-//      assertTrue(r == iTwo.next());
-//      assertFalse(iTwo.hasNext());
-//   }
-//
-//
-//   public void testNackingReceiver() throws Exception
-//   {
-//      LocalTopic topic = new LocalTopic("");
-//
-//      ReceiverImpl nacking = new ReceiverImpl("ReceiverONE", ReceiverImpl.NACKING);
-//      assertTrue(topic.add(nacking));
-//
-//      Routable r = new MessageSupport("");
-//      assertTrue(topic.handle(r));
-//      assertTrue(topic.hasMessages());
-//
-//      Iterator i = nacking.iterator();
-//      assertFalse(i.hasNext());
-//
-//      // enable the nacking receiver
-//
-//      nacking.setState(ReceiverImpl.HANDLING);
-//
-//      assertTrue(topic.deliver());
-//      assertFalse(topic.hasMessages());
-//
-//      i = nacking.iterator();
-//      assertTrue(r == i.next());
-//      assertFalse(i.hasNext());
-//   }
-//
-//   public void testNackingAndHandlingReceivers() throws Exception
-//   {
-//      LocalTopic topic = new LocalTopic("");
-//
-//      Routable rOne = new MessageSupport("ONE");
-//      assertTrue(topic.handle(rOne));
-//      assertFalse(topic.hasMessages());
-//
-//      ReceiverImpl nacking = new ReceiverImpl("ReceiverA", ReceiverImpl.NACKING);
-//      assertTrue(topic.add(nacking));
-//
-//      Routable rTwo = new MessageSupport("TWO");
-//      assertTrue(topic.handle(rTwo));
-//      assertTrue(topic.hasMessages());
-//      Iterator i = nacking.iterator();
-//      assertFalse(i.hasNext());
-//
-//      ReceiverImpl handling = new ReceiverImpl("ReceiverB", ReceiverImpl.HANDLING);
-//      assertTrue(topic.add(handling));
-//      i = handling.iterator();
-//      assertFalse(i.hasNext());
-//
-//      Routable rThree = new MessageSupport("THREE");
-//      assertTrue(topic.handle(rThree));
-//      assertTrue(topic.hasMessages());
-//
-//      i = nacking.iterator();
-//      assertFalse(i.hasNext());
-//      i = handling.iterator();
-//      assertTrue(rThree == i.next());
-//      assertFalse(i.hasNext());
-//      handling.clear();
-//
-//      // enable ReceiverA
-//
-//      nacking.setState(ReceiverImpl.HANDLING);
-//      assertTrue(topic.deliver());
-//      assertFalse(topic.hasMessages());
-//
-//      List l = nacking.getMessages();
-//      assertEquals(2, l.size());
-//      assertTrue(l.contains(rTwo));
-//      assertTrue(l.contains(rThree));
-//      i = handling.iterator();
-//      assertFalse(i.hasNext());
-//   }
-//
-//   public void testBrokenReceiver() throws Exception
-//   {
-//      LocalTopic topic = new LocalTopic("");
-//
-//      ReceiverImpl broken = new ReceiverImpl("ReceiverONE", ReceiverImpl.BROKEN);
-//      assertTrue(topic.add(broken));
-//
-//      Routable r = new MessageSupport("");
-//      assertTrue(topic.handle(r));
-//      assertFalse(topic.hasMessages());
-//
-//      Iterator i = broken.iterator();
-//      assertFalse(i.hasNext());
-//
-//      ReceiverImpl handling = new ReceiverImpl("ReceiverTWO", ReceiverImpl.HANDLING);
-//      assertTrue(topic.add(handling));
-//      assertTrue(topic.handle(r));
-//
-//      i = broken.iterator();
-//      assertFalse(i.hasNext());
-//
-//      i = handling.iterator();
-//      assertTrue(r == i.next());
-//      assertFalse(i.hasNext());
-//   }
-}

Deleted: trunk/tests/src/org/jboss/test/messaging/core/LocalTopicAsDistributorTest.java
===================================================================
--- trunk/tests/src/org/jboss/test/messaging/core/LocalTopicAsDistributorTest.java	2006-08-30 09:26:13 UTC (rev 1236)
+++ trunk/tests/src/org/jboss/test/messaging/core/LocalTopicAsDistributorTest.java	2006-08-30 18:36:36 UTC (rev 1237)
@@ -1,56 +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.core;
-
-
-/**
- * @author <a href="mailto:ovidiu at jboss.org">Ovidiu Feodorov</a>
- * @version <tt>$Revision$</tt>
- */
-public class LocalTopicAsDistributorTest extends DistributorTest
-{
-   // Constructors --------------------------------------------------
-
-   public LocalTopicAsDistributorTest(String name)
-   {
-      super(name);
-   }
-
-//   public void setUp() throws Exception
-//   {
-//      super.setUp();
-//
-//      // Create a LocalQueue to be tested by the superclass tests
-//      distributor = new LocalTopic("LocalTopicID");
-//   }
-//
-//   public void tearDown()throws Exception
-//   {
-//      distributor.clear();
-//      distributor = null;
-//      super.tearDown();
-//   }
-//
-//   //
-//   // This test also runs all DistributorTest's tests
-//   //
-}

Deleted: trunk/tests/src/org/jboss/test/messaging/core/PointToMultipointRouterAsDistributorTest.java
===================================================================
--- trunk/tests/src/org/jboss/test/messaging/core/PointToMultipointRouterAsDistributorTest.java	2006-08-30 09:26:13 UTC (rev 1236)
+++ trunk/tests/src/org/jboss/test/messaging/core/PointToMultipointRouterAsDistributorTest.java	2006-08-30 18:36:36 UTC (rev 1237)
@@ -1,231 +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.core;
-
-
-/**
- * @author <a href="mailto:ovidiu at jboss.org">Ovidiu Feodorov</a>
- * @version <tt>$Revision$</tt>
- */
-public class PointToMultipointRouterAsDistributorTest extends DistributorTest
-{
-   // Constructors --------------------------------------------------
-
-   public PointToMultipointRouterAsDistributorTest(String name)
-   {
-      super(name);
-   }
-
-//   public void setUp() throws Exception
-//   {
-//      super.setUp();
-//
-//      // Create a PointToMultipointRouter to be tested by the superclass tests
-//      distributor = new PointToMultipointRouter("P2MPRouterID");
-//   }
-//
-//   public void tearDown()throws Exception
-//   {
-//      distributor.clear();
-//      distributor = null;
-//      super.tearDown();
-//   }
-//
-//   //
-//   // This test also runs all DistributorTest's tests
-//   //
-//
-//   public void testPointToMultipointRouter() throws Exception
-//   {
-//      PointToMultipointRouter router = new PointToMultipointRouter("");
-//
-//      // by default, the router sends the message by reference
-//      assertTrue(router.isPassByReference());
-//
-//      // send without a receiver
-//
-//      Routable m = new MessageSupport(new Integer(0));
-//      Set acks = router.handle(m);
-//      assertEquals(0, acks.size());
-//
-//      // send with one receiver
-//
-//      ReceiverImpl rOne = new ReceiverImpl("ONE", ReceiverImpl.HANDLING);
-//      assertTrue(router.add(rOne));
-//
-//      m = new MessageSupport(new Integer(1));
-//      Set result = router.handle(m);
-//      assertEquals(1, result.size());
-//      Acknowledgment a = (Acknowledgment)result.iterator().next();
-//      assertTrue(a.isPositive());
-//      assertEquals("ONE", a.getReceiverID());
-//
-//      Iterator i = rOne.iterator();
-//      Routable n = (Routable)i.next();
-//      assertFalse(i.hasNext());
-//      assertTrue(m == n);
-//
-//      rOne.clear();
-//
-//      // send with two receivers
-//
-//      ReceiverImpl rTwo = new ReceiverImpl("TWO", ReceiverImpl.HANDLING);
-//      assertTrue(router.add(rTwo));
-//
-//      m = new MessageSupport(new Integer(2));
-//      result = router.handle(m);
-//      assertEquals(2, result.size());
-//      Set ids = new HashSet();
-//      for(Iterator j = result.iterator(); j.hasNext(); )
-//      {
-//         Acknowledgment ack = (Acknowledgment)j.next();
-//         assertTrue(ack.isPositive());
-//         ids.add(ack.getReceiverID());
-//      }
-//      assertTrue(ids.contains("ONE"));
-//      assertTrue(ids.contains("TWO"));
-//
-//      Iterator iOne = rOne.iterator();
-//      n = (Routable)iOne.next();
-//      assertFalse(iOne.hasNext());
-//      assertTrue(m == n);
-//
-//      Iterator iTwo = rTwo.iterator();
-//      n = (Routable)iTwo.next();
-//      assertFalse(iTwo.hasNext());
-//      assertTrue(m == n);
-//   }
-//
-//
-//   public void testNackingReceiver() throws Exception
-//   {
-//      PointToMultipointRouter router = new PointToMultipointRouter("");
-//
-//      // one NACKing receiver
-//
-//      ReceiverImpl nacking = new ReceiverImpl("ReceiverONE", ReceiverImpl.NACKING);
-//      assertTrue(router.add(nacking));
-//
-//      Routable m = new MessageSupport("");
-//      Set result = router.handle(m);
-//      assertEquals(1, result.size());
-//      Acknowledgment a = (Acknowledgment)result.iterator().next();
-//      assertTrue(a.isNegative());
-//      assertEquals("ReceiverONE", a.getReceiverID());
-//
-//      Iterator i = nacking.iterator();
-//      assertFalse(i.hasNext());
-//
-//      // a NACKing and a handling receiver
-//
-//      ReceiverImpl handling = new ReceiverImpl("ReceiverTWO", ReceiverImpl.HANDLING);
-//      assertTrue(router.add(handling));
-//      result = router.handle(m);
-//
-//      assertEquals(2, result.size());
-//      Set booleans = new HashSet();
-//      Set ids = new HashSet();
-//      for(Iterator j = result.iterator(); j.hasNext(); )
-//      {
-//         Acknowledgment ack = (Acknowledgment)j.next();
-//         booleans.add(new Boolean(ack.isPositive()));
-//         ids.add(ack.getReceiverID());
-//      }
-//      assertTrue(booleans.contains(Boolean.TRUE));
-//      assertTrue(booleans.contains(Boolean.FALSE));
-//      assertTrue(ids.contains("ReceiverONE"));
-//      assertTrue(ids.contains("ReceiverTWO"));
-//
-//
-//      i = nacking.iterator();
-//      assertFalse(i.hasNext());
-//      i = handling.iterator();
-//      assertTrue(m == i.next());
-//      assertFalse(i.hasNext());
-//
-//   }
-//
-//   public void testBrokenReceiver() throws Exception
-//   {
-//      PointToMultipointRouter router = new PointToMultipointRouter("");
-//
-//      // a broken receiver
-//
-//      ReceiverImpl broken = new ReceiverImpl("ReceiverONE", ReceiverImpl.BROKEN);
-//      assertTrue(router.add(broken));
-//
-//      Routable m = new MessageSupport("");
-//      Set result = router.handle(m);
-//      assertEquals(0, result.size());
-//
-//      Iterator i = broken.iterator();
-//      assertFalse(i.hasNext());
-//
-//      // a broken receiver and a handling receiver
-//
-//      ReceiverImpl handling = new ReceiverImpl("ReceiverTWO", ReceiverImpl.HANDLING);
-//      assertTrue(router.add(handling));
-//      result = router.handle(m);
-//      assertEquals(1, result.size());
-//      Acknowledgment a = (Acknowledgment)result.iterator().next();
-//      assertTrue(a.isPositive());
-//      assertEquals("ReceiverTWO", a.getReceiverID());
-//
-//
-//      i = broken.iterator();
-//      assertFalse(i.hasNext());
-//      i = handling.iterator();
-//      assertTrue(m == i.next());
-//      assertFalse(i.hasNext());
-//
-//      handling.clear();
-//
-//      // a broken, handling and NACKing receivers
-//
-//      ReceiverImpl nacking = new ReceiverImpl("ReceiverTHREE", ReceiverImpl.NACKING);
-//      assertTrue(router.add(nacking));
-//      result = router.handle(m);
-//
-//      assertEquals(2, result.size());
-//      Set booleans = new HashSet();
-//      Set ids = new HashSet();
-//      for(Iterator j = result.iterator(); j.hasNext(); )
-//      {
-//         Acknowledgment ack = (Acknowledgment)j.next();
-//         booleans.add(new Boolean(ack.isPositive()));
-//         ids.add(ack.getReceiverID());
-//      }
-//      assertTrue(booleans.contains(Boolean.TRUE));
-//      assertTrue(booleans.contains(Boolean.FALSE));
-//      assertTrue(ids.contains("ReceiverTHREE"));
-//      assertTrue(ids.contains("ReceiverTWO"));
-//
-//
-//      i = broken.iterator();
-//      assertFalse(i.hasNext());
-//      i = handling.iterator();
-//      assertTrue(m == i.next());
-//      assertFalse(i.hasNext());
-//      i = nacking.iterator();
-//      assertFalse(i.hasNext());
-//   }
-}

Deleted: trunk/tests/src/org/jboss/test/messaging/core/PointToPointRouterAsDistributorTest.java
===================================================================
--- trunk/tests/src/org/jboss/test/messaging/core/PointToPointRouterAsDistributorTest.java	2006-08-30 09:26:13 UTC (rev 1236)
+++ trunk/tests/src/org/jboss/test/messaging/core/PointToPointRouterAsDistributorTest.java	2006-08-30 18:36:36 UTC (rev 1237)
@@ -1,206 +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.core;
-
-/**
- * @author <a href="mailto:ovidiu at jboss.org">Ovidiu Feodorov</a>
- * @version <tt>$Revision$</tt>
- */
-public class PointToPointRouterAsDistributorTest extends DistributorTest
-{
-   // Constructors --------------------------------------------------
-
-   public PointToPointRouterAsDistributorTest(String name)
-   {
-      super(name);
-   }
-
-//   public void setUp() throws Exception
-//   {
-//      super.setUp();
-//
-//      // Create a PointToMultipointRouter to be tested by the superclass tests
-//      distributor = new PointToPointRouter("P2PRouterID");
-//   }
-//
-//   public void tearDown()throws Exception
-//   {
-//      distributor.clear();
-//      distributor = null;
-//      super.tearDown();
-//   }
-//
-//   public void testPointToPointRouter() throws Exception
-//   {
-//      PointToPointRouter router = new PointToPointRouter("");
-//
-//      // send without a receiver
-//
-//      Routable r = new MessageSupport(new Integer(0));
-//      Set result = router.handle(r);
-//      assertEquals(0, result.size());
-//
-//      // send with one receiver
-//
-//      ReceiverImpl rOne = new ReceiverImpl("ONE", ReceiverImpl.HANDLING);
-//      assertTrue(router.add(rOne));
-//
-//      r = new MessageSupport(new Integer(1));
-//      result = router.handle(r);
-//      assertEquals(1, result.size());
-//      Acknowledgment a = (Acknowledgment)result.iterator().next();
-//      assertTrue(a.isPositive());
-//      assertEquals("ONE", a.getReceiverID());
-//
-//      Iterator i = rOne.iterator();
-//      r = (Routable)i.next();
-//      assertFalse(i.hasNext());
-//      assertEquals(new Integer(1), r.getMessageID());
-//
-//      rOne.clear();
-//
-//      // send with two receivers
-//
-//      ReceiverImpl rTwo = new ReceiverImpl("TWO", ReceiverImpl.HANDLING);
-//      assertTrue(router.add(rTwo));
-//
-//      r = new MessageSupport(new Integer(2));
-//      result = router.handle(r);
-//      assertEquals(1, result.size());
-//      a = (Acknowledgment)result.iterator().next();
-//      assertTrue(a.isPositive());
-//
-//      Iterator iOne = rOne.iterator(), iTwo = rTwo.iterator();
-//      if (iOne.hasNext())
-//      {
-//         // then rOne got the message
-//         r = (Routable)iOne.next();
-//         assertFalse(iOne.hasNext());
-//         assertEquals(new Integer(2), r.getMessageID());
-//         assertFalse(iOne.hasNext());
-//      }
-//      else
-//      {
-//         // otherwise rTwo got the message
-//         r = (Routable)iTwo.next();
-//         assertFalse(iTwo.hasNext());
-//         assertEquals(new Integer(2), r.getMessageID());
-//         assertFalse(iOne.hasNext());
-//      }
-//   }
-//
-//
-//   public void testNackingReceiver() throws Exception
-//   {
-//      PointToPointRouter router = new PointToPointRouter("");
-//
-//      ReceiverImpl denying = new ReceiverImpl("NackingID", ReceiverImpl.NACKING);
-//      assertTrue(router.add(denying));
-//
-//      Routable r = new MessageSupport("");
-//      Set result = router.handle(r);
-//      assertEquals(1, result.size());
-//      Acknowledgment a = (Acknowledgment)result.iterator().next();
-//      assertTrue(a.isNegative());
-//      assertEquals("NackingID", a.getReceiverID());
-//
-//      Iterator i = denying.iterator();
-//      assertFalse(i.hasNext());
-//
-//      ReceiverImpl handling = new ReceiverImpl("HandlingID", ReceiverImpl.HANDLING);
-//      assertTrue(router.add(handling));
-//      result = router.handle(r);
-//
-//      assertEquals(1, result.size());
-//      a = (Acknowledgment)result.iterator().next();
-//      assertTrue(a.isNegative());
-//      assertEquals("NackingID", a.getReceiverID());
-//
-//      i = denying.iterator();
-//      assertFalse(i.hasNext());
-//
-//      i = handling.iterator();
-//      assertFalse(i.hasNext());
-//   }
-//
-//   public void testBrokenReceiver() throws Exception
-//   {
-//      PointToPointRouter router = new PointToPointRouter("");
-//
-//      // one broken receiver
-//
-//      ReceiverImpl broken1 = new ReceiverImpl("BrokenID1", ReceiverImpl.BROKEN);
-//      assertTrue(router.add(broken1));
-//
-//      Routable r = new MessageSupport("");
-//      Set acks = router.handle(r);
-//      assertEquals(0, acks.size());
-//
-//      assertFalse(broken1.iterator().hasNext());
-//
-//      // two broken receivers
-//
-//      ReceiverImpl broken2 = new ReceiverImpl("BrokenID2", ReceiverImpl.BROKEN);
-//      assertTrue(router.add(broken2));
-//
-//      acks = router.handle(r);
-//      assertEquals(0, acks.size());
-//
-//      assertFalse(broken1.iterator().hasNext());
-//      assertFalse(broken2.iterator().hasNext());
-//
-//      // two broken receivers and a nacking receiver
-//
-//      ReceiverImpl nacking = new ReceiverImpl("NackingID", ReceiverImpl.NACKING);
-//      assertTrue(router.add(nacking));
-//
-//      Set result = router.handle(r);
-//      assertEquals(1, result.size());
-//      Acknowledgment a = (Acknowledgment)result.iterator().next();
-//      assertTrue(a.isNegative());
-//      assertEquals("NackingID", a.getReceiverID());
-//
-//      assertFalse(broken1.iterator().hasNext());
-//      assertFalse(broken2.iterator().hasNext());
-//      assertFalse(nacking.iterator().hasNext());
-//
-//      // two broken receivers and a handling receiver
-//      assertEquals(nacking, router.remove("NackingID"));
-//
-//      ReceiverImpl handling = new ReceiverImpl("HandlingID", ReceiverImpl.HANDLING);
-//      assertTrue(router.add(handling));
-//
-//      result = router.handle(r);
-//      assertEquals(1, result.size());
-//      a = (Acknowledgment)result.iterator().next();
-//      assertTrue(a.isPositive());
-//      assertEquals("HandlingID", a.getReceiverID());
-//
-//      assertFalse(broken1.iterator().hasNext());
-//      assertFalse(broken2.iterator().hasNext());
-//
-//      Iterator i = handling.iterator();
-//      r = (Routable)i.next();
-//      assertFalse(i.hasNext());
-//      assertEquals("", r.getMessageID());
-//   }
-}

Deleted: trunk/tests/src/org/jboss/test/messaging/core/ReplicatorOutputDeliveryTest.java
===================================================================
--- trunk/tests/src/org/jboss/test/messaging/core/ReplicatorOutputDeliveryTest.java	2006-08-30 09:26:13 UTC (rev 1236)
+++ trunk/tests/src/org/jboss/test/messaging/core/ReplicatorOutputDeliveryTest.java	2006-08-30 18:36:36 UTC (rev 1237)
@@ -1,79 +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.core;
-
-import org.jboss.test.messaging.core.base.SingleReceiverDeliveryTestBase;
-import org.jboss.messaging.core.DeliveryObserver;
-import org.jboss.messaging.core.distributed.replicator.ReplicatorOutputDelivery;
-
-/**
- * @author <a href="mailto:ovidiu at jboss.org">Ovidiu Feodorov</a>
- * @version <tt>$Revision$</tt>
- * 
- * $Id$
- */
-public class ReplicatorOutputDeliveryTest extends SingleReceiverDeliveryTestBase
-{
-   // Constants -----------------------------------------------------
-
-   // Static --------------------------------------------------------
-   
-   // Attributes ----------------------------------------------------
-
-   protected DeliveryObserver observer;
-
-   // Constructors --------------------------------------------------
-
-   public ReplicatorOutputDeliveryTest(String name)
-   {
-      super(name);
-   }
-
-   // ChannelTestBase overrides  ------------------------------------
-
-   public void setUp() throws Exception
-   {
-      super.setUp();
-
-      observer = new SimpleDeliveryObserver();
-      delivery = new ReplicatorOutputDelivery(observer, null, "replicatorOutput0", false);
-
-      log.debug("setup done");
-   }
-
-   public void tearDown() throws Exception
-   {
-      delivery = null;
-      observer = null;
-      super.tearDown();
-   }
-
-   // Public --------------------------------------------------------
-
-   // Package protected ---------------------------------------------
-   
-   // Protected -----------------------------------------------------
-   
-   // Private -------------------------------------------------------
-   
-   // Inner classes -------------------------------------------------   
-}

Modified: trunk/tests/src/org/jboss/test/messaging/core/SimpleDeliveryTest.java
===================================================================
--- trunk/tests/src/org/jboss/test/messaging/core/SimpleDeliveryTest.java	2006-08-30 09:26:13 UTC (rev 1236)
+++ trunk/tests/src/org/jboss/test/messaging/core/SimpleDeliveryTest.java	2006-08-30 18:36:36 UTC (rev 1237)
@@ -21,22 +21,25 @@
 */
 package org.jboss.test.messaging.core;
 
-import org.jboss.test.messaging.core.base.SingleReceiverDeliveryTestBase;
-import org.jboss.test.messaging.tools.jmx.ServiceContainer;
+import org.jboss.messaging.core.Delivery;
 import org.jboss.messaging.core.DeliveryObserver;
 import org.jboss.messaging.core.SimpleDelivery;
+import org.jboss.messaging.core.plugin.IdManager;
 import org.jboss.messaging.core.plugin.JDBCPersistenceManager;
 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.test.messaging.MessagingTestCase;
+import org.jboss.test.messaging.tools.jmx.ServiceContainer;
 
 /**
  * @author <a href="mailto:ovidiu at jboss.org">Ovidiu Feodorov</a>
+ * @author <a href="mailto:tim.fox at jboss.org">Tim Fox</a>
  * @version <tt>$Revision$</tt>
  * 
  * $Id$
  */
-public class SimpleDeliveryTest extends SingleReceiverDeliveryTestBase
+public class SimpleDeliveryTest extends MessagingTestCase
 {
    // Constants -----------------------------------------------------
 
@@ -45,6 +48,8 @@
    // Attributes ----------------------------------------------------
 
    protected DeliveryObserver observer;
+   
+   protected Delivery delivery;
 
    // Constructors --------------------------------------------------
 
@@ -74,6 +79,24 @@
 
    // Public --------------------------------------------------------
    
+   public void testAcknowledgment() throws Throwable
+   {
+      assertFalse(delivery.isDone());
+
+      delivery.acknowledge(null);
+
+      assertTrue(delivery.isDone());
+   }
+   
+   public void testCancellation() throws Throwable
+   {
+      assertFalse(delivery.isCancelled());
+
+      delivery.cancel();
+
+      assertTrue(delivery.isCancelled());
+   }
+   
    public void testDoneIsSetWithTransaction() throws Throwable
    {
       //Calling acknowledge on a SimpleDelivery
@@ -94,9 +117,8 @@
       ((JDBCPersistenceManager)pm).start();
       
       TransactionRepository tr = new TransactionRepository();
+      tr.injectAttributes(pm, new IdManager("TRANSACTION_ID", 10, pm));
       
-      tr.start(pm);
-      
       Transaction tx = tr.createTransaction();
       
       ((SimpleDelivery)delivery).acknowledge(tx);
@@ -105,10 +127,7 @@
       
       pm.stop();
       
-      tr.stop();
-      
       sc.stop();
-
    }
 
    // Package protected ---------------------------------------------

Modified: trunk/tests/src/org/jboss/test/messaging/core/SimpleFilter.java
===================================================================
--- trunk/tests/src/org/jboss/test/messaging/core/SimpleFilter.java	2006-08-30 09:26:13 UTC (rev 1236)
+++ trunk/tests/src/org/jboss/test/messaging/core/SimpleFilter.java	2006-08-30 18:36:36 UTC (rev 1237)
@@ -31,6 +31,7 @@
  * A simple test Filter that accepts a message based on the presence of a certain header value.
  *
  * @author <a href="mailto:ovidiu at jboss.org">Ovidiu Feodorov</a>
+ * @author <a href="mailto:tim.fox at jboss.com">Tim Fox</a>
  * @version <tt>$Revision$</tt>
  *
  * $Id$
@@ -39,6 +40,8 @@
 {
    // Constants -----------------------------------------------------
 
+   private static final long serialVersionUID = 4962761960390959612L;
+
    private static final Logger log = Logger.getLogger(SimpleFilter.class);
 
    // Static --------------------------------------------------------
@@ -57,6 +60,11 @@
    }
 
    // Filter implementation -----------------------------------------
+   
+   public String getFilterString()
+   {
+      return null;
+   }
 
    public boolean accept(Routable r)
    {

Modified: trunk/tests/src/org/jboss/test/messaging/core/SimpleReceiver.java
===================================================================
--- trunk/tests/src/org/jboss/test/messaging/core/SimpleReceiver.java	2006-08-30 09:26:13 UTC (rev 1236)
+++ trunk/tests/src/org/jboss/test/messaging/core/SimpleReceiver.java	2006-08-30 18:36:36 UTC (rev 1237)
@@ -21,25 +21,24 @@
 */
 package org.jboss.test.messaging.core;
 
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+
+import org.jboss.logging.Logger;
+import org.jboss.messaging.core.Channel;
+import org.jboss.messaging.core.Delivery;
+import org.jboss.messaging.core.DeliveryObserver;
 import org.jboss.messaging.core.Message;
 import org.jboss.messaging.core.MessageReference;
 import org.jboss.messaging.core.Receiver;
 import org.jboss.messaging.core.Routable;
-import org.jboss.messaging.core.Delivery;
-import org.jboss.messaging.core.DeliveryObserver;
 import org.jboss.messaging.core.SimpleDelivery;
-import org.jboss.messaging.core.Channel;
-import org.jboss.messaging.core.SingleReceiverDelivery;
 import org.jboss.messaging.core.tx.Transaction;
 import org.jboss.messaging.core.tx.TxCallback;
-import org.jboss.logging.Logger;
 
-import java.util.Map;
-import java.util.HashMap;
-import java.util.List;
-import java.util.ArrayList;
-import java.util.Iterator;
-
 /**
  * A simple Receiver implementation that consumes undelivered by storing them internally. Used for
  * testing. The receiver can be configured to immediately return a "done" delivery (ACKING),
@@ -277,14 +276,14 @@
       log.debug(this + " acknowledging "  + r);
 
       Object[] touple = null;
-      SingleReceiverDelivery d = null;
+      Delivery d = null;
       for (Iterator i = messages.iterator(); i.hasNext(); )
       {
          Object[] o = (Object[])i.next();
          Message m = (Message)o[0];
          if (m == r)
          {
-            d = (SingleReceiverDelivery)o[1];
+            d = (Delivery)o[1];
             touple = o;
             break;
          }
@@ -314,14 +313,14 @@
    public void cancel(Routable r) throws Throwable
    {
       Object[] touple = null;
-      SingleReceiverDelivery d = null;
+      Delivery d = null;
       for (Iterator i = messages.iterator(); i.hasNext(); )
       {
          Object[] o = (Object[])i.next();
          Message m = (Message)o[0];
          if (m == r)
          {
-            d = (SingleReceiverDelivery)o[1];
+            d = (Delivery)o[1];
             touple = o;
             i.remove();
             break;

Deleted: trunk/tests/src/org/jboss/test/messaging/core/SingleOutputChannelSupportTest.java
===================================================================
--- trunk/tests/src/org/jboss/test/messaging/core/SingleOutputChannelSupportTest.java	2006-08-30 09:26:13 UTC (rev 1236)
+++ trunk/tests/src/org/jboss/test/messaging/core/SingleOutputChannelSupportTest.java	2006-08-30 18:36:36 UTC (rev 1237)
@@ -1,70 +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.core;
-
-
-/**
- * @author <a href="mailto:ovidiu at jboss.org">Ovidiu Feodorov</a>
- * @version <tt>$Revision$</tt>
- */
-public class SingleOutputChannelSupportTest extends TransactionalChannelSupportTest
-{
-//   // Attributes ----------------------------------------------------
-//
-//   SingleOutputChannelSupport singleOutputChannel;
-//
-   // Constructors --------------------------------------------------
-
-   public SingleOutputChannelSupportTest(String name)
-   {
-      super(name);
-   }
-//
-//   public void setUp() throws Exception
-//   {
-//      singleOutputChannel = (SingleOutputChannelSupport)channel;
-//      super.setUp();
-//   }
-//
-//   public void tearDown()throws Exception
-//   {
-//      singleOutputChannel = null;
-//      super.tearDown();
-//   }
-//
-//   //
-//   //
-//   //
-//
-//   public void testGetOutputID()
-//   {
-//      if (skip()) { return; }
-//
-//      assertEquals(receiverOne.getReceiverID(), singleOutputChannel.getOutputID());
-//   }
-//
-//   private boolean skip()
-//   {
-//      return singleOutputChannel == null;
-//   }
-//
-}
\ No newline at end of file

Deleted: trunk/tests/src/org/jboss/test/messaging/core/TransactionalChannelSupportTest.java
===================================================================
--- trunk/tests/src/org/jboss/test/messaging/core/TransactionalChannelSupportTest.java	2006-08-30 09:26:13 UTC (rev 1236)
+++ trunk/tests/src/org/jboss/test/messaging/core/TransactionalChannelSupportTest.java	2006-08-30 18:36:36 UTC (rev 1237)
@@ -1,419 +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.core;
-
-
-
-
-/**
- * @author <a href="mailto:ovidiu at jboss.org">Ovidiu Feodorov</a>
- * @version <tt>$Revision$</tt>
- */
-public class TransactionalChannelSupportTest extends ChannelSupportTest
-{
-//   // Attributes ----------------------------------------------------
-//
-//   protected TransactionManagerImpl tm;
-//   private TransactionalChannel transactionalChannel;
-//
-//   // Constructors --------------------------------------------------
-//
-   public TransactionalChannelSupportTest(String name)
-   {
-      super(name);
-   }
-//
-//   public void setUp() throws Exception
-//   {
-//      if (channel != null)
-//      {
-//         transactionalChannel = (TransactionalChannel)channel;
-//         tm = TransactionManagerImpl.getInstance();
-//         transactionalChannel.setTransactionManager(tm);
-//      }
-//
-//      super.setUp();
-//   }
-//
-//   public void tearDown()throws Exception
-//   {
-//      transactionalChannel = null;
-//      if (tm != null)
-//      {
-//         tm.setState(TransactionManagerImpl.OPERATIONAL);
-//      }
-//      tm = null;
-//      super.tearDown();
-//   }
-//
-//
-//   //
-//   // Will also run all ChannelSupportTest's tests
-//   //
-//
-//   public void testSetTransactionManager()
-//   {
-//      if (skip()) { return; }
-//
-//      assertTrue(tm == transactionalChannel.getTransactionManager());
-//
-//      transactionalChannel.setTransactionManager(null);
-//      assertNull(transactionalChannel.getTransactionManager());
-//
-//      transactionalChannel.setTransactionManager(tm);
-//      assertTrue(tm == transactionalChannel.getTransactionManager());
-//   }
-//
-//   public void testIsTransactional()
-//   {
-//      if (skip()) { return; }
-//
-//      assertTrue(transactionalChannel.isTransactional());
-//
-//      transactionalChannel.setTransactionManager(null);
-//      assertFalse(transactionalChannel.isTransactional());
-//   }
-//
-//
-//   //
-//   // Transacted handle() tests
-//   //
-//
-//   public void testHandleNoTransactionManager()
-//   {
-//      if (skip()) { return; }
-//
-//      transactionalChannel.setTransactionManager(null);
-//      assertNull(transactionalChannel.getTransactionManager());
-//
-//      RoutableSupport r = new RoutableSupport("one");
-//
-//      // no transaction manager means regular non-transactional handling
-//      assertTrue(transactionalChannel.handle(r));
-//
-//      assertFalse(transactionalChannel.hasMessages());
-//      List l = receiverOne.getMessages();
-//      assertEquals(1, l.size());
-//      assertEquals("one", ((RoutableSupport)l.get(0)).getMessageID());
-//   }
-//
-//   public void testHandleBrokenTransactionManager()
-//   {
-//      if (skip()) { return; }
-//
-//      tm.setState(TransactionManagerImpl.BROKEN);
-//
-//      try
-//      {
-//         transactionalChannel.handle(new RoutableSupport(""));
-//         fail("Should have thrown exception");
-//      }
-//      catch(IllegalStateException e)
-//      {
-//         // OK
-//      }
-//   }
-//
-//   public void testHandleNoActiveTransaction()
-//   {
-//      if (skip()) { return; }
-//
-//      RoutableSupport r = new RoutableSupport("one");
-//
-//      // no active transaction means regular non-transactional handling
-//      assertTrue(transactionalChannel.handle(r));
-//
-//      assertFalse(transactionalChannel.hasMessages());
-//      List l = receiverOne.getMessages();
-//      assertEquals(1, l.size());
-//      assertEquals("one", ((RoutableSupport)l.get(0)).getMessageID());
-//   }
-//
-//   public void testHandleActiveTransactionSynchronousChannel() throws Exception
-//   {
-//      if (skip()) { return; }
-//
-//      assertTrue(transactionalChannel.setSynchronous(true));
-//
-//      RoutableSupport r = new RoutableSupport("one");
-//
-//      tm.begin();
-//      Transaction transaction = tm.getTransaction();
-//
-//      transactionalChannel.handle(r);
-//
-//      assertFalse(transactionalChannel.hasMessages());
-//      assertTrue(receiverOne.getMessages().isEmpty());
-//
-//      try
-//      {
-//         transaction.commit();
-//         fail("should have thrown RollbackException");
-//      }
-//      catch(RollbackException e)
-//      {
-//         // OK
-//      }
-//   }
-//
-//   public void testHandleActiveTransactionAsynchronousChannel() throws Exception
-//   {
-//      if (skip()) { return; }
-//
-//      assertTrue(transactionalChannel.setSynchronous(false));
-//
-//      RoutableSupport r = new RoutableSupport("one");
-//
-//      tm.begin();
-//      Transaction transaction = tm.getTransaction();
-//
-//      transactionalChannel.handle(r);
-//
-//      assertFalse(transactionalChannel.hasMessages());
-//      assertTrue(receiverOne.getMessages().isEmpty());
-//
-//      transaction.commit();
-//
-//      assertFalse(transactionalChannel.hasMessages());
-//      List l = receiverOne.getMessages();
-//      assertEquals(1, l.size());
-//      assertEquals("one", ((RoutableSupport)l.get(0)).getMessageID());
-//   }
-//
-//   public void testHandleActiveTransactionAsynchronousChannel2() throws Exception
-//   {
-//      if (skip()) { return; }
-//
-//      assertTrue(transactionalChannel.setSynchronous(false));
-//
-//      RoutableSupport r1 = new RoutableSupport("1");
-//      RoutableSupport r2 = new RoutableSupport("2");
-//      RoutableSupport r3 = new RoutableSupport("3");
-//
-//      tm.begin();
-//      Transaction transaction = tm.getTransaction();
-//
-//
-//      transactionalChannel.handle(r1);
-//      transactionalChannel.handle(r2);
-//      transactionalChannel.handle(r3);
-//
-//      assertFalse(transactionalChannel.hasMessages());
-//      assertTrue(receiverOne.getMessages().isEmpty());
-//
-//      transaction.commit();
-//
-//      // all messages went to the receiver
-//      assertFalse(transactionalChannel.hasMessages());
-//      List l = receiverOne.getMessages();
-//      assertEquals(3, l.size());
-//
-//      Set ids = new HashSet();
-//      for(Iterator i = receiverOne.iterator(); i.hasNext(); )
-//      {
-//         ids.add(((RoutableSupport)i.next()).getMessageID());
-//      }
-//      assertTrue(ids.contains("1"));
-//      assertTrue(ids.contains("2"));
-//      assertTrue(ids.contains("3"));
-//
-//   }
-//
-//   //
-//   // Transacted acknowledge() tests
-//   //
-//
-//   public void testAcknowledgeNoTransactionManager()
-//   {
-//      if (skip()) { return; }
-//
-//      transactionalChannel.setTransactionManager(null);
-//      assertNull(transactionalChannel.getTransactionManager());
-//
-//      // add an undeliverable message to the channel
-//      assertTrue(transactionalChannel.setSynchronous(false));
-//      receiverOne.setState(ReceiverImpl.NACKING);
-//      RoutableSupport r = new RoutableSupport("one");
-//      assertTrue(transactionalChannel.handle(r));
-//      assertTrue(transactionalChannel.hasMessages());
-//      Set undelivered = transactionalChannel.getUndelivered();
-//      assertEquals(1, undelivered.size());
-//      assertEquals("one", undelivered.iterator().next());
-//
-//      // no transaction manager means regular non-transactional acknowledgment
-//      transactionalChannel.acknowledge("one", receiverOne.getReceiverID());
-//
-//      assertFalse(transactionalChannel.hasMessages());
-//      assertTrue(transactionalChannel.getUndelivered().isEmpty());
-//   }
-//
-//   public void testAcknowledgeBrokenTransactionManager()
-//   {
-//      if (skip()) { return; }
-//
-//      // add an undeliverable message to the channel
-//      assertTrue(transactionalChannel.setSynchronous(false));
-//      receiverOne.setState(ReceiverImpl.NACKING);
-//      RoutableSupport r = new RoutableSupport("one");
-//      assertTrue(transactionalChannel.handle(r));
-//      assertTrue(transactionalChannel.hasMessages());
-//      Set undelivered = transactionalChannel.getUndelivered();
-//      assertEquals(1, undelivered.size());
-//      assertEquals("one", undelivered.iterator().next());
-//
-//
-//      // break the transaction manager
-//      tm.setState(TransactionManagerImpl.BROKEN);
-//
-//      try
-//      {
-//         transactionalChannel.acknowledge("one", receiverOne.getReceiverID());
-//         fail("Should have thrown exception");
-//      }
-//      catch(IllegalStateException e)
-//      {
-//         // OK
-//      }
-//
-//      assertTrue(transactionalChannel.hasMessages());
-//      undelivered = transactionalChannel.getUndelivered();
-//      assertEquals(1, undelivered.size());
-//      assertEquals("one", undelivered.iterator().next());
-//   }
-//
-//   public void testAcknowledgeNoActiveTransaction()
-//   {
-//      if (skip()) { return; }
-//
-//      // add an undeliverable message to the channel
-//      assertTrue(transactionalChannel.setSynchronous(false));
-//      receiverOne.setState(ReceiverImpl.NACKING);
-//      RoutableSupport r = new RoutableSupport("one");
-//      assertTrue(transactionalChannel.handle(r));
-//      assertTrue(transactionalChannel.hasMessages());
-//      Set undelivered = transactionalChannel.getUndelivered();
-//      assertEquals(1, undelivered.size());
-//      assertEquals("one", undelivered.iterator().next());
-//
-//      // no active transaction means regular non-transactional acknowledgment
-//      transactionalChannel.acknowledge("one", receiverOne.getReceiverID());
-//
-//      assertFalse(transactionalChannel.hasMessages());
-//      assertTrue(transactionalChannel.getUndelivered().isEmpty());
-//   }
-//
-//   public void testAcknowledgeActiveTransaction() throws Exception
-//   {
-//      if (skip()) { return; }
-//
-//      // add an undeliverable message to the channel
-//      assertTrue(transactionalChannel.setSynchronous(false));
-//      receiverOne.setState(ReceiverImpl.NACKING);
-//      RoutableSupport r = new RoutableSupport("one");
-//      assertTrue(transactionalChannel.handle(r));
-//      assertTrue(transactionalChannel.hasMessages());
-//      Set undelivered = transactionalChannel.getUndelivered();
-//      assertEquals(1, undelivered.size());
-//      assertEquals("one", undelivered.iterator().next());
-//
-//
-//      tm.begin();
-//      Transaction transaction = tm.getTransaction();
-//
-//      // acknowledge transactionally
-//      transactionalChannel.acknowledge("one", receiverOne.getReceiverID());
-//
-//      // the channel should still keep the message
-//      assertTrue(transactionalChannel.hasMessages());
-//      undelivered = transactionalChannel.getUndelivered();
-//      assertEquals(1, undelivered.size());
-//      assertEquals("one", undelivered.iterator().next());
-//
-//      transaction.commit();
-//
-//      assertFalse(transactionalChannel.hasMessages());
-//      assertTrue(transactionalChannel.getUndelivered().isEmpty());
-//   }
-//
-//   public void testAcknowledgeActiveTransactionMultipleMessages() throws Exception
-//   {
-//      if (skip()) { return; }
-//
-//      // add an undeliverable message to the channel
-//      assertTrue(transactionalChannel.setSynchronous(false));
-//      receiverOne.setState(ReceiverImpl.NACKING);
-//      assertTrue(transactionalChannel.handle(new RoutableSupport("one")));
-//      assertTrue(transactionalChannel.handle(new RoutableSupport("two")));
-//      assertTrue(transactionalChannel.handle(new RoutableSupport("three")));
-//      assertTrue(transactionalChannel.hasMessages());
-//      Set undelivered = transactionalChannel.getUndelivered();
-//      assertEquals(3, undelivered.size());
-//      assertTrue(undelivered.contains("one"));
-//      assertTrue(undelivered.contains("two"));
-//      assertTrue(undelivered.contains("three"));
-//
-//      tm.begin();
-//      Transaction transaction = tm.getTransaction();
-//
-//      // acknowledge transactionally
-//      transactionalChannel.acknowledge("one", receiverOne.getReceiverID());
-//      transactionalChannel.acknowledge("two", receiverOne.getReceiverID());
-//
-//      // the channel should still keep the message
-//      assertTrue(transactionalChannel.hasMessages());
-//      undelivered = transactionalChannel.getUndelivered();
-//      assertEquals(3, undelivered.size());
-//      assertTrue(undelivered.contains("one"));
-//      assertTrue(undelivered.contains("two"));
-//      assertTrue(undelivered.contains("three"));
-//
-//      transaction.commit();
-//
-//      // the channel should still keep one message
-//      assertTrue(transactionalChannel.hasMessages());
-//      undelivered = transactionalChannel.getUndelivered();
-//      assertEquals(1, undelivered.size());
-//      assertTrue(undelivered.contains("three"));
-//
-//      tm.begin();
-//      transaction = tm.getTransaction();
-//      transactionalChannel.acknowledge("three", receiverOne.getReceiverID());
-//
-//      // the channel should still keep one message
-//      assertTrue(transactionalChannel.hasMessages());
-//      undelivered = transactionalChannel.getUndelivered();
-//      assertEquals(1, undelivered.size());
-//      assertTrue(undelivered.contains("three"));
-//
-//      transaction.commit();
-//
-//      assertFalse(transactionalChannel.hasMessages());
-//      assertTrue(transactionalChannel.getUndelivered().isEmpty());
-//   }
-//
-//
-//   private boolean skip()
-//   {
-//      return transactionalChannel == null;
-//   }
-
-}
\ No newline at end of file

Deleted: trunk/tests/src/org/jboss/test/messaging/core/base/ChannelTestBase.java
===================================================================
--- trunk/tests/src/org/jboss/test/messaging/core/base/ChannelTestBase.java	2006-08-30 09:26:13 UTC (rev 1236)
+++ trunk/tests/src/org/jboss/test/messaging/core/base/ChannelTestBase.java	2006-08-30 18:36:36 UTC (rev 1237)
@@ -1,6303 +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.core.base;
-
-import java.util.ArrayList;
-import java.util.Iterator;
-import java.util.List;
-
-import javax.naming.InitialContext;
-
-import org.jboss.messaging.core.Delivery;
-import org.jboss.messaging.core.Message;
-import org.jboss.messaging.core.MessageReference;
-import org.jboss.messaging.core.Receiver;
-import org.jboss.messaging.core.Routable;
-import org.jboss.messaging.core.message.MessageFactory;
-import org.jboss.messaging.core.plugin.JDBCPersistenceManager;
-import org.jboss.messaging.core.plugin.SimpleMessageStore;
-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.test.messaging.core.BrokenReceiver;
-import org.jboss.test.messaging.core.SimpleDeliveryObserver;
-import org.jboss.test.messaging.core.SimpleReceiver;
-
-/**
- * The Channel test strategy is to try as many combination as it makes sense of the following
- * variables:
- *
- * 1. The channel can be non-recoverable (does not have access to a PersistenceManager) or
- *    recoverable. A non-recoverable channel can accept reliable messages or not.
- * 2. The channel may have zero or one receivers (the behavior for more than one receiver depends
- *    on the particular router implementation).
- * 3. The receiver may be ACKING or NACKING (the case when it throws unchecked exceptions is handled
- *    at the Router level).
- * 4. The sender can send message(s) non-transactionally or transactionally (and then can commit
- *    or rollback the transaction).
- * 5. The NACKING receiver can send acknowledgment(s) non-transactionally or transactionally (and
- *    then can commit or rollback the transaction).
- * 6. The message can be non-reliable or reliable.
- * 7. The sender can send one or multiple messages.
- * 8. A recoverable channel may be crashed and tested if it successfully recovers.
- *
- * This test base also tests the Distributor interface.
- *
- * @author <a href="mailto:ovidiu at jboss.org">Ovidiu Feodorov</a>
- * @author <a href="mailto:tim.fox at jboss.com">Tim Fox</a>
- * @version <tt>$Revision$</tt>
- *
- * $Id$
- */
-public abstract class ChannelTestBase extends NoTestsChannelTestBase
-{
-   // Constants -----------------------------------------------------
-
-   public static final int NUMBER_OF_MESSAGES = 10;
-
-   // Static --------------------------------------------------------
-   
-   // Attributes ----------------------------------------------------
-
-   // the MessageStore requires a PersistenceManager, othewise it will reject reliable messages
-   protected PersistenceManager msPersistenceManagerDelegate;
-   protected TransactionRepository tr;
-   protected MessageStore ms;
-
-   // Constructors --------------------------------------------------
-
-   public ChannelTestBase(String name)
-   {
-      super(name);
-   }
-
-   // Public --------------------------------------------------------
-
-   public void setUp() throws Exception
-   {
-      super.setUp();
-
-      InitialContext ic = new InitialContext();
-      tr = new TransactionRepository();
-      ic.close();
-
-      msPersistenceManagerDelegate =
-         new JDBCPersistenceManager(sc.getDataSource(), sc.getTransactionManager());
-      
-      ((JDBCPersistenceManager)msPersistenceManagerDelegate).start();
-      
-      tr.start(this.msPersistenceManagerDelegate);
-      
-      ms = new SimpleMessageStore("s47");
-
-   }
-
-   public void tearDown() throws Exception
-   {
-      ms = null;
-      tr = null;
-      super.tearDown();
-   }
-
-   public static void assertEqualSets(Routable[] a, List routables)
-   {
-      assertEquals(a.length, routables.size());
-      List l = new ArrayList(routables);
-
-      for(int i = 0; i < a.length; i++)
-      {
-         for(Iterator j = l.iterator(); j.hasNext(); )
-         {
-            Object o = j.next();
-            Message m = null;
-            if (o instanceof MessageReference)
-            {
-               MessageReference ref = (MessageReference)o;
-               m = ref.getMessage();
-            }
-            else
-            {
-               m = (Message)o;
-            }
-
-            if (a[i].getMessageID() == m.getMessageID() &&
-                (a[i] instanceof Message ? ((Message)a[i]).getPayload().equals(m.getPayload()) : true))
-            {
-               j.remove();
-               break;
-            }
-         }
-      }
-
-      if (!l.isEmpty())
-      {
-         fail("Messages " + l + " do not match!");
-      }
-   }
-
-   public static void assertEqualSets(Delivery[] a, List deliveries)
-   {
-      assertEquals(a.length, deliveries.size());
-      List l = new ArrayList(deliveries);
-
-      for(int i = 0; i < a.length; i++)
-      {
-         for(Iterator j = l.iterator(); j.hasNext(); )
-         {
-            Delivery d = (Delivery)j.next();
-            MessageReference ref = d.getReference();
-
-            if (a[i].getReference().getMessageID() == ref.getMessageID())
-            {
-               j.remove();
-               break;
-            }
-         }
-      }
-
-      if (!l.isEmpty())
-      {
-         fail("Deliveries " + l + " do not match!");
-      }
-   }
-
-
-   // Channel tests -------------------------------------------------
-   
-   
-   
-   /*
-    * If a channel has a set a receiver and remove is called with a different receiver
-    * need to ensure the receiver is not removed (since it doesn't match)
-    */
-   public void testRemoveDifferentReceiver() throws Exception
-   {
-      Receiver receiver1 = new SimpleReceiver();
-      
-      Receiver receiver2 = new SimpleReceiver();
-      
-      assertFalse(channel.iterator().hasNext());
-      
-      channel.add(receiver1);
-      
-      assertTrue(channel.contains(receiver1));
-      
-      channel.remove(receiver1);
-      
-      assertFalse(channel.iterator().hasNext());
-      
-      assertFalse(channel.contains(receiver1));
-      
-      channel.add(receiver1);
-      
-      assertTrue(channel.contains(receiver1));
-      
-      channel.remove(receiver2);
-      
-      assertTrue(channel.contains(receiver1));
-                 
-   }
-
-   public void testClosedChannel() throws Exception
-   {
-      channel.close();
-      try
-      {
-         channel.handle(null, MessageFactory.createCoreMessage(0), null);
-         fail("should throw exception");
-      }
-      catch(IllegalStateException e)
-      {
-         //OK
-      }
-   }
-
-   public void testHandleNullRoutable() throws Exception
-   {
-      SimpleDeliveryObserver observer = new SimpleDeliveryObserver();
-      assertNull(channel.handle(observer, null, null));
-   }
-
-   //////////////////////////////////
-   ////////////////////////////////// Test matrix
-   //////////////////////////////////
-
-   //
-   // Non-recoverable channel
-   //
-
-   ////
-   //// Zero receivers
-   ////
-
-   //////
-   ////// Non-transacted send
-   //////
-
-   ////////
-   //////// Non-reliable message
-   ////////
-
-   //////////
-   ////////// One message
-   //////////
-
-   public void testNonRecoverableChannel_1() throws Exception
-   {
-      if (channel.isRecoverable())
-      {
-         // we test only non-recoverable channels now
-         return;
-      }
-
-      // the channel has no receivers
-      assertFalse(channel.iterator().hasNext());
-
-      Message m = MessageFactory.createCoreMessage(0, false, "payload");
-      SimpleDeliveryObserver observer = new SimpleDeliveryObserver();
-
-      // non-transacted send, non-reliable message, one message
-      Delivery delivery = channel.handle(observer, m, null);
-
-      assertTrue(delivery.isDone());
-
-      List stored = channel.browse();
-      assertEquals(1, stored.size());
-
-      Message sm = (Message)stored.iterator().next();
-      assertFalse(sm.isReliable());
-      assertEquals(0, sm.getMessageID());
-
-      SimpleReceiver receiver = new SimpleReceiver("ACKING", SimpleReceiver.ACKING);
-      channel.add(receiver);
-      channel.deliver(true);
-      assertEquals(1, receiver.getMessages().size());
-      assertEquals(0, ((Message)receiver.getMessages().get(0)).getMessageID());
-
-      channel.deliver(true);
-      assertEquals(1, receiver.getMessages().size());
-
-
-   }
-
-   //////////
-   ////////// Multiple message
-   //////////
-
-   public void testNonRecoverableChannel_2() throws Exception
-   {
-      if (channel.isRecoverable())
-      {
-         // we test only non-recoverable channels now
-         return;
-      }
-
-      // the channel has no receivers
-      assertFalse(channel.iterator().hasNext());
-
-      SimpleDeliveryObserver observer = new SimpleDeliveryObserver();
-
-      Message[] messages = new Message[NUMBER_OF_MESSAGES];
-      for(int i = 0; i < NUMBER_OF_MESSAGES; i++)
-      {
-         messages[i] = MessageFactory.createCoreMessage(i, false, "payload" + i);
-
-         // non-transacted send, non-reliable message, multiple messages
-         Delivery delivery = channel.handle(observer, messages[i], null);
-
-         assertTrue(delivery.isDone());
-      }
-
-      List stored = channel.browse();
-      assertEqualSets(messages, stored);
-
-      SimpleReceiver receiver = new SimpleReceiver("ACKING", SimpleReceiver.ACKING);
-      channel.add(receiver);
-      channel.deliver(true);
-      assertEquals(10, receiver.getMessages().size());
-      for(int i = 0; i < NUMBER_OF_MESSAGES; i++)
-      {
-         assertEquals(i, ((Message)receiver.getMessages().get(i)).getMessageID());         
-      }
-      receiver.clear();
-
-      channel.deliver(true);
-      assertEquals(0, receiver.getMessages().size());
-   }
-
-   ////////
-   //////// Reliable message
-   ////////
-
-   //////////
-   ////////// One message
-   //////////
-
-   ///////////
-   /////////// Channel does NOT accept reliable messages
-   ///////////
-
-   public void testNonRecoverableChannel_3_1() throws Exception
-   {
-      if (channel.isRecoverable())
-      {
-         // we test only non-recoverable channels now
-         return;
-      }
-
-      if (channel.acceptReliableMessages())
-      {
-         // we test channels that don't accept reliable messages
-         return;
-      }
-
-      // the channel has no receivers
-      assertFalse(channel.iterator().hasNext());
-
-      Message m = MessageFactory.createCoreMessage(0, true, "payload");
-      SimpleDeliveryObserver observer = new SimpleDeliveryObserver();
-
-      // non-transacted send, reliable message, one message
-      Delivery delivery = channel.handle(observer, m, null);
-
-      // the channel must not accept the message
-      assertNull(delivery);
-
-      assertTrue(channel.browse().isEmpty());
-
-      channel.deliver(true);
-      
-      Receiver r = new SimpleReceiver("ACKING", SimpleReceiver.ACKING);
-      
-      channel.add(r);
-      
-      channel.deliver(true);
-   }
-
-   ///////////
-   /////////// Channel accepts reliable messages
-   ///////////
-
-   public void testNonRecoverableChannel_3_2() throws Exception
-   {
-      if (channel.isRecoverable())
-      {
-         // we test only non-recoverable channels now
-         return;
-      }
-
-      if (!channel.acceptReliableMessages())
-      {
-         // we test channels that accept reliable messages
-         return;
-      }
-
-      // the channel has no receivers
-      assertFalse(channel.iterator().hasNext());
-
-      Message m = MessageFactory.createCoreMessage(0, true, "payload");
-      SimpleDeliveryObserver observer = new SimpleDeliveryObserver();
-
-      // non-transacted send, reliable message, one message
-      Delivery delivery = channel.handle(observer, m, null);
-
-      assertTrue(delivery.isDone());
-
-      List stored = channel.browse();
-      assertEquals(1, stored.size());
-
-      Message sm = (Message)stored.iterator().next();
-      assertTrue(sm.isReliable());
-      assertEquals(0, sm.getMessageID());
-
-      channel.deliver(true);
-
-      SimpleReceiver receiver = new SimpleReceiver("ACKING", SimpleReceiver.ACKING);
-      channel.add(receiver);
-      channel.deliver(true);
-      assertEquals(1, receiver.getMessages().size());
-      assertEquals(0, ((Message)receiver.getMessages().get(0)).getMessageID());
-
-      channel.deliver(true);
-      assertEquals(1, receiver.getMessages().size());
-   }
-
-   //////////
-   ////////// Multiple message
-   //////////
-
-   ///////////
-   /////////// Channel does NOT accept reliable messages
-   ///////////
-
-   public void testNonRecoverableChannel_4_1() throws Exception
-   {
-      if (channel.isRecoverable())
-      {
-         // we test only non-recoverable channels now
-         return;
-      }
-
-      if (channel.acceptReliableMessages())
-      {
-         // we test channels that don't accept reliable messages
-         return;
-      }
-
-      // the channel has no receivers
-      assertFalse(channel.iterator().hasNext());
-
-      SimpleDeliveryObserver observer = new SimpleDeliveryObserver();
-
-      Message[] messages = new Message[NUMBER_OF_MESSAGES];
-      for(int i = 0; i < NUMBER_OF_MESSAGES; i++)
-      {
-         messages[i] = MessageFactory.createCoreMessage(i, true, "payload" + i);
-
-         // non-transacted send, reliable message, multiple messages
-         Delivery delivery = channel.handle(observer, messages[i], null);
-
-         // the channel must not accept the message
-         assertNull(delivery);
-
-         channel.deliver(true);
-         
-         Receiver r = new SimpleReceiver("ACKING", SimpleReceiver.ACKING);
-         
-         channel.add(r);
-         
-         channel.deliver(true);
-      }
-
-      assertTrue(channel.browse().isEmpty());
-   }
-
-   ///////////
-   /////////// Channel accepts reliable messages
-   ///////////
-
-   public void testNonRecoverableChannel_4_2() throws Exception
-   {
-      if (channel.isRecoverable())
-      {
-         // we test only non-recoverable channels now
-         return;
-      }
-
-      if (!channel.acceptReliableMessages())
-      {
-         // we test channels that accept reliable messages
-         return;
-      }
-
-      // the channel has no receivers
-      assertFalse(channel.iterator().hasNext());
-
-      SimpleDeliveryObserver observer = new SimpleDeliveryObserver();
-
-      Message[] messages = new Message[NUMBER_OF_MESSAGES];
-      for(int i = 0; i < NUMBER_OF_MESSAGES; i++)
-      {
-         messages[i] = MessageFactory.createCoreMessage(i, true, "payload" + i);
-
-         // non-transacted send, reliable message, multiple messages
-         Delivery delivery = channel.handle(observer, messages[i], null);
-
-         assertTrue(delivery.isDone());
-      }
-
-      assertEqualSets(messages, channel.browse());
-
-      SimpleReceiver receiver = new SimpleReceiver("ACKING", SimpleReceiver.ACKING);
-      channel.add(receiver);
-      channel.deliver(true);
-      assertEquals(10, receiver.getMessages().size());
-      for(int i = 0; i < NUMBER_OF_MESSAGES; i++)
-      {
-         assertEquals(i, ((Message)receiver.getMessages().get(i)).getMessageID());         
-      }
-      receiver.clear();
-
-      channel.deliver(true);
-      assertEquals(0, receiver.getMessages().size());
-   }
-
-
-
-   //////
-   ////// Transacted send and commit
-   //////
-
-   ////////
-   //////// Non-reliable message
-   ////////
-
-   //////////
-   ////////// One message
-   //////////
-
-   public void testNonRecoverableChannel_5() throws Exception
-   {
-      if (channel.isRecoverable())
-      {
-         // we test only non-recoverable channels now
-         return;
-      }
-
-      // the channel has no receivers
-      assertFalse(channel.iterator().hasNext());
-
-      Message m = MessageFactory.createCoreMessage(0, false, "payload");
-      SimpleDeliveryObserver observer = new SimpleDeliveryObserver();
-
-      Transaction tx = tr.createTransaction();
-
-      // transacted send, non-reliable message, one message
-      // for a transactional send, handle() return value is unspecified
-      channel.handle(observer, m, tx);
-
-      // no messages in the channel yet
-      assertEquals(0, channel.browse().size());
-
-      tx.commit();
-
-      List stored = channel.browse();
-      assertEquals(1, stored.size());
-
-      Message sm = (Message)stored.iterator().next();
-      assertFalse(sm.isReliable());
-      assertEquals(0, sm.getMessageID());
-   }
-
-
-
-   //////////
-   ////////// Multiple message
-   //////////
-
-   public void testNonRecoverableChannel_6() throws Exception
-   {
-      if (channel.isRecoverable())
-      {
-         // we test only non-recoverable channels now
-         return;
-      }
-
-      // the channel has no receivers
-      assertFalse(channel.iterator().hasNext());
-
-      SimpleDeliveryObserver observer = new SimpleDeliveryObserver();
-
-      Transaction tx = tr.createTransaction();
-
-      Message[] messages = new Message[NUMBER_OF_MESSAGES];
-      for(int i = 0; i < NUMBER_OF_MESSAGES; i++)
-      {
-         messages[i] = MessageFactory.createCoreMessage(i, false, "payload" + i);
-
-         // transacted send, non-reliable message, multiple messages
-         // for a transactional send, handle() return value is unspecified
-         channel.handle(observer, messages[i], tx);
-      }
-
-      // no messages in the channel yet
-      assertEquals(0, channel.browse().size());
-
-      tx.commit();
-
-      List stored = channel.browse();
-      assertEqualSets(messages, stored);
-   }
-
-   ////////
-   //////// Reliable message
-   ////////
-
-   //////////
-   ////////// One message
-   //////////
-
-   ///////////
-   /////////// Channel does NOT accept reliable messages
-   ///////////
-
-   public void testNonRecoverableChannel_7_1() throws Exception
-   {
-      if (channel.isRecoverable())
-      {
-         // we test only non-recoverable channels now
-         return;
-      }
-
-      if (channel.acceptReliableMessages())
-      {
-         // we test channels that don't accept reliable messages
-         return;
-      }
-
-      // the channel has no receivers
-      assertFalse(channel.iterator().hasNext());
-
-      Message m = MessageFactory.createCoreMessage(0, true, "payload");
-      SimpleDeliveryObserver observer = new SimpleDeliveryObserver();
-
-      Transaction tx = tr.createTransaction();
-
-      // transacted send, reliable message, one message
-      // for a transactional send, handle() return value is unspecified
-      channel.handle(observer, m, tx);
-
-      // no messages in the channel yet
-      assertEquals(0, channel.browse().size());
-
-      try
-      {
-         tx.commit();
-         fail("this should throw exception");
-      }
-      catch(Exception e)
-      {
-         // OK
-      }
-
-      // still no messages in the channel
-      assertEquals(0, channel.browse().size());
-   }
-
-   ///////////
-   /////////// Channel accepts reliable messages
-   ///////////
-
-   public void testNonRecoverableChannel_7_2() throws Exception
-   {
-      if (channel.isRecoverable())
-      {
-         // we test only non-recoverable channels now
-         return;
-      }
-
-      if (!channel.acceptReliableMessages())
-      {
-         // we test channels that don't accept reliable messages
-         return;
-      }
-
-      // the channel has no receivers
-      assertFalse(channel.iterator().hasNext());
-
-      Message m = MessageFactory.createCoreMessage(0, true, "payload");
-      SimpleDeliveryObserver observer = new SimpleDeliveryObserver();
-
-      Transaction tx = tr.createTransaction();
-
-      // transacted send, reliable message, one message
-      // for a transactional send, handle() return value is unspecified
-      channel.handle(observer, m, tx);
-
-      // no messages in the channel yet
-      assertEquals(0, channel.browse().size());
-
-      tx.commit();
-
-      List stored = channel.browse();
-      assertEquals(1, stored.size());
-
-      Message sm = (Message)stored.iterator().next();
-      assertTrue(sm.isReliable());
-      assertEquals(0, sm.getMessageID());
-   }
-
-   //////////
-   ////////// Multiple message
-   //////////
-
-   ///////////
-   /////////// Channel does NOT accept reliable messages
-   ///////////
-
-   public void testNonRecoverableChannel_8_1() throws Exception
-   {
-      if (channel.isRecoverable())
-      {
-         // we test only non-recoverable channels now
-         return;
-      }
-
-      if (channel.acceptReliableMessages())
-      {
-         // we test channels that don't accept reliable messages
-         return;
-      }
-
-      // the channel has no receivers
-      assertFalse(channel.iterator().hasNext());
-
-      SimpleDeliveryObserver observer = new SimpleDeliveryObserver();
-
-      Transaction tx = tr.createTransaction();
-
-      Message[] messages = new Message[NUMBER_OF_MESSAGES];
-      for(int i = 0; i < NUMBER_OF_MESSAGES; i++)
-      {
-         messages[i] = MessageFactory.createCoreMessage(i, true, "payload" + i);
-
-         // transacted send, reliable message, multiple messages
-         // for a transactional send, handle() return value is unspecified
-         channel.handle(observer, messages[i], tx);
-      }
-
-      // no messages in the channel yet
-      assertEquals(0, channel.browse().size());
-
-      try
-      {
-         tx.commit();
-         fail("this should throw exception");
-      }
-      catch(Exception e)
-      {
-         // OK
-      }
-
-      // still no messages in the channel
-      assertEquals(0, channel.browse().size());
-
-   }
-
-   /**
-    * This is a variation where I send a mixture of reliable and non-reliable messages,
-    */
-   public void testNonRecoverableChannel_8_1_mixed() throws Exception
-   {
-      if (channel.isRecoverable())
-      {
-         // we test only non-recoverable channels now
-         return;
-      }
-
-      if (channel.acceptReliableMessages())
-      {
-         // we test channels that don't accept reliable messages
-         return;
-      }
-
-      // the channel has no receivers
-      assertFalse(channel.iterator().hasNext());
-
-      SimpleDeliveryObserver observer = new SimpleDeliveryObserver();
-
-      Transaction tx = tr.createTransaction();
-
-      Message[] messages = new Message[NUMBER_OF_MESSAGES];
-      for(int i = 0; i < NUMBER_OF_MESSAGES; i++)
-      {
-         // send a mixture of reliable and non-reliable messages
-         messages[i] = MessageFactory.createCoreMessage(i, (i % 2 == 1), "payload" + i);
-
-         // transacted send, reliable/non-reliable messages, multiple messages
-         // for a transactional send, handle() return value is unspecified
-         channel.handle(observer, messages[i], tx);
-      }
-
-      // no messages in the channel yet
-      assertEquals(0, channel.browse().size());
-
-      try
-      {
-         tx.commit();
-         fail("this should throw exception");
-      }
-      catch(Exception e)
-      {
-         // OK
-      }
-
-      // still no messages in the channel
-      assertEquals(0, channel.browse().size());
-
-   }
-   
-   public void testNonRecoverableChannel_8_1_mixed_1() throws Exception
-   {
-      if (channel.isRecoverable())
-      {
-         // we test only non-recoverable channels now
-         return;
-      }
-
-      if (channel.acceptReliableMessages())
-      {
-         // we test channels that don't accept reliable messages
-         return;
-      }
-
-      // the channel has no receivers
-      assertFalse(channel.iterator().hasNext());
-
-      SimpleDeliveryObserver observer = new SimpleDeliveryObserver();
-
-      Transaction tx = tr.createTransaction();
-
-      Message[] messages = new Message[NUMBER_OF_MESSAGES * 2];
-      for(int i = 0; i < NUMBER_OF_MESSAGES; i++)
-      {
-         // send a mixture of reliable and non-reliable messages
-         messages[i] = MessageFactory.createCoreMessage(i, false, "payload" + i);
-
-         // transacted send, reliable/non-reliable messages, multiple messages
-         // for a transactional send, handle() return value is unspecified
-         channel.handle(observer, messages[i], tx);
-      }
-      for(int i = 0; i < NUMBER_OF_MESSAGES; i++)
-      {
-         // send a mixture of reliable and non-reliable messages
-         messages[i + NUMBER_OF_MESSAGES] = MessageFactory.createCoreMessage(i + NUMBER_OF_MESSAGES , true, "payload" + i);
-
-         // transacted send, reliable/non-reliable messages, multiple messages
-         // for a transactional send, handle() return value is unspecified
-         channel.handle(observer, messages[i + NUMBER_OF_MESSAGES], tx);
-      }
-
-      // no messages in the channel yet
-      assertEquals(0, channel.browse().size());
-
-      try
-      {
-         tx.commit();
-         fail("this should throw exception");
-      }
-      catch(Exception e)
-      {
-         // OK
-      }
-
-      // still no messages in the channel
-      assertEquals(0, channel.browse().size());
-
-   }
-   
-
-   public void testNonRecoverableChannel_8_1_mixed_2() throws Exception
-   {
-      if (channel.isRecoverable())
-      {
-         // we test only non-recoverable channels now
-         return;
-      }
-
-      if (channel.acceptReliableMessages())
-      {
-         // we test channels that don't accept reliable messages
-         return;
-      }
-
-      // the channel has no receivers
-      assertFalse(channel.iterator().hasNext());
-
-      SimpleDeliveryObserver observer = new SimpleDeliveryObserver();
-
-      Transaction tx = tr.createTransaction();
-
-      Message[] messages = new Message[NUMBER_OF_MESSAGES * 2];
-      for(int i = 0; i < NUMBER_OF_MESSAGES; i++)
-      {
-         // send a mixture of reliable and non-reliable messages
-         messages[i] = MessageFactory.createCoreMessage(i, true, "payload" + i);
-
-         // transacted send, reliable/non-reliable messages, multiple messages
-         // for a transactional send, handle() return value is unspecified
-         channel.handle(observer, messages[i], tx);
-      }
-      for(int i = 0; i < NUMBER_OF_MESSAGES; i++)
-      {
-         // send a mixture of reliable and non-reliable messages
-         messages[i + NUMBER_OF_MESSAGES] = MessageFactory.createCoreMessage(i + NUMBER_OF_MESSAGES , true, "payload" + i);
-
-         // transacted send, reliable/non-reliable messages, multiple messages
-         // for a transactional send, handle() return value is unspecified
-         channel.handle(observer, messages[i + NUMBER_OF_MESSAGES], tx);
-      }
-
-      // no messages in the channel yet
-      assertEquals(0, channel.browse().size());
-
-      try
-      {
-         tx.commit();
-         fail("this should throw exception");
-      }
-      catch(Exception e)
-      {
-         // OK
-      }
-
-      // still no messages in the channel
-      assertEquals(0, channel.browse().size());
-
-   }
-
-   ///////////
-   /////////// Channel accepts reliable messages
-   ///////////
-
-   public void testNonRecoverableChannel_8_2() throws Exception
-   {
-      if (channel.isRecoverable())
-      {
-         // we test only non-recoverable channels now
-         return;
-      }
-
-      if (!channel.acceptReliableMessages())
-      {
-         // we test channels that accept reliable messages
-         return;
-      }
-
-      // the channel has no receivers
-      assertFalse(channel.iterator().hasNext());
-
-      SimpleDeliveryObserver observer = new SimpleDeliveryObserver();
-
-      Transaction tx = tr.createTransaction();
-
-      Message[] messages = new Message[NUMBER_OF_MESSAGES];
-      for(int i = 0; i < NUMBER_OF_MESSAGES; i++)
-      {
-         messages[i] = MessageFactory.createCoreMessage(i, true, "payload" + i);
-
-         // transacted send, reliable message, multiple messages
-         // for a transactional send, handle() return value is unspecified
-         channel.handle(observer, messages[i], tx);
-      }
-
-      // no messages in the channel yet
-      assertEquals(0, channel.browse().size());
-
-      tx.commit();
-
-      assertEqualSets(messages, channel.browse());
-   }
-
-   /**
-    * This is a variation where I send a mixture of reliable and non-reliable messages,
-    */
-   public void testNonRecoverableChannel_8_2_mixed() throws Exception
-   {
-      if (channel.isRecoverable())
-      {
-         // we test only non-recoverable channels now
-         return;
-      }
-
-      if (!channel.acceptReliableMessages())
-      {
-         // we test channels that accept reliable messages
-         return;
-      }
-
-      // the channel has no receivers
-      assertFalse(channel.iterator().hasNext());
-
-      SimpleDeliveryObserver observer = new SimpleDeliveryObserver();
-
-      Transaction tx = tr.createTransaction();
-
-      Message[] messages = new Message[NUMBER_OF_MESSAGES];
-      for(int i = 0; i < NUMBER_OF_MESSAGES; i++)
-      {
-         // send a mixture of reliable and non-reliable messages
-         messages[i] = MessageFactory.createCoreMessage(i, (i % 2 == 1), "payload" + i);
-
-         // transacted send, reliable/non-reliable messages, multiple messages
-         // for a transactional send, handle() return value is unspecified
-         channel.handle(observer, messages[i], tx);
-      }
-
-      // no messages in the channel yet
-      assertEquals(0, channel.browse().size());
-
-      tx.commit();
-
-      assertEqualSets(messages, channel.browse());
-   }
-
-
-   //////
-   ////// Transacted send and rollback
-   //////
-
-   ////////
-   //////// Non-reliable message
-   ////////
-
-   //////////
-   ////////// One message
-   //////////
-
-   public void testNonRecoverableChannel_9() throws Exception
-   {
-      if (channel.isRecoverable())
-      {
-         // we test only non-recoverable channels now
-         return;
-      }
-
-      // the channel has no receivers
-      assertFalse(channel.iterator().hasNext());
-
-      Message m = MessageFactory.createCoreMessage(0, false, "payload");
-      SimpleDeliveryObserver observer = new SimpleDeliveryObserver();
-
-      Transaction tx = tr.createTransaction();
-
-      // transacted send, non-reliable message, one message
-      // for a transactional send, handle() return value is unspecified
-      channel.handle(observer, m, tx);
-
-      // no messages in the channel yet
-      assertEquals(0, channel.browse().size());
-
-      tx.rollback();
-
-      // still no messages in the channel
-      assertEquals(0, channel.browse().size());
-   }
-
-   //////////
-   ////////// Multiple message
-   //////////
-
-   public void testNonRecoverableChannel_10() throws Exception
-   {
-      if (channel.isRecoverable())
-      {
-         // we test only non-recoverable channels now
-         return;
-      }
-
-      // the channel has no receivers
-      assertFalse(channel.iterator().hasNext());
-
-      SimpleDeliveryObserver observer = new SimpleDeliveryObserver();
-
-      Transaction tx = tr.createTransaction();
-
-      Message[] messages = new Message[NUMBER_OF_MESSAGES];
-      for(int i = 0; i < NUMBER_OF_MESSAGES; i++)
-      {
-         messages[i] = MessageFactory.createCoreMessage(i, false, "payload" + i);
-
-         // transacted send, non-reliable message, multiple messages
-         // for a transactional send, handle() return value is unspecified
-         channel.handle(observer, messages[i], tx);
-      }
-
-      // no messages in the channel yet
-      assertEquals(0, channel.browse().size());
-
-      tx.rollback();
-
-      // still no messages in the channel
-      assertEquals(0, channel.browse().size());
-   }
-
-   ////////
-   //////// Reliable message
-   ////////
-
-   //////////
-   ////////// One message
-   //////////
-
-   public void testNonRecoverableChannel_11() throws Exception
-   {
-      if (channel.isRecoverable())
-      {
-         // we test only non-recoverable channels now
-         return;
-      }
-
-      // the channel has no receivers
-      assertFalse(channel.iterator().hasNext());
-
-      Message m = MessageFactory.createCoreMessage(0, true, "payload");
-      SimpleDeliveryObserver observer = new SimpleDeliveryObserver();
-
-      Transaction tx = tr.createTransaction();
-
-      // transacted send, reliable message, one message
-      // for a transactional send, handle() return value is unspecified
-      channel.handle(observer, m, tx);
-
-      // no messages in the channel yet
-      assertEquals(0, channel.browse().size());
-
-      tx.rollback();
-
-      // still no messages in the channel
-      assertEquals(0, channel.browse().size());
-   }
-
-   //////////
-   ////////// Multiple message
-   //////////
-
-   public void testNonRecoverableChannel_12() throws Exception
-   {
-      if (channel.isRecoverable())
-      {
-         // we test only non-recoverable channels now
-         return;
-      }
-
-      // the channel has no receivers
-      assertFalse(channel.iterator().hasNext());
-
-      SimpleDeliveryObserver observer = new SimpleDeliveryObserver();
-
-      Transaction tx = tr.createTransaction();
-
-      Message[] messages = new Message[NUMBER_OF_MESSAGES];
-      for(int i = 0; i < NUMBER_OF_MESSAGES; i++)
-      {
-         messages[i] = MessageFactory.createCoreMessage(i, true, "payload" + i);
-
-         // transacted send, reliable message, multiple messages
-         // for a transactional send, handle() return value is unspecified
-         channel.handle(observer, messages[i], tx);
-      }
-
-      // no messages in the channel yet
-      assertEquals(0, channel.browse().size());
-
-      tx.rollback();
-
-      // still no messages in the channel
-      assertEquals(0, channel.browse().size());
-   }
-
-   /**
-    * This is a variation where I send a mixture of reliable and non-reliable messages,
-    */
-   public void testNonRecoverableChannel_12_mixed() throws Exception
-   {
-      if (channel.isRecoverable())
-      {
-         // we test only non-recoverable channels now
-         return;
-      }
-
-      // the channel has no receivers
-      assertFalse(channel.iterator().hasNext());
-
-      SimpleDeliveryObserver observer = new SimpleDeliveryObserver();
-
-      Transaction tx = tr.createTransaction();
-
-      Message[] messages = new Message[NUMBER_OF_MESSAGES];
-      for(int i = 0; i < NUMBER_OF_MESSAGES; i++)
-      {
-         // send a mixture of reliable and non-reliable messages
-         messages[i] = MessageFactory.createCoreMessage(i, (i % 2 == 1), "payload" + i);
-
-         // transacted send, reliable/non-reliable messages, multiple messages
-         // for a transactional send, handle() return value is unspecified
-         channel.handle(observer, messages[i], tx);
-      }
-
-      // no messages in the channel yet
-      assertEquals(0, channel.browse().size());
-
-      tx.rollback();
-
-      // still no messages in the channel
-      assertEquals(0, channel.browse().size());
-   }
-
-   ////
-   //// One receiver
-   ////
-
-   //////
-   ////// ACKING receiver
-   //////
-
-   //////
-   ////// Non-transacted send
-   //////
-
-   ////////
-   //////// Non-reliable message
-   ////////
-
-   //////////
-   ////////// One message
-   //////////
-
-   public void testNonRecoverableChannel_13() throws Exception
-   {
-      if (channel.isRecoverable())
-      {
-         // we test only non-recoverable channels now
-         return;
-      }
-
-      // add an ACKING receiver to the channel
-      SimpleReceiver r = new SimpleReceiver("AckingReceiver", SimpleReceiver.ACKING);
-      assertTrue(channel.add(r));
-
-      Message m = MessageFactory.createCoreMessage(0, false, "payload");
-      SimpleDeliveryObserver observer = new SimpleDeliveryObserver();
-
-      // non-transacted send, non-reliable message, one message
-      Delivery delivery = channel.handle(observer, m, null);
-
-      assertTrue(delivery.isDone());
-      assertTrue(channel.browse().isEmpty());
-
-      List received = r.getMessages();
-      assertEquals(1, received.size());
-      Message sm = (Message)received.iterator().next();
-      assertFalse(sm.isReliable());
-      assertEquals(0, sm.getMessageID());
-   }
-
-   //////////
-   ////////// Multiple message
-   //////////
-
-   public void testNonRecoverableChannel_14() throws Exception
-   {
-      if (channel.isRecoverable())
-      {
-         // we test only non-recoverable channels now
-         return;
-      }
-
-      // add an ACKING receiver to the channel
-      SimpleReceiver r = new SimpleReceiver("AckingReceiver", SimpleReceiver.ACKING);
-      assertTrue(channel.add(r));
-
-      SimpleDeliveryObserver observer = new SimpleDeliveryObserver();
-
-      Message[] messages = new Message[NUMBER_OF_MESSAGES];
-      for(int i = 0; i < NUMBER_OF_MESSAGES; i++)
-      {
-         messages[i] = MessageFactory.createCoreMessage(i, false, "payload" + i);
-
-         // non-transacted send, non-reliable message, multiple messages
-         Delivery delivery = channel.handle(observer, messages[i], null);
-
-         assertTrue(delivery.isDone());
-      }
-
-      assertTrue(channel.browse().isEmpty());
-
-      List received = r.getMessages();
-      assertEqualSets(messages, received);
-   }
-
-   ////////
-   //////// Reliable message
-   ////////
-
-   //////////
-   ////////// One message
-   //////////
-
-   ///////////
-   /////////// Channel does NOT accept reliable messages
-   ///////////
-
-   public void testNonRecoverableChannel_15_1() throws Exception
-   {
-      if (channel.isRecoverable())
-      {
-         // we test only non-recoverable channels now
-         return;
-      }
-
-      if (channel.acceptReliableMessages())
-      {
-         // we test channels that don't accept reliable messages
-         return;
-      }
-
-      // add an ACKING receiver to the channel
-      SimpleReceiver r = new SimpleReceiver("AckingReceiver", SimpleReceiver.ACKING);
-      assertTrue(channel.add(r));
-
-      Message m = MessageFactory.createCoreMessage(0, true, "payload");
-      SimpleDeliveryObserver observer = new SimpleDeliveryObserver();
-
-      // non-transacted send, reliable message, one message
-      Delivery delivery = channel.handle(observer, m, null);
-
-      assertNull(delivery);
-
-      assertTrue(channel.browse().isEmpty());
-      assertTrue(r.getMessages().isEmpty());
-   }
-
-   ///////////
-   /////////// Channel accepts reliable messages
-   ///////////
-
-   public void testNonRecoverableChannel_15_2() throws Exception
-   {
-      if (channel.isRecoverable())
-      {
-         // we test only non-recoverable channels now
-         return;
-      }
-
-      if (!channel.acceptReliableMessages())
-      {
-         // we test channels that accept reliable messages
-         return;
-      }
-
-      // add an ACKING receiver to the channel
-      SimpleReceiver r = new SimpleReceiver("AckingReceiver", SimpleReceiver.ACKING);
-      assertTrue(channel.add(r));
-
-      Message m = MessageFactory.createCoreMessage(0, true, "payload");
-      SimpleDeliveryObserver observer = new SimpleDeliveryObserver();
-
-      // non-transacted send, reliable message, one message
-      Delivery delivery = channel.handle(observer, m, null);
-
-      assertTrue(delivery.isDone());
-
-      assertTrue(channel.browse().isEmpty());
-
-      List received = r.getMessages();
-      assertEquals(1, received.size());
-      Message sm = (Message)received.iterator().next();
-      assertTrue(sm.isReliable());
-      assertEquals(0, sm.getMessageID());
-   }
-
-   //////////
-   ////////// Multiple message
-   //////////
-
-   ///////////
-   /////////// Channel does NOT accept reliable messages
-   ///////////
-
-   public void testNonRecoverableChannel_16_1() throws Exception
-   {
-      if (channel.isRecoverable())
-      {
-         // we test only non-recoverable channels now
-         return;
-      }
-
-      if (channel.acceptReliableMessages())
-      {
-         // we test channels that don't accept reliable messages
-         return;
-      }
-
-      // add an ACKING receiver to the channel
-      SimpleReceiver r = new SimpleReceiver("AckingReceiver", SimpleReceiver.ACKING);
-      assertTrue(channel.add(r));
-
-      SimpleDeliveryObserver observer = new SimpleDeliveryObserver();
-
-      Message[] messages = new Message[NUMBER_OF_MESSAGES];
-      for(int i = 0; i < NUMBER_OF_MESSAGES; i++)
-      {
-         messages[i] = MessageFactory.createCoreMessage(i, true, "payload" + i);
-
-         // non-transacted send, reliable message, multiple messages
-         Delivery delivery = channel.handle(observer, messages[i], null);
-
-         assertNull(delivery);
-      }
-
-      assertTrue(channel.browse().isEmpty());
-      assertTrue(r.getMessages().isEmpty());
-   }
-
-   ///////////
-   /////////// Channel accepts reliable messages
-   ///////////
-
-   public void testNonRecoverableChannel_16_2() throws Exception
-   {
-      if (channel.isRecoverable())
-      {
-         // we test only non-recoverable channels now
-         return;
-      }
-
-      if (!channel.acceptReliableMessages())
-      {
-         // we test channels that accept reliable messages
-         return;
-      }
-
-      // add an ACKING receiver to the channel
-      SimpleReceiver r = new SimpleReceiver("AckingReceiver", SimpleReceiver.ACKING);
-      assertTrue(channel.add(r));
-
-      SimpleDeliveryObserver observer = new SimpleDeliveryObserver();
-
-      Message[] messages = new Message[NUMBER_OF_MESSAGES];
-      for(int i = 0; i < NUMBER_OF_MESSAGES; i++)
-      {
-         messages[i] = MessageFactory.createCoreMessage(i, true, "payload" + i);
-
-         // non-transacted send, reliable message, multiple messages
-         Delivery delivery = channel.handle(observer, messages[i], null);
-
-         assertTrue(delivery.isDone());
-      }
-
-      assertTrue(channel.browse().isEmpty());
-      assertEqualSets(messages, r.getMessages());
-   }
-
-   //////
-   ////// Transacted send and commit
-   //////
-
-   ////////
-   //////// Non-reliable message
-   ////////
-
-   //////////
-   ////////// One message
-   //////////
-
-   public void testNonRecoverableChannel_17() throws Exception
-   {
-      if (channel.isRecoverable())
-      {
-         // we test only non-recoverable channels now
-         return;
-      }
-
-      // add an ACKING receiver to the channel
-      SimpleReceiver r = new SimpleReceiver("AckingReceiver", SimpleReceiver.ACKING);
-      assertTrue(channel.add(r));
-
-      Message m = MessageFactory.createCoreMessage(0, false, "payload");
-      SimpleDeliveryObserver observer = new SimpleDeliveryObserver();
-
-      Transaction tx = tr.createTransaction();
-
-      // transacted send, non-reliable message, one message
-      // for a transactional send, handle() return value is unspecified
-      channel.handle(observer, m, tx);
-
-      // no messages in the channel
-      assertEquals(0, channel.browse().size());
-
-      // no message at the receiver
-      assertTrue(r.getMessages().isEmpty());
-
-      tx.commit();
-
-      assertTrue(channel.browse().isEmpty());
-
-      List received = r.getMessages();
-      assertEquals(1, received.size());
-      Message sm = (Message)received.iterator().next();
-      assertFalse(sm.isReliable());
-      assertEquals(0, sm.getMessageID());
-   }
-
-   //////////
-   ////////// Multiple message
-   //////////
-
-   public void testNonRecoverableChannel_18() throws Exception
-   {
-      if (channel.isRecoverable())
-      {
-         // we test only non-recoverable channels now
-         return;
-      }
-
-      // add an ACKING receiver to the channel
-      SimpleReceiver r = new SimpleReceiver("AckingReceiver", SimpleReceiver.ACKING);
-      assertTrue(channel.add(r));
-
-      SimpleDeliveryObserver observer = new SimpleDeliveryObserver();
-
-      Transaction tx = tr.createTransaction();
-
-      Message[] messages = new Message[NUMBER_OF_MESSAGES];
-      for(int i = 0; i < NUMBER_OF_MESSAGES; i++)
-      {
-         messages[i] = MessageFactory.createCoreMessage(i, false, "payload" + i);
-
-         // transacted send, non-reliable message, multiple messages
-         // for a transactional send, handle() return value is unspecified
-         channel.handle(observer, messages[i], tx);
-      }
-
-      // no messages in the channel
-      assertEquals(0, channel.browse().size());
-
-      // no message at the receiver
-      assertTrue(r.getMessages().isEmpty());
-
-      tx.commit();
-
-      assertTrue(channel.browse().isEmpty());
-      assertEqualSets(messages, r.getMessages());
-   }
-
-   ////////
-   //////// Reliable message
-   ////////
-
-   //////////
-   ////////// One message
-   //////////
-
-   ///////////
-   /////////// Channel does NOT accept reliable messages
-   ///////////
-
-   public void testNonRecoverableChannel_19_1() throws Exception
-   {
-      if (channel.isRecoverable())
-      {
-         // we test only non-recoverable channels now
-         return;
-      }
-
-      if (channel.acceptReliableMessages())
-      {
-         // we test channels that don't accept reliable messages
-         return;
-      }
-
-      // add an ACKING receiver to the channel
-      SimpleReceiver r = new SimpleReceiver("AckingReceiver", SimpleReceiver.ACKING);
-      assertTrue(channel.add(r));
-
-
-      Message m = MessageFactory.createCoreMessage(0, true, "payload");
-      SimpleDeliveryObserver observer = new SimpleDeliveryObserver();
-
-      Transaction tx = tr.createTransaction();
-
-      // transacted send, reliable message, one message
-      // for a transactional send, handle() return value is unspecified
-      channel.handle(observer, m, tx);
-
-      // no messages in the channel yet
-      assertEquals(0, channel.browse().size());
-
-      // no message at the receiver
-      assertTrue(r.getMessages().isEmpty());
-
-      try
-      {
-         tx.commit();
-         fail("this should throw exception");
-      }
-      catch(Exception e)
-      {
-         // OK
-      }
-
-      // no messages in the channel
-      assertEquals(0, channel.browse().size());
-
-      // no message at the receiver
-      assertTrue(r.getMessages().isEmpty());
-   }
-
-   ///////////
-   /////////// Channel accepts reliable messages
-   ///////////
-
-   public void testNonRecoverableChannel_19_2() throws Exception
-   {
-      if (channel.isRecoverable())
-      {
-         // we test only non-recoverable channels now
-         return;
-      }
-
-      if (!channel.acceptReliableMessages())
-      {
-         // we test channels that accept reliable messages
-         return;
-      }
-
-      // add an ACKING receiver to the channel
-      SimpleReceiver r = new SimpleReceiver("AckingReceiver", SimpleReceiver.ACKING);
-      assertTrue(channel.add(r));
-
-
-      Message m = MessageFactory.createCoreMessage(0, true, "payload");
-      SimpleDeliveryObserver observer = new SimpleDeliveryObserver();
-
-      Transaction tx = tr.createTransaction();
-
-      // transacted send, reliable message, one message
-      // for a transactional send, handle() return value is unspecified
-      channel.handle(observer, m, tx);
-
-      // no messages in the channel yet
-      assertEquals(0, channel.browse().size());
-
-      // no message at the receiver
-      assertTrue(r.getMessages().isEmpty());
-
-      tx.commit();
-
-      // no messages in the channel
-      assertEquals(0, channel.browse().size());
-
-      List received = r.getMessages();
-      assertEquals(1, received.size());
-      Message sm = (Message)received.iterator().next();
-      assertTrue(sm.isReliable());
-      assertEquals(0, sm.getMessageID());
-   }
-
-   //////////
-   ////////// Multiple message
-   //////////
-
-   ///////////
-   /////////// Channel does NOT accept reliable messages
-   ///////////
-
-   public void testNonRecoverableChannel_20_1() throws Exception
-   {
-      if (channel.isRecoverable())
-      {
-         // we test only non-recoverable channels now
-         return;
-      }
-
-      if (channel.acceptReliableMessages())
-      {
-         // we test channels that don't accept reliable messages
-         return;
-      }
-
-      // add an ACKING receiver to the channel
-      SimpleReceiver r = new SimpleReceiver("AckingReceiver", SimpleReceiver.ACKING);
-      assertTrue(channel.add(r));
-
-      SimpleDeliveryObserver observer = new SimpleDeliveryObserver();
-
-      Transaction tx = tr.createTransaction();
-
-      Message[] messages = new Message[NUMBER_OF_MESSAGES];
-      for(int i = 0; i < NUMBER_OF_MESSAGES; i++)
-      {
-         messages[i] = MessageFactory.createCoreMessage(i, true, "payload" + i);
-
-         // transacted send, reliable message, multiple messages
-         // for a transactional send, handle() return value is unspecified
-         channel.handle(observer, messages[i], tx);
-      }
-
-      // no messages in the channel yet
-      assertEquals(0, channel.browse().size());
-
-      // no message at the receiver
-      assertTrue(r.getMessages().isEmpty());
-
-      try
-      {
-         tx.commit();
-         fail("this should throw exception");
-      }
-      catch(Exception e)
-      {
-         // OK
-      }
-
-      // no messages in the channel
-      assertEquals(0, channel.browse().size());
-
-      // no message at the receiver
-      assertTrue(r.getMessages().isEmpty());
-   }
-
-   /**
-    * This is a variation where I send a mixture of reliable and non-reliable messages,
-    */
-   public void testNonRecoverableChannel_20_1_mixed() throws Exception
-   {
-      if (channel.isRecoverable())
-      {
-         // we test only non-recoverable channels now
-         return;
-      }
-
-      if (channel.acceptReliableMessages())
-      {
-         // we test channels that don't accept reliable messages
-         return;
-      }
-
-      // add an ACKING receiver to the channel
-      SimpleReceiver r = new SimpleReceiver("AckingReceiver", SimpleReceiver.ACKING);
-      assertTrue(channel.add(r));
-
-
-      SimpleDeliveryObserver observer = new SimpleDeliveryObserver();
-
-      Transaction tx = tr.createTransaction();
-
-      Message[] messages = new Message[NUMBER_OF_MESSAGES];
-      for(int i = 0; i < NUMBER_OF_MESSAGES; i++)
-      {
-         // send a mixture of reliable and non-reliable messages
-         messages[i] = MessageFactory.createCoreMessage(i, (i % 2 == 1), "payload" + i);
-
-         // transacted send, reliable/non-reliable messages, multiple messages
-         // for a transactional send, handle() return value is unspecified
-         channel.handle(observer, messages[i], tx);
-      }
-
-      // no messages in the channel
-      assertEquals(0, channel.browse().size());
-
-      // no message at the receiver
-      assertTrue(r.getMessages().isEmpty());
-
-      try
-      {
-         tx.commit();
-         fail("this should throw exception");
-      }
-      catch(Exception e)
-      {
-         // OK
-      }
-
-      // no messages in the channel
-      assertEquals(0, channel.browse().size());
-
-      // no message at the receiver
-      assertTrue(r.getMessages().isEmpty());
-   }
-
-   ///////////
-   /////////// Channel accepts reliable messages
-   ///////////
-
-   public void testNonRecoverableChannel_20_2() throws Exception
-   {
-      if (channel.isRecoverable())
-      {
-         // we test only non-recoverable channels now
-         return;
-      }
-
-      if (!channel.acceptReliableMessages())
-      {
-         // we test channels that accept reliable messages
-         return;
-      }
-
-      // add an ACKING receiver to the channel
-      SimpleReceiver r = new SimpleReceiver("AckingReceiver", SimpleReceiver.ACKING);
-      assertTrue(channel.add(r));
-
-      SimpleDeliveryObserver observer = new SimpleDeliveryObserver();
-
-      Transaction tx = tr.createTransaction();
-
-      Message[] messages = new Message[NUMBER_OF_MESSAGES];
-      for(int i = 0; i < NUMBER_OF_MESSAGES; i++)
-      {
-         messages[i] = MessageFactory.createCoreMessage(i, true, "payload" + i);
-
-         // transacted send, reliable message, multiple messages
-         // for a transactional send, handle() return value is unspecified
-         channel.handle(observer, messages[i], tx);
-      }
-
-      // no messages in the channel yet
-      assertEquals(0, channel.browse().size());
-
-      // no message at the receiver
-      assertTrue(r.getMessages().isEmpty());
-
-      tx.commit();
-
-      // no messages in the channel
-      assertEquals(0, channel.browse().size());
-
-      assertEqualSets(messages, r.getMessages());
-   }
-
-   /**
-    * This is a variation where I send a mixture of reliable and non-reliable messages,
-    */
-   public void testNonRecoverableChannel_20_2_mixed() throws Exception
-   {
-      if (channel.isRecoverable())
-      {
-         // we test only non-recoverable channels now
-         return;
-      }
-
-      if (!channel.acceptReliableMessages())
-      {
-         // we test channels that accept reliable messages
-         return;
-      }
-
-      // add an ACKING receiver to the channel
-      SimpleReceiver r = new SimpleReceiver("AckingReceiver", SimpleReceiver.ACKING);
-      assertTrue(channel.add(r));
-
-
-      SimpleDeliveryObserver observer = new SimpleDeliveryObserver();
-
-      Transaction tx = tr.createTransaction();
-
-      Message[] messages = new Message[NUMBER_OF_MESSAGES];
-      for(int i = 0; i < NUMBER_OF_MESSAGES; i++)
-      {
-         // send a mixture of reliable and non-reliable messages
-         messages[i] = MessageFactory.createCoreMessage(i, (i % 2 == 1), "payload" + i);
-
-         // transacted send, reliable/non-reliable messages, multiple messages
-         // for a transactional send, handle() return value is unspecified
-         channel.handle(observer, messages[i], tx);
-      }
-
-      // no messages in the channel
-      assertEquals(0, channel.browse().size());
-
-      // no message at the receiver
-      assertTrue(r.getMessages().isEmpty());
-
-      tx.commit();
-
-      // no messages in the channel
-      assertEquals(0, channel.browse().size());
-
-      assertEqualSets(messages, r.getMessages());
-   }
-
-   //////
-   ////// Transacted send and rollback
-   //////
-
-   ////////
-   //////// Non-reliable message
-   ////////
-
-   //////////
-   ////////// One message
-   //////////
-
-   public void testNonRecoverableChannel_21() throws Exception
-   {
-      if (channel.isRecoverable())
-      {
-         // we test only non-recoverable channels now
-         return;
-      }
-
-      // add an ACKING receiver to the channel
-      SimpleReceiver r = new SimpleReceiver("AckingReceiver", SimpleReceiver.ACKING);
-      assertTrue(channel.add(r));
-
-
-      Message m = MessageFactory.createCoreMessage(0, false, "payload");
-      SimpleDeliveryObserver observer = new SimpleDeliveryObserver();
-
-      Transaction tx = tr.createTransaction();
-
-      // transacted send, non-reliable message, one message
-      // for a transactional send, handle() return value is unspecified
-      channel.handle(observer, m, tx);
-
-      // no messages in the channel
-      assertEquals(0, channel.browse().size());
-
-      // no message at the receiver
-      assertTrue(r.getMessages().isEmpty());
-
-
-      tx.rollback();
-
-      // no messages in the channel
-      assertEquals(0, channel.browse().size());
-
-      // no message at the receiver
-      assertTrue(r.getMessages().isEmpty());
-
-   }
-
-   //////////
-   ////////// Multiple message
-   //////////
-
-   public void testNonRecoverableChannel_22() throws Exception
-   {
-      if (channel.isRecoverable())
-      {
-         // we test only non-recoverable channels now
-         return;
-      }
-
-      // add an ACKING receiver to the channel
-      SimpleReceiver r = new SimpleReceiver("AckingReceiver", SimpleReceiver.ACKING);
-      assertTrue(channel.add(r));
-
-      SimpleDeliveryObserver observer = new SimpleDeliveryObserver();
-
-      Transaction tx = tr.createTransaction();
-
-      Message[] messages = new Message[NUMBER_OF_MESSAGES];
-      for(int i = 0; i < NUMBER_OF_MESSAGES; i++)
-      {
-         messages[i] = MessageFactory.createCoreMessage(i, false, "payload" + i);
-
-         // transacted send, non-reliable message, multiple messages
-         // for a transactional send, handle() return value is unspecified
-         channel.handle(observer, messages[i], tx);
-      }
-
-      // no messages in the channel
-      assertEquals(0, channel.browse().size());
-
-      // no message at the receiver
-      assertTrue(r.getMessages().isEmpty());
-
-      tx.rollback();
-
-      // no messages in the channel
-      assertEquals(0, channel.browse().size());
-
-      // no message at the receiver
-      assertTrue(r.getMessages().isEmpty());
-   }
-
-   ////////
-   //////// Reliable message
-   ////////
-
-   //////////
-   ////////// One message
-   //////////
-
-   public void testNonRecoverableChannel_23() throws Exception
-   {
-      if (channel.isRecoverable())
-      {
-         // we test only non-recoverable channels now
-         return;
-      }
-
-      // add an ACKING receiver to the channel
-      SimpleReceiver r = new SimpleReceiver("AckingReceiver", SimpleReceiver.ACKING);
-      assertTrue(channel.add(r));
-
-
-      Message m = MessageFactory.createCoreMessage(0, true, "payload");
-      SimpleDeliveryObserver observer = new SimpleDeliveryObserver();
-
-      Transaction tx = tr.createTransaction();
-
-      // transacted send, reliable message, one message
-      // for a transactional send, handle() return value is unspecified
-      channel.handle(observer, m, tx);
-
-      // no messages in the channel
-      assertEquals(0, channel.browse().size());
-
-      // no message at the receiver
-      assertTrue(r.getMessages().isEmpty());
-
-      tx.rollback();
-
-      // no messages in the channel
-      assertEquals(0, channel.browse().size());
-
-      // no message at the receiver
-      assertTrue(r.getMessages().isEmpty());
-   }
-
-   //////////
-   ////////// Multiple message
-   //////////
-
-   public void testNonRecoverableChannel_24() throws Exception
-   {
-      if (channel.isRecoverable())
-      {
-         // we test only non-recoverable channels now
-         return;
-      }
-
-      // add an ACKING receiver to the channel
-      SimpleReceiver r = new SimpleReceiver("AckingReceiver", SimpleReceiver.ACKING);
-      assertTrue(channel.add(r));
-
-
-      SimpleDeliveryObserver observer = new SimpleDeliveryObserver();
-
-      Transaction tx = tr.createTransaction();
-
-      Message[] messages = new Message[NUMBER_OF_MESSAGES];
-      for(int i = 0; i < NUMBER_OF_MESSAGES; i++)
-      {
-         messages[i] = MessageFactory.createCoreMessage(i, true, "payload" + i);
-
-         // transacted send, reliable message, multiple messages
-         // for a transactional send, handle() return value is unspecified
-         channel.handle(observer, messages[i], tx);
-      }
-
-      // no messages in the channel
-      assertEquals(0, channel.browse().size());
-
-      // no message at the receiver
-      assertTrue(r.getMessages().isEmpty());
-
-      tx.rollback();
-
-      // no messages in the channel
-      assertEquals(0, channel.browse().size());
-
-      // no message at the receiver
-      assertTrue(r.getMessages().isEmpty());
-   }
-
-   /**
-    * This is a variation where I send a mixture of reliable and non-reliable messages,
-    */
-   public void testNonRecoverableChannel_24_mixed() throws Exception
-   {
-      if (channel.isRecoverable())
-      {
-         // we test only non-recoverable channels now
-         return;
-      }
-
-      // add an ACKING receiver to the channel
-      SimpleReceiver r = new SimpleReceiver("AckingReceiver", SimpleReceiver.ACKING);
-      assertTrue(channel.add(r));
-
-
-      SimpleDeliveryObserver observer = new SimpleDeliveryObserver();
-
-      Transaction tx = tr.createTransaction();
-
-      Message[] messages = new Message[NUMBER_OF_MESSAGES];
-      for(int i = 0; i < NUMBER_OF_MESSAGES; i++)
-      {
-         // send a mixture of reliable and non-reliable messages
-         messages[i] = MessageFactory.createCoreMessage(i, (i % 2 == 1), "payload" + i);
-
-         // transacted send, reliable/non-reliable messages, multiple messages
-         // for a transactional send, handle() return value is unspecified
-         channel.handle(observer, messages[i], tx);
-      }
-
-      // no messages in the channel
-      assertEquals(0, channel.browse().size());
-
-      // no message at the receiver
-      assertTrue(r.getMessages().isEmpty());
-
-      tx.rollback();
-
-      // no messages in the channel
-      assertEquals(0, channel.browse().size());
-
-      // no message at the receiver
-      assertTrue(r.getMessages().isEmpty());
-   }
-
-   //////
-   ////// NACKING receiver
-   //////
-
-   //////
-   ////// Non-transacted send
-   //////
-
-   ////////
-   //////// Non-reliable message
-   ////////
-
-   //////////
-   ////////// One message
-   //////////
-
-   ////////////
-   //////////// Non-transacted acknowledgment
-   ////////////
-
-   public void testNonRecoverableChannel_25() throws Throwable
-   {
-      if (channel.isRecoverable())
-      {
-         // we test only non-recoverable channels now
-         return;
-      }
-
-      // add an NACKING receiver to the channel
-      SimpleReceiver r = new SimpleReceiver("NackingReceiver", SimpleReceiver.NACKING);
-      assertTrue(channel.add(r));
-
-      Message m = MessageFactory.createCoreMessage(0, false, "payload");
-      SimpleDeliveryObserver observer = new SimpleDeliveryObserver();
-
-      // non-transacted send, non-reliable message, one message
-      Delivery delivery = channel.handle(observer, m, null);
-
-      assertTrue(delivery.isDone());
-
-      List delivering = channel.browse();
-      assertEquals(1, delivering.size());
-      assertEquals(0, ((Message)delivering.get(0)).getMessageID());
-
-      List acknowledging = r.getMessages();
-      assertEquals(1, acknowledging.size());
-      Message ackm = (Message)acknowledging.get(0);
-      assertEquals(0, ackm.getMessageID());
-
-      // non-transacted acknowledgment
-      r.acknowledge(ackm, null);
-
-      assertTrue(channel.browse().isEmpty());
-   }
-
-   /**
-    * The same test as before, but with a Receiver configured to acknowledge immediately
-    * on the Delivery. Simulates a race condition in which the acknoledgment arrives before
-    * the Delivery is returned to channel.
-    *
-    * @throws Throwable
-    */
-   public void testNonRecoverableChannel_25_race() throws Throwable
-   {
-      if (channel.isRecoverable())
-      {
-         // we test only non-recoverable channels now
-         return;
-      }
-
-      // add an NACKING receiver to the channel
-      SimpleReceiver r = new SimpleReceiver("NackingReceiver", SimpleReceiver.NACKING);
-      r.setImmediateAsynchronousAcknowledgment(true);
-      assertTrue(channel.add(r));
-
-      Message m = MessageFactory.createCoreMessage(0, false, "payload");
-      SimpleDeliveryObserver observer = new SimpleDeliveryObserver();
-
-      // non-transacted send, non-reliable message, one message
-      Delivery delivery = channel.handle(observer, m, null);
-
-      assertTrue(delivery.isDone());
-
-      // the receiver should have returned a "done" delivery
-      assertTrue(channel.browse().isEmpty());
-
-      List messages = r.getMessages();
-      assertEquals(1, messages.size());
-      Message ackm = (Message)messages.get(0);
-      assertEquals(0, ackm.getMessageID());
-
-      // an extra acknowledgment should be discarded
-      r.acknowledge(ackm, null);
-
-      assertTrue(channel.browse().isEmpty());
-   }
-
-
-   ////////////
-   //////////// Transacted acknowledgment and commit
-   ////////////
-
-   public void testNonRecoverableChannel_25_1() throws Throwable
-   {
-      if (channel.isRecoverable())
-      {
-         // we test only non-recoverable channels now
-         return;
-      }
-
-      // add an NACKING receiver to the channel
-      SimpleReceiver r = new SimpleReceiver("NackingReceiver", SimpleReceiver.NACKING);
-      assertTrue(channel.add(r));
-
-      Message m = MessageFactory.createCoreMessage(0, false, "payload");
-      SimpleDeliveryObserver observer = new SimpleDeliveryObserver();
-
-      // non-transacted send, non-reliable message, one message
-      Delivery delivery = channel.handle(observer, m, null);
-
-      assertTrue(delivery.isDone());
-
-      List delivering = channel.browse();
-      assertEquals(1, delivering.size());
-      assertEquals(0, ((Message)delivering.get(0)).getMessageID());
-
-      List acknowledging = r.getMessages();
-      assertEquals(1, acknowledging.size());
-      Message ackm = (Message)acknowledging.get(0);
-      assertEquals(0, ackm.getMessageID());
-
-      Transaction tx = tr.createTransaction();
-
-      // transacted acknowledgment
-      r.acknowledge(ackm, tx);
-
-      delivering = channel.browse();
-      assertEquals(1, delivering.size());
-      assertEquals(0, ((Message)delivering.get(0)).getMessageID());
-
-      tx.commit();
-
-      assertTrue(channel.browse().isEmpty());
-   }
-
-
-   ////////////
-   //////////// Transacted acknowledgment and rollback
-   ////////////
-
-   public void testNonRecoverableChannel_25_2() throws Throwable
-   {
-      if (channel.isRecoverable())
-      {
-         // we test only non-recoverable channels now
-         return;
-      }
-
-      // add an NACKING receiver to the channel
-      SimpleReceiver r = new SimpleReceiver("NackingReceiver", SimpleReceiver.NACKING);
-      assertTrue(channel.add(r));
-
-      Message m = MessageFactory.createCoreMessage(0, false, "payload");
-      SimpleDeliveryObserver observer = new SimpleDeliveryObserver();
-
-      // non-transacted send, non-reliable message, one message
-      Delivery delivery = channel.handle(observer, m, null);
-
-      assertTrue(delivery.isDone());
-
-      List delivering = channel.browse();
-      assertEquals(1, delivering.size());
-      assertEquals(0, ((Message)delivering.get(0)).getMessageID());
-
-      List acknowledging = r.getMessages();
-      assertEquals(1, acknowledging.size());
-      Message ackm = (Message)acknowledging.get(0);
-      assertEquals(0, ackm.getMessageID());
-
-      Transaction tx = tr.createTransaction();
-
-      // transacted acknowledgment
-      r.acknowledge(ackm, tx);
-
-      delivering = channel.browse();
-      assertEquals(1, delivering.size());
-      assertEquals(0, ((Message)delivering.get(0)).getMessageID());
-
-      tx.rollback();
-
-      delivering = channel.browse();
-      assertEquals(1, delivering.size());
-      assertEquals(0, ((Message)delivering.get(0)).getMessageID());
-
-      // acknowledge non-transactionally
-      r.acknowledge(ackm, null);
-
-      assertTrue(channel.browse().isEmpty());
-   }
-
-
-   //////////
-   ////////// Multiple message
-   //////////
-
-   ////////////
-   //////////// Non-transacted acknowledgment
-   ////////////
-
-   public void testNonRecoverableChannel_26() throws Throwable
-   {
-      if (channel.isRecoverable())
-      {
-         // we test only non-recoverable channels now
-         return;
-      }
-
-      // add an NACKING receiver to the channel
-      SimpleReceiver r = new SimpleReceiver("NackingReceiver", SimpleReceiver.NACKING);
-      assertTrue(channel.add(r));
-
-      SimpleDeliveryObserver observer = new SimpleDeliveryObserver();
-
-      Message[] messages = new Message[NUMBER_OF_MESSAGES];
-      for(int i = 0; i < NUMBER_OF_MESSAGES; i++)
-      {
-         messages[i] = MessageFactory.createCoreMessage(i, false, "payload" + i);
-
-         // non-transacted send, non-reliable message, multiple messages
-         Delivery delivery = channel.handle(observer, messages[i], null);
-
-         assertTrue(delivery.isDone());
-      }
-
-      assertEqualSets(messages, channel.browse());
-      assertEqualSets(messages, r.getMessages());
-
-      for(Iterator i = r.getMessages().iterator(); i.hasNext();)
-      {
-         Message ackm = (Message)i.next();
-         // non-transacted acknowledgment
-         r.acknowledge(ackm, null);
-      }
-
-      assertTrue(channel.browse().isEmpty());
-
-   }
-
-   ////////////
-   //////////// Transacted acknowledgment and commit
-   ////////////
-
-   public void testNonRecoverableChannel_26_1() throws Throwable
-   {
-      if (channel.isRecoverable())
-      {
-         // we test only non-recoverable channels now
-         return;
-      }
-
-      // add an NACKING receiver to the channel
-      SimpleReceiver r = new SimpleReceiver("NackingReceiver", SimpleReceiver.NACKING);
-      assertTrue(channel.add(r));
-
-      SimpleDeliveryObserver observer = new SimpleDeliveryObserver();
-
-      Message[] messages = new Message[NUMBER_OF_MESSAGES];
-      for(int i = 0; i < NUMBER_OF_MESSAGES; i++)
-      {
-         messages[i] = MessageFactory.createCoreMessage(i, false, "payload" + i);
-
-         // non-transacted send, non-reliable message, multiple messages
-         Delivery delivery = channel.handle(observer, messages[i], null);
-
-         assertTrue(delivery.isDone());
-      }
-
-      assertEqualSets(messages, channel.browse());
-      assertEqualSets(messages, r.getMessages());
-
-      Transaction tx = tr.createTransaction();
-
-      for(Iterator i = r.getMessages().iterator(); i.hasNext();)
-      {
-         Message ackm = (Message)i.next();
-         // transacted acknowledgment
-         r.acknowledge(ackm, tx);
-      }
-
-      assertEqualSets(messages, channel.browse());
-
-      tx.commit();
-
-      assertTrue(channel.browse().isEmpty());
-   }
-
-
-   ////////////
-   //////////// Transacted acknowledgment and rollback
-   ////////////
-
-   public void testNonRecoverableChannel_26_2() throws Throwable
-   {
-      if (channel.isRecoverable())
-      {
-         // we test only non-recoverable channels now
-         return;
-      }
-
-      // add an NACKING receiver to the channel
-      SimpleReceiver r = new SimpleReceiver("NackingReceiver", SimpleReceiver.NACKING);
-      assertTrue(channel.add(r));
-
-      SimpleDeliveryObserver observer = new SimpleDeliveryObserver();
-
-      Message[] messages = new Message[NUMBER_OF_MESSAGES];
-      for(int i = 0; i < NUMBER_OF_MESSAGES; i++)
-      {
-         messages[i] = MessageFactory.createCoreMessage(i, false, "payload" + i);
-
-         // non-transacted send, non-reliable message, multiple messages
-         Delivery delivery = channel.handle(observer, messages[i], null);
-
-         assertTrue(delivery.isDone());
-      }
-
-      assertEqualSets(messages, channel.browse());
-      assertEqualSets(messages, r.getMessages());
-
-      Transaction tx = tr.createTransaction();
-
-      for(Iterator i = r.getMessages().iterator(); i.hasNext();)
-      {
-         Message ackm = (Message)i.next();
-         // transacted acknowledgment
-         r.acknowledge(ackm, tx);
-      }
-
-      assertEqualSets(messages, channel.browse());
-
-      tx.rollback();
-
-      assertEqualSets(messages, channel.browse());
-
-      // acknowledge non-transactionally
-      for(Iterator i = r.getMessages().iterator(); i.hasNext();)
-      {
-         Message ackm = (Message)i.next();
-         // non-transacted acknowledgment
-         r.acknowledge(ackm, null);
-      }
-
-      assertTrue(channel.browse().isEmpty());
-   }
-
-   ////////
-   //////// Reliable message
-   ////////
-
-   //////////
-   ////////// One message
-   //////////
-
-   ////////////
-   //////////// Non-transacted acknowledgment
-   ////////////
-
-   ///////////
-   /////////// Channel does NOT accept reliable messages
-   ///////////
-
-   public void testNonRecoverableChannel_27_1_1() throws Exception
-   {
-      if (channel.isRecoverable())
-      {
-         // we test only non-recoverable channels now
-         return;
-      }
-
-      if (channel.acceptReliableMessages())
-      {
-         // we test channels that don't accept reliable messages
-         return;
-      }
-
-      // add an NACKING receiver to the channel
-      SimpleReceiver r = new SimpleReceiver("NackingReceiver", SimpleReceiver.NACKING);
-      assertTrue(channel.add(r));
-
-      Message m = MessageFactory.createCoreMessage(0, true, "payload");
-      SimpleDeliveryObserver observer = new SimpleDeliveryObserver();
-
-      // non-transacted send, reliable message, one message
-      Delivery delivery = channel.handle(observer, m, null);
-
-      // not accepted by the channel
-      assertNull(delivery);
-      assertTrue(channel.browse().isEmpty());
-      assertTrue(r.getMessages().isEmpty());
-
-   }
-
-   ///////////
-   /////////// Channel accepts reliable messages
-   ///////////
-
-   public void testNonRecoverableChannel_27_1_2() throws Throwable
-   {
-      if (channel.isRecoverable())
-      {
-         // we test only non-recoverable channels now
-         return;
-      }
-
-      if (!channel.acceptReliableMessages())
-      {
-         // we test channels that accept reliable messages
-         return;
-      }
-
-      // add an NACKING receiver to the channel
-      SimpleReceiver r = new SimpleReceiver("NackingReceiver", SimpleReceiver.NACKING);
-      assertTrue(channel.add(r));
-
-      Message m = MessageFactory.createCoreMessage(0, true, "payload");
-      SimpleDeliveryObserver observer = new SimpleDeliveryObserver();
-
-      // non-transacted send, reliable message, one message
-      Delivery delivery = channel.handle(observer, m, null);
-
-      assertTrue(delivery.isDone());
-
-      List stored = channel.browse();
-      assertEquals(1, stored.size());
-      Message sm = (Message)stored.iterator().next();
-      assertTrue(sm.isReliable());
-      assertEquals(0, sm.getMessageID());
-
-      List received = r.getMessages();
-      assertEquals(1, received.size());
-      Message rm = (Message)received.iterator().next();
-      assertTrue(rm.isReliable());
-      assertEquals(0, rm.getMessageID());
-
-      r.acknowledge(rm, null);
-
-      assertTrue(channel.browse().isEmpty());
-   }
-
-
-   ////////////
-   //////////// Transacted acknowledgment
-   ////////////
-
-   ///////////
-   /////////// Channel does NOT accept reliable messages
-   ///////////
-
-
-   // Doesn't make sense, the message won't be accepted anyway.
-
-   ///////////
-   /////////// Channel accepts reliable messages
-   ///////////
-
-
-   public void testNonRecoverableChannel_27_2_2() throws Throwable
-   {
-      if (channel.isRecoverable())
-      {
-         // we test only non-recoverable channels now
-         return;
-      }
-
-      if (!channel.acceptReliableMessages())
-      {
-         // we test channels that accept reliable messages
-         return;
-      }
-
-      // add an NACKING receiver to the channel
-      SimpleReceiver r = new SimpleReceiver("NackingReceiver", SimpleReceiver.NACKING);
-      assertTrue(channel.add(r));
-
-      Message m = MessageFactory.createCoreMessage(0, true, "payload");
-      SimpleDeliveryObserver observer = new SimpleDeliveryObserver();
-
-      // non-transacted send, reliable message, one message
-      Delivery delivery = channel.handle(observer, m, null);
-
-      assertTrue(delivery.isDone());
-
-      List stored = channel.browse();
-      assertEquals(1, stored.size());
-      Message sm = (Message)stored.iterator().next();
-      assertTrue(sm.isReliable());
-      assertEquals(0, sm.getMessageID());
-
-      List received = r.getMessages();
-      assertEquals(1, received.size());
-      Message rm = (Message)received.iterator().next();
-      assertTrue(rm.isReliable());
-      assertEquals(0, rm.getMessageID());
-
-      Transaction tx = tr.createTransaction();
-
-      r.acknowledge(rm, tx);
-
-      stored = channel.browse();
-      assertEquals(1, stored.size());
-      sm = (Message)stored.iterator().next();
-      assertTrue(sm.isReliable());
-      assertEquals(0, sm.getMessageID());
-
-      tx.commit();
-
-      assertTrue(channel.browse().isEmpty());
-   }
-
-   //////////
-   ////////// Multiple message
-   //////////
-
-   ////////////
-   //////////// Non-transacted acknowledgment
-   ////////////
-
-   ///////////
-   /////////// Channel does NOT accept reliable messages
-   ///////////
-
-   public void testNonRecoverableChannel_28_1_1() throws Exception
-   {
-      if (channel.isRecoverable())
-      {
-         // we test only non-recoverable channels now
-         return;
-      }
-
-      if (channel.acceptReliableMessages())
-      {
-         // we test channels that don't accept reliable messages
-         return;
-      }
-
-      // add an NACKING receiver to the channel
-      SimpleReceiver r = new SimpleReceiver("NackingReceiver", SimpleReceiver.NACKING);
-      assertTrue(channel.add(r));
-
-      SimpleDeliveryObserver observer = new SimpleDeliveryObserver();
-
-      Message[] messages = new Message[NUMBER_OF_MESSAGES];
-      for(int i = 0; i < NUMBER_OF_MESSAGES; i++)
-      {
-         messages[i] = MessageFactory.createCoreMessage(i, true, "payload" + i);
-
-         // non-transacted send, reliable message, multiple messages
-         Delivery delivery = channel.handle(observer, messages[i], null);
-
-         // not accepted by the channel
-         assertNull(delivery);
-      }
-
-      assertTrue(channel.browse().isEmpty());
-      assertTrue(r.getMessages().isEmpty());
-   }
-
-   ///////////
-   /////////// Channel accepts reliable messages
-   ///////////
-
-   public void testNonRecoverableChannel_28_1_2() throws Throwable
-   {
-      if (channel.isRecoverable())
-      {
-         // we test only non-recoverable channels now
-         return;
-      }
-
-      if (!channel.acceptReliableMessages())
-      {
-         // we test channels that accept reliable messages
-         return;
-      }
-
-      // add an NACKING receiver to the channel
-      SimpleReceiver r = new SimpleReceiver("NackingReceiver", SimpleReceiver.NACKING);
-      assertTrue(channel.add(r));
-
-      SimpleDeliveryObserver observer = new SimpleDeliveryObserver();
-
-      Message[] messages = new Message[NUMBER_OF_MESSAGES];
-      for(int i = 0; i < NUMBER_OF_MESSAGES; i++)
-      {
-         messages[i] = MessageFactory.createCoreMessage(i, true, "payload" + i);
-
-         // non-transacted send, reliable message, multiple messages
-         Delivery delivery = channel.handle(observer, messages[i], null);
-
-         assertTrue(delivery.isDone());
-      }
-
-      assertEqualSets(messages, channel.browse());
-      assertEqualSets(messages, r.getMessages());
-
-      for(Iterator i = r.getMessages().iterator(); i.hasNext();)
-      {
-         Message ackm = (Message)i.next();
-         // non-transacted acknowledgment
-         r.acknowledge(ackm, null);
-      }
-
-      assertTrue(channel.browse().isEmpty());
-   }
-
-
-   ////////////
-   //////////// Transacted acknowledgment
-   ////////////
-
-   ///////////
-   /////////// Channel does NOT accept reliable messages
-   ///////////
-
-   // Doesn't make sense, the message won't be accepted anyway.
-
-   ///////////
-   /////////// Channel accepts reliable messages
-   ///////////
-
-   public void testNonRecoverableChannel_28_2_2() throws Throwable
-   {
-      if (channel.isRecoverable())
-      {
-         // we test only non-recoverable channels now
-         return;
-      }
-
-      if (!channel.acceptReliableMessages())
-      {
-         // we test channels that accept reliable messages
-         return;
-      }
-
-      // add an NACKING receiver to the channel
-      SimpleReceiver r = new SimpleReceiver("NackingReceiver", SimpleReceiver.NACKING);
-      assertTrue(channel.add(r));
-
-      SimpleDeliveryObserver observer = new SimpleDeliveryObserver();
-
-      Message[] messages = new Message[NUMBER_OF_MESSAGES];
-      for(int i = 0; i < NUMBER_OF_MESSAGES; i++)
-      {
-         messages[i] = MessageFactory.createCoreMessage(i, true, "payload" + i);
-
-         // non-transacted send, reliable message, multiple messages
-         Delivery delivery = channel.handle(observer, messages[i], null);
-
-         assertTrue(delivery.isDone());
-      }
-
-      assertEqualSets(messages, channel.browse());
-      assertEqualSets(messages, r.getMessages());
-
-      Transaction tx = tr.createTransaction();
-
-      for(Iterator i = r.getMessages().iterator(); i.hasNext();)
-      {
-         Message ackm = (Message)i.next();
-         r.acknowledge(ackm, tx);
-      }
-
-      assertEqualSets(messages, channel.browse());
-
-      tx.commit();
-
-      assertTrue(channel.browse().isEmpty());
-   }
-
-   //////
-   ////// Transacted send and commit
-   //////
-
-   ////////
-   //////// Non-reliable message
-   ////////
-
-   //////////
-   ////////// One message
-   //////////
-
-   public void testNonRecoverableChannel_29() throws Throwable
-   {
-      if (channel.isRecoverable())
-      {
-         // we test only non-recoverable channels now
-         return;
-      }
-
-      // add an NACKING receiver to the channel
-      SimpleReceiver r = new SimpleReceiver("NackingReceiver", SimpleReceiver.NACKING);
-      assertTrue(channel.add(r));
-
-      Message m = MessageFactory.createCoreMessage(0, false, "payload");
-      SimpleDeliveryObserver observer = new SimpleDeliveryObserver();
-
-      Transaction tx = tr.createTransaction();
-
-      // transacted send, non-reliable message, one message
-      // for a transactional send, handle() return value is unspecified
-      channel.handle(observer, m, tx);
-
-      // no messages in the channel
-      assertEquals(0, channel.browse().size());
-
-      // no message at the receiver
-      assertTrue(r.getMessages().isEmpty());
-
-      tx.commit();
-
-      List delivering = channel.browse();
-      assertEquals(1, delivering.size());
-      assertEquals(0, ((Message)delivering.get(0)).getMessageID());
-
-      List acknowledging = r.getMessages();
-      assertEquals(1, acknowledging.size());
-      Message ackm = (Message)acknowledging.get(0);
-      assertEquals(0, ackm.getMessageID());
-
-      // non-transacted acknowledgment
-      r.acknowledge(ackm, null);
-
-      assertTrue(channel.browse().isEmpty());
-   }
-
-   //////////
-   ////////// Multiple message
-   //////////
-
-   public void testNonRecoverableChannel_30() throws Throwable
-   {
-      if (channel.isRecoverable())
-      {
-         // we test only non-recoverable channels now
-         return;
-      }
-
-      // add an NACKING receiver to the channel
-      SimpleReceiver r = new SimpleReceiver("NackingReceiver", SimpleReceiver.NACKING);
-      assertTrue(channel.add(r));
-
-      SimpleDeliveryObserver observer = new SimpleDeliveryObserver();
-
-      Transaction tx = tr.createTransaction();
-
-      Message[] messages = new Message[NUMBER_OF_MESSAGES];
-      for(int i = 0; i < NUMBER_OF_MESSAGES; i++)
-      {
-         messages[i] = MessageFactory.createCoreMessage(i, false, "payload" + i);
-
-         // transacted send, non-reliable message, multiple messages
-         // for a transactional send, handle() return value is unspecified
-         channel.handle(observer, messages[i], tx);
-      }
-
-      // no messages in the channel
-      assertEquals(0, channel.browse().size());
-
-      // no message at the receiver
-      assertTrue(r.getMessages().isEmpty());
-
-      tx.commit();
-
-      assertEqualSets(messages, channel.browse());
-      assertEqualSets(messages, r.getMessages());
-
-      for(Iterator i = r.getMessages().iterator(); i.hasNext();)
-      {
-         Message ackm = (Message)i.next();
-         // non-transacted acknowledgment
-         r.acknowledge(ackm, null);
-      }
-
-      assertTrue(channel.browse().isEmpty());
-   }
-
-   ////////
-   //////// Reliable message
-   ////////
-
-   //////////
-   ////////// One message
-   //////////
-
-   ///////////
-   /////////// Channel does NOT accept reliable messages
-   ///////////
-
-   public void testNonRecoverableChannel_31_1() throws Exception
-   {
-      if (channel.isRecoverable())
-      {
-         // we test only non-recoverable channels now
-         return;
-      }
-
-      if (channel.acceptReliableMessages())
-      {
-         // we test channels that don't accept reliable messages
-         return;
-      }
-
-      // add an NACKING receiver to the channel
-      SimpleReceiver r = new SimpleReceiver("NackingReceiver", SimpleReceiver.NACKING);
-      assertTrue(channel.add(r));
-
-
-      Message m = MessageFactory.createCoreMessage(0, true, "payload");
-      SimpleDeliveryObserver observer = new SimpleDeliveryObserver();
-
-      Transaction tx = tr.createTransaction();
-
-      // transacted send, reliable message, one message
-      // for a transactional send, handle() return value is unspecified
-      channel.handle(observer, m, tx);
-
-      // no messages in the channel yet
-      assertEquals(0, channel.browse().size());
-
-      // no message at the receiver
-      assertTrue(r.getMessages().isEmpty());
-
-      try
-      {
-         tx.commit();
-         fail("this should throw exception");
-      }
-      catch(Exception e)
-      {
-         // OK
-      }
-
-      // no messages in the channel
-      assertEquals(0, channel.browse().size());
-
-      // no message at the receiver
-      assertTrue(r.getMessages().isEmpty());
-   }
-
-   ///////////
-   /////////// Channel does accepts reliable messages
-   ///////////
-
-   public void testNonRecoverableChannel_31_2() throws Exception
-   {
-      if (channel.isRecoverable())
-      {
-         // we test only non-recoverable channels now
-         return;
-      }
-
-      if (!channel.acceptReliableMessages())
-      {
-         // we test channels that accept reliable messages
-         return;
-      }
-
-      // add an NACKING receiver to the channel
-      SimpleReceiver r = new SimpleReceiver("NackingReceiver", SimpleReceiver.NACKING);
-      assertTrue(channel.add(r));
-
-
-      Message m = MessageFactory.createCoreMessage(0, true, "payload");
-      SimpleDeliveryObserver observer = new SimpleDeliveryObserver();
-
-      Transaction tx = tr.createTransaction();
-
-      // transacted send, reliable message, one message
-      // for a transactional send, handle() return value is unspecified
-      channel.handle(observer, m, tx);
-
-      // no messages in the channel yet
-      assertEquals(0, channel.browse().size());
-
-      // no message at the receiver
-      assertTrue(r.getMessages().isEmpty());
-
-      tx.commit();
-
-      List stored = channel.browse();
-      assertEquals(1, stored.size());
-      Message sm = (Message)stored.iterator().next();
-      assertTrue(sm.isReliable());
-      assertEquals(0, sm.getMessageID());
-
-      List received = r.getMessages();
-      assertEquals(1, received.size());
-      Message rm = (Message)received.iterator().next();
-      assertTrue(rm.isReliable());
-      assertEquals(0, rm.getMessageID());
-   }
-
-
-   //////////
-   ////////// Multiple message
-   //////////
-
-   ///////////
-   /////////// Channel does NOT accept reliable messages
-   ///////////
-
-   public void testNonRecoverableChannel_32_1() throws Exception
-   {
-      if (channel.isRecoverable())
-      {
-         // we test only non-recoverable channels now
-         return;
-      }
-
-      if (channel.acceptReliableMessages())
-      {
-         // we test channels that don't accept reliable messages
-         return;
-      }
-
-      // add an NACKING receiver to the channel
-      SimpleReceiver r = new SimpleReceiver("NackingReceiver", SimpleReceiver.NACKING);
-      assertTrue(channel.add(r));
-
-      SimpleDeliveryObserver observer = new SimpleDeliveryObserver();
-
-      Transaction tx = tr.createTransaction();
-
-      Message[] messages = new Message[NUMBER_OF_MESSAGES];
-      for(int i = 0; i < NUMBER_OF_MESSAGES; i++)
-      {
-         messages[i] = MessageFactory.createCoreMessage(i, true, "payload" + i);
-
-         // transacted send, reliable message, multiple messages
-         // for a transactional send, handle() return value is unspecified
-         channel.handle(observer, messages[i], tx);
-      }
-
-      // no messages in the channel yet
-      assertEquals(0, channel.browse().size());
-
-      // no message at the receiver
-      assertTrue(r.getMessages().isEmpty());
-
-      try
-      {
-         tx.commit();
-         fail("this should throw exception");
-      }
-      catch(Exception e)
-      {
-         // OK
-      }
-
-      // no messages in the channel
-      assertEquals(0, channel.browse().size());
-
-      // no message at the receiver
-      assertTrue(r.getMessages().isEmpty());
-   }
-
-   /**
-    * This is a variation where I send a mixture of reliable and non-reliable messages,
-    */
-   public void testNonRecoverableChannel_32_1_mixed() throws Exception
-   {
-      if (channel.isRecoverable())
-      {
-         // we test only non-recoverable channels now
-         return;
-      }
-
-      if (channel.acceptReliableMessages())
-      {
-         // we test channels that don't accept reliable messages
-         return;
-      }
-
-      // add an NACKING receiver to the channel
-      SimpleReceiver r = new SimpleReceiver("NackingReceiver", SimpleReceiver.NACKING);
-      assertTrue(channel.add(r));
-
-
-      SimpleDeliveryObserver observer = new SimpleDeliveryObserver();
-
-      Transaction tx = tr.createTransaction();
-
-      Message[] messages = new Message[NUMBER_OF_MESSAGES];
-      for(int i = 0; i < NUMBER_OF_MESSAGES; i++)
-      {
-         // send a mixture of reliable and non-reliable messages
-         messages[i] = MessageFactory.createCoreMessage(i, (i % 2 == 1), "payload" + i);
-
-         // transacted send, reliable/non-reliable messages, multiple messages
-         // for a transactional send, handle() return value is unspecified
-         channel.handle(observer, messages[i], tx);
-      }
-
-      // no messages in the channel
-      assertEquals(0, channel.browse().size());
-
-      // no message at the receiver
-      assertTrue(r.getMessages().isEmpty());
-
-      try
-      {
-         tx.commit();
-         fail("this should throw exception");
-      }
-      catch(Exception e)
-      {
-         // OK
-      }
-
-      // no messages in the channel
-      assertEquals(0, channel.browse().size());
-
-      // no message at the receiver
-      assertTrue(r.getMessages().isEmpty());
-   }
-
-   ///////////
-   /////////// Channel accepts reliable messages
-   ///////////
-
-   public void testNonRecoverableChannel_32_2() throws Exception
-   {
-      if (channel.isRecoverable())
-      {
-         // we test only non-recoverable channels now
-         return;
-      }
-
-      if (!channel.acceptReliableMessages())
-      {
-         // we test channels that accept reliable messages
-         return;
-      }
-
-      // add an NACKING receiver to the channel
-      SimpleReceiver r = new SimpleReceiver("NackingReceiver", SimpleReceiver.NACKING);
-      assertTrue(channel.add(r));
-
-      SimpleDeliveryObserver observer = new SimpleDeliveryObserver();
-
-      Transaction tx = tr.createTransaction();
-
-      Message[] messages = new Message[NUMBER_OF_MESSAGES];
-      for(int i = 0; i < NUMBER_OF_MESSAGES; i++)
-      {
-         messages[i] = MessageFactory.createCoreMessage(i, true, "payload" + i);
-
-         // transacted send, reliable message, multiple messages
-         // for a transactional send, handle() return value is unspecified
-         channel.handle(observer, messages[i], tx);
-      }
-
-      // no messages in the channel yet
-      assertEquals(0, channel.browse().size());
-
-      // no message at the receiver
-      assertTrue(r.getMessages().isEmpty());
-
-      tx.commit();
-
-      assertEqualSets(messages, channel.browse());
-      assertEqualSets(messages, r.getMessages());
-   }
-
-   /**
-    * This is a variation where I send a mixture of reliable and non-reliable messages,
-    */
-   public void testNonRecoverableChannel_32_2_mixed() throws Exception
-   {
-      if (channel.isRecoverable())
-      {
-         // we test only non-recoverable channels now
-         return;
-      }
-
-      if (!channel.acceptReliableMessages())
-      {
-         // we test channels that accept reliable messages
-         return;
-      }
-
-      // add an NACKING receiver to the channel
-      SimpleReceiver r = new SimpleReceiver("NackingReceiver", SimpleReceiver.NACKING);
-      assertTrue(channel.add(r));
-
-
-      SimpleDeliveryObserver observer = new SimpleDeliveryObserver();
-
-      Transaction tx = tr.createTransaction();
-
-      Message[] messages = new Message[NUMBER_OF_MESSAGES];
-      for(int i = 0; i < NUMBER_OF_MESSAGES; i++)
-      {
-         // send a mixture of reliable and non-reliable messages
-         messages[i] = MessageFactory.createCoreMessage(i, (i % 2 == 1), "payload" + i);
-
-         // transacted send, reliable/non-reliable messages, multiple messages
-         // for a transactional send, handle() return value is unspecified
-         channel.handle(observer, messages[i], tx);
-      }
-
-      // no messages in the channel
-      assertEquals(0, channel.browse().size());
-
-      // no message at the receiver
-      assertTrue(r.getMessages().isEmpty());
-
-      tx.commit();
-
-      assertEqualSets(messages, channel.browse());
-      assertEqualSets(messages, r.getMessages());
-   }
-
-
-
-   //////
-   ////// Transacted send and rollback
-   //////
-
-   ////////
-   //////// Non-reliable message
-   ////////
-
-   //////////
-   ////////// One message
-   //////////
-
-   public void testNonRecoverableChannel_33() throws Exception
-   {
-      if (channel.isRecoverable())
-      {
-         // we test only non-recoverable channels now
-         return;
-      }
-
-      // add an NACKING receiver to the channel
-      SimpleReceiver r = new SimpleReceiver("NackingReceiver", SimpleReceiver.NACKING);
-      assertTrue(channel.add(r));
-
-
-      Message m = MessageFactory.createCoreMessage(0, false, "payload");
-      SimpleDeliveryObserver observer = new SimpleDeliveryObserver();
-
-      Transaction tx = tr.createTransaction();
-
-      // transacted send, non-reliable message, one message
-      // for a transactional send, handle() return value is unspecified
-      channel.handle(observer, m, tx);
-
-      // no messages in the channel
-      assertEquals(0, channel.browse().size());
-
-      // no message at the receiver
-      assertTrue(r.getMessages().isEmpty());
-
-
-      tx.rollback();
-
-      // no messages in the channel
-      assertEquals(0, channel.browse().size());
-
-      // no message at the receiver
-      assertTrue(r.getMessages().isEmpty());
-
-   }
-
-   //////////
-   ////////// Multiple message
-   //////////
-
-   public void testNonRecoverableChannel_34() throws Exception
-   {
-      if (channel.isRecoverable())
-      {
-         // we test only non-recoverable channels now
-         return;
-      }
-
-      // add an NACKING receiver to the channel
-      SimpleReceiver r = new SimpleReceiver("NackingReceiver", SimpleReceiver.NACKING);
-      assertTrue(channel.add(r));
-
-      SimpleDeliveryObserver observer = new SimpleDeliveryObserver();
-
-      Transaction tx = tr.createTransaction();
-
-      Message[] messages = new Message[NUMBER_OF_MESSAGES];
-      for(int i = 0; i < NUMBER_OF_MESSAGES; i++)
-      {
-         messages[i] = MessageFactory.createCoreMessage(i, false, "payload" + i);
-
-         // transacted send, non-reliable message, multiple messages
-         // for a transactional send, handle() return value is unspecified
-         channel.handle(observer, messages[i], tx);
-      }
-
-      // no messages in the channel
-      assertEquals(0, channel.browse().size());
-
-      // no message at the receiver
-      assertTrue(r.getMessages().isEmpty());
-
-      tx.rollback();
-
-      // no messages in the channel
-      assertEquals(0, channel.browse().size());
-
-      // no message at the receiver
-      assertTrue(r.getMessages().isEmpty());
-   }
-
-   ////////
-   //////// Reliable message
-   ////////
-
-   //////////
-   ////////// One message
-   //////////
-
-   public void testNonRecoverableChannel_35() throws Exception
-   {
-      if (channel.isRecoverable())
-      {
-         // we test only non-recoverable channels now
-         return;
-      }
-
-      // add an NACKING receiver to the channel
-      SimpleReceiver r = new SimpleReceiver("NackingReceiver", SimpleReceiver.NACKING);
-      assertTrue(channel.add(r));
-
-
-      Message m = MessageFactory.createCoreMessage(0, true, "payload");
-      SimpleDeliveryObserver observer = new SimpleDeliveryObserver();
-
-      Transaction tx = tr.createTransaction();
-
-      // transacted send, reliable message, one message
-      // for a transactional send, handle() return value is unspecified
-      channel.handle(observer, m, tx);
-
-      // no messages in the channel
-      assertEquals(0, channel.browse().size());
-
-      // no message at the receiver
-      assertTrue(r.getMessages().isEmpty());
-
-      tx.rollback();
-
-      // no messages in the channel
-      assertEquals(0, channel.browse().size());
-
-      // no message at the receiver
-      assertTrue(r.getMessages().isEmpty());
-   }
-
-   //////////
-   ////////// Multiple message
-   //////////
-
-   public void testNonRecoverableChannel_36() throws Exception
-   {
-      if (channel.isRecoverable())
-      {
-         // we test only non-recoverable channels now
-         return;
-      }
-
-      // add an NACKING receiver to the channel
-      SimpleReceiver r = new SimpleReceiver("NackingReceiver", SimpleReceiver.NACKING);
-      assertTrue(channel.add(r));
-
-
-      SimpleDeliveryObserver observer = new SimpleDeliveryObserver();
-
-      Transaction tx = tr.createTransaction();
-
-      Message[] messages = new Message[NUMBER_OF_MESSAGES];
-      for(int i = 0; i < NUMBER_OF_MESSAGES; i++)
-      {
-         messages[i] = MessageFactory.createCoreMessage(i, true, "payload" + i);
-
-         // transacted send, reliable message, multiple messages
-         // for a transactional send, handle() return value is unspecified
-         channel.handle(observer, messages[i], tx);
-      }
-
-      // no messages in the channel
-      assertEquals(0, channel.browse().size());
-
-      // no message at the receiver
-      assertTrue(r.getMessages().isEmpty());
-
-      tx.rollback();
-
-      // no messages in the channel
-      assertEquals(0, channel.browse().size());
-
-      // no message at the receiver
-      assertTrue(r.getMessages().isEmpty());
-   }
-
-   /**
-    * This is a variation where I send a mixture of reliable and non-reliable messages,
-    */
-   public void testNonRecoverableChannel_36_mixed() throws Exception
-   {
-      if (channel.isRecoverable())
-      {
-         // we test only non-recoverable channels now
-         return;
-      }
-
-
-      // add an NACKING receiver to the channel
-      SimpleReceiver r = new SimpleReceiver("NackingReceiver", SimpleReceiver.NACKING);
-      assertTrue(channel.add(r));
-
-
-      SimpleDeliveryObserver observer = new SimpleDeliveryObserver();
-
-      Transaction tx = tr.createTransaction();
-
-      Message[] messages = new Message[NUMBER_OF_MESSAGES];
-      for(int i = 0; i < NUMBER_OF_MESSAGES; i++)
-      {
-         // send a mixture of reliable and non-reliable messages
-         messages[i] = MessageFactory.createCoreMessage(i, (i % 2 == 1), "payload" + i);
-
-         // transacted send, reliable/non-reliable messages, multiple messages
-         // for a transactional send, handle() return value is unspecified
-         channel.handle(observer, messages[i], tx);
-      }
-
-      // no messages in the channel
-      assertEquals(0, channel.browse().size());
-
-      // no message at the receiver
-      assertTrue(r.getMessages().isEmpty());
-
-      tx.rollback();
-
-      // no messages in the channel
-      assertEquals(0, channel.browse().size());
-
-      // no message at the receiver
-      assertTrue(r.getMessages().isEmpty());
-   }
-
-
-
-
-   //
-   // Recoverable channel
-   //
-
-   public void testRecoverableChannel_0() throws Exception
-   {
-      if (channel.isRecoverable())
-      {
-         assertTrue(channel.acceptReliableMessages());
-      }
-   }
-
-   ////
-   //// Zero receivers
-   ////
-
-   //////
-   ////// Non-transacted send
-   //////
-
-   ////////
-   //////// Non-reliable message
-   ////////
-
-   //////////
-   ////////// One message
-   //////////
-
-   public void testRecoverableChannel_1() throws Exception
-   {
-      if (!channel.isRecoverable())
-      {
-         // we test only recoverable channels now
-         return;
-      }
-
-      // the channel has no receivers
-      assertFalse(channel.iterator().hasNext());
-
-      Message m = MessageFactory.createCoreMessage(0, false, "payload");
-      SimpleDeliveryObserver observer = new SimpleDeliveryObserver();
-
-      // non-transacted send, non-reliable message, one message
-      Delivery delivery = channel.handle(observer, m, null);
-
-      assertTrue(delivery.isDone());
-
-      List stored = channel.browse();
-      assertEquals(1, stored.size());
-
-      Message sm = (Message)stored.iterator().next();
-      assertFalse(sm.isReliable());
-      assertEquals(0, sm.getMessageID());
-   }
-
-   //////////
-   ////////// Multiple message
-   //////////
-
-   public void testRecoverableChannel_2() throws Exception
-   {
-      if (!channel.isRecoverable())
-      {
-         // we test only recoverable channels now
-         return;
-      }
-
-      // the channel has no receivers
-      assertFalse(channel.iterator().hasNext());
-
-      SimpleDeliveryObserver observer = new SimpleDeliveryObserver();
-
-      Message[] messages = new Message[NUMBER_OF_MESSAGES];
-      for(int i = 0; i < NUMBER_OF_MESSAGES; i++)
-      {
-         messages[i] = MessageFactory.createCoreMessage(i, false, "payload" + i);
-
-         // non-transacted send, non-reliable message, multiple messages
-         Delivery delivery = channel.handle(observer, messages[i], null);
-
-         assertTrue(delivery.isDone());
-      }
-
-      assertEqualSets(messages, channel.browse());
-   }
-
-   ////////
-   //////// Reliable message
-   ////////
-
-   //////////
-   ////////// One message
-   //////////
-
-   public void testRecoverableChannel_3() throws Exception
-   {
-      if (!channel.isRecoverable())
-      {
-         // we test only recoverable channels now
-         return;
-      }
-
-      // the channel has no receivers
-      assertFalse(channel.iterator().hasNext());
-
-      Message m = MessageFactory.createCoreMessage(0, true, "payload");
-      SimpleDeliveryObserver observer = new SimpleDeliveryObserver();
-
-      // non-transacted send, reliable message, one message
-      Delivery delivery = channel.handle(observer, m, null);
-
-      assertTrue(delivery.isDone());
-
-      List stored = channel.browse();
-      assertEquals(1, stored.size());
-
-      Message sm = (Message)stored.iterator().next();
-      assertTrue(sm.isReliable());
-      assertEquals(0, sm.getMessageID());
-   }
-
-   //////////
-   ////////// Multiple message
-   //////////
-
-   public void testRecoverableChannel_4() throws Exception
-   {
-      if (!channel.isRecoverable())
-      {
-         // we test only recoverable channels now
-         return;
-      }
-
-      // the channel has no receivers
-      assertFalse(channel.iterator().hasNext());
-
-      SimpleDeliveryObserver observer = new SimpleDeliveryObserver();
-
-      Message[] messages = new Message[NUMBER_OF_MESSAGES];
-      for(int i = 0; i < NUMBER_OF_MESSAGES; i++)
-      {
-         messages[i] = MessageFactory.createCoreMessage(i, true, "payload" + i);
-
-         // non-transacted send, reliable message, multiple messages
-         Delivery delivery = channel.handle(observer, messages[i], null);
-
-         assertTrue(delivery.isDone());
-      }
-
-      assertEqualSets(messages, channel.browse());
-
-   }
-
-   //////
-   ////// Transacted send and commit
-   //////
-
-   ////////
-   //////// Non-reliable message
-   ////////
-
-   //////////
-   ////////// One message
-   //////////
-
-   public void testRecoverableChannel_5() throws Exception
-   {
-      if (!channel.isRecoverable())
-      {
-         // we test only recoverable channels now
-         return;
-      }
-
-
-      // the channel has no receivers
-      assertFalse(channel.iterator().hasNext());
-
-      Message m = MessageFactory.createCoreMessage(0, false, "payload");
-      SimpleDeliveryObserver observer = new SimpleDeliveryObserver();
-
-      Transaction tx = tr.createTransaction();
-
-      // transacted send, non-reliable message, one message
-      // for a transactional send, handle() return value is unspecified
-      channel.handle(observer, m, tx);
-
-      // no messages in the channel yet
-      assertEquals(0, channel.browse().size());
-
-      tx.commit();
-
-      List stored = channel.browse();
-      assertEquals(1, stored.size());
-
-      Message sm = (Message)stored.iterator().next();
-      assertFalse(sm.isReliable());
-      assertEquals(0, sm.getMessageID());
-   }
-
-   //////////
-   ////////// Multiple message
-   //////////
-
-   public void testRecoverableChannel_6() throws Exception
-   {
-      if (!channel.isRecoverable())
-      {
-         // we test only recoverable channels now
-         return;
-      }
-
-      // the channel has no receivers
-      assertFalse(channel.iterator().hasNext());
-
-      SimpleDeliveryObserver observer = new SimpleDeliveryObserver();
-
-      Transaction tx = tr.createTransaction();
-
-      Message[] messages = new Message[NUMBER_OF_MESSAGES];
-      for(int i = 0; i < NUMBER_OF_MESSAGES; i++)
-      {
-         messages[i] = MessageFactory.createCoreMessage(i, false, "payload" + i);
-
-         // transacted send, non-reliable message, multiple messages
-         // for a transactional send, handle() return value is unspecified
-         channel.handle(observer, messages[i], tx);
-      }
-
-      // no messages in the channel yet
-      assertEquals(0, channel.browse().size());
-
-      tx.commit();
-
-      assertEqualSets(messages, channel.browse());
-   }
-
-   ////////
-   //////// Reliable message
-   ////////
-
-   //////////
-   ////////// One message
-   //////////
-
-   public void testRecoverableChannel_7() throws Exception
-   {
-      if (!channel.isRecoverable())
-      {
-         // we test only recoverable channels now
-         return;
-      }
-
-      // the channel has no receivers
-      assertFalse(channel.iterator().hasNext());
-
-      Message m = MessageFactory.createCoreMessage(0, true, "payload");
-      SimpleDeliveryObserver observer = new SimpleDeliveryObserver();
-
-      Transaction tx = tr.createTransaction();
-
-      // transacted send, reliable message, one message
-      // for a transactional send, handle() return value is unspecified
-      channel.handle(observer, m, tx);
-
-      // no messages in the channel yet
-      assertEquals(0, channel.browse().size());
-
-      tx.commit();
-
-      List stored = channel.browse();
-      assertEquals(1, stored.size());
-
-      Message sm = (Message)stored.iterator().next();
-      assertTrue(sm.isReliable());
-      assertEquals(0, sm.getMessageID());
-   }
-
-   //////////
-   ////////// Multiple message
-   //////////
-
-   public void testRecoverableChannel_8() throws Exception
-   {
-      if (!channel.isRecoverable())
-      {
-         // we test only recoverable channels now
-         return;
-      }
-
-
-      // the channel has no receivers
-      assertFalse(channel.iterator().hasNext());
-
-      SimpleDeliveryObserver observer = new SimpleDeliveryObserver();
-
-      Transaction tx = tr.createTransaction();
-
-      Message[] messages = new Message[NUMBER_OF_MESSAGES];
-      for(int i = 0; i < NUMBER_OF_MESSAGES; i++)
-      {
-         messages[i] = MessageFactory.createCoreMessage(i, true, "payload" + i);
-
-         // transacted send, reliable message, multiple messages
-         // for a transactional send, handle() return value is unspecified
-         channel.handle(observer, messages[i], tx);
-      }
-
-      // no messages in the channel yet
-      assertEquals(0, channel.browse().size());
-
-      tx.commit();
-
-      assertEqualSets(messages, channel.browse());
-   }
-
-   /**
-    * This is a variation where I send a mixture of reliable and non-reliable messages,
-    */
-   public void testRecoverableChannel_8_mixed() throws Exception
-   {
-      if (!channel.isRecoverable())
-      {
-         // we test only recoverable channels now
-         return;
-      }
-
-
-      // the channel has no receivers
-      assertFalse(channel.iterator().hasNext());
-
-      SimpleDeliveryObserver observer = new SimpleDeliveryObserver();
-
-      Transaction tx = tr.createTransaction();
-
-      Message[] messages = new Message[NUMBER_OF_MESSAGES];
-      for(int i = 0; i < NUMBER_OF_MESSAGES; i++)
-      {
-         // send a mixture of reliable and non-reliable messages
-         messages[i] = MessageFactory.createCoreMessage(i, (i % 2 == 1), "payload" + i);
-
-         // transacted send, reliable/non-reliable messages, multiple messages
-         // for a transactional send, handle() return value is unspecified
-         channel.handle(observer, messages[i], tx);
-      }
-
-      // no messages in the channel yet
-      assertEquals(0, channel.browse().size());
-
-      tx.commit();
-
-      assertEqualSets(messages, channel.browse());
-   }
-
-
-   //////
-   ////// Transacted send and rollback
-   //////
-
-   ////////
-   //////// Non-reliable message
-   ////////
-
-   //////////
-   ////////// One message
-   //////////
-
-   public void testRecoverableChannel_9() throws Exception
-   {
-      if (!channel.isRecoverable())
-      {
-         // we test only recoverable channels now
-         return;
-      }
-
-      // the channel has no receivers
-      assertFalse(channel.iterator().hasNext());
-
-      Message m = MessageFactory.createCoreMessage(0, false, "payload");
-      SimpleDeliveryObserver observer = new SimpleDeliveryObserver();
-
-      Transaction tx = tr.createTransaction();
-
-      // transacted send, non-reliable message, one message
-      // for a transactional send, handle() return value is unspecified
-      channel.handle(observer, m, tx);
-
-      // no messages in the channel yet
-      assertEquals(0, channel.browse().size());
-
-      tx.rollback();
-
-      // still no messages in the channel
-      assertEquals(0, channel.browse().size());
-   }
-
-   //////////
-   ////////// Multiple message
-   //////////
-
-   public void testRecoverableChannel_10() throws Exception
-   {
-      if (!channel.isRecoverable())
-      {
-         // we test only recoverable channels now
-         return;
-      }
-
-      // the channel has no receivers
-      assertFalse(channel.iterator().hasNext());
-
-      SimpleDeliveryObserver observer = new SimpleDeliveryObserver();
-
-      Transaction tx = tr.createTransaction();
-
-      Message[] messages = new Message[NUMBER_OF_MESSAGES];
-      for(int i = 0; i < NUMBER_OF_MESSAGES; i++)
-      {
-         messages[i] = MessageFactory.createCoreMessage(i, false, "payload" + i);
-
-         // transacted send, non-reliable message, multiple messages
-         // for a transactional send, handle() return value is unspecified
-         channel.handle(observer, messages[i], tx);
-      }
-
-      // no messages in the channel yet
-      assertEquals(0, channel.browse().size());
-
-      tx.rollback();
-
-      // still no messages in the channel
-      assertEquals(0, channel.browse().size());
-   }
-
-   ////////
-   //////// Reliable message
-   ////////
-
-   //////////
-   ////////// One message
-   //////////
-
-   public void testRecoverableChannel_11() throws Exception
-   {
-      if (!channel.isRecoverable())
-      {
-         // we test only recoverable channels now
-         return;
-      }
-
-      // the channel has no receivers
-      assertFalse(channel.iterator().hasNext());
-
-      Message m = MessageFactory.createCoreMessage(0, true, "payload");
-      SimpleDeliveryObserver observer = new SimpleDeliveryObserver();
-
-      Transaction tx = tr.createTransaction();
-
-      // transacted send, reliable message, one message
-      // for a transactional send, handle() return value is unspecified
-      channel.handle(observer, m, tx);
-
-      // no messages in the channel yet
-      assertEquals(0, channel.browse().size());
-
-      tx.rollback();
-
-      // still no messages in the channel
-      assertEquals(0, channel.browse().size());
-   }
-
-   //////////
-   ////////// Multiple message
-   //////////
-
-   public void testRecoverableChannel_12() throws Exception
-   {
-      if (!channel.isRecoverable())
-      {
-         // we test only recoverable channels now
-         return;
-      }
-
-      // the channel has no receivers
-      assertFalse(channel.iterator().hasNext());
-
-      SimpleDeliveryObserver observer = new SimpleDeliveryObserver();
-
-      Transaction tx = tr.createTransaction();
-
-      Message[] messages = new Message[NUMBER_OF_MESSAGES];
-      for(int i = 0; i < NUMBER_OF_MESSAGES; i++)
-      {
-         messages[i] = MessageFactory.createCoreMessage(i, true, "payload" + i);
-
-         // transacted send, reliable message, multiple messages
-         // for a transactional send, handle() return value is unspecified
-         channel.handle(observer, messages[i], tx);
-      }
-
-      // no messages in the channel yet
-      assertEquals(0, channel.browse().size());
-
-      tx.rollback();
-
-      // still no messages in the channel
-      assertEquals(0, channel.browse().size());
-   }
-
-   /**
-    * This is a variation where I send a mixture of reliable and non-reliable messages,
-    */
-   public void testRecoverableChannel_12_mixed() throws Exception
-   {
-      if (!channel.isRecoverable())
-      {
-         // we test only recoverable channels now
-         return;
-      }
-
-
-      // the channel has no receivers
-      assertFalse(channel.iterator().hasNext());
-
-      SimpleDeliveryObserver observer = new SimpleDeliveryObserver();
-
-      Transaction tx = tr.createTransaction();
-
-      Message[] messages = new Message[NUMBER_OF_MESSAGES];
-      for(int i = 0; i < NUMBER_OF_MESSAGES; i++)
-      {
-         // send a mixture of reliable and non-reliable messages
-         messages[i] = MessageFactory.createCoreMessage(i, (i % 2 == 1), "payload" + i);
-
-         // transacted send, reliable/non-reliable messages, multiple messages
-         // for a transactional send, handle() return value is unspecified
-         channel.handle(observer, messages[i], tx);
-      }
-
-      // no messages in the channel yet
-      assertEquals(0, channel.browse().size());
-
-      tx.rollback();
-
-      // still no messages in the channel
-      assertEquals(0, channel.browse().size());
-   }
-
-   ////
-   //// One receiver
-   ////
-
-   //////
-   ////// ACKING receiver
-   //////
-
-   //////
-   ////// Non-transacted send
-   //////
-
-   ////////
-   //////// Non-reliable message
-   ////////
-
-   //////////
-   ////////// One message
-   //////////
-
-   public void testRecoverableChannel_13() throws Exception
-   {
-      if (!channel.isRecoverable())
-      {
-         // we test only recoverable channels now
-         return;
-      }
-
-      // add an ACKING receiver to the channel
-      SimpleReceiver r = new SimpleReceiver("AckingReceiver", SimpleReceiver.ACKING);
-      assertTrue(channel.add(r));
-
-      Message m = MessageFactory.createCoreMessage(0, false, "payload");
-      SimpleDeliveryObserver observer = new SimpleDeliveryObserver();
-
-      // non-transacted send, non-reliable message, one message
-      Delivery delivery = channel.handle(observer, m, null);
-
-      assertTrue(delivery.isDone());
-      assertTrue(channel.browse().isEmpty());
-
-      List received = r.getMessages();
-      assertEquals(1, received.size());
-      Message sm = (Message)received.iterator().next();
-      assertFalse(sm.isReliable());
-      assertEquals(0, sm.getMessageID());
-   }
-
-   //////////
-   ////////// Multiple message
-   //////////
-
-   public void testRecoverableChannel_14() throws Exception
-   {
-      if (!channel.isRecoverable())
-      {
-         // we test only recoverable channels now
-         return;
-      }
-
-      // add an ACKING receiver to the channel
-      SimpleReceiver r = new SimpleReceiver("AckingReceiver", SimpleReceiver.ACKING);
-      assertTrue(channel.add(r));
-
-      SimpleDeliveryObserver observer = new SimpleDeliveryObserver();
-
-      Message[] messages = new Message[NUMBER_OF_MESSAGES];
-      for(int i = 0; i < NUMBER_OF_MESSAGES; i++)
-      {
-         messages[i] = MessageFactory.createCoreMessage(i, false, "payload" + i);
-
-         // non-transacted send, non-reliable message, multiple messages
-         Delivery delivery = channel.handle(observer, messages[i], null);
-
-         assertTrue(delivery.isDone());
-      }
-
-      assertTrue(channel.browse().isEmpty());
-
-      List received = r.getMessages();
-      assertEqualSets(messages, received);
-   }
-
-   ////////
-   //////// Reliable message
-   ////////
-
-   //////////
-   ////////// One message
-   //////////
-
-   public void testRecoverableChannel_15() throws Exception
-   {
-      if (!channel.isRecoverable())
-      {
-         // we test only recoverable channels now
-         return;
-      }
-
-
-      // add an ACKING receiver to the channel
-      SimpleReceiver r = new SimpleReceiver("AckingReceiver", SimpleReceiver.ACKING);
-      assertTrue(channel.add(r));
-
-      Message m = MessageFactory.createCoreMessage(0, true, "payload");
-      SimpleDeliveryObserver observer = new SimpleDeliveryObserver();
-
-      // non-transacted send, reliable message, one message
-      Delivery delivery = channel.handle(observer, m, null);
-
-      assertTrue(delivery.isDone());
-
-      assertTrue(channel.browse().isEmpty());
-
-      List received = r.getMessages();
-      assertEquals(1, received.size());
-      Message sm = (Message)received.iterator().next();
-      assertTrue(sm.isReliable());
-      assertEquals(0, sm.getMessageID());
-   }
-
-   //////////
-   ////////// Multiple message
-   //////////
-
-   public void testRecoverableChannel_16() throws Exception
-   {
-      if (!channel.isRecoverable())
-      {
-         // we test only recoverable channels now
-         return;
-      }
-
-      // add an ACKING receiver to the channel
-      SimpleReceiver r = new SimpleReceiver("AckingReceiver", SimpleReceiver.ACKING);
-      assertTrue(channel.add(r));
-
-      SimpleDeliveryObserver observer = new SimpleDeliveryObserver();
-
-      Message[] messages = new Message[NUMBER_OF_MESSAGES];
-      for(int i = 0; i < NUMBER_OF_MESSAGES; i++)
-      {
-         messages[i] = MessageFactory.createCoreMessage(i, true, "payload" + i);
-
-         // non-transacted send, reliable message, multiple messages
-         Delivery delivery = channel.handle(observer, messages[i], null);
-
-         assertTrue(delivery.isDone());
-      }
-
-      assertTrue(channel.browse().isEmpty());
-      assertEqualSets(messages, r.getMessages());
-   }
-
-   //////
-   ////// Transacted send and commit
-   //////
-
-   ////////
-   //////// Non-reliable message
-   ////////
-
-   //////////
-   ////////// One message
-   //////////
-
-   public void testRecoverableChannel_17() throws Exception
-   {
-      if (!channel.isRecoverable())
-      {
-         // we test only recoverable channels now
-         return;
-      }
-
-      // add an ACKING receiver to the channel
-      SimpleReceiver r = new SimpleReceiver("AckingReceiver", SimpleReceiver.ACKING);
-      assertTrue(channel.add(r));
-
-      Message m = MessageFactory.createCoreMessage(0, false, "payload");
-      SimpleDeliveryObserver observer = new SimpleDeliveryObserver();
-
-      Transaction tx = tr.createTransaction();
-
-      // transacted send, non-reliable message, one message
-      // for a transactional send, handle() return value is unspecified
-      channel.handle(observer, m, tx);
-
-      // no messages in the channel
-      assertEquals(0, channel.browse().size());
-
-      // no message at the receiver
-      assertTrue(r.getMessages().isEmpty());
-
-      tx.commit();
-
-      assertTrue(channel.browse().isEmpty());
-
-      List received = r.getMessages();
-      assertEquals(1, received.size());
-      Message sm = (Message)received.iterator().next();
-      assertFalse(sm.isReliable());
-      assertEquals(0, sm.getMessageID());
-   }
-
-
-   public void testRecoverableChannel_17_1() throws Exception
-   {
-      if (!channel.isRecoverable())
-      {
-         // we test only recoverable channels now
-         return;
-      }
-
-      BrokenReceiver brokenReceiver = new BrokenReceiver(2);
-      assertTrue(channel.add(brokenReceiver));
-
-      Message m = MessageFactory.createCoreMessage(0, false, "payload");
-      SimpleDeliveryObserver observer = new SimpleDeliveryObserver();
-
-      Transaction tx = tr.createTransaction();
-
-
-      log.debug("sending message 1");
-
-      // transacted send, non-reliable message, one message
-      // for a transactional send, handle() return value is unspecified
-      channel.handle(observer, m, tx);
-
-      m = MessageFactory.createCoreMessage(1, false, "payload");
-
-      log.debug("sending message 2");
-      channel.handle(observer, m, tx);
-
-      m = MessageFactory.createCoreMessage(2, false, "payload");
-
-      log.debug("sending message 3");
-      channel.handle(observer, m, tx);
-
-      // no messages in the channel
-      assertEquals(0, channel.browse().size());
-
-      tx.commit();
-
-      assertEquals(2, channel.browse().size());
-      assertEquals(1, brokenReceiver.getMessages().size());
-   }
-
-
-   //////////
-   ////////// Multiple message
-   //////////
-
-   public void testRecoverableChannel_18() throws Exception
-   {
-      if (!channel.isRecoverable())
-      {
-         // we test only recoverable channels now
-         return;
-      }
-
-      // add an ACKING receiver to the channel
-      SimpleReceiver r = new SimpleReceiver("AckingReceiver", SimpleReceiver.ACKING);
-      assertTrue(channel.add(r));
-
-      SimpleDeliveryObserver observer = new SimpleDeliveryObserver();
-
-      Transaction tx = tr.createTransaction();
-
-      Message[] messages = new Message[NUMBER_OF_MESSAGES];
-      for(int i = 0; i < NUMBER_OF_MESSAGES; i++)
-      {
-         messages[i] = MessageFactory.createCoreMessage(i, false, "payload" + i);
-
-         // transacted send, non-reliable message, multiple messages
-         // for a transactional send, handle() return value is unspecified
-         channel.handle(observer, messages[i], tx);
-      }
-
-      // no messages in the channel
-      assertEquals(0, channel.browse().size());
-
-      // no message at the receiver
-      assertTrue(r.getMessages().isEmpty());
-
-      tx.commit();
-
-      assertTrue(channel.browse().isEmpty());
-      assertEqualSets(messages, r.getMessages());
-   }
-
-   ////////
-   //////// Reliable message
-   ////////
-
-   //////////
-   ////////// One message
-   //////////
-
-   public void testRecoverableChannel_19() throws Exception
-   {
-      if (!channel.isRecoverable())
-      {
-         // we test only recoverable channels now
-         return;
-      }
-
-      // add an ACKING receiver to the channel
-      SimpleReceiver r = new SimpleReceiver("AckingReceiver", SimpleReceiver.ACKING);
-      assertTrue(channel.add(r));
-
-
-      Message m = MessageFactory.createCoreMessage(0, true, "payload");
-      SimpleDeliveryObserver observer = new SimpleDeliveryObserver();
-
-      Transaction tx = tr.createTransaction();
-
-      // transacted send, reliable message, one message
-      // for a transactional send, handle() return value is unspecified
-      channel.handle(observer, m, tx);
-
-      // no messages in the channel yet
-      assertEquals(0, channel.browse().size());
-
-      // no message at the receiver
-      assertTrue(r.getMessages().isEmpty());
-
-      tx.commit();
-
-      // no messages in the channel
-      assertEquals(0, channel.browse().size());
-
-      List received = r.getMessages();
-      assertEquals(1, received.size());
-      Message sm = (Message)received.iterator().next();
-      assertTrue(sm.isReliable());
-      assertEquals(0, sm.getMessageID());
-   }
-
-   //////////
-   ////////// Multiple message
-   //////////
-
-   public void testRecoverableChannel_20() throws Exception
-   {
-      if (!channel.isRecoverable())
-      {
-         // we test only recoverable channels now
-         return;
-      }
-
-
-      // add an ACKING receiver to the channel
-      SimpleReceiver r = new SimpleReceiver("AckingReceiver", SimpleReceiver.ACKING);
-      assertTrue(channel.add(r));
-
-      SimpleDeliveryObserver observer = new SimpleDeliveryObserver();
-
-      Transaction tx = tr.createTransaction();
-
-      Message[] messages = new Message[NUMBER_OF_MESSAGES];
-      for(int i = 0; i < NUMBER_OF_MESSAGES; i++)
-      {
-         messages[i] = MessageFactory.createCoreMessage(i, true, "payload" + i);
-
-         // transacted send, reliable message, multiple messages
-         // for a transactional send, handle() return value is unspecified
-         channel.handle(observer, messages[i], tx);
-      }
-
-      // no messages in the channel yet
-      assertEquals(0, channel.browse().size());
-
-      // no message at the receiver
-      assertTrue(r.getMessages().isEmpty());
-
-      tx.commit();
-
-      // no messages in the channel
-      assertEquals(0, channel.browse().size());
-
-      assertEqualSets(messages, r.getMessages());
-   }
-
-   /**
-    * This is a variation where I send a mixture of reliable and non-reliable messages,
-    */
-   public void testRecoverableChannel_20_mixed() throws Exception
-   {
-      if (!channel.isRecoverable())
-      {
-         // we test only recoverable channels now
-         return;
-      }
-
-
-      // add an ACKING receiver to the channel
-      SimpleReceiver r = new SimpleReceiver("AckingReceiver", SimpleReceiver.ACKING);
-      assertTrue(channel.add(r));
-
-
-      SimpleDeliveryObserver observer = new SimpleDeliveryObserver();
-
-      Transaction tx = tr.createTransaction();
-
-      Message[] messages = new Message[NUMBER_OF_MESSAGES];
-      for(int i = 0; i < NUMBER_OF_MESSAGES; i++)
-      {
-         // send a mixture of reliable and non-reliable messages
-         messages[i] = MessageFactory.createCoreMessage(i, (i % 2 == 1), "payload" + i);
-
-         // transacted send, reliable/non-reliable messages, multiple messages
-         // for a transactional send, handle() return value is unspecified
-         channel.handle(observer, messages[i], tx);
-      }
-
-      // no messages in the channel
-      assertEquals(0, channel.browse().size());
-
-      // no message at the receiver
-      assertTrue(r.getMessages().isEmpty());
-
-      tx.commit();
-
-      // no messages in the channel
-      assertEquals(0, channel.browse().size());
-
-      assertEqualSets(messages, r.getMessages());
-   }
-
-
-   //////
-   ////// Transacted send and rollback
-   //////
-
-   ////////
-   //////// Non-reliable message
-   ////////
-
-   //////////
-   ////////// One message
-   //////////
-
-   public void testRecoverableChannel_21() throws Exception
-   {
-      if (!channel.isRecoverable())
-      {
-         // we test only recoverable channels now
-         return;
-      }
-
-      // add an ACKING receiver to the channel
-      SimpleReceiver r = new SimpleReceiver("AckingReceiver", SimpleReceiver.ACKING);
-      assertTrue(channel.add(r));
-
-
-      Message m = MessageFactory.createCoreMessage(0, false, "payload");
-      SimpleDeliveryObserver observer = new SimpleDeliveryObserver();
-
-      Transaction tx = tr.createTransaction();
-
-      // transacted send, non-reliable message, one message
-      // for a transactional send, handle() return value is unspecified
-      channel.handle(observer, m, tx);
-
-      // no messages in the channel
-      assertEquals(0, channel.browse().size());
-
-      // no message at the receiver
-      assertTrue(r.getMessages().isEmpty());
-
-
-      tx.rollback();
-
-      // no messages in the channel
-      assertEquals(0, channel.browse().size());
-
-      // no message at the receiver
-      assertTrue(r.getMessages().isEmpty());
-
-   }
-
-   //////////
-   ////////// Multiple message
-   //////////
-
-   public void testRecoverableChannel_22() throws Exception
-   {
-      if (!channel.isRecoverable())
-      {
-         // we test only recoverable channels now
-         return;
-      }
-
-
-      // add an ACKING receiver to the channel
-      SimpleReceiver r = new SimpleReceiver("AckingReceiver", SimpleReceiver.ACKING);
-      assertTrue(channel.add(r));
-
-      SimpleDeliveryObserver observer = new SimpleDeliveryObserver();
-
-      Transaction tx = tr.createTransaction();
-
-      Message[] messages = new Message[NUMBER_OF_MESSAGES];
-      for(int i = 0; i < NUMBER_OF_MESSAGES; i++)
-      {
-         messages[i] = MessageFactory.createCoreMessage(i, false, "payload" + i);
-
-         // transacted send, non-reliable message, multiple messages
-         // for a transactional send, handle() return value is unspecified
-         channel.handle(observer, messages[i], tx);
-      }
-
-      // no messages in the channel
-      assertEquals(0, channel.browse().size());
-
-      // no message at the receiver
-      assertTrue(r.getMessages().isEmpty());
-
-      tx.rollback();
-
-      // no messages in the channel
-      assertEquals(0, channel.browse().size());
-
-      // no message at the receiver
-      assertTrue(r.getMessages().isEmpty());
-   }
-
-   ////////
-   //////// Reliable message
-   ////////
-
-   //////////
-   ////////// One message
-   //////////
-
-   public void testRecoverableChannel_23() throws Exception
-   {
-      if (!channel.isRecoverable())
-      {
-         // we test only recoverable channels now
-         return;
-      }
-
-
-      // add an ACKING receiver to the channel
-      SimpleReceiver r = new SimpleReceiver("AckingReceiver", SimpleReceiver.ACKING);
-      assertTrue(channel.add(r));
-
-
-      Message m = MessageFactory.createCoreMessage(0, true, "payload");
-      SimpleDeliveryObserver observer = new SimpleDeliveryObserver();
-
-      Transaction tx = tr.createTransaction();
-
-      // transacted send, reliable message, one message
-      // for a transactional send, handle() return value is unspecified
-      channel.handle(observer, m, tx);
-
-      // no messages in the channel
-      assertEquals(0, channel.browse().size());
-
-      // no message at the receiver
-      assertTrue(r.getMessages().isEmpty());
-
-      tx.rollback();
-
-      // no messages in the channel
-      assertEquals(0, channel.browse().size());
-
-      // no message at the receiver
-      assertTrue(r.getMessages().isEmpty());
-   }
-
-   //////////
-   ////////// Multiple message
-   //////////
-
-   public void testRecoverableChannel_24() throws Exception
-   {
-      if (!channel.isRecoverable())
-      {
-         // we test only recoverable channels now
-         return;
-      }
-
-      // add an ACKING receiver to the channel
-      SimpleReceiver r = new SimpleReceiver("AckingReceiver", SimpleReceiver.ACKING);
-      assertTrue(channel.add(r));
-
-
-      SimpleDeliveryObserver observer = new SimpleDeliveryObserver();
-
-      Transaction tx = tr.createTransaction();
-
-      Message[] messages = new Message[NUMBER_OF_MESSAGES];
-      for(int i = 0; i < NUMBER_OF_MESSAGES; i++)
-      {
-         messages[i] = MessageFactory.createCoreMessage(i, true, "payload" + i);
-
-         // transacted send, reliable message, multiple messages
-         // for a transactional send, handle() return value is unspecified
-         channel.handle(observer, messages[i], tx);
-      }
-
-      // no messages in the channel
-      assertEquals(0, channel.browse().size());
-
-      // no message at the receiver
-      assertTrue(r.getMessages().isEmpty());
-
-      tx.rollback();
-
-      // no messages in the channel
-      assertEquals(0, channel.browse().size());
-
-      // no message at the receiver
-      assertTrue(r.getMessages().isEmpty());
-   }
-
-   /**
-    * This is a variation where I send a mixture of reliable and non-reliable messages,
-    */
-   public void testRecoverableChannel_24_mixed() throws Exception
-   {
-      if (!channel.isRecoverable())
-      {
-         // we test only recoverable channels now
-         return;
-      }
-
-
-      // add an ACKING receiver to the channel
-      SimpleReceiver r = new SimpleReceiver("AckingReceiver", SimpleReceiver.ACKING);
-      assertTrue(channel.add(r));
-
-
-      SimpleDeliveryObserver observer = new SimpleDeliveryObserver();
-
-      Transaction tx = tr.createTransaction();
-
-      Message[] messages = new Message[NUMBER_OF_MESSAGES];
-      for(int i = 0; i < NUMBER_OF_MESSAGES; i++)
-      {
-         // send a mixture of reliable and non-reliable messages
-         messages[i] = MessageFactory.createCoreMessage(i, (i % 2 == 1), "payload" + i);
-
-         // transacted send, reliable/non-reliable messages, multiple messages
-         // for a transactional send, handle() return value is unspecified
-         channel.handle(observer, messages[i], tx);
-      }
-
-      // no messages in the channel
-      assertEquals(0, channel.browse().size());
-
-      // no message at the receiver
-      assertTrue(r.getMessages().isEmpty());
-
-      tx.rollback();
-
-      // no messages in the channel
-      assertEquals(0, channel.browse().size());
-
-      // no message at the receiver
-      assertTrue(r.getMessages().isEmpty());
-   }
-
-   //////
-   ////// NACKING receiver
-   //////
-
-   //////
-   ////// Non-transacted send
-   //////
-
-   ////////
-   //////// Non-reliable message
-   ////////
-
-   //////////
-   ////////// One message
-   //////////
-
-   ////////////
-   //////////// Non-transacted acknowledgment
-   ////////////
-
-   public void testRecoverableChannel_25() throws Throwable
-   {
-      if (!channel.isRecoverable())
-      {
-         // we test only recoverable channels now
-         return;
-      }
-
-      // add an NACKING receiver to the channel
-      SimpleReceiver r = new SimpleReceiver("NackingReceiver", SimpleReceiver.NACKING);
-      assertTrue(channel.add(r));
-
-      Message m = MessageFactory.createCoreMessage(0, false, "payload");
-      SimpleDeliveryObserver observer = new SimpleDeliveryObserver();
-
-      // non-transacted send, non-reliable message, one message
-      Delivery delivery = channel.handle(observer, m, null);
-
-      assertTrue(delivery.isDone());
-
-      List delivering = channel.browse();
-      assertEquals(1, delivering.size());
-      assertEquals(0, ((Message)delivering.get(0)).getMessageID());
-
-      List acknowledging = r.getMessages();
-      assertEquals(1, acknowledging.size());
-      Message ackm = (Message)acknowledging.get(0);
-      assertEquals(0, ackm.getMessageID());
-
-      // non-transacted acknowledgment
-      r.acknowledge(ackm, null);
-
-      assertTrue(channel.browse().isEmpty());
-   }
-
-   /**
-    * The same test as before, but with a Receiver configured to acknowledge immediately
-    * on the Delivery. Simulates a race condition in which the acknoledgment arrives before
-    * the Delivery is returned to channel.
-    *
-    * @throws Throwable
-    */
-   public void testRecoverableChannel_25_race() throws Throwable
-   {
-      if (!channel.isRecoverable())
-      {
-         // we test only recoverable channels now
-         return;
-      }
-
-      // add an NACKING receiver to the channel
-      SimpleReceiver r = new SimpleReceiver("NackingReceiver", SimpleReceiver.NACKING);
-      r.setImmediateAsynchronousAcknowledgment(true);
-      assertTrue(channel.add(r));
-
-      Message m = MessageFactory.createCoreMessage(0, false, "payload");
-      SimpleDeliveryObserver observer = new SimpleDeliveryObserver();
-
-      // non-transacted send, non-reliable message, one message
-      Delivery delivery = channel.handle(observer, m, null);
-
-      assertTrue(delivery.isDone());
-
-      // the receiver should have returned a "done" delivery
-      assertTrue(channel.browse().isEmpty());
-
-      List messages = r.getMessages();
-      assertEquals(1, messages.size());
-      Message ackm = (Message)messages.get(0);
-      assertEquals(0, ackm.getMessageID());
-
-      // an extra acknowledgment should be discarded
-      r.acknowledge(ackm, null);
-
-      assertTrue(channel.browse().isEmpty());
-   }
-
-
-   ////////////
-   //////////// Transacted acknowledgment and commit
-   ////////////
-
-   public void testRecoverableChannel_25_1() throws Throwable
-   {
-      if (!channel.isRecoverable())
-      {
-         // we test only recoverable channels now
-         return;
-      }
-
-      // add an NACKING receiver to the channel
-      SimpleReceiver r = new SimpleReceiver("NackingReceiver", SimpleReceiver.NACKING);
-      assertTrue(channel.add(r));
-
-      Message m = MessageFactory.createCoreMessage(0, false, "payload");
-      SimpleDeliveryObserver observer = new SimpleDeliveryObserver();
-
-      // non-transacted send, non-reliable message, one message
-      Delivery delivery = channel.handle(observer, m, null);
-
-      assertTrue(delivery.isDone());
-
-      List delivering = channel.browse();
-      assertEquals(1, delivering.size());
-      assertEquals(0, ((Message)delivering.get(0)).getMessageID());
-
-      List acknowledging = r.getMessages();
-      assertEquals(1, acknowledging.size());
-      Message ackm = (Message)acknowledging.get(0);
-      assertEquals(0, ackm.getMessageID());
-
-      Transaction tx = tr.createTransaction();
-
-      // transacted acknowledgment
-      r.acknowledge(ackm, tx);
-
-      delivering = channel.browse();
-      assertEquals(1, delivering.size());
-      assertEquals(0, ((Message)delivering.get(0)).getMessageID());
-
-      tx.commit();
-
-      assertTrue(channel.browse().isEmpty());
-   }
-
-
-   ////////////
-   //////////// Transacted acknowledgment and rollback
-   ////////////
-
-   public void testRecoverableChannel_25_2() throws Throwable
-   {
-      if (!channel.isRecoverable())
-      {
-         // we test only recoverable channels now
-         return;
-      }
-
-      // add an NACKING receiver to the channel
-      SimpleReceiver r = new SimpleReceiver("NackingReceiver", SimpleReceiver.NACKING);
-      assertTrue(channel.add(r));
-
-      Message m = MessageFactory.createCoreMessage(0, false, "payload");
-      SimpleDeliveryObserver observer = new SimpleDeliveryObserver();
-
-      // non-transacted send, non-reliable message, one message
-      Delivery delivery = channel.handle(observer, m, null);
-
-      assertTrue(delivery.isDone());
-
-      List delivering = channel.browse();
-      assertEquals(1, delivering.size());
-      assertEquals(0, ((Message)delivering.get(0)).getMessageID());
-
-      List acknowledging = r.getMessages();
-      assertEquals(1, acknowledging.size());
-      Message ackm = (Message)acknowledging.get(0);
-      assertEquals(0, ackm.getMessageID());
-
-      Transaction tx = tr.createTransaction();
-
-      // transacted acknowledgment
-      r.acknowledge(ackm, tx);
-
-      delivering = channel.browse();
-      assertEquals(1, delivering.size());
-      assertEquals(0, ((Message)delivering.get(0)).getMessageID());
-
-      tx.rollback();
-
-      delivering = channel.browse();
-      assertEquals(1, delivering.size());
-      assertEquals(0, ((Message)delivering.get(0)).getMessageID());
-
-      // acknowledge non-transactionally
-      r.acknowledge(ackm, null);
-
-      assertTrue(channel.browse().isEmpty());
-   }
-
-
-   //////////
-   ////////// Multiple message
-   //////////
-
-   ////////////
-   //////////// Non-transacted acknowledgment
-   ////////////
-
-   public void testRecoverableChannel_26() throws Throwable
-   {
-      if (!channel.isRecoverable())
-      {
-         // we test only recoverable channels now
-         return;
-      }
-
-      // add an NACKING receiver to the channel
-      SimpleReceiver r = new SimpleReceiver("NackingReceiver", SimpleReceiver.NACKING);
-      assertTrue(channel.add(r));
-
-      SimpleDeliveryObserver observer = new SimpleDeliveryObserver();
-
-      Message[] messages = new Message[NUMBER_OF_MESSAGES];
-      for(int i = 0; i < NUMBER_OF_MESSAGES; i++)
-      {
-         messages[i] = MessageFactory.createCoreMessage(i, false, "payload" + i);
-
-         // non-transacted send, non-reliable message, multiple messages
-         Delivery delivery = channel.handle(observer, messages[i], null);
-
-         assertTrue(delivery.isDone());
-      }
-
-      assertEqualSets(messages, channel.browse());
-      assertEqualSets(messages, r.getMessages());
-
-      for(Iterator i = r.getMessages().iterator(); i.hasNext();)
-      {
-         Message ackm = (Message)i.next();
-         // non-transacted acknowledgment
-         r.acknowledge(ackm, null);
-      }
-
-      assertTrue(channel.browse().isEmpty());
-
-   }
-
-   ////////////
-   //////////// Transacted acknowledgment and commit
-   ////////////
-
-   public void testRecoverableChannel_26_1() throws Throwable
-   {
-      if (!channel.isRecoverable())
-      {
-         // we test only recoverable channels now
-         return;
-      }
-
-      // add an NACKING receiver to the channel
-      SimpleReceiver r = new SimpleReceiver("NackingReceiver", SimpleReceiver.NACKING);
-      assertTrue(channel.add(r));
-
-      SimpleDeliveryObserver observer = new SimpleDeliveryObserver();
-
-      Message[] messages = new Message[NUMBER_OF_MESSAGES];
-      for(int i = 0; i < NUMBER_OF_MESSAGES; i++)
-      {
-         messages[i] = MessageFactory.createCoreMessage(i, false, "payload" + i);
-
-         // non-transacted send, non-reliable message, multiple messages
-         Delivery delivery = channel.handle(observer, messages[i], null);
-
-         assertTrue(delivery.isDone());
-      }
-
-      assertEqualSets(messages, channel.browse());
-      assertEqualSets(messages, r.getMessages());
-
-      Transaction tx = tr.createTransaction();
-
-      for(Iterator i = r.getMessages().iterator(); i.hasNext();)
-      {
-         Message ackm = (Message)i.next();
-         // transacted acknowledgment
-         r.acknowledge(ackm, tx);
-      }
-
-      assertEqualSets(messages, channel.browse());
-
-      tx.commit();
-
-      assertTrue(channel.browse().isEmpty());
-   }
-
-
-   ////////////
-   //////////// Transacted acknowledgment and rollback
-   ////////////
-
-   public void testRecoverableChannel_26_2() throws Throwable
-   {
-      if (!channel.isRecoverable())
-      {
-         // we test only recoverable channels now
-         return;
-      }
-
-      // add an NACKING receiver to the channel
-      SimpleReceiver r = new SimpleReceiver("NackingReceiver", SimpleReceiver.NACKING);
-      assertTrue(channel.add(r));
-
-      SimpleDeliveryObserver observer = new SimpleDeliveryObserver();
-
-      Message[] messages = new Message[NUMBER_OF_MESSAGES];
-      for(int i = 0; i < NUMBER_OF_MESSAGES; i++)
-      {
-         messages[i] = MessageFactory.createCoreMessage(i, false, "payload" + i);
-
-         // non-transacted send, non-reliable message, multiple messages
-         Delivery delivery = channel.handle(observer, messages[i], null);
-
-         assertTrue(delivery.isDone());
-      }
-
-      assertEqualSets(messages, channel.browse());
-      assertEqualSets(messages, r.getMessages());
-
-      Transaction tx = tr.createTransaction();
-
-      for(Iterator i = r.getMessages().iterator(); i.hasNext();)
-      {
-         Message ackm = (Message)i.next();
-         // transacted acknowledgment
-         r.acknowledge(ackm, tx);
-      }
-
-      assertEqualSets(messages, channel.browse());
-
-      tx.rollback();
-
-      assertEqualSets(messages, channel.browse());
-
-      // acknowledge non-transactionally
-      for(Iterator i = r.getMessages().iterator(); i.hasNext();)
-      {
-         Message ackm = (Message)i.next();
-         // non-transacted acknowledgment
-         r.acknowledge(ackm, null);
-      }
-
-      assertTrue(channel.browse().isEmpty());
-   }
-
-   ////////
-   //////// Reliable message
-   ////////
-
-   //////////
-   ////////// One message
-   //////////
-
-   ////////////
-   //////////// Non-transacted acknowledgment
-   ////////////
-
-   public void testRecoverableChannel_27() throws Throwable
-   {
-      if (!channel.isRecoverable())
-      {
-         // we test only recoverable channels now
-         return;
-      }
-
-
-      // add an NACKING receiver to the channel
-      SimpleReceiver r = new SimpleReceiver("NackingReceiver", SimpleReceiver.NACKING);
-      assertTrue(channel.add(r));
-
-      Message m = MessageFactory.createCoreMessage(0, true, "payload");
-      SimpleDeliveryObserver observer = new SimpleDeliveryObserver();
-
-      // non-transacted send, reliable message, one message
-      Delivery delivery = channel.handle(observer, m, null);
-
-      assertTrue(delivery.isDone());
-
-      List delivering = channel.browse();
-      assertEquals(1, delivering.size());
-      assertEquals(0, ((Message)delivering.get(0)).getMessageID());
-
-      List acknowledging = r.getMessages();
-      assertEquals(1, acknowledging.size());
-      Message ackm = (Message)acknowledging.get(0);
-      assertEquals(0, ackm.getMessageID());
-
-      // non-transacted acknowledgment
-      r.acknowledge(ackm, null);
-
-      assertTrue(channel.browse().isEmpty());
-   }
-
-   /**
-    * The same test as before, but with a Receiver configured to acknowledge immediately
-    * on the Delivery. Simulates a race condition in which the acknoledgment arrives before
-    * the Delivery is returned to channel.
-    *
-    * @throws Throwable
-    */
-   public void testRecoverableChannel_27_race() throws Throwable
-   {
-      if (!channel.isRecoverable())
-      {
-         // we test only recoverable channels now
-         return;
-      }
-
-      // add an NACKING receiver to the channel
-      SimpleReceiver r = new SimpleReceiver("NackingReceiver", SimpleReceiver.NACKING);
-      r.setImmediateAsynchronousAcknowledgment(true);
-      assertTrue(channel.add(r));
-
-      Message m = MessageFactory.createCoreMessage(0, true, "payload");
-      SimpleDeliveryObserver observer = new SimpleDeliveryObserver();
-
-      // non-transacted send, reliable message, one message
-      Delivery delivery = channel.handle(observer, m, null);
-
-      assertTrue(delivery.isDone());
-
-      // the receiver should have returned a "done" delivery
-      assertTrue(channel.browse().isEmpty());
-
-      List messages = r.getMessages();
-      assertEquals(1, messages.size());
-      Message ackm = (Message)messages.get(0);
-      assertEquals(0, ackm.getMessageID());
-
-      // an extra acknowledgment should be discarded
-      r.acknowledge(ackm, null);
-
-      assertTrue(channel.browse().isEmpty());
-   }
-
-
-   ////////////
-   //////////// Transacted acknowledgment and commit
-   ////////////
-
-   public void testRecoverableChannel_27_1() throws Throwable
-   {
-      if (!channel.isRecoverable())
-      {
-         // we test only recoverable channels now
-         return;
-      }
-
-
-      // add an NACKING receiver to the channel
-      SimpleReceiver r = new SimpleReceiver("NackingReceiver", SimpleReceiver.NACKING);
-      assertTrue(channel.add(r));
-
-      Message m = MessageFactory.createCoreMessage(0, true, "payload");
-      SimpleDeliveryObserver observer = new SimpleDeliveryObserver();
-
-      // non-transacted send, reliable message, one message
-      Delivery delivery = channel.handle(observer, m, null);
-
-      assertTrue(delivery.isDone());
-
-      List delivering = channel.browse();
-      assertEquals(1, delivering.size());
-      assertEquals(0, ((Message)delivering.get(0)).getMessageID());
-
-      List acknowledging = r.getMessages();
-      assertEquals(1, acknowledging.size());
-      Message ackm = (Message)acknowledging.get(0);
-      assertEquals(0, ackm.getMessageID());
-
-      Transaction tx = tr.createTransaction();
-
-      // transacted acknowledgment
-      r.acknowledge(ackm, tx);
-
-      delivering = channel.browse();
-      assertEquals(1, delivering.size());
-      assertEquals(0, ((Message)delivering.get(0)).getMessageID());
-
-      tx.commit();
-
-      assertTrue(channel.browse().isEmpty());
-   }
-
-
-   ////////////
-   //////////// Transacted acknowledgment and rollback
-   ////////////
-
-   public void testRecoverableChannel_27_2() throws Throwable
-   {
-      if (!channel.isRecoverable())
-      {
-         // we test only recoverable channels now
-         return;
-      }
-
-
-      // add an NACKING receiver to the channel
-      SimpleReceiver r = new SimpleReceiver("NackingReceiver", SimpleReceiver.NACKING);
-      assertTrue(channel.add(r));
-
-      Message m = MessageFactory.createCoreMessage(0, true, "payload");
-      SimpleDeliveryObserver observer = new SimpleDeliveryObserver();
-
-      // non-transacted send, reliable message, one message
-      Delivery delivery = channel.handle(observer, m, null);
-
-      assertTrue(delivery.isDone());
-
-      List delivering = channel.browse();
-      assertEquals(1, delivering.size());
-      assertEquals(0, ((Message)delivering.get(0)).getMessageID());
-
-      List acknowledging = r.getMessages();
-      assertEquals(1, acknowledging.size());
-      Message ackm = (Message)acknowledging.get(0);
-      assertEquals(0, ackm.getMessageID());
-
-      Transaction tx = tr.createTransaction();
-
-      // transacted acknowledgment
-      r.acknowledge(ackm, tx);
-
-      delivering = channel.browse();
-      assertEquals(1, delivering.size());
-      assertEquals(0, ((Message)delivering.get(0)).getMessageID());
-
-      tx.rollback();
-
-      delivering = channel.browse();
-      assertEquals(1, delivering.size());
-      assertEquals(0, ((Message)delivering.get(0)).getMessageID());
-
-      // acknowledge non-transactionally
-      r.acknowledge(ackm, null);
-
-      assertTrue(channel.browse().isEmpty());
-   }
-
-
-   //////////
-   ////////// Multiple message
-   //////////
-
-   ////////////
-   //////////// Non-transacted acknowledgment
-   ////////////
-
-   public void testRecoverableChannel_28() throws Throwable
-   {
-      if (!channel.isRecoverable())
-      {
-         // we test only recoverable channels now
-         return;
-      }
-
-
-      // add an NACKING receiver to the channel
-      SimpleReceiver r = new SimpleReceiver("NackingReceiver", SimpleReceiver.NACKING);
-      assertTrue(channel.add(r));
-
-      SimpleDeliveryObserver observer = new SimpleDeliveryObserver();
-
-      Message[] messages = new Message[NUMBER_OF_MESSAGES];
-      for(int i = 0; i < NUMBER_OF_MESSAGES; i++)
-      {
-         messages[i] = MessageFactory.createCoreMessage(i, true, "payload" + i);
-
-         // non-transacted send, reliable message, multiple messages
-         Delivery delivery = channel.handle(observer, messages[i], null);
-
-         assertTrue(delivery.isDone());
-      }
-
-      assertEqualSets(messages, channel.browse());
-      assertEqualSets(messages, r.getMessages());
-
-      for(Iterator i = r.getMessages().iterator(); i.hasNext();)
-      {
-         Message ackm = (Message)i.next();
-         // non-transacted acknowledgment
-         r.acknowledge(ackm, null);
-      }
-
-      assertTrue(channel.browse().isEmpty());
-   }
-
-   ////////////
-   //////////// Transacted acknowledgment and commit
-   ////////////
-
-   public void testRecoverableChannel_28_1() throws Throwable
-   {
-      if (!channel.isRecoverable())
-      {
-         // we test only recoverable channels now
-         return;
-      }
-
-
-      // add an NACKING receiver to the channel
-      SimpleReceiver r = new SimpleReceiver("NackingReceiver", SimpleReceiver.NACKING);
-      assertTrue(channel.add(r));
-
-      SimpleDeliveryObserver observer = new SimpleDeliveryObserver();
-
-      Message[] messages = new Message[NUMBER_OF_MESSAGES];
-      for(int i = 0; i < NUMBER_OF_MESSAGES; i++)
-      {
-         messages[i] = MessageFactory.createCoreMessage(i, true, "payload" + i);
-
-         // non-transacted send, reliable message, multiple messages
-         Delivery delivery = channel.handle(observer, messages[i], null);
-
-         assertTrue(delivery.isDone());
-      }
-
-      assertEqualSets(messages, channel.browse());
-      assertEqualSets(messages, r.getMessages());
-
-      Transaction tx = tr.createTransaction();
-
-      for(Iterator i = r.getMessages().iterator(); i.hasNext();)
-      {
-         Message ackm = (Message)i.next();
-         // transacted acknowledgment
-         r.acknowledge(ackm, tx);
-      }
-
-      assertEqualSets(messages, channel.browse());
-
-      tx.commit();
-
-      assertTrue(channel.browse().isEmpty());
-   }
-
-   ////////////
-   //////////// Transacted acknowledgment and rollback
-   ////////////
-
-   public void testRecoverableChannel_28_2() throws Throwable
-   {
-      if (!channel.isRecoverable())
-      {
-         // we test only recoverable channels now
-         return;
-      }
-
-
-      // add an NACKING receiver to the channel
-      SimpleReceiver r = new SimpleReceiver("NackingReceiver", SimpleReceiver.NACKING);
-      assertTrue(channel.add(r));
-
-      SimpleDeliveryObserver observer = new SimpleDeliveryObserver();
-
-      Message[] messages = new Message[NUMBER_OF_MESSAGES];
-      for(int i = 0; i < NUMBER_OF_MESSAGES; i++)
-      {
-         messages[i] = MessageFactory.createCoreMessage(i, true, "payload" + i);
-
-         // non-transacted send, reliable message, multiple messages
-         Delivery delivery = channel.handle(observer, messages[i], null);
-
-         assertTrue(delivery.isDone());
-      }
-
-      assertEqualSets(messages, channel.browse());
-      assertEqualSets(messages, r.getMessages());
-
-      Transaction tx = tr.createTransaction();
-
-      for(Iterator i = r.getMessages().iterator(); i.hasNext();)
-      {
-         Message ackm = (Message)i.next();
-         // transacted acknowledgment
-         r.acknowledge(ackm, tx);
-      }
-
-      assertEqualSets(messages, channel.browse());
-
-      tx.rollback();
-
-      assertEqualSets(messages, channel.browse());
-
-      // acknowledge non-transactionally
-      for(Iterator i = r.getMessages().iterator(); i.hasNext();)
-      {
-         Message ackm = (Message)i.next();
-         // non-transacted acknowledgment
-         r.acknowledge(ackm, null);
-      }
-
-      assertTrue(channel.browse().isEmpty());
-   }
-
-
-   //////
-   ////// Transacted send and commit
-   //////
-
-   ////////
-   //////// Non-reliable message
-   ////////
-
-   //////////
-   ////////// One message
-   //////////
-
-   public void testRecoverableChannel_29() throws Throwable
-   {
-      if (!channel.isRecoverable())
-      {
-         // we test only recoverable channels now
-         return;
-      }
-
-
-      // add an NACKING receiver to the channel
-      SimpleReceiver r = new SimpleReceiver("NackingReceiver", SimpleReceiver.NACKING);
-      assertTrue(channel.add(r));
-
-      Message m = MessageFactory.createCoreMessage(0, false, "payload");
-      SimpleDeliveryObserver observer = new SimpleDeliveryObserver();
-
-      Transaction tx = tr.createTransaction();
-
-      // transacted send, non-reliable message, one message
-      // for a transactional send, handle() return value is unspecified
-      channel.handle(observer, m, tx);
-
-      // no messages in the channel
-      assertEquals(0, channel.browse().size());
-
-      // no message at the receiver
-      assertTrue(r.getMessages().isEmpty());
-
-      tx.commit();
-
-      List delivering = channel.browse();
-      assertEquals(1, delivering.size());
-      assertEquals(0, ((Message)delivering.get(0)).getMessageID());
-
-      List acknowledging = r.getMessages();
-      assertEquals(1, acknowledging.size());
-      Message ackm = (Message)acknowledging.get(0);
-      assertEquals(0, ackm.getMessageID());
-
-      // non-transacted acknowledgment
-      r.acknowledge(ackm, null);
-
-      assertTrue(channel.browse().isEmpty());
-   }
-
-   //////////
-   ////////// Multiple message
-   //////////
-
-   public void testRecoverableChannel_30() throws Throwable
-   {
-      if (!channel.isRecoverable())
-      {
-         // we test only recoverable channels now
-         return;
-      }
-
-
-      // add an NACKING receiver to the channel
-      SimpleReceiver r = new SimpleReceiver("NackingReceiver", SimpleReceiver.NACKING);
-      assertTrue(channel.add(r));
-
-      SimpleDeliveryObserver observer = new SimpleDeliveryObserver();
-
-      Transaction tx = tr.createTransaction();
-
-      Message[] messages = new Message[NUMBER_OF_MESSAGES];
-      for(int i = 0; i < NUMBER_OF_MESSAGES; i++)
-      {
-         messages[i] = MessageFactory.createCoreMessage(i, false, "payload" + i);
-
-         // transacted send, non-reliable message, multiple messages
-         // for a transactional send, handle() return value is unspecified
-         channel.handle(observer, messages[i], tx);
-      }
-
-      // no messages in the channel
-      assertEquals(0, channel.browse().size());
-
-      // no message at the receiver
-      assertTrue(r.getMessages().isEmpty());
-
-      tx.commit();
-
-      assertEqualSets(messages, channel.browse());
-      assertEqualSets(messages, r.getMessages());
-
-      for(Iterator i = r.getMessages().iterator(); i.hasNext();)
-      {
-         Message ackm = (Message)i.next();
-         // non-transacted acknowledgment
-         r.acknowledge(ackm, null);
-      }
-
-      assertTrue(channel.browse().isEmpty());
-   }
-
-   ////////
-   //////// Reliable message
-   ////////
-
-   //////////
-   ////////// One message
-   //////////
-
-   public void testRecoverableChannel_31() throws Throwable
-   {
-      if (!channel.isRecoverable())
-      {
-         // we test only recoverable channels now
-         return;
-      }
-
-
-      // add an NACKING receiver to the channel
-      SimpleReceiver r = new SimpleReceiver("NackingReceiver", SimpleReceiver.NACKING);
-      assertTrue(channel.add(r));
-
-
-      Message m = MessageFactory.createCoreMessage(0, true, "payload");
-      SimpleDeliveryObserver observer = new SimpleDeliveryObserver();
-
-      Transaction tx = tr.createTransaction();
-
-      // transacted send, reliable message, one message
-      // for a transactional send, handle() return value is unspecified
-      channel.handle(observer, m, tx);
-
-      // no messages in the channel yet
-      assertEquals(0, channel.browse().size());
-
-      // no message at the receiver
-      assertTrue(r.getMessages().isEmpty());
-
-      tx.commit();
-
-      List delivering = channel.browse();
-      assertEquals(1, delivering.size());
-      assertEquals(0, ((Message)delivering.get(0)).getMessageID());
-
-      List acknowledging = r.getMessages();
-      assertEquals(1, acknowledging.size());
-      Message ackm = (Message)acknowledging.get(0);
-      assertEquals(0, ackm.getMessageID());
-
-      // non-transacted acknowledgment
-      r.acknowledge(ackm, null);
-
-      assertTrue(channel.browse().isEmpty());
-   }
-
-   //////////
-   ////////// Multiple message
-   //////////
-
-   public void testRecoverableChannel_32() throws Throwable
-   {
-      if (!channel.isRecoverable())
-      {
-         // we test only recoverable channels now
-         return;
-      }
-
-      // add an NACKING receiver to the channel
-      SimpleReceiver r = new SimpleReceiver("NackingReceiver", SimpleReceiver.NACKING);
-      assertTrue(channel.add(r));
-
-      SimpleDeliveryObserver observer = new SimpleDeliveryObserver();
-
-      Transaction tx = tr.createTransaction();
-
-      Message[] messages = new Message[NUMBER_OF_MESSAGES];
-      for(int i = 0; i < NUMBER_OF_MESSAGES; i++)
-      {
-         messages[i] = MessageFactory.createCoreMessage(i, true, "payload" + i);
-
-         // transacted send, reliable message, multiple messages
-         // for a transactional send, handle() return value is unspecified
-         channel.handle(observer, messages[i], tx);
-      }
-
-      // no messages in the channel yet
-      assertEquals(0, channel.browse().size());
-
-      // no message at the receiver
-      assertTrue(r.getMessages().isEmpty());
-
-      tx.commit();
-
-      assertEqualSets(messages, channel.browse());
-      assertEqualSets(messages, r.getMessages());
-
-      for(Iterator i = r.getMessages().iterator(); i.hasNext();)
-      {
-         Message ackm = (Message)i.next();
-         // non-transacted acknowledgment
-         r.acknowledge(ackm, null);
-      }
-
-      assertTrue(channel.browse().isEmpty());
-   }
-
-   /**
-    * This is a variation where I send a mixture of reliable and non-reliable messages,
-    */
-   public void testRecoverableChannel_32_mixed() throws Throwable
-   {
-      if (!channel.isRecoverable())
-      {
-         // we test only recoverable channels now
-         return;
-      }
-
-
-      // add an NACKING receiver to the channel
-      SimpleReceiver r = new SimpleReceiver("NackingReceiver", SimpleReceiver.NACKING);
-      assertTrue(channel.add(r));
-
-
-      SimpleDeliveryObserver observer = new SimpleDeliveryObserver();
-
-      Transaction tx = tr.createTransaction();
-
-      Message[] messages = new Message[NUMBER_OF_MESSAGES];
-      for(int i = 0; i < NUMBER_OF_MESSAGES; i++)
-      {
-         // send a mixture of reliable and non-reliable messages
-         messages[i] = MessageFactory.createCoreMessage(i, (i % 2 == 1), "payload" + i);
-
-         // transacted send, reliable/non-reliable messages, multiple messages
-         // for a transactional send, handle() return value is unspecified
-         channel.handle(observer, messages[i], tx);
-      }
-
-      // no messages in the channel
-      assertEquals(0, channel.browse().size());
-
-      // no message at the receiver
-      assertTrue(r.getMessages().isEmpty());
-
-      tx.commit();
-
-      assertEqualSets(messages, channel.browse());
-      assertEqualSets(messages, r.getMessages());
-
-      for(Iterator i = r.getMessages().iterator(); i.hasNext();)
-      {
-         Message ackm = (Message)i.next();
-         // non-transacted acknowledgment
-         r.acknowledge(ackm, null);
-      }
-
-      assertTrue(channel.browse().isEmpty());
-   }
-
-
-   //////
-   ////// Transacted send and rollback
-   //////
-
-   ////////
-   //////// Non-reliable message
-   ////////
-
-   //////////
-   ////////// One message
-   //////////
-
-   public void testRecoverableChannel_33() throws Exception
-   {
-      if (!channel.isRecoverable())
-      {
-         // we test only recoverable channels now
-         return;
-      }
-
-      // add an NACKING receiver to the channel
-      SimpleReceiver r = new SimpleReceiver("NackingReceiver", SimpleReceiver.NACKING);
-      assertTrue(channel.add(r));
-
-
-      Message m = MessageFactory.createCoreMessage(0, false, "payload");
-      SimpleDeliveryObserver observer = new SimpleDeliveryObserver();
-
-      Transaction tx = tr.createTransaction();
-
-      // transacted send, non-reliable message, one message
-      // for a transactional send, handle() return value is unspecified
-      channel.handle(observer, m, tx);
-
-      // no messages in the channel
-      assertEquals(0, channel.browse().size());
-
-      // no message at the receiver
-      assertTrue(r.getMessages().isEmpty());
-
-
-      tx.rollback();
-
-      // no messages in the channel
-      assertEquals(0, channel.browse().size());
-
-      // no message at the receiver
-      assertTrue(r.getMessages().isEmpty());
-
-   }
-
-   //////////
-   ////////// Multiple message
-   //////////
-
-   public void testRecoverableChannel_34() throws Exception
-   {
-      if (!channel.isRecoverable())
-      {
-         // we test only recoverable channels now
-         return;
-      }
-
-      // add an NACKING receiver to the channel
-      SimpleReceiver r = new SimpleReceiver("NackingReceiver", SimpleReceiver.NACKING);
-      assertTrue(channel.add(r));
-
-      SimpleDeliveryObserver observer = new SimpleDeliveryObserver();
-
-      Transaction tx = tr.createTransaction();
-
-      Message[] messages = new Message[NUMBER_OF_MESSAGES];
-      for(int i = 0; i < NUMBER_OF_MESSAGES; i++)
-      {
-         messages[i] = MessageFactory.createCoreMessage(i, false, "payload" + i);
-
-         // transacted send, non-reliable message, multiple messages
-         // for a transactional send, handle() return value is unspecified
-         channel.handle(observer, messages[i], tx);
-      }
-
-      // no messages in the channel
-      assertEquals(0, channel.browse().size());
-
-      // no message at the receiver
-      assertTrue(r.getMessages().isEmpty());
-
-      tx.rollback();
-
-      // no messages in the channel
-      assertEquals(0, channel.browse().size());
-
-      // no message at the receiver
-      assertTrue(r.getMessages().isEmpty());
-   }
-
-   ////////
-   //////// Reliable message
-   ////////
-
-   //////////
-   ////////// One message
-   //////////
-
-   public void testRecoverableChannel_35() throws Exception
-   {
-      if (!channel.isRecoverable())
-      {
-         // we test only recoverable channels now
-         return;
-      }
-
-      // add an NACKING receiver to the channel
-      SimpleReceiver r = new SimpleReceiver("NackingReceiver", SimpleReceiver.NACKING);
-      assertTrue(channel.add(r));
-
-
-      Message m = MessageFactory.createCoreMessage(0, true, "payload");
-      SimpleDeliveryObserver observer = new SimpleDeliveryObserver();
-
-      Transaction tx = tr.createTransaction();
-
-      // transacted send, reliable message, one message
-      // for a transactional send, handle() return value is unspecified
-      channel.handle(observer, m, tx);
-
-      // no messages in the channel
-      assertEquals(0, channel.browse().size());
-
-      // no message at the receiver
-      assertTrue(r.getMessages().isEmpty());
-
-      tx.rollback();
-
-      // no messages in the channel
-      assertEquals(0, channel.browse().size());
-
-      // no message at the receiver
-      assertTrue(r.getMessages().isEmpty());
-   }
-
-   //////////
-   ////////// Multiple message
-   //////////
-
-   public void testRecoverableChannel_36() throws Exception
-   {
-      if (!channel.isRecoverable())
-      {
-         // we test only recoverable channels now
-         return;
-      }
-
-      // add an NACKING receiver to the channel
-      SimpleReceiver r = new SimpleReceiver("NackingReceiver", SimpleReceiver.NACKING);
-      assertTrue(channel.add(r));
-
-
-      SimpleDeliveryObserver observer = new SimpleDeliveryObserver();
-
-      Transaction tx = tr.createTransaction();
-
-      Message[] messages = new Message[NUMBER_OF_MESSAGES];
-      for(int i = 0; i < NUMBER_OF_MESSAGES; i++)
-      {
-         messages[i] = MessageFactory.createCoreMessage(i, true, "payload" + i);
-
-         // transacted send, reliable message, multiple messages
-         // for a transactional send, handle() return value is unspecified
-         channel.handle(observer, messages[i], tx);
-      }
-
-      // no messages in the channel
-      assertEquals(0, channel.browse().size());
-
-      // no message at the receiver
-      assertTrue(r.getMessages().isEmpty());
-
-      tx.rollback();
-
-      // no messages in the channel
-      assertEquals(0, channel.browse().size());
-
-      // no message at the receiver
-      assertTrue(r.getMessages().isEmpty());
-   }
-
-   /**
-    * This is a variation where I send a mixture of reliable and non-reliable messages,
-    */
-   public void testRecoverableChannel_36_mixed() throws Exception
-   {
-      if (!channel.isRecoverable())
-      {
-         // we test only recoverable channels now
-         return;
-      }
-
-      // add an NACKING receiver to the channel
-      SimpleReceiver r = new SimpleReceiver("NackingReceiver", SimpleReceiver.NACKING);
-      assertTrue(channel.add(r));
-
-
-      SimpleDeliveryObserver observer = new SimpleDeliveryObserver();
-
-      Transaction tx = tr.createTransaction();
-
-      Message[] messages = new Message[NUMBER_OF_MESSAGES];
-      for(int i = 0; i < NUMBER_OF_MESSAGES; i++)
-      {
-         // send a mixture of reliable and non-reliable messages
-         messages[i] = MessageFactory.createCoreMessage(i, (i % 2 == 1), "payload" + i);
-
-         // transacted send, reliable/non-reliable messages, multiple messages
-         // for a transactional send, handle() return value is unspecified
-         channel.handle(observer, messages[i], tx);
-      }
-
-      // no messages in the channel
-      assertEquals(0, channel.browse().size());
-
-      // no message at the receiver
-      assertTrue(r.getMessages().isEmpty());
-
-      tx.rollback();
-
-      // no messages in the channel
-      assertEquals(0, channel.browse().size());
-
-      // no message at the receiver
-      assertTrue(r.getMessages().isEmpty());
-   }
-
-   ///////////////////////////////
-   /////////////////////////////// Add receiver tests
-   ///////////////////////////////
-   ///////////////////////////////
-   ///////////////////////////////
-
-   //
-   // Non-recoverable channel
-   //
-
-   ////
-   //// Non-reliable message
-   ////
-
-   //////
-   ////// Broken receiver
-   //////
-
-   public void testAddReceiver_1() throws Exception
-   {
-      if (channel.isRecoverable())
-      {
-         // we test only non-recoverable channels now
-         return;
-      }
-
-      // the channel has no receivers
-      assertFalse(channel.iterator().hasNext());
-
-      Message m = MessageFactory.createCoreMessage(0, false, "payload");
-      SimpleDeliveryObserver observer = new SimpleDeliveryObserver();
-
-      // non-recoverable channel, non-reliable message
-      Delivery delivery = channel.handle(observer, m, null);
-      assertTrue(delivery.isDone());
-
-      List stored = channel.browse();
-      assertEquals(1, stored.size());
-
-
-      SimpleReceiver receiver = new SimpleReceiver("BrokenReceiver", SimpleReceiver.BROKEN);
-      assertTrue(channel.add(receiver));
-
-      stored = channel.browse();
-      assertEquals(1, stored.size());
-      Message sm = (Message)stored.iterator().next();
-      assertFalse(sm.isReliable());
-      assertEquals(0, sm.getMessageID());
-
-      assertTrue(receiver.getMessages().isEmpty());
-   }
-
-   //////
-   ////// ACKING receiver
-   //////
-
-   public void testAddReceiver_2() throws Exception
-   {
-      if (channel.isRecoverable())
-      {
-         // we test only non-recoverable channels now
-         return;
-      }
-
-      // the channel has no receivers
-      assertFalse(channel.iterator().hasNext());
-
-      Message m = MessageFactory.createCoreMessage(0, false, "payload");
-      SimpleDeliveryObserver observer = new SimpleDeliveryObserver();
-
-      // non-recoverable channel, non-reliable message
-      Delivery delivery = channel.handle(observer, m, null);
-      assertTrue(delivery.isDone());
-
-      List stored = channel.browse();
-      assertEquals(1, stored.size());
-
-      SimpleReceiver receiver =
-            new SimpleReceiver("ACKINGReceiver", SimpleReceiver.ACKING, channel);
-      assertTrue(channel.add(receiver));
-
-      assertEquals(1, channel.browse().size());
-
-      // receiver explicitely asks for message
-      receiver.requestMessages();
-
-      assertTrue(channel.browse().isEmpty());
-
-      List messages = receiver.getMessages();
-      assertEquals(1, messages.size());
-      Message sm = (Message)messages.iterator().next();
-      assertFalse(sm.isReliable());
-      assertEquals(0, sm.getMessageID());
-   }
-
-   //////
-   ////// NACKING receiver
-   //////
-
-   public void testAddReceiver_3() throws Throwable
-   {
-      if (channel.isRecoverable())
-      {
-         // we test only non-recoverable channels now
-         return;
-      }
-
-      // the channel has no receivers
-      assertFalse(channel.iterator().hasNext());
-
-      Message m = MessageFactory.createCoreMessage(0, false, "payload");
-      SimpleDeliveryObserver observer = new SimpleDeliveryObserver();
-
-      // non-recoverable channel, non-reliable message
-      Delivery delivery = channel.handle(observer, m, null);
-      assertTrue(delivery.isDone());
-
-      List stored = channel.browse();
-      assertEquals(1, stored.size());
-
-      SimpleReceiver receiver =
-            new SimpleReceiver("NACKINGReceiver", SimpleReceiver.NACKING, channel);
-      assertTrue(channel.add(receiver));
-
-      assertEquals(1, channel.browse().size());
-
-      // receiver explicitely asks for message
-      receiver.requestMessages();
-
-      assertEquals(1, channel.browse().size());
-
-      List messages = receiver.getMessages();
-      assertEquals(1, messages.size());
-      Message sm = (Message)messages.iterator().next();
-      assertFalse(sm.isReliable());
-      assertEquals(0, sm.getMessageID());
-
-      receiver.acknowledge(sm, null);
-
-      assertTrue(channel.browse().isEmpty());
-
-      messages = receiver.getMessages();
-      assertEquals(1, messages.size());
-      sm = (Message)messages.iterator().next();
-      assertFalse(sm.isReliable());
-      assertEquals(0, sm.getMessageID());
-   }
-
-   //
-   // Recoverable channel
-   //
-
-   ////
-   //// Reliable message
-   ////
-
-   public void testAddReceiver_4() throws Exception
-   {
-      if (!channel.isRecoverable())
-      {
-         // we test only recoverable channels now
-         return;
-      }
-
-      // the channel has no receivers
-      assertFalse(channel.iterator().hasNext());
-
-      Message m = MessageFactory.createCoreMessage(0, true, "payload");
-      SimpleDeliveryObserver observer = new SimpleDeliveryObserver();
-
-      // non-recoverable channel, non-reliable message
-      Delivery delivery = channel.handle(observer, m, null);
-      assertTrue(delivery.isDone());
-
-      List stored = channel.browse();
-      assertEquals(1, stored.size());
-
-
-      SimpleReceiver receiver = new SimpleReceiver("BrokenReceiver", SimpleReceiver.BROKEN);
-      assertTrue(channel.add(receiver));
-
-      stored = channel.browse();
-      assertEquals(1, stored.size());
-      Message sm = (Message)stored.iterator().next();
-      assertTrue(sm.isReliable());
-      assertEquals(0, sm.getMessageID());
-
-      assertTrue(receiver.getMessages().isEmpty());
-   }
-
-   //////
-   ////// ACKING receiver
-   //////
-
-   public void testAddReceiver_5() throws Exception
-   {
-      if (!channel.isRecoverable())
-      {
-         // we test only recoverable channels now
-         return;
-      }
-
-      // the channel has no receivers
-      assertFalse(channel.iterator().hasNext());
-
-      Message m = MessageFactory.createCoreMessage(0, true, "payload");
-      SimpleDeliveryObserver observer = new SimpleDeliveryObserver();
-
-      // non-recoverable channel, non-reliable message
-      Delivery delivery = channel.handle(observer, m, null);
-      assertTrue(delivery.isDone());
-
-      List stored = channel.browse();
-      assertEquals(1, stored.size());
-
-      SimpleReceiver receiver =
-            new SimpleReceiver("ACKINGReceiver", SimpleReceiver.ACKING, channel);
-      assertTrue(channel.add(receiver));
-
-      // receiver explicitely asks for message
-      receiver.requestMessages();
-
-      assertTrue(channel.browse().isEmpty());
-
-      List messages = receiver.getMessages();
-      assertEquals(1, messages.size());
-      Message sm = (Message)messages.iterator().next();
-      assertTrue(sm.isReliable());
-      assertEquals(0, sm.getMessageID());
-   }
-
-   //////
-   ////// NACKING receiver
-   //////
-
-   public void testAddReceiver_6() throws Throwable
-   {
-      if (!channel.isRecoverable())
-      {
-         // we test only recoverable channels now
-         return;
-      }
-
-      // the channel has no receivers
-      assertFalse(channel.iterator().hasNext());
-
-      Message m = MessageFactory.createCoreMessage(0, true, "payload");
-      SimpleDeliveryObserver observer = new SimpleDeliveryObserver();
-
-      // non-recoverable channel, non-reliable message
-      Delivery delivery = channel.handle(observer, m, null);
-      assertTrue(delivery.isDone());
-
-      List stored = channel.browse();
-      assertEquals(1, stored.size());
-
-      SimpleReceiver receiver =
-            new SimpleReceiver("NACKINGReceiver", SimpleReceiver.NACKING, channel);
-      assertTrue(channel.add(receiver));
-
-      assertEquals(1, channel.browse().size());
-
-      // receiver explicitely asks for message
-      receiver.requestMessages();
-
-      assertEquals(1, channel.browse().size());
-
-      List messages = receiver.getMessages();
-      assertEquals(1, messages.size());
-      Message sm = (Message)messages.iterator().next();
-      assertTrue(sm.isReliable());
-      assertEquals(0, sm.getMessageID());
-
-      receiver.acknowledge(sm, null);
-
-      assertTrue(channel.browse().isEmpty());
-
-      messages = receiver.getMessages();
-      assertEquals(1, messages.size());
-      sm = (Message)messages.iterator().next();
-      assertTrue(sm.isReliable());
-      assertEquals(0, sm.getMessageID());
-   }
-
-
-
-
-   ///////////////////////////////
-   /////////////////////////////// Channel crash tests
-   ///////////////////////////////
-
-//   public void testReliableChannelFailure() throws Throwable
-//   {
-//      if (!channel.isRecoverable())
-//      {
-//         return;
-//      }
-//
-//      SimpleDeliveryObserver observer = new SimpleDeliveryObserver();
-//      SimpleReceiver r = new SimpleReceiver("ONE", SimpleReceiver.NACKING);
-//      channel.add(r);
-//
-//      Routable m = Factory.createMessage("m0", true, "payload");
-//      Delivery d = channel.handle(observer, m, null);
-//      assertTrue(d.isDone());
-//
-//      List l = r.getMessages();
-//      assertEquals(1, l.size());
-//      Message rm  = (Message)l.get(0);
-//      assertEquals(rm.getMessageID(), m.getMessageID());
-//
-//      crashChannel();
-//
-//      recoverChannel();
-//
-//      // make sure the recovered channel still holds the message
-//
-//      l = channel.browse();
-//      assertEquals(1, l.size());
-//      MessageReference ref = (MessageReference)l.get(0);
-//      rm  = ref.getMessage();
-//      assertEquals(rm.getMessageID(), m.getMessageID());
-//
-//
-//      // TODO review this
-//      try
-//      {
-//         r.acknowledge(m, null);
-//         fail("should throw exception");
-//      }
-//      catch(IllegalStateException e)
-//      {
-//         // OK
-//      }
-//   }
-
-
-   // Distributor tests ---------------------------------------------
-
-   public void testAddOneReceiver()
-   {
-      Receiver r = new SimpleReceiver("ONE");
-
-      assertTrue(channel.add(r));
-      assertFalse(channel.add(r));
-
-      assertTrue(channel.contains(r));
-
-      Iterator i = channel.iterator();
-      assertEquals(r, i.next());
-      assertFalse(i.hasNext());
-
-      channel.clear();
-      assertFalse(channel.iterator().hasNext());
-   }
-
-   public void testRemoveInexistentReceiver()
-   {
-      assertFalse(channel.remove(new SimpleReceiver("INEXISTENT")));
-   }
-
-
-   // Package protected ---------------------------------------------
-   
-   // Protected -----------------------------------------------------
-
-   protected abstract void crashChannel() throws Exception;
-
-   protected abstract void recoverChannel() throws Exception;
-
-   // Private -------------------------------------------------------
-   
-   // Inner classes -------------------------------------------------
-
-}

Deleted: trunk/tests/src/org/jboss/test/messaging/core/base/DeliveryTestBase.java
===================================================================
--- trunk/tests/src/org/jboss/test/messaging/core/base/DeliveryTestBase.java	2006-08-30 09:26:13 UTC (rev 1236)
+++ trunk/tests/src/org/jboss/test/messaging/core/base/DeliveryTestBase.java	2006-08-30 18:36:36 UTC (rev 1237)
@@ -1,57 +0,0 @@
-/**
- * JBoss, Home of Professional Open Source
- *
- * Distributable under LGPL license.
- * See terms of license at gnu.org.
- */
-
-
-package org.jboss.test.messaging.core.base;
-
-import org.jboss.messaging.core.Delivery;
-import org.jboss.test.messaging.MessagingTestCase;
-
-
-/**
- * @author <a href="mailto:ovidiu at jboss.org">Ovidiu Feodorov</a>
- * @version <tt>$Revision$</tt>
- *
- * $Id$
- */
-public abstract class DeliveryTestBase extends MessagingTestCase
-{
-   // Constants -----------------------------------------------------
-
-   // Static --------------------------------------------------------
-   
-   // Attributes ----------------------------------------------------
-
-   protected Delivery delivery;
-
-   // Constructors --------------------------------------------------
-
-   public DeliveryTestBase(String name)
-   {
-      super(name);
-   }
-
-   // Public --------------------------------------------------------
-
-   public void setUp() throws Exception
-   {
-      super.setUp();
-   }
-
-   public void tearDown() throws Exception
-   {
-      super.tearDown();
-   }
-
-   // Package protected ---------------------------------------------
-   
-   // Protected -----------------------------------------------------
-
-   // Private -------------------------------------------------------
-   
-   // Inner classes -------------------------------------------------
-}

Added: trunk/tests/src/org/jboss/test/messaging/core/base/MessageQueueTestBase.java
===================================================================
--- trunk/tests/src/org/jboss/test/messaging/core/base/MessageQueueTestBase.java	2006-08-30 09:26:13 UTC (rev 1236)
+++ trunk/tests/src/org/jboss/test/messaging/core/base/MessageQueueTestBase.java	2006-08-30 18:36:36 UTC (rev 1237)
@@ -0,0 +1,6388 @@
+/*
+* 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.core.base;
+
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.util.List;
+
+import javax.naming.InitialContext;
+
+import org.jboss.messaging.core.Channel;
+import org.jboss.messaging.core.Delivery;
+import org.jboss.messaging.core.Message;
+import org.jboss.messaging.core.MessageReference;
+import org.jboss.messaging.core.Receiver;
+import org.jboss.messaging.core.Routable;
+import org.jboss.messaging.core.message.MessageFactory;
+import org.jboss.messaging.core.plugin.IdManager;
+import org.jboss.messaging.core.plugin.JDBCPersistenceManager;
+import org.jboss.messaging.core.plugin.SimpleMessageStore;
+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.test.messaging.MessagingTestCase;
+import org.jboss.test.messaging.core.BrokenReceiver;
+import org.jboss.test.messaging.core.SimpleDeliveryObserver;
+import org.jboss.test.messaging.core.SimpleReceiver;
+import org.jboss.test.messaging.tools.jmx.ServiceContainer;
+
+/**
+ * The MessageQueueTest test strategy is to try as many combination as it makes sense of the following
+ * variables:
+ *
+ * 1. The MessageQueue can be non-recoverable  or
+ *    recoverable. A non-recoverable channel can accept reliable messages or not.
+ * 2. The MessageQueue may have zero or one receivers (the behavior for more than one receiver depends
+ *    on the particular router implementation).
+ * 3. The receiver may be ACKING or NACKING (the case when it throws unchecked exceptions is handled
+ *    at the Router level).
+ * 4. The sender can send message(s) non-transactionally or transactionally (and then can commit
+ *    or rollback the transaction).
+ * 5. The NACKING receiver can send acknowledgment(s) non-transactionally or transactionally (and
+ *    then can commit or rollback the transaction).
+ * 6. The message can be non-reliable or reliable.
+ * 7. The sender can send one or multiple messages.
+ * 8. A recoverable channel may be crashed and tested if it successfully recovers.
+ *
+ * This test base also tests the Distributor interface.
+ *
+ * @author <a href="mailto:ovidiu at jboss.org">Ovidiu Feodorov</a>
+ * @author <a href="mailto:tim.fox at jboss.com">Tim Fox</a>
+ * @version <tt>$Revision: 1019 $</tt>
+ *
+ * $Id: ChannelTestBase.java 1019 2006-07-17 17:15:04Z timfox $
+ */
+public abstract class MessageQueueTestBase extends MessagingTestCase
+{
+   // Constants -----------------------------------------------------
+
+   public static final int NUMBER_OF_MESSAGES = 10;
+
+   // Static --------------------------------------------------------
+   
+   // Attributes ----------------------------------------------------
+
+   protected PersistenceManager pm;
+   
+   protected TransactionRepository tr;
+   
+   protected MessageStore ms;
+   
+   protected ServiceContainer sc;
+
+   protected Channel messageQueue;
+
+
+   // Constructors --------------------------------------------------
+
+   public MessageQueueTestBase(String name)
+   {
+      super(name);
+   }
+
+   // Public --------------------------------------------------------
+
+   public void setUp() throws Exception
+   {
+      super.setUp();
+      
+      sc = new ServiceContainer("all,-remoting,-security");
+      sc.start();
+
+      InitialContext ic = new InitialContext();
+      tr = new TransactionRepository();
+      ic.close();
+
+      pm =
+         new JDBCPersistenceManager(sc.getDataSource(), sc.getTransactionManager());
+      
+      ((JDBCPersistenceManager)pm).start();
+      
+      IdManager idManager = new IdManager("TRANSACTION_ID", 10, pm);
+      
+      tr.injectAttributes(pm, idManager);
+      
+      ms = new SimpleMessageStore();
+
+   }
+
+   public void tearDown() throws Exception
+   {
+      sc.stop();
+      sc = null;
+      
+      ms = null;
+      tr = null;
+      super.tearDown();
+   }
+
+   public static void assertEqualSets(Routable[] a, List routables)
+   {
+      assertEquals(a.length, routables.size());
+      List l = new ArrayList(routables);
+
+      for(int i = 0; i < a.length; i++)
+      {
+         for(Iterator j = l.iterator(); j.hasNext(); )
+         {
+            Object o = j.next();
+            Message m = null;
+            if (o instanceof MessageReference)
+            {
+               MessageReference ref = (MessageReference)o;
+               m = ref.getMessage();
+            }
+            else
+            {
+               m = (Message)o;
+            }
+
+            if (a[i].getMessageID() == m.getMessageID() &&
+                (a[i] instanceof Message ? ((Message)a[i]).getPayload().equals(m.getPayload()) : true))
+            {
+               j.remove();
+               break;
+            }
+         }
+      }
+
+      if (!l.isEmpty())
+      {
+         fail("Messages " + l + " do not match!");
+      }
+   }
+
+   public static void assertEqualSets(Delivery[] a, List deliveries)
+   {
+      assertEquals(a.length, deliveries.size());
+      List l = new ArrayList(deliveries);
+
+      for(int i = 0; i < a.length; i++)
+      {
+         for(Iterator j = l.iterator(); j.hasNext(); )
+         {
+            Delivery d = (Delivery)j.next();
+            MessageReference ref = d.getReference();
+
+            if (a[i].getReference().getMessageID() == ref.getMessageID())
+            {
+               j.remove();
+               break;
+            }
+         }
+      }
+
+      if (!l.isEmpty())
+      {
+         fail("Deliveries " + l + " do not match!");
+      }
+   }
+
+
+   // Channel tests -------------------------------------------------
+   
+   public void testUnreliableSynchronousDeliveryTwoReceivers() throws Exception
+   {
+      if (messageQueue.isRecoverable())
+      {
+         // we test only non-recoverable channels now
+         return;
+      }
+
+      SimpleDeliveryObserver observer = new SimpleDeliveryObserver();
+      SimpleReceiver r1 = new SimpleReceiver("ONE", SimpleReceiver.ACKING);
+      SimpleReceiver r2 = new SimpleReceiver("TWO", SimpleReceiver.ACKING);
+      messageQueue.add(r1);
+      messageQueue.add(r2);
+
+      Delivery d = messageQueue.handle(observer, MessageFactory.createCoreMessage(0, false, "payload"), null);
+
+      assertTrue(d.isDone());
+      List l1 = r1.getMessages();
+      List l2 = r2.getMessages();
+      if (l2.isEmpty())
+      {
+         assertEquals(1, l1.size());
+         Message m = (Message)l1.get(0);
+         assertEquals("payload", m.getPayload());
+      }
+      else
+      {
+         assertTrue(l1.isEmpty());
+         assertEquals(1, l2.size());
+         Message m = (Message)l2.get(0);
+         assertEquals("payload", m.getPayload());
+      }
+   }
+
+
+   public void testReliableSynchronousDeliveryTwoReceivers() throws Exception
+   {
+      if (!messageQueue.isRecoverable())
+      {
+         // we test only recoverable channels now
+         return;
+      }
+
+      SimpleDeliveryObserver observer = new SimpleDeliveryObserver();
+      SimpleReceiver r1 = new SimpleReceiver("ONE", SimpleReceiver.ACKING);
+      SimpleReceiver r2 = new SimpleReceiver("TWO", SimpleReceiver.ACKING);
+      assertTrue(messageQueue.add(r1));
+      assertTrue(messageQueue.add(r2));
+
+      Delivery d = messageQueue.handle(observer, MessageFactory.createCoreMessage(0, true, "payload"), null);
+
+      assertTrue(d.isDone());
+      List l1 = r1.getMessages();
+      List l2 = r2.getMessages();
+      if (l2.isEmpty())
+      {
+         assertEquals(1, l1.size());
+         Message m = (Message)l1.get(0);
+         assertEquals("payload", m.getPayload());
+      }
+      else
+      {
+         assertTrue(l1.isEmpty());
+         assertEquals(1, l2.size());
+         Message m = (Message)l2.get(0);
+         assertEquals("payload", m.getPayload());
+      }
+   }
+   
+   /*
+    * If a channel has a set a receiver and remove is called with a different receiver
+    * need to ensure the receiver is not removed (since it doesn't match)
+    */
+   public void testRemoveDifferentReceiver() throws Exception
+   {
+      Receiver receiver1 = new SimpleReceiver();
+      
+      Receiver receiver2 = new SimpleReceiver();
+      
+      assertFalse(messageQueue.iterator().hasNext());
+      
+      messageQueue.add(receiver1);
+      
+      assertTrue(messageQueue.contains(receiver1));
+      
+      messageQueue.remove(receiver1);
+      
+      assertFalse(messageQueue.iterator().hasNext());
+      
+      assertFalse(messageQueue.contains(receiver1));
+      
+      messageQueue.add(receiver1);
+      
+      assertTrue(messageQueue.contains(receiver1));
+      
+      messageQueue.remove(receiver2);
+      
+      assertTrue(messageQueue.contains(receiver1));
+                 
+   }
+
+   public void testClosedChannel() throws Exception
+   {
+      messageQueue.close();
+      try
+      {
+         messageQueue.handle(null, MessageFactory.createCoreMessage(0), null);
+         fail("should throw exception");
+      }
+      catch(IllegalStateException e)
+      {
+         //OK
+      }
+   }
+
+   public void testHandleNullRoutable() throws Exception
+   {
+      SimpleDeliveryObserver observer = new SimpleDeliveryObserver();
+      assertNull(messageQueue.handle(observer, null, null));
+   }
+
+   //////////////////////////////////
+   ////////////////////////////////// Test matrix
+   //////////////////////////////////
+
+   //
+   // Non-recoverable channel
+   //
+
+   ////
+   //// Zero receivers
+   ////
+
+   //////
+   ////// Non-transacted send
+   //////
+
+   ////////
+   //////// Non-reliable message
+   ////////
+
+   //////////
+   ////////// One message
+   //////////
+
+   public void testNonRecoverableChannel_1() throws Exception
+   {
+      if (messageQueue.isRecoverable())
+      {
+         // we test only non-recoverable channels now
+         return;
+      }
+
+      // the channel has no receivers
+      assertFalse(messageQueue.iterator().hasNext());
+
+      Message m = MessageFactory.createCoreMessage(0, false, "payload");
+      SimpleDeliveryObserver observer = new SimpleDeliveryObserver();
+
+      // non-transacted send, non-reliable message, one message
+      Delivery delivery = messageQueue.handle(observer, m, null);
+
+      assertTrue(delivery.isDone());
+
+      List stored = messageQueue.browse();
+      assertEquals(1, stored.size());
+
+      Message sm = (Message)stored.iterator().next();
+      assertFalse(sm.isReliable());
+      assertEquals(0, sm.getMessageID());
+
+      SimpleReceiver receiver = new SimpleReceiver("ACKING", SimpleReceiver.ACKING);
+      messageQueue.add(receiver);
+      messageQueue.deliver(true);
+      assertEquals(1, receiver.getMessages().size());
+      assertEquals(0, ((Message)receiver.getMessages().get(0)).getMessageID());
+
+      messageQueue.deliver(true);
+      assertEquals(1, receiver.getMessages().size());
+
+
+   }
+
+   //////////
+   ////////// Multiple message
+   //////////
+
+   public void testNonRecoverableChannel_2() throws Exception
+   {
+      if (messageQueue.isRecoverable())
+      {
+         // we test only non-recoverable channels now
+         return;
+      }
+
+      // the channel has no receivers
+      assertFalse(messageQueue.iterator().hasNext());
+
+      SimpleDeliveryObserver observer = new SimpleDeliveryObserver();
+
+      Message[] messages = new Message[NUMBER_OF_MESSAGES];
+      for(int i = 0; i < NUMBER_OF_MESSAGES; i++)
+      {
+         messages[i] = MessageFactory.createCoreMessage(i, false, "payload" + i);
+
+         // non-transacted send, non-reliable message, multiple messages
+         Delivery delivery = messageQueue.handle(observer, messages[i], null);
+
+         assertTrue(delivery.isDone());
+      }
+
+      List stored = messageQueue.browse();
+      assertEqualSets(messages, stored);
+
+      SimpleReceiver receiver = new SimpleReceiver("ACKING", SimpleReceiver.ACKING);
+      messageQueue.add(receiver);
+      messageQueue.deliver(true);
+      assertEquals(10, receiver.getMessages().size());
+      for(int i = 0; i < NUMBER_OF_MESSAGES; i++)
+      {
+         assertEquals(i, ((Message)receiver.getMessages().get(i)).getMessageID());         
+      }
+      receiver.clear();
+
+      messageQueue.deliver(true);
+      assertEquals(0, receiver.getMessages().size());
+   }
+
+   ////////
+   //////// Reliable message
+   ////////
+
+   //////////
+   ////////// One message
+   //////////
+
+   ///////////
+   /////////// Channel does NOT accept reliable messages
+   ///////////
+
+   public void testNonRecoverableChannel_3_1() throws Exception
+   {
+      if (messageQueue.isRecoverable())
+      {
+         // we test only non-recoverable channels now
+         return;
+      }
+
+      if (messageQueue.acceptReliableMessages())
+      {
+         // we test channels that don't accept reliable messages
+         return;
+      }
+
+      // the channel has no receivers
+      assertFalse(messageQueue.iterator().hasNext());
+
+      Message m = MessageFactory.createCoreMessage(0, true, "payload");
+      SimpleDeliveryObserver observer = new SimpleDeliveryObserver();
+
+      // non-transacted send, reliable message, one message
+      Delivery delivery = messageQueue.handle(observer, m, null);
+
+      // the channel must not accept the message
+      assertNull(delivery);
+
+      assertTrue(messageQueue.browse().isEmpty());
+
+      messageQueue.deliver(true);
+      
+      Receiver r = new SimpleReceiver("ACKING", SimpleReceiver.ACKING);
+      
+      messageQueue.add(r);
+      
+      messageQueue.deliver(true);
+   }
+
+   ///////////
+   /////////// Channel accepts reliable messages
+   ///////////
+
+   public void testNonRecoverableChannel_3_2() throws Exception
+   {
+      if (messageQueue.isRecoverable())
+      {
+         // we test only non-recoverable channels now
+         return;
+      }
+
+      if (!messageQueue.acceptReliableMessages())
+      {
+         // we test channels that accept reliable messages
+         return;
+      }
+
+      // the channel has no receivers
+      assertFalse(messageQueue.iterator().hasNext());
+
+      Message m = MessageFactory.createCoreMessage(0, true, "payload");
+      SimpleDeliveryObserver observer = new SimpleDeliveryObserver();
+
+      // non-transacted send, reliable message, one message
+      Delivery delivery = messageQueue.handle(observer, m, null);
+
+      assertTrue(delivery.isDone());
+
+      List stored = messageQueue.browse();
+      assertEquals(1, stored.size());
+
+      Message sm = (Message)stored.iterator().next();
+      assertTrue(sm.isReliable());
+      assertEquals(0, sm.getMessageID());
+
+      messageQueue.deliver(true);
+
+      SimpleReceiver receiver = new SimpleReceiver("ACKING", SimpleReceiver.ACKING);
+      messageQueue.add(receiver);
+      messageQueue.deliver(true);
+      assertEquals(1, receiver.getMessages().size());
+      assertEquals(0, ((Message)receiver.getMessages().get(0)).getMessageID());
+
+      messageQueue.deliver(true);
+      assertEquals(1, receiver.getMessages().size());
+   }
+
+   //////////
+   ////////// Multiple message
+   //////////
+
+   ///////////
+   /////////// Channel does NOT accept reliable messages
+   ///////////
+
+   public void testNonRecoverableChannel_4_1() throws Exception
+   {
+      if (messageQueue.isRecoverable())
+      {
+         // we test only non-recoverable channels now
+         return;
+      }
+
+      if (messageQueue.acceptReliableMessages())
+      {
+         // we test channels that don't accept reliable messages
+         return;
+      }
+
+      // the channel has no receivers
+      assertFalse(messageQueue.iterator().hasNext());
+
+      SimpleDeliveryObserver observer = new SimpleDeliveryObserver();
+
+      Message[] messages = new Message[NUMBER_OF_MESSAGES];
+      for(int i = 0; i < NUMBER_OF_MESSAGES; i++)
+      {
+         messages[i] = MessageFactory.createCoreMessage(i, true, "payload" + i);
+
+         // non-transacted send, reliable message, multiple messages
+         Delivery delivery = messageQueue.handle(observer, messages[i], null);
+
+         // the channel must not accept the message
+         assertNull(delivery);
+
+         messageQueue.deliver(true);
+         
+         Receiver r = new SimpleReceiver("ACKING", SimpleReceiver.ACKING);
+         
+         messageQueue.add(r);
+         
+         messageQueue.deliver(true);
+      }
+
+      assertTrue(messageQueue.browse().isEmpty());
+   }
+
+   ///////////
+   /////////// Channel accepts reliable messages
+   ///////////
+
+   public void testNonRecoverableChannel_4_2() throws Exception
+   {
+      if (messageQueue.isRecoverable())
+      {
+         // we test only non-recoverable channels now
+         return;
+      }
+
+      if (!messageQueue.acceptReliableMessages())
+      {
+         // we test channels that accept reliable messages
+         return;
+      }
+
+      // the channel has no receivers
+      assertFalse(messageQueue.iterator().hasNext());
+
+      SimpleDeliveryObserver observer = new SimpleDeliveryObserver();
+
+      Message[] messages = new Message[NUMBER_OF_MESSAGES];
+      for(int i = 0; i < NUMBER_OF_MESSAGES; i++)
+      {
+         messages[i] = MessageFactory.createCoreMessage(i, true, "payload" + i);
+
+         // non-transacted send, reliable message, multiple messages
+         Delivery delivery = messageQueue.handle(observer, messages[i], null);
+
+         assertTrue(delivery.isDone());
+      }
+
+      assertEqualSets(messages, messageQueue.browse());
+
+      SimpleReceiver receiver = new SimpleReceiver("ACKING", SimpleReceiver.ACKING);
+      messageQueue.add(receiver);
+      messageQueue.deliver(true);
+      assertEquals(10, receiver.getMessages().size());
+      for(int i = 0; i < NUMBER_OF_MESSAGES; i++)
+      {
+         assertEquals(i, ((Message)receiver.getMessages().get(i)).getMessageID());         
+      }
+      receiver.clear();
+
+      messageQueue.deliver(true);
+      assertEquals(0, receiver.getMessages().size());
+   }
+
+
+
+   //////
+   ////// Transacted send and commit
+   //////
+
+   ////////
+   //////// Non-reliable message
+   ////////
+
+   //////////
+   ////////// One message
+   //////////
+
+   public void testNonRecoverableChannel_5() throws Exception
+   {
+      if (messageQueue.isRecoverable())
+      {
+         // we test only non-recoverable channels now
+         return;
+      }
+
+      // the channel has no receivers
+      assertFalse(messageQueue.iterator().hasNext());
+
+      Message m = MessageFactory.createCoreMessage(0, false, "payload");
+      SimpleDeliveryObserver observer = new SimpleDeliveryObserver();
+
+      Transaction tx = tr.createTransaction();
+
+      // transacted send, non-reliable message, one message
+      // for a transactional send, handle() return value is unspecified
+      messageQueue.handle(observer, m, tx);
+
+      // no messages in the channel yet
+      assertEquals(0, messageQueue.browse().size());
+
+      tx.commit();
+
+      List stored = messageQueue.browse();
+      assertEquals(1, stored.size());
+
+      Message sm = (Message)stored.iterator().next();
+      assertFalse(sm.isReliable());
+      assertEquals(0, sm.getMessageID());
+   }
+
+
+
+   //////////
+   ////////// Multiple message
+   //////////
+
+   public void testNonRecoverableChannel_6() throws Exception
+   {
+      if (messageQueue.isRecoverable())
+      {
+         // we test only non-recoverable channels now
+         return;
+      }
+
+      // the channel has no receivers
+      assertFalse(messageQueue.iterator().hasNext());
+
+      SimpleDeliveryObserver observer = new SimpleDeliveryObserver();
+
+      Transaction tx = tr.createTransaction();
+
+      Message[] messages = new Message[NUMBER_OF_MESSAGES];
+      for(int i = 0; i < NUMBER_OF_MESSAGES; i++)
+      {
+         messages[i] = MessageFactory.createCoreMessage(i, false, "payload" + i);
+
+         // transacted send, non-reliable message, multiple messages
+         // for a transactional send, handle() return value is unspecified
+         messageQueue.handle(observer, messages[i], tx);
+      }
+
+      // no messages in the channel yet
+      assertEquals(0, messageQueue.browse().size());
+
+      tx.commit();
+
+      List stored = messageQueue.browse();
+      assertEqualSets(messages, stored);
+   }
+
+   ////////
+   //////// Reliable message
+   ////////
+
+   //////////
+   ////////// One message
+   //////////
+
+   ///////////
+   /////////// Channel does NOT accept reliable messages
+   ///////////
+
+   public void testNonRecoverableChannel_7_1() throws Exception
+   {
+      if (messageQueue.isRecoverable())
+      {
+         // we test only non-recoverable channels now
+         return;
+      }
+
+      if (messageQueue.acceptReliableMessages())
+      {
+         // we test channels that don't accept reliable messages
+         return;
+      }
+
+      // the channel has no receivers
+      assertFalse(messageQueue.iterator().hasNext());
+
+      Message m = MessageFactory.createCoreMessage(0, true, "payload");
+      SimpleDeliveryObserver observer = new SimpleDeliveryObserver();
+
+      Transaction tx = tr.createTransaction();
+
+      // transacted send, reliable message, one message
+      // for a transactional send, handle() return value is unspecified
+      messageQueue.handle(observer, m, tx);
+
+      // no messages in the channel yet
+      assertEquals(0, messageQueue.browse().size());
+
+      try
+      {
+         tx.commit();
+         fail("this should throw exception");
+      }
+      catch(Exception e)
+      {
+         // OK
+      }
+
+      // still no messages in the channel
+      assertEquals(0, messageQueue.browse().size());
+   }
+
+   ///////////
+   /////////// Channel accepts reliable messages
+   ///////////
+
+   public void testNonRecoverableChannel_7_2() throws Exception
+   {
+      if (messageQueue.isRecoverable())
+      {
+         // we test only non-recoverable channels now
+         return;
+      }
+
+      if (!messageQueue.acceptReliableMessages())
+      {
+         // we test channels that don't accept reliable messages
+         return;
+      }
+
+      // the channel has no receivers
+      assertFalse(messageQueue.iterator().hasNext());
+
+      Message m = MessageFactory.createCoreMessage(0, true, "payload");
+      SimpleDeliveryObserver observer = new SimpleDeliveryObserver();
+
+      Transaction tx = tr.createTransaction();
+
+      // transacted send, reliable message, one message
+      // for a transactional send, handle() return value is unspecified
+      messageQueue.handle(observer, m, tx);
+
+      // no messages in the channel yet
+      assertEquals(0, messageQueue.browse().size());
+
+      tx.commit();
+
+      List stored = messageQueue.browse();
+      assertEquals(1, stored.size());
+
+      Message sm = (Message)stored.iterator().next();
+      assertTrue(sm.isReliable());
+      assertEquals(0, sm.getMessageID());
+   }
+
+   //////////
+   ////////// Multiple message
+   //////////
+
+   ///////////
+   /////////// Channel does NOT accept reliable messages
+   ///////////
+
+   public void testNonRecoverableChannel_8_1() throws Exception
+   {
+      if (messageQueue.isRecoverable())
+      {
+         // we test only non-recoverable channels now
+         return;
+      }
+
+      if (messageQueue.acceptReliableMessages())
+      {
+         // we test channels that don't accept reliable messages
+         return;
+      }
+
+      // the channel has no receivers
+      assertFalse(messageQueue.iterator().hasNext());
+
+      SimpleDeliveryObserver observer = new SimpleDeliveryObserver();
+
+      Transaction tx = tr.createTransaction();
+
+      Message[] messages = new Message[NUMBER_OF_MESSAGES];
+      for(int i = 0; i < NUMBER_OF_MESSAGES; i++)
+      {
+         messages[i] = MessageFactory.createCoreMessage(i, true, "payload" + i);
+
+         // transacted send, reliable message, multiple messages
+         // for a transactional send, handle() return value is unspecified
+         messageQueue.handle(observer, messages[i], tx);
+      }
+
+      // no messages in the channel yet
+      assertEquals(0, messageQueue.browse().size());
+
+      try
+      {
+         tx.commit();
+         fail("this should throw exception");
+      }
+      catch(Exception e)
+      {
+         // OK
+      }
+
+      // still no messages in the channel
+      assertEquals(0, messageQueue.browse().size());
+
+   }
+
+   /**
+    * This is a variation where I send a mixture of reliable and non-reliable messages,
+    */
+   public void testNonRecoverableChannel_8_1_mixed() throws Exception
+   {
+      if (messageQueue.isRecoverable())
+      {
+         // we test only non-recoverable channels now
+         return;
+      }
+
+      if (messageQueue.acceptReliableMessages())
+      {
+         // we test channels that don't accept reliable messages
+         return;
+      }
+
+      // the channel has no receivers
+      assertFalse(messageQueue.iterator().hasNext());
+
+      SimpleDeliveryObserver observer = new SimpleDeliveryObserver();
+
+      Transaction tx = tr.createTransaction();
+
+      Message[] messages = new Message[NUMBER_OF_MESSAGES];
+      for(int i = 0; i < NUMBER_OF_MESSAGES; i++)
+      {
+         // send a mixture of reliable and non-reliable messages
+         messages[i] = MessageFactory.createCoreMessage(i, (i % 2 == 1), "payload" + i);
+
+         // transacted send, reliable/non-reliable messages, multiple messages
+         // for a transactional send, handle() return value is unspecified
+         messageQueue.handle(observer, messages[i], tx);
+      }
+
+      // no messages in the channel yet
+      assertEquals(0, messageQueue.browse().size());
+
+      try
+      {
+         tx.commit();
+         fail("this should throw exception");
+      }
+      catch(Exception e)
+      {
+         // OK
+      }
+
+      // still no messages in the channel
+      assertEquals(0, messageQueue.browse().size());
+
+   }
+   
+   public void testNonRecoverableChannel_8_1_mixed_1() throws Exception
+   {
+      if (messageQueue.isRecoverable())
+      {
+         // we test only non-recoverable channels now
+         return;
+      }
+
+      if (messageQueue.acceptReliableMessages())
+      {
+         // we test channels that don't accept reliable messages
+         return;
+      }
+
+      // the channel has no receivers
+      assertFalse(messageQueue.iterator().hasNext());
+
+      SimpleDeliveryObserver observer = new SimpleDeliveryObserver();
+
+      Transaction tx = tr.createTransaction();
+
+      Message[] messages = new Message[NUMBER_OF_MESSAGES * 2];
+      for(int i = 0; i < NUMBER_OF_MESSAGES; i++)
+      {
+         // send a mixture of reliable and non-reliable messages
+         messages[i] = MessageFactory.createCoreMessage(i, false, "payload" + i);
+
+         // transacted send, reliable/non-reliable messages, multiple messages
+         // for a transactional send, handle() return value is unspecified
+         messageQueue.handle(observer, messages[i], tx);
+      }
+      for(int i = 0; i < NUMBER_OF_MESSAGES; i++)
+      {
+         // send a mixture of reliable and non-reliable messages
+         messages[i + NUMBER_OF_MESSAGES] = MessageFactory.createCoreMessage(i + NUMBER_OF_MESSAGES , true, "payload" + i);
+
+         // transacted send, reliable/non-reliable messages, multiple messages
+         // for a transactional send, handle() return value is unspecified
+         messageQueue.handle(observer, messages[i + NUMBER_OF_MESSAGES], tx);
+      }
+
+      // no messages in the channel yet
+      assertEquals(0, messageQueue.browse().size());
+
+      try
+      {
+         tx.commit();
+         fail("this should throw exception");
+      }
+      catch(Exception e)
+      {
+         // OK
+      }
+
+      // still no messages in the channel
+      assertEquals(0, messageQueue.browse().size());
+
+   }
+   
+
+   public void testNonRecoverableChannel_8_1_mixed_2() throws Exception
+   {
+      if (messageQueue.isRecoverable())
+      {
+         // we test only non-recoverable channels now
+         return;
+      }
+
+      if (messageQueue.acceptReliableMessages())
+      {
+         // we test channels that don't accept reliable messages
+         return;
+      }
+
+      // the channel has no receivers
+      assertFalse(messageQueue.iterator().hasNext());
+
+      SimpleDeliveryObserver observer = new SimpleDeliveryObserver();
+
+      Transaction tx = tr.createTransaction();
+
+      Message[] messages = new Message[NUMBER_OF_MESSAGES * 2];
+      for(int i = 0; i < NUMBER_OF_MESSAGES; i++)
+      {
+         // send a mixture of reliable and non-reliable messages
+         messages[i] = MessageFactory.createCoreMessage(i, true, "payload" + i);
+
+         // transacted send, reliable/non-reliable messages, multiple messages
+         // for a transactional send, handle() return value is unspecified
+         messageQueue.handle(observer, messages[i], tx);
+      }
+      for(int i = 0; i < NUMBER_OF_MESSAGES; i++)
+      {
+         // send a mixture of reliable and non-reliable messages
+         messages[i + NUMBER_OF_MESSAGES] = MessageFactory.createCoreMessage(i + NUMBER_OF_MESSAGES , true, "payload" + i);
+
+         // transacted send, reliable/non-reliable messages, multiple messages
+         // for a transactional send, handle() return value is unspecified
+         messageQueue.handle(observer, messages[i + NUMBER_OF_MESSAGES], tx);
+      }
+
+      // no messages in the channel yet
+      assertEquals(0, messageQueue.browse().size());
+
+      try
+      {
+         tx.commit();
+         fail("this should throw exception");
+      }
+      catch(Exception e)
+      {
+         // OK
+      }
+
+      // still no messages in the channel
+      assertEquals(0, messageQueue.browse().size());
+
+   }
+
+   ///////////
+   /////////// Channel accepts reliable messages
+   ///////////
+
+   public void testNonRecoverableChannel_8_2() throws Exception
+   {
+      if (messageQueue.isRecoverable())
+      {
+         // we test only non-recoverable channels now
+         return;
+      }
+
+      if (!messageQueue.acceptReliableMessages())
+      {
+         // we test channels that accept reliable messages
+         return;
+      }
+
+      // the channel has no receivers
+      assertFalse(messageQueue.iterator().hasNext());
+
+      SimpleDeliveryObserver observer = new SimpleDeliveryObserver();
+
+      Transaction tx = tr.createTransaction();
+
+      Message[] messages = new Message[NUMBER_OF_MESSAGES];
+      for(int i = 0; i < NUMBER_OF_MESSAGES; i++)
+      {
+         messages[i] = MessageFactory.createCoreMessage(i, true, "payload" + i);
+
+         // transacted send, reliable message, multiple messages
+         // for a transactional send, handle() return value is unspecified
+         messageQueue.handle(observer, messages[i], tx);
+      }
+
+      // no messages in the channel yet
+      assertEquals(0, messageQueue.browse().size());
+
+      tx.commit();
+
+      assertEqualSets(messages, messageQueue.browse());
+   }
+
+   /**
+    * This is a variation where I send a mixture of reliable and non-reliable messages,
+    */
+   public void testNonRecoverableChannel_8_2_mixed() throws Exception
+   {
+      if (messageQueue.isRecoverable())
+      {
+         // we test only non-recoverable channels now
+         return;
+      }
+
+      if (!messageQueue.acceptReliableMessages())
+      {
+         // we test channels that accept reliable messages
+         return;
+      }
+
+      // the channel has no receivers
+      assertFalse(messageQueue.iterator().hasNext());
+
+      SimpleDeliveryObserver observer = new SimpleDeliveryObserver();
+
+      Transaction tx = tr.createTransaction();
+
+      Message[] messages = new Message[NUMBER_OF_MESSAGES];
+      for(int i = 0; i < NUMBER_OF_MESSAGES; i++)
+      {
+         // send a mixture of reliable and non-reliable messages
+         messages[i] = MessageFactory.createCoreMessage(i, (i % 2 == 1), "payload" + i);
+
+         // transacted send, reliable/non-reliable messages, multiple messages
+         // for a transactional send, handle() return value is unspecified
+         messageQueue.handle(observer, messages[i], tx);
+      }
+
+      // no messages in the channel yet
+      assertEquals(0, messageQueue.browse().size());
+
+      tx.commit();
+
+      assertEqualSets(messages, messageQueue.browse());
+   }
+
+
+   //////
+   ////// Transacted send and rollback
+   //////
+
+   ////////
+   //////// Non-reliable message
+   ////////
+
+   //////////
+   ////////// One message
+   //////////
+
+   public void testNonRecoverableChannel_9() throws Exception
+   {
+      if (messageQueue.isRecoverable())
+      {
+         // we test only non-recoverable channels now
+         return;
+      }
+
+      // the channel has no receivers
+      assertFalse(messageQueue.iterator().hasNext());
+
+      Message m = MessageFactory.createCoreMessage(0, false, "payload");
+      SimpleDeliveryObserver observer = new SimpleDeliveryObserver();
+
+      Transaction tx = tr.createTransaction();
+
+      // transacted send, non-reliable message, one message
+      // for a transactional send, handle() return value is unspecified
+      messageQueue.handle(observer, m, tx);
+
+      // no messages in the channel yet
+      assertEquals(0, messageQueue.browse().size());
+
+      tx.rollback();
+
+      // still no messages in the channel
+      assertEquals(0, messageQueue.browse().size());
+   }
+
+   //////////
+   ////////// Multiple message
+   //////////
+
+   public void testNonRecoverableChannel_10() throws Exception
+   {
+      if (messageQueue.isRecoverable())
+      {
+         // we test only non-recoverable channels now
+         return;
+      }
+
+      // the channel has no receivers
+      assertFalse(messageQueue.iterator().hasNext());
+
+      SimpleDeliveryObserver observer = new SimpleDeliveryObserver();
+
+      Transaction tx = tr.createTransaction();
+
+      Message[] messages = new Message[NUMBER_OF_MESSAGES];
+      for(int i = 0; i < NUMBER_OF_MESSAGES; i++)
+      {
+         messages[i] = MessageFactory.createCoreMessage(i, false, "payload" + i);
+
+         // transacted send, non-reliable message, multiple messages
+         // for a transactional send, handle() return value is unspecified
+         messageQueue.handle(observer, messages[i], tx);
+      }
+
+      // no messages in the channel yet
+      assertEquals(0, messageQueue.browse().size());
+
+      tx.rollback();
+
+      // still no messages in the channel
+      assertEquals(0, messageQueue.browse().size());
+   }
+
+   ////////
+   //////// Reliable message
+   ////////
+
+   //////////
+   ////////// One message
+   //////////
+
+   public void testNonRecoverableChannel_11() throws Exception
+   {
+      if (messageQueue.isRecoverable())
+      {
+         // we test only non-recoverable channels now
+         return;
+      }
+
+      // the channel has no receivers
+      assertFalse(messageQueue.iterator().hasNext());
+
+      Message m = MessageFactory.createCoreMessage(0, true, "payload");
+      SimpleDeliveryObserver observer = new SimpleDeliveryObserver();
+
+      Transaction tx = tr.createTransaction();
+
+      // transacted send, reliable message, one message
+      // for a transactional send, handle() return value is unspecified
+      messageQueue.handle(observer, m, tx);
+
+      // no messages in the channel yet
+      assertEquals(0, messageQueue.browse().size());
+
+      tx.rollback();
+
+      // still no messages in the channel
+      assertEquals(0, messageQueue.browse().size());
+   }
+
+   //////////
+   ////////// Multiple message
+   //////////
+
+   public void testNonRecoverableChannel_12() throws Exception
+   {
+      if (messageQueue.isRecoverable())
+      {
+         // we test only non-recoverable channels now
+         return;
+      }
+
+      // the channel has no receivers
+      assertFalse(messageQueue.iterator().hasNext());
+
+      SimpleDeliveryObserver observer = new SimpleDeliveryObserver();
+
+      Transaction tx = tr.createTransaction();
+
+      Message[] messages = new Message[NUMBER_OF_MESSAGES];
+      for(int i = 0; i < NUMBER_OF_MESSAGES; i++)
+      {
+         messages[i] = MessageFactory.createCoreMessage(i, true, "payload" + i);
+
+         // transacted send, reliable message, multiple messages
+         // for a transactional send, handle() return value is unspecified
+         messageQueue.handle(observer, messages[i], tx);
+      }
+
+      // no messages in the channel yet
+      assertEquals(0, messageQueue.browse().size());
+
+      tx.rollback();
+
+      // still no messages in the channel
+      assertEquals(0, messageQueue.browse().size());
+   }
+
+   /**
+    * This is a variation where I send a mixture of reliable and non-reliable messages,
+    */
+   public void testNonRecoverableChannel_12_mixed() throws Exception
+   {
+      if (messageQueue.isRecoverable())
+      {
+         // we test only non-recoverable channels now
+         return;
+      }
+
+      // the channel has no receivers
+      assertFalse(messageQueue.iterator().hasNext());
+
+      SimpleDeliveryObserver observer = new SimpleDeliveryObserver();
+
+      Transaction tx = tr.createTransaction();
+
+      Message[] messages = new Message[NUMBER_OF_MESSAGES];
+      for(int i = 0; i < NUMBER_OF_MESSAGES; i++)
+      {
+         // send a mixture of reliable and non-reliable messages
+         messages[i] = MessageFactory.createCoreMessage(i, (i % 2 == 1), "payload" + i);
+
+         // transacted send, reliable/non-reliable messages, multiple messages
+         // for a transactional send, handle() return value is unspecified
+         messageQueue.handle(observer, messages[i], tx);
+      }
+
+      // no messages in the channel yet
+      assertEquals(0, messageQueue.browse().size());
+
+      tx.rollback();
+
+      // still no messages in the channel
+      assertEquals(0, messageQueue.browse().size());
+   }
+
+   ////
+   //// One receiver
+   ////
+
+   //////
+   ////// ACKING receiver
+   //////
+
+   //////
+   ////// Non-transacted send
+   //////
+
+   ////////
+   //////// Non-reliable message
+   ////////
+
+   //////////
+   ////////// One message
+   //////////
+
+   public void testNonRecoverableChannel_13() throws Exception
+   {
+      if (messageQueue.isRecoverable())
+      {
+         // we test only non-recoverable channels now
+         return;
+      }
+
+      // add an ACKING receiver to the channel
+      SimpleReceiver r = new SimpleReceiver("AckingReceiver", SimpleReceiver.ACKING);
+      assertTrue(messageQueue.add(r));
+
+      Message m = MessageFactory.createCoreMessage(0, false, "payload");
+      SimpleDeliveryObserver observer = new SimpleDeliveryObserver();
+
+      // non-transacted send, non-reliable message, one message
+      Delivery delivery = messageQueue.handle(observer, m, null);
+
+      assertTrue(delivery.isDone());
+      assertTrue(messageQueue.browse().isEmpty());
+
+      List received = r.getMessages();
+      assertEquals(1, received.size());
+      Message sm = (Message)received.iterator().next();
+      assertFalse(sm.isReliable());
+      assertEquals(0, sm.getMessageID());
+   }
+
+   //////////
+   ////////// Multiple message
+   //////////
+
+   public void testNonRecoverableChannel_14() throws Exception
+   {
+      if (messageQueue.isRecoverable())
+      {
+         // we test only non-recoverable channels now
+         return;
+      }
+
+      // add an ACKING receiver to the channel
+      SimpleReceiver r = new SimpleReceiver("AckingReceiver", SimpleReceiver.ACKING);
+      assertTrue(messageQueue.add(r));
+
+      SimpleDeliveryObserver observer = new SimpleDeliveryObserver();
+
+      Message[] messages = new Message[NUMBER_OF_MESSAGES];
+      for(int i = 0; i < NUMBER_OF_MESSAGES; i++)
+      {
+         messages[i] = MessageFactory.createCoreMessage(i, false, "payload" + i);
+
+         // non-transacted send, non-reliable message, multiple messages
+         Delivery delivery = messageQueue.handle(observer, messages[i], null);
+
+         assertTrue(delivery.isDone());
+      }
+
+      assertTrue(messageQueue.browse().isEmpty());
+
+      List received = r.getMessages();
+      assertEqualSets(messages, received);
+   }
+
+   ////////
+   //////// Reliable message
+   ////////
+
+   //////////
+   ////////// One message
+   //////////
+
+   ///////////
+   /////////// Channel does NOT accept reliable messages
+   ///////////
+
+   public void testNonRecoverableChannel_15_1() throws Exception
+   {
+      if (messageQueue.isRecoverable())
+      {
+         // we test only non-recoverable channels now
+         return;
+      }
+
+      if (messageQueue.acceptReliableMessages())
+      {
+         // we test channels that don't accept reliable messages
+         return;
+      }
+
+      // add an ACKING receiver to the channel
+      SimpleReceiver r = new SimpleReceiver("AckingReceiver", SimpleReceiver.ACKING);
+      assertTrue(messageQueue.add(r));
+
+      Message m = MessageFactory.createCoreMessage(0, true, "payload");
+      SimpleDeliveryObserver observer = new SimpleDeliveryObserver();
+
+      // non-transacted send, reliable message, one message
+      Delivery delivery = messageQueue.handle(observer, m, null);
+
+      assertNull(delivery);
+
+      assertTrue(messageQueue.browse().isEmpty());
+      assertTrue(r.getMessages().isEmpty());
+   }
+
+   ///////////
+   /////////// Channel accepts reliable messages
+   ///////////
+
+   public void testNonRecoverableChannel_15_2() throws Exception
+   {
+      if (messageQueue.isRecoverable())
+      {
+         // we test only non-recoverable channels now
+         return;
+      }
+
+      if (!messageQueue.acceptReliableMessages())
+      {
+         // we test channels that accept reliable messages
+         return;
+      }
+
+      // add an ACKING receiver to the channel
+      SimpleReceiver r = new SimpleReceiver("AckingReceiver", SimpleReceiver.ACKING);
+      assertTrue(messageQueue.add(r));
+
+      Message m = MessageFactory.createCoreMessage(0, true, "payload");
+      SimpleDeliveryObserver observer = new SimpleDeliveryObserver();
+
+      // non-transacted send, reliable message, one message
+      Delivery delivery = messageQueue.handle(observer, m, null);
+
+      assertTrue(delivery.isDone());
+
+      assertTrue(messageQueue.browse().isEmpty());
+
+      List received = r.getMessages();
+      assertEquals(1, received.size());
+      Message sm = (Message)received.iterator().next();
+      assertTrue(sm.isReliable());
+      assertEquals(0, sm.getMessageID());
+   }
+
+   //////////
+   ////////// Multiple message
+   //////////
+
+   ///////////
+   /////////// Channel does NOT accept reliable messages
+   ///////////
+
+   public void testNonRecoverableChannel_16_1() throws Exception
+   {
+      if (messageQueue.isRecoverable())
+      {
+         // we test only non-recoverable channels now
+         return;
+      }
+
+      if (messageQueue.acceptReliableMessages())
+      {
+         // we test channels that don't accept reliable messages
+         return;
+      }
+
+      // add an ACKING receiver to the channel
+      SimpleReceiver r = new SimpleReceiver("AckingReceiver", SimpleReceiver.ACKING);
+      assertTrue(messageQueue.add(r));
+
+      SimpleDeliveryObserver observer = new SimpleDeliveryObserver();
+
+      Message[] messages = new Message[NUMBER_OF_MESSAGES];
+      for(int i = 0; i < NUMBER_OF_MESSAGES; i++)
+      {
+         messages[i] = MessageFactory.createCoreMessage(i, true, "payload" + i);
+
+         // non-transacted send, reliable message, multiple messages
+         Delivery delivery = messageQueue.handle(observer, messages[i], null);
+
+         assertNull(delivery);
+      }
+
+      assertTrue(messageQueue.browse().isEmpty());
+      assertTrue(r.getMessages().isEmpty());
+   }
+
+   ///////////
+   /////////// Channel accepts reliable messages
+   ///////////
+
+   public void testNonRecoverableChannel_16_2() throws Exception
+   {
+      if (messageQueue.isRecoverable())
+      {
+         // we test only non-recoverable channels now
+         return;
+      }
+
+      if (!messageQueue.acceptReliableMessages())
+      {
+         // we test channels that accept reliable messages
+         return;
+      }
+
+      // add an ACKING receiver to the channel
+      SimpleReceiver r = new SimpleReceiver("AckingReceiver", SimpleReceiver.ACKING);
+      assertTrue(messageQueue.add(r));
+
+      SimpleDeliveryObserver observer = new SimpleDeliveryObserver();
+
+      Message[] messages = new Message[NUMBER_OF_MESSAGES];
+      for(int i = 0; i < NUMBER_OF_MESSAGES; i++)
+      {
+         messages[i] = MessageFactory.createCoreMessage(i, true, "payload" + i);
+
+         // non-transacted send, reliable message, multiple messages
+         Delivery delivery = messageQueue.handle(observer, messages[i], null);
+
+         assertTrue(delivery.isDone());
+      }
+
+      assertTrue(messageQueue.browse().isEmpty());
+      assertEqualSets(messages, r.getMessages());
+   }
+
+   //////
+   ////// Transacted send and commit
+   //////
+
+   ////////
+   //////// Non-reliable message
+   ////////
+
+   //////////
+   ////////// One message
+   //////////
+
+   public void testNonRecoverableChannel_17() throws Exception
+   {
+      if (messageQueue.isRecoverable())
+      {
+         // we test only non-recoverable channels now
+         return;
+      }
+
+      // add an ACKING receiver to the channel
+      SimpleReceiver r = new SimpleReceiver("AckingReceiver", SimpleReceiver.ACKING);
+      assertTrue(messageQueue.add(r));
+
+      Message m = MessageFactory.createCoreMessage(0, false, "payload");
+      SimpleDeliveryObserver observer = new SimpleDeliveryObserver();
+
+      Transaction tx = tr.createTransaction();
+
+      // transacted send, non-reliable message, one message
+      // for a transactional send, handle() return value is unspecified
+      messageQueue.handle(observer, m, tx);
+
+      // no messages in the channel
+      assertEquals(0, messageQueue.browse().size());
+
+      // no message at the receiver
+      assertTrue(r.getMessages().isEmpty());
+
+      tx.commit();
+
+      assertTrue(messageQueue.browse().isEmpty());
+
+      List received = r.getMessages();
+      assertEquals(1, received.size());
+      Message sm = (Message)received.iterator().next();
+      assertFalse(sm.isReliable());
+      assertEquals(0, sm.getMessageID());
+   }
+
+   //////////
+   ////////// Multiple message
+   //////////
+
+   public void testNonRecoverableChannel_18() throws Exception
+   {
+      if (messageQueue.isRecoverable())
+      {
+         // we test only non-recoverable channels now
+         return;
+      }
+
+      // add an ACKING receiver to the channel
+      SimpleReceiver r = new SimpleReceiver("AckingReceiver", SimpleReceiver.ACKING);
+      assertTrue(messageQueue.add(r));
+
+      SimpleDeliveryObserver observer = new SimpleDeliveryObserver();
+
+      Transaction tx = tr.createTransaction();
+
+      Message[] messages = new Message[NUMBER_OF_MESSAGES];
+      for(int i = 0; i < NUMBER_OF_MESSAGES; i++)
+      {
+         messages[i] = MessageFactory.createCoreMessage(i, false, "payload" + i);
+
+         // transacted send, non-reliable message, multiple messages
+         // for a transactional send, handle() return value is unspecified
+         messageQueue.handle(observer, messages[i], tx);
+      }
+
+      // no messages in the channel
+      assertEquals(0, messageQueue.browse().size());
+
+      // no message at the receiver
+      assertTrue(r.getMessages().isEmpty());
+
+      tx.commit();
+
+      assertTrue(messageQueue.browse().isEmpty());
+      assertEqualSets(messages, r.getMessages());
+   }
+
+   ////////
+   //////// Reliable message
+   ////////
+
+   //////////
+   ////////// One message
+   //////////
+
+   ///////////
+   /////////// Channel does NOT accept reliable messages
+   ///////////
+
+   public void testNonRecoverableChannel_19_1() throws Exception
+   {
+      if (messageQueue.isRecoverable())
+      {
+         // we test only non-recoverable channels now
+         return;
+      }
+
+      if (messageQueue.acceptReliableMessages())
+      {
+         // we test channels that don't accept reliable messages
+         return;
+      }
+
+      // add an ACKING receiver to the channel
+      SimpleReceiver r = new SimpleReceiver("AckingReceiver", SimpleReceiver.ACKING);
+      assertTrue(messageQueue.add(r));
+
+
+      Message m = MessageFactory.createCoreMessage(0, true, "payload");
+      SimpleDeliveryObserver observer = new SimpleDeliveryObserver();
+
+      Transaction tx = tr.createTransaction();
+
+      // transacted send, reliable message, one message
+      // for a transactional send, handle() return value is unspecified
+      messageQueue.handle(observer, m, tx);
+
+      // no messages in the channel yet
+      assertEquals(0, messageQueue.browse().size());
+
+      // no message at the receiver
+      assertTrue(r.getMessages().isEmpty());
+
+      try
+      {
+         tx.commit();
+         fail("this should throw exception");
+      }
+      catch(Exception e)
+      {
+         // OK
+      }
+
+      // no messages in the channel
+      assertEquals(0, messageQueue.browse().size());
+
+      // no message at the receiver
+      assertTrue(r.getMessages().isEmpty());
+   }
+
+   ///////////
+   /////////// Channel accepts reliable messages
+   ///////////
+
+   public void testNonRecoverableChannel_19_2() throws Exception
+   {
+      if (messageQueue.isRecoverable())
+      {
+         // we test only non-recoverable channels now
+         return;
+      }
+
+      if (!messageQueue.acceptReliableMessages())
+      {
+         // we test channels that accept reliable messages
+         return;
+      }
+
+      // add an ACKING receiver to the channel
+      SimpleReceiver r = new SimpleReceiver("AckingReceiver", SimpleReceiver.ACKING);
+      assertTrue(messageQueue.add(r));
+
+
+      Message m = MessageFactory.createCoreMessage(0, true, "payload");
+      SimpleDeliveryObserver observer = new SimpleDeliveryObserver();
+
+      Transaction tx = tr.createTransaction();
+
+      // transacted send, reliable message, one message
+      // for a transactional send, handle() return value is unspecified
+      messageQueue.handle(observer, m, tx);
+
+      // no messages in the channel yet
+      assertEquals(0, messageQueue.browse().size());
+
+      // no message at the receiver
+      assertTrue(r.getMessages().isEmpty());
+
+      tx.commit();
+
+      // no messages in the channel
+      assertEquals(0, messageQueue.browse().size());
+
+      List received = r.getMessages();
+      assertEquals(1, received.size());
+      Message sm = (Message)received.iterator().next();
+      assertTrue(sm.isReliable());
+      assertEquals(0, sm.getMessageID());
+   }
+
+   //////////
+   ////////// Multiple message
+   //////////
+
+   ///////////
+   /////////// Channel does NOT accept reliable messages
+   ///////////
+
+   public void testNonRecoverableChannel_20_1() throws Exception
+   {
+      if (messageQueue.isRecoverable())
+      {
+         // we test only non-recoverable channels now
+         return;
+      }
+
+      if (messageQueue.acceptReliableMessages())
+      {
+         // we test channels that don't accept reliable messages
+         return;
+      }
+
+      // add an ACKING receiver to the channel
+      SimpleReceiver r = new SimpleReceiver("AckingReceiver", SimpleReceiver.ACKING);
+      assertTrue(messageQueue.add(r));
+
+      SimpleDeliveryObserver observer = new SimpleDeliveryObserver();
+
+      Transaction tx = tr.createTransaction();
+
+      Message[] messages = new Message[NUMBER_OF_MESSAGES];
+      for(int i = 0; i < NUMBER_OF_MESSAGES; i++)
+      {
+         messages[i] = MessageFactory.createCoreMessage(i, true, "payload" + i);
+
+         // transacted send, reliable message, multiple messages
+         // for a transactional send, handle() return value is unspecified
+         messageQueue.handle(observer, messages[i], tx);
+      }
+
+      // no messages in the channel yet
+      assertEquals(0, messageQueue.browse().size());
+
+      // no message at the receiver
+      assertTrue(r.getMessages().isEmpty());
+
+      try
+      {
+         tx.commit();
+         fail("this should throw exception");
+      }
+      catch(Exception e)
+      {
+         // OK
+      }
+
+      // no messages in the channel
+      assertEquals(0, messageQueue.browse().size());
+
+      // no message at the receiver
+      assertTrue(r.getMessages().isEmpty());
+   }
+
+   /**
+    * This is a variation where I send a mixture of reliable and non-reliable messages,
+    */
+   public void testNonRecoverableChannel_20_1_mixed() throws Exception
+   {
+      if (messageQueue.isRecoverable())
+      {
+         // we test only non-recoverable channels now
+         return;
+      }
+
+      if (messageQueue.acceptReliableMessages())
+      {
+         // we test channels that don't accept reliable messages
+         return;
+      }
+
+      // add an ACKING receiver to the channel
+      SimpleReceiver r = new SimpleReceiver("AckingReceiver", SimpleReceiver.ACKING);
+      assertTrue(messageQueue.add(r));
+
+
+      SimpleDeliveryObserver observer = new SimpleDeliveryObserver();
+
+      Transaction tx = tr.createTransaction();
+
+      Message[] messages = new Message[NUMBER_OF_MESSAGES];
+      for(int i = 0; i < NUMBER_OF_MESSAGES; i++)
+      {
+         // send a mixture of reliable and non-reliable messages
+         messages[i] = MessageFactory.createCoreMessage(i, (i % 2 == 1), "payload" + i);
+
+         // transacted send, reliable/non-reliable messages, multiple messages
+         // for a transactional send, handle() return value is unspecified
+         messageQueue.handle(observer, messages[i], tx);
+      }
+
+      // no messages in the channel
+      assertEquals(0, messageQueue.browse().size());
+
+      // no message at the receiver
+      assertTrue(r.getMessages().isEmpty());
+
+      try
+      {
+         tx.commit();
+         fail("this should throw exception");
+      }
+      catch(Exception e)
+      {
+         // OK
+      }
+
+      // no messages in the channel
+      assertEquals(0, messageQueue.browse().size());
+
+      // no message at the receiver
+      assertTrue(r.getMessages().isEmpty());
+   }
+
+   ///////////
+   /////////// Channel accepts reliable messages
+   ///////////
+
+   public void testNonRecoverableChannel_20_2() throws Exception
+   {
+      if (messageQueue.isRecoverable())
+      {
+         // we test only non-recoverable channels now
+         return;
+      }
+
+      if (!messageQueue.acceptReliableMessages())
+      {
+         // we test channels that accept reliable messages
+         return;
+      }
+
+      // add an ACKING receiver to the channel
+      SimpleReceiver r = new SimpleReceiver("AckingReceiver", SimpleReceiver.ACKING);
+      assertTrue(messageQueue.add(r));
+
+      SimpleDeliveryObserver observer = new SimpleDeliveryObserver();
+
+      Transaction tx = tr.createTransaction();
+
+      Message[] messages = new Message[NUMBER_OF_MESSAGES];
+      for(int i = 0; i < NUMBER_OF_MESSAGES; i++)
+      {
+         messages[i] = MessageFactory.createCoreMessage(i, true, "payload" + i);
+
+         // transacted send, reliable message, multiple messages
+         // for a transactional send, handle() return value is unspecified
+         messageQueue.handle(observer, messages[i], tx);
+      }
+
+      // no messages in the channel yet
+      assertEquals(0, messageQueue.browse().size());
+
+      // no message at the receiver
+      assertTrue(r.getMessages().isEmpty());
+
+      tx.commit();
+
+      // no messages in the channel
+      assertEquals(0, messageQueue.browse().size());
+
+      assertEqualSets(messages, r.getMessages());
+   }
+
+   /**
+    * This is a variation where I send a mixture of reliable and non-reliable messages,
+    */
+   public void testNonRecoverableChannel_20_2_mixed() throws Exception
+   {
+      if (messageQueue.isRecoverable())
+      {
+         // we test only non-recoverable channels now
+         return;
+      }
+
+      if (!messageQueue.acceptReliableMessages())
+      {
+         // we test channels that accept reliable messages
+         return;
+      }
+
+      // add an ACKING receiver to the channel
+      SimpleReceiver r = new SimpleReceiver("AckingReceiver", SimpleReceiver.ACKING);
+      assertTrue(messageQueue.add(r));
+
+
+      SimpleDeliveryObserver observer = new SimpleDeliveryObserver();
+
+      Transaction tx = tr.createTransaction();
+
+      Message[] messages = new Message[NUMBER_OF_MESSAGES];
+      for(int i = 0; i < NUMBER_OF_MESSAGES; i++)
+      {
+         // send a mixture of reliable and non-reliable messages
+         messages[i] = MessageFactory.createCoreMessage(i, (i % 2 == 1), "payload" + i);
+
+         // transacted send, reliable/non-reliable messages, multiple messages
+         // for a transactional send, handle() return value is unspecified
+         messageQueue.handle(observer, messages[i], tx);
+      }
+
+      // no messages in the channel
+      assertEquals(0, messageQueue.browse().size());
+
+      // no message at the receiver
+      assertTrue(r.getMessages().isEmpty());
+
+      tx.commit();
+
+      // no messages in the channel
+      assertEquals(0, messageQueue.browse().size());
+
+      assertEqualSets(messages, r.getMessages());
+   }
+
+   //////
+   ////// Transacted send and rollback
+   //////
+
+   ////////
+   //////// Non-reliable message
+   ////////
+
+   //////////
+   ////////// One message
+   //////////
+
+   public void testNonRecoverableChannel_21() throws Exception
+   {
+      if (messageQueue.isRecoverable())
+      {
+         // we test only non-recoverable channels now
+         return;
+      }
+
+      // add an ACKING receiver to the channel
+      SimpleReceiver r = new SimpleReceiver("AckingReceiver", SimpleReceiver.ACKING);
+      assertTrue(messageQueue.add(r));
+
+
+      Message m = MessageFactory.createCoreMessage(0, false, "payload");
+      SimpleDeliveryObserver observer = new SimpleDeliveryObserver();
+
+      Transaction tx = tr.createTransaction();
+
+      // transacted send, non-reliable message, one message
+      // for a transactional send, handle() return value is unspecified
+      messageQueue.handle(observer, m, tx);
+
+      // no messages in the channel
+      assertEquals(0, messageQueue.browse().size());
+
+      // no message at the receiver
+      assertTrue(r.getMessages().isEmpty());
+
+
+      tx.rollback();
+
+      // no messages in the channel
+      assertEquals(0, messageQueue.browse().size());
+
+      // no message at the receiver
+      assertTrue(r.getMessages().isEmpty());
+
+   }
+
+   //////////
+   ////////// Multiple message
+   //////////
+
+   public void testNonRecoverableChannel_22() throws Exception
+   {
+      if (messageQueue.isRecoverable())
+      {
+         // we test only non-recoverable channels now
+         return;
+      }
+
+      // add an ACKING receiver to the channel
+      SimpleReceiver r = new SimpleReceiver("AckingReceiver", SimpleReceiver.ACKING);
+      assertTrue(messageQueue.add(r));
+
+      SimpleDeliveryObserver observer = new SimpleDeliveryObserver();
+
+      Transaction tx = tr.createTransaction();
+
+      Message[] messages = new Message[NUMBER_OF_MESSAGES];
+      for(int i = 0; i < NUMBER_OF_MESSAGES; i++)
+      {
+         messages[i] = MessageFactory.createCoreMessage(i, false, "payload" + i);
+
+         // transacted send, non-reliable message, multiple messages
+         // for a transactional send, handle() return value is unspecified
+         messageQueue.handle(observer, messages[i], tx);
+      }
+
+      // no messages in the channel
+      assertEquals(0, messageQueue.browse().size());
+
+      // no message at the receiver
+      assertTrue(r.getMessages().isEmpty());
+
+      tx.rollback();
+
+      // no messages in the channel
+      assertEquals(0, messageQueue.browse().size());
+
+      // no message at the receiver
+      assertTrue(r.getMessages().isEmpty());
+   }
+
+   ////////
+   //////// Reliable message
+   ////////
+
+   //////////
+   ////////// One message
+   //////////
+
+   public void testNonRecoverableChannel_23() throws Exception
+   {
+      if (messageQueue.isRecoverable())
+      {
+         // we test only non-recoverable channels now
+         return;
+      }
+
+      // add an ACKING receiver to the channel
+      SimpleReceiver r = new SimpleReceiver("AckingReceiver", SimpleReceiver.ACKING);
+      assertTrue(messageQueue.add(r));
+
+
+      Message m = MessageFactory.createCoreMessage(0, true, "payload");
+      SimpleDeliveryObserver observer = new SimpleDeliveryObserver();
+
+      Transaction tx = tr.createTransaction();
+
+      // transacted send, reliable message, one message
+      // for a transactional send, handle() return value is unspecified
+      messageQueue.handle(observer, m, tx);
+
+      // no messages in the channel
+      assertEquals(0, messageQueue.browse().size());
+
+      // no message at the receiver
+      assertTrue(r.getMessages().isEmpty());
+
+      tx.rollback();
+
+      // no messages in the channel
+      assertEquals(0, messageQueue.browse().size());
+
+      // no message at the receiver
+      assertTrue(r.getMessages().isEmpty());
+   }
+
+   //////////
+   ////////// Multiple message
+   //////////
+
+   public void testNonRecoverableChannel_24() throws Exception
+   {
+      if (messageQueue.isRecoverable())
+      {
+         // we test only non-recoverable channels now
+         return;
+      }
+
+      // add an ACKING receiver to the channel
+      SimpleReceiver r = new SimpleReceiver("AckingReceiver", SimpleReceiver.ACKING);
+      assertTrue(messageQueue.add(r));
+
+
+      SimpleDeliveryObserver observer = new SimpleDeliveryObserver();
+
+      Transaction tx = tr.createTransaction();
+
+      Message[] messages = new Message[NUMBER_OF_MESSAGES];
+      for(int i = 0; i < NUMBER_OF_MESSAGES; i++)
+      {
+         messages[i] = MessageFactory.createCoreMessage(i, true, "payload" + i);
+
+         // transacted send, reliable message, multiple messages
+         // for a transactional send, handle() return value is unspecified
+         messageQueue.handle(observer, messages[i], tx);
+      }
+
+      // no messages in the channel
+      assertEquals(0, messageQueue.browse().size());
+
+      // no message at the receiver
+      assertTrue(r.getMessages().isEmpty());
+
+      tx.rollback();
+
+      // no messages in the channel
+      assertEquals(0, messageQueue.browse().size());
+
+      // no message at the receiver
+      assertTrue(r.getMessages().isEmpty());
+   }
+
+   /**
+    * This is a variation where I send a mixture of reliable and non-reliable messages,
+    */
+   public void testNonRecoverableChannel_24_mixed() throws Exception
+   {
+      if (messageQueue.isRecoverable())
+      {
+         // we test only non-recoverable channels now
+         return;
+      }
+
+      // add an ACKING receiver to the channel
+      SimpleReceiver r = new SimpleReceiver("AckingReceiver", SimpleReceiver.ACKING);
+      assertTrue(messageQueue.add(r));
+
+
+      SimpleDeliveryObserver observer = new SimpleDeliveryObserver();
+
+      Transaction tx = tr.createTransaction();
+
+      Message[] messages = new Message[NUMBER_OF_MESSAGES];
+      for(int i = 0; i < NUMBER_OF_MESSAGES; i++)
+      {
+         // send a mixture of reliable and non-reliable messages
+         messages[i] = MessageFactory.createCoreMessage(i, (i % 2 == 1), "payload" + i);
+
+         // transacted send, reliable/non-reliable messages, multiple messages
+         // for a transactional send, handle() return value is unspecified
+         messageQueue.handle(observer, messages[i], tx);
+      }
+
+      // no messages in the channel
+      assertEquals(0, messageQueue.browse().size());
+
+      // no message at the receiver
+      assertTrue(r.getMessages().isEmpty());
+
+      tx.rollback();
+
+      // no messages in the channel
+      assertEquals(0, messageQueue.browse().size());
+
+      // no message at the receiver
+      assertTrue(r.getMessages().isEmpty());
+   }
+
+   //////
+   ////// NACKING receiver
+   //////
+
+   //////
+   ////// Non-transacted send
+   //////
+
+   ////////
+   //////// Non-reliable message
+   ////////
+
+   //////////
+   ////////// One message
+   //////////
+
+   ////////////
+   //////////// Non-transacted acknowledgment
+   ////////////
+
+   public void testNonRecoverableChannel_25() throws Throwable
+   {
+      if (messageQueue.isRecoverable())
+      {
+         // we test only non-recoverable channels now
+         return;
+      }
+
+      // add an NACKING receiver to the channel
+      SimpleReceiver r = new SimpleReceiver("NackingReceiver", SimpleReceiver.NACKING);
+      assertTrue(messageQueue.add(r));
+
+      Message m = MessageFactory.createCoreMessage(0, false, "payload");
+      SimpleDeliveryObserver observer = new SimpleDeliveryObserver();
+
+      // non-transacted send, non-reliable message, one message
+      Delivery delivery = messageQueue.handle(observer, m, null);
+
+      assertTrue(delivery.isDone());
+
+      List delivering = messageQueue.browse();
+      assertEquals(1, delivering.size());
+      assertEquals(0, ((Message)delivering.get(0)).getMessageID());
+
+      List acknowledging = r.getMessages();
+      assertEquals(1, acknowledging.size());
+      Message ackm = (Message)acknowledging.get(0);
+      assertEquals(0, ackm.getMessageID());
+
+      // non-transacted acknowledgment
+      r.acknowledge(ackm, null);
+
+      assertTrue(messageQueue.browse().isEmpty());
+   }
+
+   /**
+    * The same test as before, but with a Receiver configured to acknowledge immediately
+    * on the Delivery. Simulates a race condition in which the acknoledgment arrives before
+    * the Delivery is returned to channel.
+    *
+    * @throws Throwable
+    */
+   public void testNonRecoverableChannel_25_race() throws Throwable
+   {
+      if (messageQueue.isRecoverable())
+      {
+         // we test only non-recoverable channels now
+         return;
+      }
+
+      // add an NACKING receiver to the channel
+      SimpleReceiver r = new SimpleReceiver("NackingReceiver", SimpleReceiver.NACKING);
+      r.setImmediateAsynchronousAcknowledgment(true);
+      assertTrue(messageQueue.add(r));
+
+      Message m = MessageFactory.createCoreMessage(0, false, "payload");
+      SimpleDeliveryObserver observer = new SimpleDeliveryObserver();
+
+      // non-transacted send, non-reliable message, one message
+      Delivery delivery = messageQueue.handle(observer, m, null);
+
+      assertTrue(delivery.isDone());
+
+      // the receiver should have returned a "done" delivery
+      assertTrue(messageQueue.browse().isEmpty());
+
+      List messages = r.getMessages();
+      assertEquals(1, messages.size());
+      Message ackm = (Message)messages.get(0);
+      assertEquals(0, ackm.getMessageID());
+
+      // an extra acknowledgment should be discarded
+      r.acknowledge(ackm, null);
+
+      assertTrue(messageQueue.browse().isEmpty());
+   }
+
+
+   ////////////
+   //////////// Transacted acknowledgment and commit
+   ////////////
+
+   public void testNonRecoverableChannel_25_1() throws Throwable
+   {
+      if (messageQueue.isRecoverable())
+      {
+         // we test only non-recoverable channels now
+         return;
+      }
+
+      // add an NACKING receiver to the channel
+      SimpleReceiver r = new SimpleReceiver("NackingReceiver", SimpleReceiver.NACKING);
+      assertTrue(messageQueue.add(r));
+
+      Message m = MessageFactory.createCoreMessage(0, false, "payload");
+      SimpleDeliveryObserver observer = new SimpleDeliveryObserver();
+
+      // non-transacted send, non-reliable message, one message
+      Delivery delivery = messageQueue.handle(observer, m, null);
+
+      assertTrue(delivery.isDone());
+
+      List delivering = messageQueue.browse();
+      assertEquals(1, delivering.size());
+      assertEquals(0, ((Message)delivering.get(0)).getMessageID());
+
+      List acknowledging = r.getMessages();
+      assertEquals(1, acknowledging.size());
+      Message ackm = (Message)acknowledging.get(0);
+      assertEquals(0, ackm.getMessageID());
+
+      Transaction tx = tr.createTransaction();
+
+      // transacted acknowledgment
+      r.acknowledge(ackm, tx);
+
+      delivering = messageQueue.browse();
+      assertEquals(1, delivering.size());
+      assertEquals(0, ((Message)delivering.get(0)).getMessageID());
+
+      tx.commit();
+
+      assertTrue(messageQueue.browse().isEmpty());
+   }
+
+
+   ////////////
+   //////////// Transacted acknowledgment and rollback
+   ////////////
+
+   public void testNonRecoverableChannel_25_2() throws Throwable
+   {
+      if (messageQueue.isRecoverable())
+      {
+         // we test only non-recoverable channels now
+         return;
+      }
+
+      // add an NACKING receiver to the channel
+      SimpleReceiver r = new SimpleReceiver("NackingReceiver", SimpleReceiver.NACKING);
+      assertTrue(messageQueue.add(r));
+
+      Message m = MessageFactory.createCoreMessage(0, false, "payload");
+      SimpleDeliveryObserver observer = new SimpleDeliveryObserver();
+
+      // non-transacted send, non-reliable message, one message
+      Delivery delivery = messageQueue.handle(observer, m, null);
+
+      assertTrue(delivery.isDone());
+
+      List delivering = messageQueue.browse();
+      assertEquals(1, delivering.size());
+      assertEquals(0, ((Message)delivering.get(0)).getMessageID());
+
+      List acknowledging = r.getMessages();
+      assertEquals(1, acknowledging.size());
+      Message ackm = (Message)acknowledging.get(0);
+      assertEquals(0, ackm.getMessageID());
+
+      Transaction tx = tr.createTransaction();
+
+      // transacted acknowledgment
+      r.acknowledge(ackm, tx);
+
+      delivering = messageQueue.browse();
+      assertEquals(1, delivering.size());
+      assertEquals(0, ((Message)delivering.get(0)).getMessageID());
+
+      tx.rollback();
+
+      delivering = messageQueue.browse();
+      assertEquals(1, delivering.size());
+      assertEquals(0, ((Message)delivering.get(0)).getMessageID());
+
+      // acknowledge non-transactionally
+      r.acknowledge(ackm, null);
+
+      assertTrue(messageQueue.browse().isEmpty());
+   }
+
+
+   //////////
+   ////////// Multiple message
+   //////////
+
+   ////////////
+   //////////// Non-transacted acknowledgment
+   ////////////
+
+   public void testNonRecoverableChannel_26() throws Throwable
+   {
+      if (messageQueue.isRecoverable())
+      {
+         // we test only non-recoverable channels now
+         return;
+      }
+
+      // add an NACKING receiver to the channel
+      SimpleReceiver r = new SimpleReceiver("NackingReceiver", SimpleReceiver.NACKING);
+      assertTrue(messageQueue.add(r));
+
+      SimpleDeliveryObserver observer = new SimpleDeliveryObserver();
+
+      Message[] messages = new Message[NUMBER_OF_MESSAGES];
+      for(int i = 0; i < NUMBER_OF_MESSAGES; i++)
+      {
+         messages[i] = MessageFactory.createCoreMessage(i, false, "payload" + i);
+
+         // non-transacted send, non-reliable message, multiple messages
+         Delivery delivery = messageQueue.handle(observer, messages[i], null);
+
+         assertTrue(delivery.isDone());
+      }
+
+      assertEqualSets(messages, messageQueue.browse());
+      assertEqualSets(messages, r.getMessages());
+
+      for(Iterator i = r.getMessages().iterator(); i.hasNext();)
+      {
+         Message ackm = (Message)i.next();
+         // non-transacted acknowledgment
+         r.acknowledge(ackm, null);
+      }
+
+      assertTrue(messageQueue.browse().isEmpty());
+
+   }
+
+   ////////////
+   //////////// Transacted acknowledgment and commit
+   ////////////
+
+   public void testNonRecoverableChannel_26_1() throws Throwable
+   {
+      if (messageQueue.isRecoverable())
+      {
+         // we test only non-recoverable channels now
+         return;
+      }
+
+      // add an NACKING receiver to the channel
+      SimpleReceiver r = new SimpleReceiver("NackingReceiver", SimpleReceiver.NACKING);
+      assertTrue(messageQueue.add(r));
+
+      SimpleDeliveryObserver observer = new SimpleDeliveryObserver();
+
+      Message[] messages = new Message[NUMBER_OF_MESSAGES];
+      for(int i = 0; i < NUMBER_OF_MESSAGES; i++)
+      {
+         messages[i] = MessageFactory.createCoreMessage(i, false, "payload" + i);
+
+         // non-transacted send, non-reliable message, multiple messages
+         Delivery delivery = messageQueue.handle(observer, messages[i], null);
+
+         assertTrue(delivery.isDone());
+      }
+
+      assertEqualSets(messages, messageQueue.browse());
+      assertEqualSets(messages, r.getMessages());
+
+      Transaction tx = tr.createTransaction();
+
+      for(Iterator i = r.getMessages().iterator(); i.hasNext();)
+      {
+         Message ackm = (Message)i.next();
+         // transacted acknowledgment
+         r.acknowledge(ackm, tx);
+      }
+
+      assertEqualSets(messages, messageQueue.browse());
+
+      tx.commit();
+
+      assertTrue(messageQueue.browse().isEmpty());
+   }
+
+
+   ////////////
+   //////////// Transacted acknowledgment and rollback
+   ////////////
+
+   public void testNonRecoverableChannel_26_2() throws Throwable
+   {
+      if (messageQueue.isRecoverable())
+      {
+         // we test only non-recoverable channels now
+         return;
+      }
+
+      // add an NACKING receiver to the channel
+      SimpleReceiver r = new SimpleReceiver("NackingReceiver", SimpleReceiver.NACKING);
+      assertTrue(messageQueue.add(r));
+
+      SimpleDeliveryObserver observer = new SimpleDeliveryObserver();
+
+      Message[] messages = new Message[NUMBER_OF_MESSAGES];
+      for(int i = 0; i < NUMBER_OF_MESSAGES; i++)
+      {
+         messages[i] = MessageFactory.createCoreMessage(i, false, "payload" + i);
+
+         // non-transacted send, non-reliable message, multiple messages
+         Delivery delivery = messageQueue.handle(observer, messages[i], null);
+
+         assertTrue(delivery.isDone());
+      }
+
+      assertEqualSets(messages, messageQueue.browse());
+      assertEqualSets(messages, r.getMessages());
+
+      Transaction tx = tr.createTransaction();
+
+      for(Iterator i = r.getMessages().iterator(); i.hasNext();)
+      {
+         Message ackm = (Message)i.next();
+         // transacted acknowledgment
+         r.acknowledge(ackm, tx);
+      }
+
+      assertEqualSets(messages, messageQueue.browse());
+
+      tx.rollback();
+
+      assertEqualSets(messages, messageQueue.browse());
+
+      // acknowledge non-transactionally
+      for(Iterator i = r.getMessages().iterator(); i.hasNext();)
+      {
+         Message ackm = (Message)i.next();
+         // non-transacted acknowledgment
+         r.acknowledge(ackm, null);
+      }
+
+      assertTrue(messageQueue.browse().isEmpty());
+   }
+
+   ////////
+   //////// Reliable message
+   ////////
+
+   //////////
+   ////////// One message
+   //////////
+
+   ////////////
+   //////////// Non-transacted acknowledgment
+   ////////////
+
+   ///////////
+   /////////// Channel does NOT accept reliable messages
+   ///////////
+
+   public void testNonRecoverableChannel_27_1_1() throws Exception
+   {
+      if (messageQueue.isRecoverable())
+      {
+         // we test only non-recoverable channels now
+         return;
+      }
+
+      if (messageQueue.acceptReliableMessages())
+      {
+         // we test channels that don't accept reliable messages
+         return;
+      }
+
+      // add an NACKING receiver to the channel
+      SimpleReceiver r = new SimpleReceiver("NackingReceiver", SimpleReceiver.NACKING);
+      assertTrue(messageQueue.add(r));
+
+      Message m = MessageFactory.createCoreMessage(0, true, "payload");
+      SimpleDeliveryObserver observer = new SimpleDeliveryObserver();
+
+      // non-transacted send, reliable message, one message
+      Delivery delivery = messageQueue.handle(observer, m, null);
+
+      // not accepted by the channel
+      assertNull(delivery);
+      assertTrue(messageQueue.browse().isEmpty());
+      assertTrue(r.getMessages().isEmpty());
+
+   }
+
+   ///////////
+   /////////// Channel accepts reliable messages
+   ///////////
+
+   public void testNonRecoverableChannel_27_1_2() throws Throwable
+   {
+      if (messageQueue.isRecoverable())
+      {
+         // we test only non-recoverable channels now
+         return;
+      }
+
+      if (!messageQueue.acceptReliableMessages())
+      {
+         // we test channels that accept reliable messages
+         return;
+      }
+
+      // add an NACKING receiver to the channel
+      SimpleReceiver r = new SimpleReceiver("NackingReceiver", SimpleReceiver.NACKING);
+      assertTrue(messageQueue.add(r));
+
+      Message m = MessageFactory.createCoreMessage(0, true, "payload");
+      SimpleDeliveryObserver observer = new SimpleDeliveryObserver();
+
+      // non-transacted send, reliable message, one message
+      Delivery delivery = messageQueue.handle(observer, m, null);
+
+      assertTrue(delivery.isDone());
+
+      List stored = messageQueue.browse();
+      assertEquals(1, stored.size());
+      Message sm = (Message)stored.iterator().next();
+      assertTrue(sm.isReliable());
+      assertEquals(0, sm.getMessageID());
+
+      List received = r.getMessages();
+      assertEquals(1, received.size());
+      Message rm = (Message)received.iterator().next();
+      assertTrue(rm.isReliable());
+      assertEquals(0, rm.getMessageID());
+
+      r.acknowledge(rm, null);
+
+      assertTrue(messageQueue.browse().isEmpty());
+   }
+
+
+   ////////////
+   //////////// Transacted acknowledgment
+   ////////////
+
+   ///////////
+   /////////// Channel does NOT accept reliable messages
+   ///////////
+
+
+   // Doesn't make sense, the message won't be accepted anyway.
+
+   ///////////
+   /////////// Channel accepts reliable messages
+   ///////////
+
+
+   public void testNonRecoverableChannel_27_2_2() throws Throwable
+   {
+      if (messageQueue.isRecoverable())
+      {
+         // we test only non-recoverable channels now
+         return;
+      }
+
+      if (!messageQueue.acceptReliableMessages())
+      {
+         // we test channels that accept reliable messages
+         return;
+      }
+
+      // add an NACKING receiver to the channel
+      SimpleReceiver r = new SimpleReceiver("NackingReceiver", SimpleReceiver.NACKING);
+      assertTrue(messageQueue.add(r));
+
+      Message m = MessageFactory.createCoreMessage(0, true, "payload");
+      SimpleDeliveryObserver observer = new SimpleDeliveryObserver();
+
+      // non-transacted send, reliable message, one message
+      Delivery delivery = messageQueue.handle(observer, m, null);
+
+      assertTrue(delivery.isDone());
+
+      List stored = messageQueue.browse();
+      assertEquals(1, stored.size());
+      Message sm = (Message)stored.iterator().next();
+      assertTrue(sm.isReliable());
+      assertEquals(0, sm.getMessageID());
+
+      List received = r.getMessages();
+      assertEquals(1, received.size());
+      Message rm = (Message)received.iterator().next();
+      assertTrue(rm.isReliable());
+      assertEquals(0, rm.getMessageID());
+
+      Transaction tx = tr.createTransaction();
+
+      r.acknowledge(rm, tx);
+
+      stored = messageQueue.browse();
+      assertEquals(1, stored.size());
+      sm = (Message)stored.iterator().next();
+      assertTrue(sm.isReliable());
+      assertEquals(0, sm.getMessageID());
+
+      tx.commit();
+
+      assertTrue(messageQueue.browse().isEmpty());
+   }
+
+   //////////
+   ////////// Multiple message
+   //////////
+
+   ////////////
+   //////////// Non-transacted acknowledgment
+   ////////////
+
+   ///////////
+   /////////// Channel does NOT accept reliable messages
+   ///////////
+
+   public void testNonRecoverableChannel_28_1_1() throws Exception
+   {
+      if (messageQueue.isRecoverable())
+      {
+         // we test only non-recoverable channels now
+         return;
+      }
+
+      if (messageQueue.acceptReliableMessages())
+      {
+         // we test channels that don't accept reliable messages
+         return;
+      }
+
+      // add an NACKING receiver to the channel
+      SimpleReceiver r = new SimpleReceiver("NackingReceiver", SimpleReceiver.NACKING);
+      assertTrue(messageQueue.add(r));
+
+      SimpleDeliveryObserver observer = new SimpleDeliveryObserver();
+
+      Message[] messages = new Message[NUMBER_OF_MESSAGES];
+      for(int i = 0; i < NUMBER_OF_MESSAGES; i++)
+      {
+         messages[i] = MessageFactory.createCoreMessage(i, true, "payload" + i);
+
+         // non-transacted send, reliable message, multiple messages
+         Delivery delivery = messageQueue.handle(observer, messages[i], null);
+
+         // not accepted by the channel
+         assertNull(delivery);
+      }
+
+      assertTrue(messageQueue.browse().isEmpty());
+      assertTrue(r.getMessages().isEmpty());
+   }
+
+   ///////////
+   /////////// Channel accepts reliable messages
+   ///////////
+
+   public void testNonRecoverableChannel_28_1_2() throws Throwable
+   {
+      if (messageQueue.isRecoverable())
+      {
+         // we test only non-recoverable channels now
+         return;
+      }
+
+      if (!messageQueue.acceptReliableMessages())
+      {
+         // we test channels that accept reliable messages
+         return;
+      }
+
+      // add an NACKING receiver to the channel
+      SimpleReceiver r = new SimpleReceiver("NackingReceiver", SimpleReceiver.NACKING);
+      assertTrue(messageQueue.add(r));
+
+      SimpleDeliveryObserver observer = new SimpleDeliveryObserver();
+
+      Message[] messages = new Message[NUMBER_OF_MESSAGES];
+      for(int i = 0; i < NUMBER_OF_MESSAGES; i++)
+      {
+         messages[i] = MessageFactory.createCoreMessage(i, true, "payload" + i);
+
+         // non-transacted send, reliable message, multiple messages
+         Delivery delivery = messageQueue.handle(observer, messages[i], null);
+
+         assertTrue(delivery.isDone());
+      }
+
+      assertEqualSets(messages, messageQueue.browse());
+      assertEqualSets(messages, r.getMessages());
+
+      for(Iterator i = r.getMessages().iterator(); i.hasNext();)
+      {
+         Message ackm = (Message)i.next();
+         // non-transacted acknowledgment
+         r.acknowledge(ackm, null);
+      }
+
+      assertTrue(messageQueue.browse().isEmpty());
+   }
+
+
+   ////////////
+   //////////// Transacted acknowledgment
+   ////////////
+
+   ///////////
+   /////////// Channel does NOT accept reliable messages
+   ///////////
+
+   // Doesn't make sense, the message won't be accepted anyway.
+
+   ///////////
+   /////////// Channel accepts reliable messages
+   ///////////
+
+   public void testNonRecoverableChannel_28_2_2() throws Throwable
+   {
+      if (messageQueue.isRecoverable())
+      {
+         // we test only non-recoverable channels now
+         return;
+      }
+
+      if (!messageQueue.acceptReliableMessages())
+      {
+         // we test channels that accept reliable messages
+         return;
+      }
+
+      // add an NACKING receiver to the channel
+      SimpleReceiver r = new SimpleReceiver("NackingReceiver", SimpleReceiver.NACKING);
+      assertTrue(messageQueue.add(r));
+
+      SimpleDeliveryObserver observer = new SimpleDeliveryObserver();
+
+      Message[] messages = new Message[NUMBER_OF_MESSAGES];
+      for(int i = 0; i < NUMBER_OF_MESSAGES; i++)
+      {
+         messages[i] = MessageFactory.createCoreMessage(i, true, "payload" + i);
+
+         // non-transacted send, reliable message, multiple messages
+         Delivery delivery = messageQueue.handle(observer, messages[i], null);
+
+         assertTrue(delivery.isDone());
+      }
+
+      assertEqualSets(messages, messageQueue.browse());
+      assertEqualSets(messages, r.getMessages());
+
+      Transaction tx = tr.createTransaction();
+
+      for(Iterator i = r.getMessages().iterator(); i.hasNext();)
+      {
+         Message ackm = (Message)i.next();
+         r.acknowledge(ackm, tx);
+      }
+
+      assertEqualSets(messages, messageQueue.browse());
+
+      tx.commit();
+
+      assertTrue(messageQueue.browse().isEmpty());
+   }
+
+   //////
+   ////// Transacted send and commit
+   //////
+
+   ////////
+   //////// Non-reliable message
+   ////////
+
+   //////////
+   ////////// One message
+   //////////
+
+   public void testNonRecoverableChannel_29() throws Throwable
+   {
+      if (messageQueue.isRecoverable())
+      {
+         // we test only non-recoverable channels now
+         return;
+      }
+
+      // add an NACKING receiver to the channel
+      SimpleReceiver r = new SimpleReceiver("NackingReceiver", SimpleReceiver.NACKING);
+      assertTrue(messageQueue.add(r));
+
+      Message m = MessageFactory.createCoreMessage(0, false, "payload");
+      SimpleDeliveryObserver observer = new SimpleDeliveryObserver();
+
+      Transaction tx = tr.createTransaction();
+
+      // transacted send, non-reliable message, one message
+      // for a transactional send, handle() return value is unspecified
+      messageQueue.handle(observer, m, tx);
+
+      // no messages in the channel
+      assertEquals(0, messageQueue.browse().size());
+
+      // no message at the receiver
+      assertTrue(r.getMessages().isEmpty());
+
+      tx.commit();
+
+      List delivering = messageQueue.browse();
+      assertEquals(1, delivering.size());
+      assertEquals(0, ((Message)delivering.get(0)).getMessageID());
+
+      List acknowledging = r.getMessages();
+      assertEquals(1, acknowledging.size());
+      Message ackm = (Message)acknowledging.get(0);
+      assertEquals(0, ackm.getMessageID());
+
+      // non-transacted acknowledgment
+      r.acknowledge(ackm, null);
+
+      assertTrue(messageQueue.browse().isEmpty());
+   }
+
+   //////////
+   ////////// Multiple message
+   //////////
+
+   public void testNonRecoverableChannel_30() throws Throwable
+   {
+      if (messageQueue.isRecoverable())
+      {
+         // we test only non-recoverable channels now
+         return;
+      }
+
+      // add an NACKING receiver to the channel
+      SimpleReceiver r = new SimpleReceiver("NackingReceiver", SimpleReceiver.NACKING);
+      assertTrue(messageQueue.add(r));
+
+      SimpleDeliveryObserver observer = new SimpleDeliveryObserver();
+
+      Transaction tx = tr.createTransaction();
+
+      Message[] messages = new Message[NUMBER_OF_MESSAGES];
+      for(int i = 0; i < NUMBER_OF_MESSAGES; i++)
+      {
+         messages[i] = MessageFactory.createCoreMessage(i, false, "payload" + i);
+
+         // transacted send, non-reliable message, multiple messages
+         // for a transactional send, handle() return value is unspecified
+         messageQueue.handle(observer, messages[i], tx);
+      }
+
+      // no messages in the channel
+      assertEquals(0, messageQueue.browse().size());
+
+      // no message at the receiver
+      assertTrue(r.getMessages().isEmpty());
+
+      tx.commit();
+
+      assertEqualSets(messages, messageQueue.browse());
+      assertEqualSets(messages, r.getMessages());
+
+      for(Iterator i = r.getMessages().iterator(); i.hasNext();)
+      {
+         Message ackm = (Message)i.next();
+         // non-transacted acknowledgment
+         r.acknowledge(ackm, null);
+      }
+
+      assertTrue(messageQueue.browse().isEmpty());
+   }
+
+   ////////
+   //////// Reliable message
+   ////////
+
+   //////////
+   ////////// One message
+   //////////
+
+   ///////////
+   /////////// Channel does NOT accept reliable messages
+   ///////////
+
+   public void testNonRecoverableChannel_31_1() throws Exception
+   {
+      if (messageQueue.isRecoverable())
+      {
+         // we test only non-recoverable channels now
+         return;
+      }
+
+      if (messageQueue.acceptReliableMessages())
+      {
+         // we test channels that don't accept reliable messages
+         return;
+      }
+
+      // add an NACKING receiver to the channel
+      SimpleReceiver r = new SimpleReceiver("NackingReceiver", SimpleReceiver.NACKING);
+      assertTrue(messageQueue.add(r));
+
+
+      Message m = MessageFactory.createCoreMessage(0, true, "payload");
+      SimpleDeliveryObserver observer = new SimpleDeliveryObserver();
+
+      Transaction tx = tr.createTransaction();
+
+      // transacted send, reliable message, one message
+      // for a transactional send, handle() return value is unspecified
+      messageQueue.handle(observer, m, tx);
+
+      // no messages in the channel yet
+      assertEquals(0, messageQueue.browse().size());
+
+      // no message at the receiver
+      assertTrue(r.getMessages().isEmpty());
+
+      try
+      {
+         tx.commit();
+         fail("this should throw exception");
+      }
+      catch(Exception e)
+      {
+         // OK
+      }
+
+      // no messages in the channel
+      assertEquals(0, messageQueue.browse().size());
+
+      // no message at the receiver
+      assertTrue(r.getMessages().isEmpty());
+   }
+
+   ///////////
+   /////////// Channel does accepts reliable messages
+   ///////////
+
+   public void testNonRecoverableChannel_31_2() throws Exception
+   {
+      if (messageQueue.isRecoverable())
+      {
+         // we test only non-recoverable channels now
+         return;
+      }
+
+      if (!messageQueue.acceptReliableMessages())
+      {
+         // we test channels that accept reliable messages
+         return;
+      }
+
+      // add an NACKING receiver to the channel
+      SimpleReceiver r = new SimpleReceiver("NackingReceiver", SimpleReceiver.NACKING);
+      assertTrue(messageQueue.add(r));
+
+
+      Message m = MessageFactory.createCoreMessage(0, true, "payload");
+      SimpleDeliveryObserver observer = new SimpleDeliveryObserver();
+
+      Transaction tx = tr.createTransaction();
+
+      // transacted send, reliable message, one message
+      // for a transactional send, handle() return value is unspecified
+      messageQueue.handle(observer, m, tx);
+
+      // no messages in the channel yet
+      assertEquals(0, messageQueue.browse().size());
+
+      // no message at the receiver
+      assertTrue(r.getMessages().isEmpty());
+
+      tx.commit();
+
+      List stored = messageQueue.browse();
+      assertEquals(1, stored.size());
+      Message sm = (Message)stored.iterator().next();
+      assertTrue(sm.isReliable());
+      assertEquals(0, sm.getMessageID());
+
+      List received = r.getMessages();
+      assertEquals(1, received.size());
+      Message rm = (Message)received.iterator().next();
+      assertTrue(rm.isReliable());
+      assertEquals(0, rm.getMessageID());
+   }
+
+
+   //////////
+   ////////// Multiple message
+   //////////
+
+   ///////////
+   /////////// Channel does NOT accept reliable messages
+   ///////////
+
+   public void testNonRecoverableChannel_32_1() throws Exception
+   {
+      if (messageQueue.isRecoverable())
+      {
+         // we test only non-recoverable channels now
+         return;
+      }
+
+      if (messageQueue.acceptReliableMessages())
+      {
+         // we test channels that don't accept reliable messages
+         return;
+      }
+
+      // add an NACKING receiver to the channel
+      SimpleReceiver r = new SimpleReceiver("NackingReceiver", SimpleReceiver.NACKING);
+      assertTrue(messageQueue.add(r));
+
+      SimpleDeliveryObserver observer = new SimpleDeliveryObserver();
+
+      Transaction tx = tr.createTransaction();
+
+      Message[] messages = new Message[NUMBER_OF_MESSAGES];
+      for(int i = 0; i < NUMBER_OF_MESSAGES; i++)
+      {
+         messages[i] = MessageFactory.createCoreMessage(i, true, "payload" + i);
+
+         // transacted send, reliable message, multiple messages
+         // for a transactional send, handle() return value is unspecified
+         messageQueue.handle(observer, messages[i], tx);
+      }
+
+      // no messages in the channel yet
+      assertEquals(0, messageQueue.browse().size());
+
+      // no message at the receiver
+      assertTrue(r.getMessages().isEmpty());
+
+      try
+      {
+         tx.commit();
+         fail("this should throw exception");
+      }
+      catch(Exception e)
+      {
+         // OK
+      }
+
+      // no messages in the channel
+      assertEquals(0, messageQueue.browse().size());
+
+      // no message at the receiver
+      assertTrue(r.getMessages().isEmpty());
+   }
+
+   /**
+    * This is a variation where I send a mixture of reliable and non-reliable messages,
+    */
+   public void testNonRecoverableChannel_32_1_mixed() throws Exception
+   {
+      if (messageQueue.isRecoverable())
+      {
+         // we test only non-recoverable channels now
+         return;
+      }
+
+      if (messageQueue.acceptReliableMessages())
+      {
+         // we test channels that don't accept reliable messages
+         return;
+      }
+
+      // add an NACKING receiver to the channel
+      SimpleReceiver r = new SimpleReceiver("NackingReceiver", SimpleReceiver.NACKING);
+      assertTrue(messageQueue.add(r));
+
+
+      SimpleDeliveryObserver observer = new SimpleDeliveryObserver();
+
+      Transaction tx = tr.createTransaction();
+
+      Message[] messages = new Message[NUMBER_OF_MESSAGES];
+      for(int i = 0; i < NUMBER_OF_MESSAGES; i++)
+      {
+         // send a mixture of reliable and non-reliable messages
+         messages[i] = MessageFactory.createCoreMessage(i, (i % 2 == 1), "payload" + i);
+
+         // transacted send, reliable/non-reliable messages, multiple messages
+         // for a transactional send, handle() return value is unspecified
+         messageQueue.handle(observer, messages[i], tx);
+      }
+
+      // no messages in the channel
+      assertEquals(0, messageQueue.browse().size());
+
+      // no message at the receiver
+      assertTrue(r.getMessages().isEmpty());
+
+      try
+      {
+         tx.commit();
+         fail("this should throw exception");
+      }
+      catch(Exception e)
+      {
+         // OK
+      }
+
+      // no messages in the channel
+      assertEquals(0, messageQueue.browse().size());
+
+      // no message at the receiver
+      assertTrue(r.getMessages().isEmpty());
+   }
+
+   ///////////
+   /////////// Channel accepts reliable messages
+   ///////////
+
+   public void testNonRecoverableChannel_32_2() throws Exception
+   {
+      if (messageQueue.isRecoverable())
+      {
+         // we test only non-recoverable channels now
+         return;
+      }
+
+      if (!messageQueue.acceptReliableMessages())
+      {
+         // we test channels that accept reliable messages
+         return;
+      }
+
+      // add an NACKING receiver to the channel
+      SimpleReceiver r = new SimpleReceiver("NackingReceiver", SimpleReceiver.NACKING);
+      assertTrue(messageQueue.add(r));
+
+      SimpleDeliveryObserver observer = new SimpleDeliveryObserver();
+
+      Transaction tx = tr.createTransaction();
+
+      Message[] messages = new Message[NUMBER_OF_MESSAGES];
+      for(int i = 0; i < NUMBER_OF_MESSAGES; i++)
+      {
+         messages[i] = MessageFactory.createCoreMessage(i, true, "payload" + i);
+
+         // transacted send, reliable message, multiple messages
+         // for a transactional send, handle() return value is unspecified
+         messageQueue.handle(observer, messages[i], tx);
+      }
+
+      // no messages in the channel yet
+      assertEquals(0, messageQueue.browse().size());
+
+      // no message at the receiver
+      assertTrue(r.getMessages().isEmpty());
+
+      tx.commit();
+
+      assertEqualSets(messages, messageQueue.browse());
+      assertEqualSets(messages, r.getMessages());
+   }
+
+   /**
+    * This is a variation where I send a mixture of reliable and non-reliable messages,
+    */
+   public void testNonRecoverableChannel_32_2_mixed() throws Exception
+   {
+      if (messageQueue.isRecoverable())
+      {
+         // we test only non-recoverable channels now
+         return;
+      }
+
+      if (!messageQueue.acceptReliableMessages())
+      {
+         // we test channels that accept reliable messages
+         return;
+      }
+
+      // add an NACKING receiver to the channel
+      SimpleReceiver r = new SimpleReceiver("NackingReceiver", SimpleReceiver.NACKING);
+      assertTrue(messageQueue.add(r));
+
+
+      SimpleDeliveryObserver observer = new SimpleDeliveryObserver();
+
+      Transaction tx = tr.createTransaction();
+
+      Message[] messages = new Message[NUMBER_OF_MESSAGES];
+      for(int i = 0; i < NUMBER_OF_MESSAGES; i++)
+      {
+         // send a mixture of reliable and non-reliable messages
+         messages[i] = MessageFactory.createCoreMessage(i, (i % 2 == 1), "payload" + i);
+
+         // transacted send, reliable/non-reliable messages, multiple messages
+         // for a transactional send, handle() return value is unspecified
+         messageQueue.handle(observer, messages[i], tx);
+      }
+
+      // no messages in the channel
+      assertEquals(0, messageQueue.browse().size());
+
+      // no message at the receiver
+      assertTrue(r.getMessages().isEmpty());
+
+      tx.commit();
+
+      assertEqualSets(messages, messageQueue.browse());
+      assertEqualSets(messages, r.getMessages());
+   }
+
+
+
+   //////
+   ////// Transacted send and rollback
+   //////
+
+   ////////
+   //////// Non-reliable message
+   ////////
+
+   //////////
+   ////////// One message
+   //////////
+
+   public void testNonRecoverableChannel_33() throws Exception
+   {
+      if (messageQueue.isRecoverable())
+      {
+         // we test only non-recoverable channels now
+         return;
+      }
+
+      // add an NACKING receiver to the channel
+      SimpleReceiver r = new SimpleReceiver("NackingReceiver", SimpleReceiver.NACKING);
+      assertTrue(messageQueue.add(r));
+
+
+      Message m = MessageFactory.createCoreMessage(0, false, "payload");
+      SimpleDeliveryObserver observer = new SimpleDeliveryObserver();
+
+      Transaction tx = tr.createTransaction();
+
+      // transacted send, non-reliable message, one message
+      // for a transactional send, handle() return value is unspecified
+      messageQueue.handle(observer, m, tx);
+
+      // no messages in the channel
+      assertEquals(0, messageQueue.browse().size());
+
+      // no message at the receiver
+      assertTrue(r.getMessages().isEmpty());
+
+
+      tx.rollback();
+
+      // no messages in the channel
+      assertEquals(0, messageQueue.browse().size());
+
+      // no message at the receiver
+      assertTrue(r.getMessages().isEmpty());
+
+   }
+
+   //////////
+   ////////// Multiple message
+   //////////
+
+   public void testNonRecoverableChannel_34() throws Exception
+   {
+      if (messageQueue.isRecoverable())
+      {
+         // we test only non-recoverable channels now
+         return;
+      }
+
+      // add an NACKING receiver to the channel
+      SimpleReceiver r = new SimpleReceiver("NackingReceiver", SimpleReceiver.NACKING);
+      assertTrue(messageQueue.add(r));
+
+      SimpleDeliveryObserver observer = new SimpleDeliveryObserver();
+
+      Transaction tx = tr.createTransaction();
+
+      Message[] messages = new Message[NUMBER_OF_MESSAGES];
+      for(int i = 0; i < NUMBER_OF_MESSAGES; i++)
+      {
+         messages[i] = MessageFactory.createCoreMessage(i, false, "payload" + i);
+
+         // transacted send, non-reliable message, multiple messages
+         // for a transactional send, handle() return value is unspecified
+         messageQueue.handle(observer, messages[i], tx);
+      }
+
+      // no messages in the channel
+      assertEquals(0, messageQueue.browse().size());
+
+      // no message at the receiver
+      assertTrue(r.getMessages().isEmpty());
+
+      tx.rollback();
+
+      // no messages in the channel
+      assertEquals(0, messageQueue.browse().size());
+
+      // no message at the receiver
+      assertTrue(r.getMessages().isEmpty());
+   }
+
+   ////////
+   //////// Reliable message
+   ////////
+
+   //////////
+   ////////// One message
+   //////////
+
+   public void testNonRecoverableChannel_35() throws Exception
+   {
+      if (messageQueue.isRecoverable())
+      {
+         // we test only non-recoverable channels now
+         return;
+      }
+
+      // add an NACKING receiver to the channel
+      SimpleReceiver r = new SimpleReceiver("NackingReceiver", SimpleReceiver.NACKING);
+      assertTrue(messageQueue.add(r));
+
+
+      Message m = MessageFactory.createCoreMessage(0, true, "payload");
+      SimpleDeliveryObserver observer = new SimpleDeliveryObserver();
+
+      Transaction tx = tr.createTransaction();
+
+      // transacted send, reliable message, one message
+      // for a transactional send, handle() return value is unspecified
+      messageQueue.handle(observer, m, tx);
+
+      // no messages in the channel
+      assertEquals(0, messageQueue.browse().size());
+
+      // no message at the receiver
+      assertTrue(r.getMessages().isEmpty());
+
+      tx.rollback();
+
+      // no messages in the channel
+      assertEquals(0, messageQueue.browse().size());
+
+      // no message at the receiver
+      assertTrue(r.getMessages().isEmpty());
+   }
+
+   //////////
+   ////////// Multiple message
+   //////////
+
+   public void testNonRecoverableChannel_36() throws Exception
+   {
+      if (messageQueue.isRecoverable())
+      {
+         // we test only non-recoverable channels now
+         return;
+      }
+
+      // add an NACKING receiver to the channel
+      SimpleReceiver r = new SimpleReceiver("NackingReceiver", SimpleReceiver.NACKING);
+      assertTrue(messageQueue.add(r));
+
+
+      SimpleDeliveryObserver observer = new SimpleDeliveryObserver();
+
+      Transaction tx = tr.createTransaction();
+
+      Message[] messages = new Message[NUMBER_OF_MESSAGES];
+      for(int i = 0; i < NUMBER_OF_MESSAGES; i++)
+      {
+         messages[i] = MessageFactory.createCoreMessage(i, true, "payload" + i);
+
+         // transacted send, reliable message, multiple messages
+         // for a transactional send, handle() return value is unspecified
+         messageQueue.handle(observer, messages[i], tx);
+      }
+
+      // no messages in the channel
+      assertEquals(0, messageQueue.browse().size());
+
+      // no message at the receiver
+      assertTrue(r.getMessages().isEmpty());
+
+      tx.rollback();
+
+      // no messages in the channel
+      assertEquals(0, messageQueue.browse().size());
+
+      // no message at the receiver
+      assertTrue(r.getMessages().isEmpty());
+   }
+
+   /**
+    * This is a variation where I send a mixture of reliable and non-reliable messages,
+    */
+   public void testNonRecoverableChannel_36_mixed() throws Exception
+   {
+      if (messageQueue.isRecoverable())
+      {
+         // we test only non-recoverable channels now
+         return;
+      }
+
+
+      // add an NACKING receiver to the channel
+      SimpleReceiver r = new SimpleReceiver("NackingReceiver", SimpleReceiver.NACKING);
+      assertTrue(messageQueue.add(r));
+
+
+      SimpleDeliveryObserver observer = new SimpleDeliveryObserver();
+
+      Transaction tx = tr.createTransaction();
+
+      Message[] messages = new Message[NUMBER_OF_MESSAGES];
+      for(int i = 0; i < NUMBER_OF_MESSAGES; i++)
+      {
+         // send a mixture of reliable and non-reliable messages
+         messages[i] = MessageFactory.createCoreMessage(i, (i % 2 == 1), "payload" + i);
+
+         // transacted send, reliable/non-reliable messages, multiple messages
+         // for a transactional send, handle() return value is unspecified
+         messageQueue.handle(observer, messages[i], tx);
+      }
+
+      // no messages in the channel
+      assertEquals(0, messageQueue.browse().size());
+
+      // no message at the receiver
+      assertTrue(r.getMessages().isEmpty());
+
+      tx.rollback();
+
+      // no messages in the channel
+      assertEquals(0, messageQueue.browse().size());
+
+      // no message at the receiver
+      assertTrue(r.getMessages().isEmpty());
+   }
+
+
+
+
+   //
+   // Recoverable channel
+   //
+
+   public void testRecoverableChannel_0() throws Exception
+   {
+      if (messageQueue.isRecoverable())
+      {
+         assertTrue(messageQueue.acceptReliableMessages());
+      }
+   }
+
+   ////
+   //// Zero receivers
+   ////
+
+   //////
+   ////// Non-transacted send
+   //////
+
+   ////////
+   //////// Non-reliable message
+   ////////
+
+   //////////
+   ////////// One message
+   //////////
+
+   public void testRecoverableChannel_1() throws Exception
+   {
+      if (!messageQueue.isRecoverable())
+      {
+         // we test only recoverable channels now
+         return;
+      }
+
+      // the channel has no receivers
+      assertFalse(messageQueue.iterator().hasNext());
+
+      Message m = MessageFactory.createCoreMessage(0, false, "payload");
+      SimpleDeliveryObserver observer = new SimpleDeliveryObserver();
+
+      // non-transacted send, non-reliable message, one message
+      Delivery delivery = messageQueue.handle(observer, m, null);
+
+      assertTrue(delivery.isDone());
+
+      List stored = messageQueue.browse();
+      assertEquals(1, stored.size());
+
+      Message sm = (Message)stored.iterator().next();
+      assertFalse(sm.isReliable());
+      assertEquals(0, sm.getMessageID());
+   }
+
+   //////////
+   ////////// Multiple message
+   //////////
+
+   public void testRecoverableChannel_2() throws Exception
+   {
+      if (!messageQueue.isRecoverable())
+      {
+         // we test only recoverable channels now
+         return;
+      }
+
+      // the channel has no receivers
+      assertFalse(messageQueue.iterator().hasNext());
+
+      SimpleDeliveryObserver observer = new SimpleDeliveryObserver();
+
+      Message[] messages = new Message[NUMBER_OF_MESSAGES];
+      for(int i = 0; i < NUMBER_OF_MESSAGES; i++)
+      {
+         messages[i] = MessageFactory.createCoreMessage(i, false, "payload" + i);
+
+         // non-transacted send, non-reliable message, multiple messages
+         Delivery delivery = messageQueue.handle(observer, messages[i], null);
+
+         assertTrue(delivery.isDone());
+      }
+
+      assertEqualSets(messages, messageQueue.browse());
+   }
+
+   ////////
+   //////// Reliable message
+   ////////
+
+   //////////
+   ////////// One message
+   //////////
+
+   public void testRecoverableChannel_3() throws Exception
+   {
+      if (!messageQueue.isRecoverable())
+      {
+         // we test only recoverable channels now
+         return;
+      }
+
+      // the channel has no receivers
+      assertFalse(messageQueue.iterator().hasNext());
+
+      Message m = MessageFactory.createCoreMessage(0, true, "payload");
+      SimpleDeliveryObserver observer = new SimpleDeliveryObserver();
+
+      // non-transacted send, reliable message, one message
+      Delivery delivery = messageQueue.handle(observer, m, null);
+
+      assertTrue(delivery.isDone());
+
+      List stored = messageQueue.browse();
+      assertEquals(1, stored.size());
+
+      Message sm = (Message)stored.iterator().next();
+      assertTrue(sm.isReliable());
+      assertEquals(0, sm.getMessageID());
+   }
+
+   //////////
+   ////////// Multiple message
+   //////////
+
+   public void testRecoverableChannel_4() throws Exception
+   {
+      if (!messageQueue.isRecoverable())
+      {
+         // we test only recoverable channels now
+         return;
+      }
+
+      // the channel has no receivers
+      assertFalse(messageQueue.iterator().hasNext());
+
+      SimpleDeliveryObserver observer = new SimpleDeliveryObserver();
+
+      Message[] messages = new Message[NUMBER_OF_MESSAGES];
+      for(int i = 0; i < NUMBER_OF_MESSAGES; i++)
+      {
+         messages[i] = MessageFactory.createCoreMessage(i, true, "payload" + i);
+
+         // non-transacted send, reliable message, multiple messages
+         Delivery delivery = messageQueue.handle(observer, messages[i], null);
+
+         assertTrue(delivery.isDone());
+      }
+
+      assertEqualSets(messages, messageQueue.browse());
+
+   }
+
+   //////
+   ////// Transacted send and commit
+   //////
+
+   ////////
+   //////// Non-reliable message
+   ////////
+
+   //////////
+   ////////// One message
+   //////////
+
+   public void testRecoverableChannel_5() throws Exception
+   {
+      if (!messageQueue.isRecoverable())
+      {
+         // we test only recoverable channels now
+         return;
+      }
+
+
+      // the channel has no receivers
+      assertFalse(messageQueue.iterator().hasNext());
+
+      Message m = MessageFactory.createCoreMessage(0, false, "payload");
+      SimpleDeliveryObserver observer = new SimpleDeliveryObserver();
+
+      Transaction tx = tr.createTransaction();
+
+      // transacted send, non-reliable message, one message
+      // for a transactional send, handle() return value is unspecified
+      messageQueue.handle(observer, m, tx);
+
+      // no messages in the channel yet
+      assertEquals(0, messageQueue.browse().size());
+
+      tx.commit();
+
+      List stored = messageQueue.browse();
+      assertEquals(1, stored.size());
+
+      Message sm = (Message)stored.iterator().next();
+      assertFalse(sm.isReliable());
+      assertEquals(0, sm.getMessageID());
+   }
+
+   //////////
+   ////////// Multiple message
+   //////////
+
+   public void testRecoverableChannel_6() throws Exception
+   {
+      if (!messageQueue.isRecoverable())
+      {
+         // we test only recoverable channels now
+         return;
+      }
+
+      // the channel has no receivers
+      assertFalse(messageQueue.iterator().hasNext());
+
+      SimpleDeliveryObserver observer = new SimpleDeliveryObserver();
+
+      Transaction tx = tr.createTransaction();
+
+      Message[] messages = new Message[NUMBER_OF_MESSAGES];
+      for(int i = 0; i < NUMBER_OF_MESSAGES; i++)
+      {
+         messages[i] = MessageFactory.createCoreMessage(i, false, "payload" + i);
+
+         // transacted send, non-reliable message, multiple messages
+         // for a transactional send, handle() return value is unspecified
+         messageQueue.handle(observer, messages[i], tx);
+      }
+
+      // no messages in the channel yet
+      assertEquals(0, messageQueue.browse().size());
+
+      tx.commit();
+
+      assertEqualSets(messages, messageQueue.browse());
+   }
+
+   ////////
+   //////// Reliable message
+   ////////
+
+   //////////
+   ////////// One message
+   //////////
+
+   public void testRecoverableChannel_7() throws Exception
+   {
+      if (!messageQueue.isRecoverable())
+      {
+         // we test only recoverable channels now
+         return;
+      }
+
+      // the channel has no receivers
+      assertFalse(messageQueue.iterator().hasNext());
+
+      Message m = MessageFactory.createCoreMessage(0, true, "payload");
+      SimpleDeliveryObserver observer = new SimpleDeliveryObserver();
+
+      Transaction tx = tr.createTransaction();
+
+      // transacted send, reliable message, one message
+      // for a transactional send, handle() return value is unspecified
+      messageQueue.handle(observer, m, tx);
+
+      // no messages in the channel yet
+      assertEquals(0, messageQueue.browse().size());
+
+      tx.commit();
+
+      List stored = messageQueue.browse();
+      assertEquals(1, stored.size());
+
+      Message sm = (Message)stored.iterator().next();
+      assertTrue(sm.isReliable());
+      assertEquals(0, sm.getMessageID());
+   }
+
+   //////////
+   ////////// Multiple message
+   //////////
+
+   public void testRecoverableChannel_8() throws Exception
+   {
+      if (!messageQueue.isRecoverable())
+      {
+         // we test only recoverable channels now
+         return;
+      }
+
+
+      // the channel has no receivers
+      assertFalse(messageQueue.iterator().hasNext());
+
+      SimpleDeliveryObserver observer = new SimpleDeliveryObserver();
+
+      Transaction tx = tr.createTransaction();
+
+      Message[] messages = new Message[NUMBER_OF_MESSAGES];
+      for(int i = 0; i < NUMBER_OF_MESSAGES; i++)
+      {
+         messages[i] = MessageFactory.createCoreMessage(i, true, "payload" + i);
+
+         // transacted send, reliable message, multiple messages
+         // for a transactional send, handle() return value is unspecified
+         messageQueue.handle(observer, messages[i], tx);
+      }
+
+      // no messages in the channel yet
+      assertEquals(0, messageQueue.browse().size());
+
+      tx.commit();
+
+      assertEqualSets(messages, messageQueue.browse());
+   }
+
+   /**
+    * This is a variation where I send a mixture of reliable and non-reliable messages,
+    */
+   public void testRecoverableChannel_8_mixed() throws Exception
+   {
+      if (!messageQueue.isRecoverable())
+      {
+         // we test only recoverable channels now
+         return;
+      }
+
+
+      // the channel has no receivers
+      assertFalse(messageQueue.iterator().hasNext());
+
+      SimpleDeliveryObserver observer = new SimpleDeliveryObserver();
+
+      Transaction tx = tr.createTransaction();
+
+      Message[] messages = new Message[NUMBER_OF_MESSAGES];
+      for(int i = 0; i < NUMBER_OF_MESSAGES; i++)
+      {
+         // send a mixture of reliable and non-reliable messages
+         messages[i] = MessageFactory.createCoreMessage(i, (i % 2 == 1), "payload" + i);
+
+         // transacted send, reliable/non-reliable messages, multiple messages
+         // for a transactional send, handle() return value is unspecified
+         messageQueue.handle(observer, messages[i], tx);
+      }
+
+      // no messages in the channel yet
+      assertEquals(0, messageQueue.browse().size());
+
+      tx.commit();
+
+      assertEqualSets(messages, messageQueue.browse());
+   }
+
+
+   //////
+   ////// Transacted send and rollback
+   //////
+
+   ////////
+   //////// Non-reliable message
+   ////////
+
+   //////////
+   ////////// One message
+   //////////
+
+   public void testRecoverableChannel_9() throws Exception
+   {
+      if (!messageQueue.isRecoverable())
+      {
+         // we test only recoverable channels now
+         return;
+      }
+
+      // the channel has no receivers
+      assertFalse(messageQueue.iterator().hasNext());
+
+      Message m = MessageFactory.createCoreMessage(0, false, "payload");
+      SimpleDeliveryObserver observer = new SimpleDeliveryObserver();
+
+      Transaction tx = tr.createTransaction();
+
+      // transacted send, non-reliable message, one message
+      // for a transactional send, handle() return value is unspecified
+      messageQueue.handle(observer, m, tx);
+
+      // no messages in the channel yet
+      assertEquals(0, messageQueue.browse().size());
+
+      tx.rollback();
+
+      // still no messages in the channel
+      assertEquals(0, messageQueue.browse().size());
+   }
+
+   //////////
+   ////////// Multiple message
+   //////////
+
+   public void testRecoverableChannel_10() throws Exception
+   {
+      if (!messageQueue.isRecoverable())
+      {
+         // we test only recoverable channels now
+         return;
+      }
+
+      // the channel has no receivers
+      assertFalse(messageQueue.iterator().hasNext());
+
+      SimpleDeliveryObserver observer = new SimpleDeliveryObserver();
+
+      Transaction tx = tr.createTransaction();
+
+      Message[] messages = new Message[NUMBER_OF_MESSAGES];
+      for(int i = 0; i < NUMBER_OF_MESSAGES; i++)
+      {
+         messages[i] = MessageFactory.createCoreMessage(i, false, "payload" + i);
+
+         // transacted send, non-reliable message, multiple messages
+         // for a transactional send, handle() return value is unspecified
+         messageQueue.handle(observer, messages[i], tx);
+      }
+
+      // no messages in the channel yet
+      assertEquals(0, messageQueue.browse().size());
+
+      tx.rollback();
+
+      // still no messages in the channel
+      assertEquals(0, messageQueue.browse().size());
+   }
+
+   ////////
+   //////// Reliable message
+   ////////
+
+   //////////
+   ////////// One message
+   //////////
+
+   public void testRecoverableChannel_11() throws Exception
+   {
+      if (!messageQueue.isRecoverable())
+      {
+         // we test only recoverable channels now
+         return;
+      }
+
+      // the channel has no receivers
+      assertFalse(messageQueue.iterator().hasNext());
+
+      Message m = MessageFactory.createCoreMessage(0, true, "payload");
+      SimpleDeliveryObserver observer = new SimpleDeliveryObserver();
+
+      Transaction tx = tr.createTransaction();
+
+      // transacted send, reliable message, one message
+      // for a transactional send, handle() return value is unspecified
+      messageQueue.handle(observer, m, tx);
+
+      // no messages in the channel yet
+      assertEquals(0, messageQueue.browse().size());
+
+      tx.rollback();
+
+      // still no messages in the channel
+      assertEquals(0, messageQueue.browse().size());
+   }
+
+   //////////
+   ////////// Multiple message
+   //////////
+
+   public void testRecoverableChannel_12() throws Exception
+   {
+      if (!messageQueue.isRecoverable())
+      {
+         // we test only recoverable channels now
+         return;
+      }
+
+      // the channel has no receivers
+      assertFalse(messageQueue.iterator().hasNext());
+
+      SimpleDeliveryObserver observer = new SimpleDeliveryObserver();
+
+      Transaction tx = tr.createTransaction();
+
+      Message[] messages = new Message[NUMBER_OF_MESSAGES];
+      for(int i = 0; i < NUMBER_OF_MESSAGES; i++)
+      {
+         messages[i] = MessageFactory.createCoreMessage(i, true, "payload" + i);
+
+         // transacted send, reliable message, multiple messages
+         // for a transactional send, handle() return value is unspecified
+         messageQueue.handle(observer, messages[i], tx);
+      }
+
+      // no messages in the channel yet
+      assertEquals(0, messageQueue.browse().size());
+
+      tx.rollback();
+
+      // still no messages in the channel
+      assertEquals(0, messageQueue.browse().size());
+   }
+
+   /**
+    * This is a variation where I send a mixture of reliable and non-reliable messages,
+    */
+   public void testRecoverableChannel_12_mixed() throws Exception
+   {
+      if (!messageQueue.isRecoverable())
+      {
+         // we test only recoverable channels now
+         return;
+      }
+
+
+      // the channel has no receivers
+      assertFalse(messageQueue.iterator().hasNext());
+
+      SimpleDeliveryObserver observer = new SimpleDeliveryObserver();
+
+      Transaction tx = tr.createTransaction();
+
+      Message[] messages = new Message[NUMBER_OF_MESSAGES];
+      for(int i = 0; i < NUMBER_OF_MESSAGES; i++)
+      {
+         // send a mixture of reliable and non-reliable messages
+         messages[i] = MessageFactory.createCoreMessage(i, (i % 2 == 1), "payload" + i);
+
+         // transacted send, reliable/non-reliable messages, multiple messages
+         // for a transactional send, handle() return value is unspecified
+         messageQueue.handle(observer, messages[i], tx);
+      }
+
+      // no messages in the channel yet
+      assertEquals(0, messageQueue.browse().size());
+
+      tx.rollback();
+
+      // still no messages in the channel
+      assertEquals(0, messageQueue.browse().size());
+   }
+
+   ////
+   //// One receiver
+   ////
+
+   //////
+   ////// ACKING receiver
+   //////
+
+   //////
+   ////// Non-transacted send
+   //////
+
+   ////////
+   //////// Non-reliable message
+   ////////
+
+   //////////
+   ////////// One message
+   //////////
+
+   public void testRecoverableChannel_13() throws Exception
+   {
+      if (!messageQueue.isRecoverable())
+      {
+         // we test only recoverable channels now
+         return;
+      }
+
+      // add an ACKING receiver to the channel
+      SimpleReceiver r = new SimpleReceiver("AckingReceiver", SimpleReceiver.ACKING);
+      assertTrue(messageQueue.add(r));
+
+      Message m = MessageFactory.createCoreMessage(0, false, "payload");
+      SimpleDeliveryObserver observer = new SimpleDeliveryObserver();
+
+      // non-transacted send, non-reliable message, one message
+      Delivery delivery = messageQueue.handle(observer, m, null);
+
+      assertTrue(delivery.isDone());
+      assertTrue(messageQueue.browse().isEmpty());
+
+      List received = r.getMessages();
+      assertEquals(1, received.size());
+      Message sm = (Message)received.iterator().next();
+      assertFalse(sm.isReliable());
+      assertEquals(0, sm.getMessageID());
+   }
+
+   //////////
+   ////////// Multiple message
+   //////////
+
+   public void testRecoverableChannel_14() throws Exception
+   {
+      if (!messageQueue.isRecoverable())
+      {
+         // we test only recoverable channels now
+         return;
+      }
+
+      // add an ACKING receiver to the channel
+      SimpleReceiver r = new SimpleReceiver("AckingReceiver", SimpleReceiver.ACKING);
+      assertTrue(messageQueue.add(r));
+
+      SimpleDeliveryObserver observer = new SimpleDeliveryObserver();
+
+      Message[] messages = new Message[NUMBER_OF_MESSAGES];
+      for(int i = 0; i < NUMBER_OF_MESSAGES; i++)
+      {
+         messages[i] = MessageFactory.createCoreMessage(i, false, "payload" + i);
+
+         // non-transacted send, non-reliable message, multiple messages
+         Delivery delivery = messageQueue.handle(observer, messages[i], null);
+
+         assertTrue(delivery.isDone());
+      }
+
+      assertTrue(messageQueue.browse().isEmpty());
+
+      List received = r.getMessages();
+      assertEqualSets(messages, received);
+   }
+
+   ////////
+   //////// Reliable message
+   ////////
+
+   //////////
+   ////////// One message
+   //////////
+
+   public void testRecoverableChannel_15() throws Exception
+   {
+      if (!messageQueue.isRecoverable())
+      {
+         // we test only recoverable channels now
+         return;
+      }
+
+
+      // add an ACKING receiver to the channel
+      SimpleReceiver r = new SimpleReceiver("AckingReceiver", SimpleReceiver.ACKING);
+      assertTrue(messageQueue.add(r));
+
+      Message m = MessageFactory.createCoreMessage(0, true, "payload");
+      SimpleDeliveryObserver observer = new SimpleDeliveryObserver();
+
+      // non-transacted send, reliable message, one message
+      Delivery delivery = messageQueue.handle(observer, m, null);
+
+      assertTrue(delivery.isDone());
+
+      assertTrue(messageQueue.browse().isEmpty());
+
+      List received = r.getMessages();
+      assertEquals(1, received.size());
+      Message sm = (Message)received.iterator().next();
+      assertTrue(sm.isReliable());
+      assertEquals(0, sm.getMessageID());
+   }
+
+   //////////
+   ////////// Multiple message
+   //////////
+
+   public void testRecoverableChannel_16() throws Exception
+   {
+      if (!messageQueue.isRecoverable())
+      {
+         // we test only recoverable channels now
+         return;
+      }
+
+      // add an ACKING receiver to the channel
+      SimpleReceiver r = new SimpleReceiver("AckingReceiver", SimpleReceiver.ACKING);
+      assertTrue(messageQueue.add(r));
+
+      SimpleDeliveryObserver observer = new SimpleDeliveryObserver();
+
+      Message[] messages = new Message[NUMBER_OF_MESSAGES];
+      for(int i = 0; i < NUMBER_OF_MESSAGES; i++)
+      {
+         messages[i] = MessageFactory.createCoreMessage(i, true, "payload" + i);
+
+         // non-transacted send, reliable message, multiple messages
+         Delivery delivery = messageQueue.handle(observer, messages[i], null);
+
+         assertTrue(delivery.isDone());
+      }
+
+      assertTrue(messageQueue.browse().isEmpty());
+      assertEqualSets(messages, r.getMessages());
+   }
+
+   //////
+   ////// Transacted send and commit
+   //////
+
+   ////////
+   //////// Non-reliable message
+   ////////
+
+   //////////
+   ////////// One message
+   //////////
+
+   public void testRecoverableChannel_17() throws Exception
+   {
+      if (!messageQueue.isRecoverable())
+      {
+         // we test only recoverable channels now
+         return;
+      }
+
+      // add an ACKING receiver to the channel
+      SimpleReceiver r = new SimpleReceiver("AckingReceiver", SimpleReceiver.ACKING);
+      assertTrue(messageQueue.add(r));
+
+      Message m = MessageFactory.createCoreMessage(0, false, "payload");
+      SimpleDeliveryObserver observer = new SimpleDeliveryObserver();
+
+      Transaction tx = tr.createTransaction();
+
+      // transacted send, non-reliable message, one message
+      // for a transactional send, handle() return value is unspecified
+      messageQueue.handle(observer, m, tx);
+
+      // no messages in the channel
+      assertEquals(0, messageQueue.browse().size());
+
+      // no message at the receiver
+      assertTrue(r.getMessages().isEmpty());
+
+      tx.commit();
+
+      assertTrue(messageQueue.browse().isEmpty());
+
+      List received = r.getMessages();
+      assertEquals(1, received.size());
+      Message sm = (Message)received.iterator().next();
+      assertFalse(sm.isReliable());
+      assertEquals(0, sm.getMessageID());
+   }
+
+
+   public void testRecoverableChannel_17_1() throws Exception
+   {
+      if (!messageQueue.isRecoverable())
+      {
+         // we test only recoverable channels now
+         return;
+      }
+
+      BrokenReceiver brokenReceiver = new BrokenReceiver(2);
+      assertTrue(messageQueue.add(brokenReceiver));
+
+      Message m = MessageFactory.createCoreMessage(0, false, "payload");
+      SimpleDeliveryObserver observer = new SimpleDeliveryObserver();
+
+      Transaction tx = tr.createTransaction();
+
+
+      log.debug("sending message 1");
+
+      // transacted send, non-reliable message, one message
+      // for a transactional send, handle() return value is unspecified
+      messageQueue.handle(observer, m, tx);
+
+      m = MessageFactory.createCoreMessage(1, false, "payload");
+
+      log.debug("sending message 2");
+      messageQueue.handle(observer, m, tx);
+
+      m = MessageFactory.createCoreMessage(2, false, "payload");
+
+      log.debug("sending message 3");
+      messageQueue.handle(observer, m, tx);
+
+      // no messages in the channel
+      assertEquals(0, messageQueue.browse().size());
+
+      tx.commit();
+
+      assertEquals(2, messageQueue.browse().size());
+      assertEquals(1, brokenReceiver.getMessages().size());
+   }
+
+
+   //////////
+   ////////// Multiple message
+   //////////
+
+   public void testRecoverableChannel_18() throws Exception
+   {
+      if (!messageQueue.isRecoverable())
+      {
+         // we test only recoverable channels now
+         return;
+      }
+
+      // add an ACKING receiver to the channel
+      SimpleReceiver r = new SimpleReceiver("AckingReceiver", SimpleReceiver.ACKING);
+      assertTrue(messageQueue.add(r));
+
+      SimpleDeliveryObserver observer = new SimpleDeliveryObserver();
+
+      Transaction tx = tr.createTransaction();
+
+      Message[] messages = new Message[NUMBER_OF_MESSAGES];
+      for(int i = 0; i < NUMBER_OF_MESSAGES; i++)
+      {
+         messages[i] = MessageFactory.createCoreMessage(i, false, "payload" + i);
+
+         // transacted send, non-reliable message, multiple messages
+         // for a transactional send, handle() return value is unspecified
+         messageQueue.handle(observer, messages[i], tx);
+      }
+
+      // no messages in the channel
+      assertEquals(0, messageQueue.browse().size());
+
+      // no message at the receiver
+      assertTrue(r.getMessages().isEmpty());
+
+      tx.commit();
+
+      assertTrue(messageQueue.browse().isEmpty());
+      assertEqualSets(messages, r.getMessages());
+   }
+
+   ////////
+   //////// Reliable message
+   ////////
+
+   //////////
+   ////////// One message
+   //////////
+
+   public void testRecoverableChannel_19() throws Exception
+   {
+      if (!messageQueue.isRecoverable())
+      {
+         // we test only recoverable channels now
+         return;
+      }
+
+      // add an ACKING receiver to the channel
+      SimpleReceiver r = new SimpleReceiver("AckingReceiver", SimpleReceiver.ACKING);
+      assertTrue(messageQueue.add(r));
+
+
+      Message m = MessageFactory.createCoreMessage(0, true, "payload");
+      SimpleDeliveryObserver observer = new SimpleDeliveryObserver();
+
+      Transaction tx = tr.createTransaction();
+
+      // transacted send, reliable message, one message
+      // for a transactional send, handle() return value is unspecified
+      messageQueue.handle(observer, m, tx);
+
+      // no messages in the channel yet
+      assertEquals(0, messageQueue.browse().size());
+
+      // no message at the receiver
+      assertTrue(r.getMessages().isEmpty());
+
+      tx.commit();
+
+      // no messages in the channel
+      assertEquals(0, messageQueue.browse().size());
+
+      List received = r.getMessages();
+      assertEquals(1, received.size());
+      Message sm = (Message)received.iterator().next();
+      assertTrue(sm.isReliable());
+      assertEquals(0, sm.getMessageID());
+   }
+
+   //////////
+   ////////// Multiple message
+   //////////
+
+   public void testRecoverableChannel_20() throws Exception
+   {
+      if (!messageQueue.isRecoverable())
+      {
+         // we test only recoverable channels now
+         return;
+      }
+
+
+      // add an ACKING receiver to the channel
+      SimpleReceiver r = new SimpleReceiver("AckingReceiver", SimpleReceiver.ACKING);
+      assertTrue(messageQueue.add(r));
+
+      SimpleDeliveryObserver observer = new SimpleDeliveryObserver();
+
+      Transaction tx = tr.createTransaction();
+
+      Message[] messages = new Message[NUMBER_OF_MESSAGES];
+      for(int i = 0; i < NUMBER_OF_MESSAGES; i++)
+      {
+         messages[i] = MessageFactory.createCoreMessage(i, true, "payload" + i);
+
+         // transacted send, reliable message, multiple messages
+         // for a transactional send, handle() return value is unspecified
+         messageQueue.handle(observer, messages[i], tx);
+      }
+
+      // no messages in the channel yet
+      assertEquals(0, messageQueue.browse().size());
+
+      // no message at the receiver
+      assertTrue(r.getMessages().isEmpty());
+
+      tx.commit();
+
+      // no messages in the channel
+      assertEquals(0, messageQueue.browse().size());
+
+      assertEqualSets(messages, r.getMessages());
+   }
+
+   /**
+    * This is a variation where I send a mixture of reliable and non-reliable messages,
+    */
+   public void testRecoverableChannel_20_mixed() throws Exception
+   {
+      if (!messageQueue.isRecoverable())
+      {
+         // we test only recoverable channels now
+         return;
+      }
+
+
+      // add an ACKING receiver to the channel
+      SimpleReceiver r = new SimpleReceiver("AckingReceiver", SimpleReceiver.ACKING);
+      assertTrue(messageQueue.add(r));
+
+
+      SimpleDeliveryObserver observer = new SimpleDeliveryObserver();
+
+      Transaction tx = tr.createTransaction();
+
+      Message[] messages = new Message[NUMBER_OF_MESSAGES];
+      for(int i = 0; i < NUMBER_OF_MESSAGES; i++)
+      {
+         // send a mixture of reliable and non-reliable messages
+         messages[i] = MessageFactory.createCoreMessage(i, (i % 2 == 1), "payload" + i);
+
+         // transacted send, reliable/non-reliable messages, multiple messages
+         // for a transactional send, handle() return value is unspecified
+         messageQueue.handle(observer, messages[i], tx);
+      }
+
+      // no messages in the channel
+      assertEquals(0, messageQueue.browse().size());
+
+      // no message at the receiver
+      assertTrue(r.getMessages().isEmpty());
+
+      tx.commit();
+
+      // no messages in the channel
+      assertEquals(0, messageQueue.browse().size());
+
+      assertEqualSets(messages, r.getMessages());
+   }
+
+
+   //////
+   ////// Transacted send and rollback
+   //////
+
+   ////////
+   //////// Non-reliable message
+   ////////
+
+   //////////
+   ////////// One message
+   //////////
+
+   public void testRecoverableChannel_21() throws Exception
+   {
+      if (!messageQueue.isRecoverable())
+      {
+         // we test only recoverable channels now
+         return;
+      }
+
+      // add an ACKING receiver to the channel
+      SimpleReceiver r = new SimpleReceiver("AckingReceiver", SimpleReceiver.ACKING);
+      assertTrue(messageQueue.add(r));
+
+
+      Message m = MessageFactory.createCoreMessage(0, false, "payload");
+      SimpleDeliveryObserver observer = new SimpleDeliveryObserver();
+
+      Transaction tx = tr.createTransaction();
+
+      // transacted send, non-reliable message, one message
+      // for a transactional send, handle() return value is unspecified
+      messageQueue.handle(observer, m, tx);
+
+      // no messages in the channel
+      assertEquals(0, messageQueue.browse().size());
+
+      // no message at the receiver
+      assertTrue(r.getMessages().isEmpty());
+
+
+      tx.rollback();
+
+      // no messages in the channel
+      assertEquals(0, messageQueue.browse().size());
+
+      // no message at the receiver
+      assertTrue(r.getMessages().isEmpty());
+
+   }
+
+   //////////
+   ////////// Multiple message
+   //////////
+
+   public void testRecoverableChannel_22() throws Exception
+   {
+      if (!messageQueue.isRecoverable())
+      {
+         // we test only recoverable channels now
+         return;
+      }
+
+
+      // add an ACKING receiver to the channel
+      SimpleReceiver r = new SimpleReceiver("AckingReceiver", SimpleReceiver.ACKING);
+      assertTrue(messageQueue.add(r));
+
+      SimpleDeliveryObserver observer = new SimpleDeliveryObserver();
+
+      Transaction tx = tr.createTransaction();
+
+      Message[] messages = new Message[NUMBER_OF_MESSAGES];
+      for(int i = 0; i < NUMBER_OF_MESSAGES; i++)
+      {
+         messages[i] = MessageFactory.createCoreMessage(i, false, "payload" + i);
+
+         // transacted send, non-reliable message, multiple messages
+         // for a transactional send, handle() return value is unspecified
+         messageQueue.handle(observer, messages[i], tx);
+      }
+
+      // no messages in the channel
+      assertEquals(0, messageQueue.browse().size());
+
+      // no message at the receiver
+      assertTrue(r.getMessages().isEmpty());
+
+      tx.rollback();
+
+      // no messages in the channel
+      assertEquals(0, messageQueue.browse().size());
+
+      // no message at the receiver
+      assertTrue(r.getMessages().isEmpty());
+   }
+
+   ////////
+   //////// Reliable message
+   ////////
+
+   //////////
+   ////////// One message
+   //////////
+
+   public void testRecoverableChannel_23() throws Exception
+   {
+      if (!messageQueue.isRecoverable())
+      {
+         // we test only recoverable channels now
+         return;
+      }
+
+
+      // add an ACKING receiver to the channel
+      SimpleReceiver r = new SimpleReceiver("AckingReceiver", SimpleReceiver.ACKING);
+      assertTrue(messageQueue.add(r));
+
+
+      Message m = MessageFactory.createCoreMessage(0, true, "payload");
+      SimpleDeliveryObserver observer = new SimpleDeliveryObserver();
+
+      Transaction tx = tr.createTransaction();
+
+      // transacted send, reliable message, one message
+      // for a transactional send, handle() return value is unspecified
+      messageQueue.handle(observer, m, tx);
+
+      // no messages in the channel
+      assertEquals(0, messageQueue.browse().size());
+
+      // no message at the receiver
+      assertTrue(r.getMessages().isEmpty());
+
+      tx.rollback();
+
+      // no messages in the channel
+      assertEquals(0, messageQueue.browse().size());
+
+      // no message at the receiver
+      assertTrue(r.getMessages().isEmpty());
+   }
+
+   //////////
+   ////////// Multiple message
+   //////////
+
+   public void testRecoverableChannel_24() throws Exception
+   {
+      if (!messageQueue.isRecoverable())
+      {
+         // we test only recoverable channels now
+         return;
+      }
+
+      // add an ACKING receiver to the channel
+      SimpleReceiver r = new SimpleReceiver("AckingReceiver", SimpleReceiver.ACKING);
+      assertTrue(messageQueue.add(r));
+
+
+      SimpleDeliveryObserver observer = new SimpleDeliveryObserver();
+
+      Transaction tx = tr.createTransaction();
+
+      Message[] messages = new Message[NUMBER_OF_MESSAGES];
+      for(int i = 0; i < NUMBER_OF_MESSAGES; i++)
+      {
+         messages[i] = MessageFactory.createCoreMessage(i, true, "payload" + i);
+
+         // transacted send, reliable message, multiple messages
+         // for a transactional send, handle() return value is unspecified
+         messageQueue.handle(observer, messages[i], tx);
+      }
+
+      // no messages in the channel
+      assertEquals(0, messageQueue.browse().size());
+
+      // no message at the receiver
+      assertTrue(r.getMessages().isEmpty());
+
+      tx.rollback();
+
+      // no messages in the channel
+      assertEquals(0, messageQueue.browse().size());
+
+      // no message at the receiver
+      assertTrue(r.getMessages().isEmpty());
+   }
+
+   /**
+    * This is a variation where I send a mixture of reliable and non-reliable messages,
+    */
+   public void testRecoverableChannel_24_mixed() throws Exception
+   {
+      if (!messageQueue.isRecoverable())
+      {
+         // we test only recoverable channels now
+         return;
+      }
+
+
+      // add an ACKING receiver to the channel
+      SimpleReceiver r = new SimpleReceiver("AckingReceiver", SimpleReceiver.ACKING);
+      assertTrue(messageQueue.add(r));
+
+
+      SimpleDeliveryObserver observer = new SimpleDeliveryObserver();
+
+      Transaction tx = tr.createTransaction();
+
+      Message[] messages = new Message[NUMBER_OF_MESSAGES];
+      for(int i = 0; i < NUMBER_OF_MESSAGES; i++)
+      {
+         // send a mixture of reliable and non-reliable messages
+         messages[i] = MessageFactory.createCoreMessage(i, (i % 2 == 1), "payload" + i);
+
+         // transacted send, reliable/non-reliable messages, multiple messages
+         // for a transactional send, handle() return value is unspecified
+         messageQueue.handle(observer, messages[i], tx);
+      }
+
+      // no messages in the channel
+      assertEquals(0, messageQueue.browse().size());
+
+      // no message at the receiver
+      assertTrue(r.getMessages().isEmpty());
+
+      tx.rollback();
+
+      // no messages in the channel
+      assertEquals(0, messageQueue.browse().size());
+
+      // no message at the receiver
+      assertTrue(r.getMessages().isEmpty());
+   }
+
+   //////
+   ////// NACKING receiver
+   //////
+
+   //////
+   ////// Non-transacted send
+   //////
+
+   ////////
+   //////// Non-reliable message
+   ////////
+
+   //////////
+   ////////// One message
+   //////////
+
+   ////////////
+   //////////// Non-transacted acknowledgment
+   ////////////
+
+   public void testRecoverableChannel_25() throws Throwable
+   {
+      if (!messageQueue.isRecoverable())
+      {
+         // we test only recoverable channels now
+         return;
+      }
+
+      // add an NACKING receiver to the channel
+      SimpleReceiver r = new SimpleReceiver("NackingReceiver", SimpleReceiver.NACKING);
+      assertTrue(messageQueue.add(r));
+
+      Message m = MessageFactory.createCoreMessage(0, false, "payload");
+      SimpleDeliveryObserver observer = new SimpleDeliveryObserver();
+
+      // non-transacted send, non-reliable message, one message
+      Delivery delivery = messageQueue.handle(observer, m, null);
+
+      assertTrue(delivery.isDone());
+
+      List delivering = messageQueue.browse();
+      assertEquals(1, delivering.size());
+      assertEquals(0, ((Message)delivering.get(0)).getMessageID());
+
+      List acknowledging = r.getMessages();
+      assertEquals(1, acknowledging.size());
+      Message ackm = (Message)acknowledging.get(0);
+      assertEquals(0, ackm.getMessageID());
+
+      // non-transacted acknowledgment
+      r.acknowledge(ackm, null);
+
+      assertTrue(messageQueue.browse().isEmpty());
+   }
+
+   /**
+    * The same test as before, but with a Receiver configured to acknowledge immediately
+    * on the Delivery. Simulates a race condition in which the acknoledgment arrives before
+    * the Delivery is returned to channel.
+    *
+    * @throws Throwable
+    */
+   public void testRecoverableChannel_25_race() throws Throwable
+   {
+      if (!messageQueue.isRecoverable())
+      {
+         // we test only recoverable channels now
+         return;
+      }
+
+      // add an NACKING receiver to the channel
+      SimpleReceiver r = new SimpleReceiver("NackingReceiver", SimpleReceiver.NACKING);
+      r.setImmediateAsynchronousAcknowledgment(true);
+      assertTrue(messageQueue.add(r));
+
+      Message m = MessageFactory.createCoreMessage(0, false, "payload");
+      SimpleDeliveryObserver observer = new SimpleDeliveryObserver();
+
+      // non-transacted send, non-reliable message, one message
+      Delivery delivery = messageQueue.handle(observer, m, null);
+
+      assertTrue(delivery.isDone());
+
+      // the receiver should have returned a "done" delivery
+      assertTrue(messageQueue.browse().isEmpty());
+
+      List messages = r.getMessages();
+      assertEquals(1, messages.size());
+      Message ackm = (Message)messages.get(0);
+      assertEquals(0, ackm.getMessageID());
+
+      // an extra acknowledgment should be discarded
+      r.acknowledge(ackm, null);
+
+      assertTrue(messageQueue.browse().isEmpty());
+   }
+
+
+   ////////////
+   //////////// Transacted acknowledgment and commit
+   ////////////
+
+   public void testRecoverableChannel_25_1() throws Throwable
+   {
+      if (!messageQueue.isRecoverable())
+      {
+         // we test only recoverable channels now
+         return;
+      }
+
+      // add an NACKING receiver to the channel
+      SimpleReceiver r = new SimpleReceiver("NackingReceiver", SimpleReceiver.NACKING);
+      assertTrue(messageQueue.add(r));
+
+      Message m = MessageFactory.createCoreMessage(0, false, "payload");
+      SimpleDeliveryObserver observer = new SimpleDeliveryObserver();
+
+      // non-transacted send, non-reliable message, one message
+      Delivery delivery = messageQueue.handle(observer, m, null);
+
+      assertTrue(delivery.isDone());
+
+      List delivering = messageQueue.browse();
+      assertEquals(1, delivering.size());
+      assertEquals(0, ((Message)delivering.get(0)).getMessageID());
+
+      List acknowledging = r.getMessages();
+      assertEquals(1, acknowledging.size());
+      Message ackm = (Message)acknowledging.get(0);
+      assertEquals(0, ackm.getMessageID());
+
+      Transaction tx = tr.createTransaction();
+
+      // transacted acknowledgment
+      r.acknowledge(ackm, tx);
+
+      delivering = messageQueue.browse();
+      assertEquals(1, delivering.size());
+      assertEquals(0, ((Message)delivering.get(0)).getMessageID());
+
+      tx.commit();
+
+      assertTrue(messageQueue.browse().isEmpty());
+   }
+
+
+   ////////////
+   //////////// Transacted acknowledgment and rollback
+   ////////////
+
+   public void testRecoverableChannel_25_2() throws Throwable
+   {
+      if (!messageQueue.isRecoverable())
+      {
+         // we test only recoverable channels now
+         return;
+      }
+
+      // add an NACKING receiver to the channel
+      SimpleReceiver r = new SimpleReceiver("NackingReceiver", SimpleReceiver.NACKING);
+      assertTrue(messageQueue.add(r));
+
+      Message m = MessageFactory.createCoreMessage(0, false, "payload");
+      SimpleDeliveryObserver observer = new SimpleDeliveryObserver();
+
+      // non-transacted send, non-reliable message, one message
+      Delivery delivery = messageQueue.handle(observer, m, null);
+
+      assertTrue(delivery.isDone());
+
+      List delivering = messageQueue.browse();
+      assertEquals(1, delivering.size());
+      assertEquals(0, ((Message)delivering.get(0)).getMessageID());
+
+      List acknowledging = r.getMessages();
+      assertEquals(1, acknowledging.size());
+      Message ackm = (Message)acknowledging.get(0);
+      assertEquals(0, ackm.getMessageID());
+
+      Transaction tx = tr.createTransaction();
+
+      // transacted acknowledgment
+      r.acknowledge(ackm, tx);
+
+      delivering = messageQueue.browse();
+      assertEquals(1, delivering.size());
+      assertEquals(0, ((Message)delivering.get(0)).getMessageID());
+
+      tx.rollback();
+
+      delivering = messageQueue.browse();
+      assertEquals(1, delivering.size());
+      assertEquals(0, ((Message)delivering.get(0)).getMessageID());
+
+      // acknowledge non-transactionally
+      r.acknowledge(ackm, null);
+
+      assertTrue(messageQueue.browse().isEmpty());
+   }
+
+
+   //////////
+   ////////// Multiple message
+   //////////
+
+   ////////////
+   //////////// Non-transacted acknowledgment
+   ////////////
+
+   public void testRecoverableChannel_26() throws Throwable
+   {
+      if (!messageQueue.isRecoverable())
+      {
+         // we test only recoverable channels now
+         return;
+      }
+
+      // add an NACKING receiver to the channel
+      SimpleReceiver r = new SimpleReceiver("NackingReceiver", SimpleReceiver.NACKING);
+      assertTrue(messageQueue.add(r));
+
+      SimpleDeliveryObserver observer = new SimpleDeliveryObserver();
+
+      Message[] messages = new Message[NUMBER_OF_MESSAGES];
+      for(int i = 0; i < NUMBER_OF_MESSAGES; i++)
+      {
+         messages[i] = MessageFactory.createCoreMessage(i, false, "payload" + i);
+
+         // non-transacted send, non-reliable message, multiple messages
+         Delivery delivery = messageQueue.handle(observer, messages[i], null);
+
+         assertTrue(delivery.isDone());
+      }
+
+      assertEqualSets(messages, messageQueue.browse());
+      assertEqualSets(messages, r.getMessages());
+
+      for(Iterator i = r.getMessages().iterator(); i.hasNext();)
+      {
+         Message ackm = (Message)i.next();
+         // non-transacted acknowledgment
+         r.acknowledge(ackm, null);
+      }
+
+      assertTrue(messageQueue.browse().isEmpty());
+
+   }
+
+   ////////////
+   //////////// Transacted acknowledgment and commit
+   ////////////
+
+   public void testRecoverableChannel_26_1() throws Throwable
+   {
+      if (!messageQueue.isRecoverable())
+      {
+         // we test only recoverable channels now
+         return;
+      }
+
+      // add an NACKING receiver to the channel
+      SimpleReceiver r = new SimpleReceiver("NackingReceiver", SimpleReceiver.NACKING);
+      assertTrue(messageQueue.add(r));
+
+      SimpleDeliveryObserver observer = new SimpleDeliveryObserver();
+
+      Message[] messages = new Message[NUMBER_OF_MESSAGES];
+      for(int i = 0; i < NUMBER_OF_MESSAGES; i++)
+      {
+         messages[i] = MessageFactory.createCoreMessage(i, false, "payload" + i);
+
+         // non-transacted send, non-reliable message, multiple messages
+         Delivery delivery = messageQueue.handle(observer, messages[i], null);
+
+         assertTrue(delivery.isDone());
+      }
+
+      assertEqualSets(messages, messageQueue.browse());
+      assertEqualSets(messages, r.getMessages());
+
+      Transaction tx = tr.createTransaction();
+
+      for(Iterator i = r.getMessages().iterator(); i.hasNext();)
+      {
+         Message ackm = (Message)i.next();
+         // transacted acknowledgment
+         r.acknowledge(ackm, tx);
+      }
+
+      assertEqualSets(messages, messageQueue.browse());
+
+      tx.commit();
+
+      assertTrue(messageQueue.browse().isEmpty());
+   }
+
+
+   ////////////
+   //////////// Transacted acknowledgment and rollback
+   ////////////
+
+   public void testRecoverableChannel_26_2() throws Throwable
+   {
+      if (!messageQueue.isRecoverable())
+      {
+         // we test only recoverable channels now
+         return;
+      }
+
+      // add an NACKING receiver to the channel
+      SimpleReceiver r = new SimpleReceiver("NackingReceiver", SimpleReceiver.NACKING);
+      assertTrue(messageQueue.add(r));
+
+      SimpleDeliveryObserver observer = new SimpleDeliveryObserver();
+
+      Message[] messages = new Message[NUMBER_OF_MESSAGES];
+      for(int i = 0; i < NUMBER_OF_MESSAGES; i++)
+      {
+         messages[i] = MessageFactory.createCoreMessage(i, false, "payload" + i);
+
+         // non-transacted send, non-reliable message, multiple messages
+         Delivery delivery = messageQueue.handle(observer, messages[i], null);
+
+         assertTrue(delivery.isDone());
+      }
+
+      assertEqualSets(messages, messageQueue.browse());
+      assertEqualSets(messages, r.getMessages());
+
+      Transaction tx = tr.createTransaction();
+
+      for(Iterator i = r.getMessages().iterator(); i.hasNext();)
+      {
+         Message ackm = (Message)i.next();
+         // transacted acknowledgment
+         r.acknowledge(ackm, tx);
+      }
+
+      assertEqualSets(messages, messageQueue.browse());
+
+      tx.rollback();
+
+      assertEqualSets(messages, messageQueue.browse());
+
+      // acknowledge non-transactionally
+      for(Iterator i = r.getMessages().iterator(); i.hasNext();)
+      {
+         Message ackm = (Message)i.next();
+         // non-transacted acknowledgment
+         r.acknowledge(ackm, null);
+      }
+
+      assertTrue(messageQueue.browse().isEmpty());
+   }
+
+   ////////
+   //////// Reliable message
+   ////////
+
+   //////////
+   ////////// One message
+   //////////
+
+   ////////////
+   //////////// Non-transacted acknowledgment
+   ////////////
+
+   public void testRecoverableChannel_27() throws Throwable
+   {
+      if (!messageQueue.isRecoverable())
+      {
+         // we test only recoverable channels now
+         return;
+      }
+
+
+      // add an NACKING receiver to the channel
+      SimpleReceiver r = new SimpleReceiver("NackingReceiver", SimpleReceiver.NACKING);
+      assertTrue(messageQueue.add(r));
+
+      Message m = MessageFactory.createCoreMessage(0, true, "payload");
+      SimpleDeliveryObserver observer = new SimpleDeliveryObserver();
+
+      // non-transacted send, reliable message, one message
+      Delivery delivery = messageQueue.handle(observer, m, null);
+
+      assertTrue(delivery.isDone());
+
+      List delivering = messageQueue.browse();
+      assertEquals(1, delivering.size());
+      assertEquals(0, ((Message)delivering.get(0)).getMessageID());
+
+      List acknowledging = r.getMessages();
+      assertEquals(1, acknowledging.size());
+      Message ackm = (Message)acknowledging.get(0);
+      assertEquals(0, ackm.getMessageID());
+
+      // non-transacted acknowledgment
+      r.acknowledge(ackm, null);
+
+      assertTrue(messageQueue.browse().isEmpty());
+   }
+
+   /**
+    * The same test as before, but with a Receiver configured to acknowledge immediately
+    * on the Delivery. Simulates a race condition in which the acknoledgment arrives before
+    * the Delivery is returned to channel.
+    *
+    * @throws Throwable
+    */
+   public void testRecoverableChannel_27_race() throws Throwable
+   {
+      if (!messageQueue.isRecoverable())
+      {
+         // we test only recoverable channels now
+         return;
+      }
+
+      // add an NACKING receiver to the channel
+      SimpleReceiver r = new SimpleReceiver("NackingReceiver", SimpleReceiver.NACKING);
+      r.setImmediateAsynchronousAcknowledgment(true);
+      assertTrue(messageQueue.add(r));
+
+      Message m = MessageFactory.createCoreMessage(0, true, "payload");
+      SimpleDeliveryObserver observer = new SimpleDeliveryObserver();
+
+      // non-transacted send, reliable message, one message
+      Delivery delivery = messageQueue.handle(observer, m, null);
+
+      assertTrue(delivery.isDone());
+
+      // the receiver should have returned a "done" delivery
+      assertTrue(messageQueue.browse().isEmpty());
+
+      List messages = r.getMessages();
+      assertEquals(1, messages.size());
+      Message ackm = (Message)messages.get(0);
+      assertEquals(0, ackm.getMessageID());
+
+      // an extra acknowledgment should be discarded
+      r.acknowledge(ackm, null);
+
+      assertTrue(messageQueue.browse().isEmpty());
+   }
+
+
+   ////////////
+   //////////// Transacted acknowledgment and commit
+   ////////////
+
+   public void testRecoverableChannel_27_1() throws Throwable
+   {
+      if (!messageQueue.isRecoverable())
+      {
+         // we test only recoverable channels now
+         return;
+      }
+
+
+      // add an NACKING receiver to the channel
+      SimpleReceiver r = new SimpleReceiver("NackingReceiver", SimpleReceiver.NACKING);
+      assertTrue(messageQueue.add(r));
+
+      Message m = MessageFactory.createCoreMessage(0, true, "payload");
+      SimpleDeliveryObserver observer = new SimpleDeliveryObserver();
+
+      // non-transacted send, reliable message, one message
+      Delivery delivery = messageQueue.handle(observer, m, null);
+
+      assertTrue(delivery.isDone());
+
+      List delivering = messageQueue.browse();
+      assertEquals(1, delivering.size());
+      assertEquals(0, ((Message)delivering.get(0)).getMessageID());
+
+      List acknowledging = r.getMessages();
+      assertEquals(1, acknowledging.size());
+      Message ackm = (Message)acknowledging.get(0);
+      assertEquals(0, ackm.getMessageID());
+
+      Transaction tx = tr.createTransaction();
+
+      // transacted acknowledgment
+      r.acknowledge(ackm, tx);
+
+      delivering = messageQueue.browse();
+      assertEquals(1, delivering.size());
+      assertEquals(0, ((Message)delivering.get(0)).getMessageID());
+
+      tx.commit();
+
+      assertTrue(messageQueue.browse().isEmpty());
+   }
+
+
+   ////////////
+   //////////// Transacted acknowledgment and rollback
+   ////////////
+
+   public void testRecoverableChannel_27_2() throws Throwable
+   {
+      if (!messageQueue.isRecoverable())
+      {
+         // we test only recoverable channels now
+         return;
+      }
+
+
+      // add an NACKING receiver to the channel
+      SimpleReceiver r = new SimpleReceiver("NackingReceiver", SimpleReceiver.NACKING);
+      assertTrue(messageQueue.add(r));
+
+      Message m = MessageFactory.createCoreMessage(0, true, "payload");
+      SimpleDeliveryObserver observer = new SimpleDeliveryObserver();
+
+      // non-transacted send, reliable message, one message
+      Delivery delivery = messageQueue.handle(observer, m, null);
+
+      assertTrue(delivery.isDone());
+
+      List delivering = messageQueue.browse();
+      assertEquals(1, delivering.size());
+      assertEquals(0, ((Message)delivering.get(0)).getMessageID());
+
+      List acknowledging = r.getMessages();
+      assertEquals(1, acknowledging.size());
+      Message ackm = (Message)acknowledging.get(0);
+      assertEquals(0, ackm.getMessageID());
+
+      Transaction tx = tr.createTransaction();
+
+      // transacted acknowledgment
+      r.acknowledge(ackm, tx);
+
+      delivering = messageQueue.browse();
+      assertEquals(1, delivering.size());
+      assertEquals(0, ((Message)delivering.get(0)).getMessageID());
+
+      tx.rollback();
+
+      delivering = messageQueue.browse();
+      assertEquals(1, delivering.size());
+      assertEquals(0, ((Message)delivering.get(0)).getMessageID());
+
+      // acknowledge non-transactionally
+      r.acknowledge(ackm, null);
+
+      assertTrue(messageQueue.browse().isEmpty());
+   }
+
+
+   //////////
+   ////////// Multiple message
+   //////////
+
+   ////////////
+   //////////// Non-transacted acknowledgment
+   ////////////
+
+   public void testRecoverableChannel_28() throws Throwable
+   {
+      if (!messageQueue.isRecoverable())
+      {
+         // we test only recoverable channels now
+         return;
+      }
+
+
+      // add an NACKING receiver to the channel
+      SimpleReceiver r = new SimpleReceiver("NackingReceiver", SimpleReceiver.NACKING);
+      assertTrue(messageQueue.add(r));
+
+      SimpleDeliveryObserver observer = new SimpleDeliveryObserver();
+
+      Message[] messages = new Message[NUMBER_OF_MESSAGES];
+      for(int i = 0; i < NUMBER_OF_MESSAGES; i++)
+      {
+         messages[i] = MessageFactory.createCoreMessage(i, true, "payload" + i);
+
+         // non-transacted send, reliable message, multiple messages
+         Delivery delivery = messageQueue.handle(observer, messages[i], null);
+
+         assertTrue(delivery.isDone());
+      }
+
+      assertEqualSets(messages, messageQueue.browse());
+      assertEqualSets(messages, r.getMessages());
+
+      for(Iterator i = r.getMessages().iterator(); i.hasNext();)
+      {
+         Message ackm = (Message)i.next();
+         // non-transacted acknowledgment
+         r.acknowledge(ackm, null);
+      }
+
+      assertTrue(messageQueue.browse().isEmpty());
+   }
+
+   ////////////
+   //////////// Transacted acknowledgment and commit
+   ////////////
+
+   public void testRecoverableChannel_28_1() throws Throwable
+   {
+      if (!messageQueue.isRecoverable())
+      {
+         // we test only recoverable channels now
+         return;
+      }
+
+
+      // add an NACKING receiver to the channel
+      SimpleReceiver r = new SimpleReceiver("NackingReceiver", SimpleReceiver.NACKING);
+      assertTrue(messageQueue.add(r));
+
+      SimpleDeliveryObserver observer = new SimpleDeliveryObserver();
+
+      Message[] messages = new Message[NUMBER_OF_MESSAGES];
+      for(int i = 0; i < NUMBER_OF_MESSAGES; i++)
+      {
+         messages[i] = MessageFactory.createCoreMessage(i, true, "payload" + i);
+
+         // non-transacted send, reliable message, multiple messages
+         Delivery delivery = messageQueue.handle(observer, messages[i], null);
+
+         assertTrue(delivery.isDone());
+      }
+
+      assertEqualSets(messages, messageQueue.browse());
+      assertEqualSets(messages, r.getMessages());
+
+      Transaction tx = tr.createTransaction();
+
+      for(Iterator i = r.getMessages().iterator(); i.hasNext();)
+      {
+         Message ackm = (Message)i.next();
+         // transacted acknowledgment
+         r.acknowledge(ackm, tx);
+      }
+
+      assertEqualSets(messages, messageQueue.browse());
+
+      tx.commit();
+
+      assertTrue(messageQueue.browse().isEmpty());
+   }
+
+   ////////////
+   //////////// Transacted acknowledgment and rollback
+   ////////////
+
+   public void testRecoverableChannel_28_2() throws Throwable
+   {
+      if (!messageQueue.isRecoverable())
+      {
+         // we test only recoverable channels now
+         return;
+      }
+
+
+      // add an NACKING receiver to the channel
+      SimpleReceiver r = new SimpleReceiver("NackingReceiver", SimpleReceiver.NACKING);
+      assertTrue(messageQueue.add(r));
+
+      SimpleDeliveryObserver observer = new SimpleDeliveryObserver();
+
+      Message[] messages = new Message[NUMBER_OF_MESSAGES];
+      for(int i = 0; i < NUMBER_OF_MESSAGES; i++)
+      {
+         messages[i] = MessageFactory.createCoreMessage(i, true, "payload" + i);
+
+         // non-transacted send, reliable message, multiple messages
+         Delivery delivery = messageQueue.handle(observer, messages[i], null);
+
+         assertTrue(delivery.isDone());
+      }
+
+      assertEqualSets(messages, messageQueue.browse());
+      assertEqualSets(messages, r.getMessages());
+
+      Transaction tx = tr.createTransaction();
+
+      for(Iterator i = r.getMessages().iterator(); i.hasNext();)
+      {
+         Message ackm = (Message)i.next();
+         // transacted acknowledgment
+         r.acknowledge(ackm, tx);
+      }
+
+      assertEqualSets(messages, messageQueue.browse());
+
+      tx.rollback();
+
+      assertEqualSets(messages, messageQueue.browse());
+
+      // acknowledge non-transactionally
+      for(Iterator i = r.getMessages().iterator(); i.hasNext();)
+      {
+         Message ackm = (Message)i.next();
+         // non-transacted acknowledgment
+         r.acknowledge(ackm, null);
+      }
+
+      assertTrue(messageQueue.browse().isEmpty());
+   }
+
+
+   //////
+   ////// Transacted send and commit
+   //////
+
+   ////////
+   //////// Non-reliable message
+   ////////
+
+   //////////
+   ////////// One message
+   //////////
+
+   public void testRecoverableChannel_29() throws Throwable
+   {
+      if (!messageQueue.isRecoverable())
+      {
+         // we test only recoverable channels now
+         return;
+      }
+
+
+      // add an NACKING receiver to the channel
+      SimpleReceiver r = new SimpleReceiver("NackingReceiver", SimpleReceiver.NACKING);
+      assertTrue(messageQueue.add(r));
+
+      Message m = MessageFactory.createCoreMessage(0, false, "payload");
+      SimpleDeliveryObserver observer = new SimpleDeliveryObserver();
+
+      Transaction tx = tr.createTransaction();
+
+      // transacted send, non-reliable message, one message
+      // for a transactional send, handle() return value is unspecified
+      messageQueue.handle(observer, m, tx);
+
+      // no messages in the channel
+      assertEquals(0, messageQueue.browse().size());
+
+      // no message at the receiver
+      assertTrue(r.getMessages().isEmpty());
+
+      tx.commit();
+
+      List delivering = messageQueue.browse();
+      assertEquals(1, delivering.size());
+      assertEquals(0, ((Message)delivering.get(0)).getMessageID());
+
+      List acknowledging = r.getMessages();
+      assertEquals(1, acknowledging.size());
+      Message ackm = (Message)acknowledging.get(0);
+      assertEquals(0, ackm.getMessageID());
+
+      // non-transacted acknowledgment
+      r.acknowledge(ackm, null);
+
+      assertTrue(messageQueue.browse().isEmpty());
+   }
+
+   //////////
+   ////////// Multiple message
+   //////////
+
+   public void testRecoverableChannel_30() throws Throwable
+   {
+      if (!messageQueue.isRecoverable())
+      {
+         // we test only recoverable channels now
+         return;
+      }
+
+
+      // add an NACKING receiver to the channel
+      SimpleReceiver r = new SimpleReceiver("NackingReceiver", SimpleReceiver.NACKING);
+      assertTrue(messageQueue.add(r));
+
+      SimpleDeliveryObserver observer = new SimpleDeliveryObserver();
+
+      Transaction tx = tr.createTransaction();
+
+      Message[] messages = new Message[NUMBER_OF_MESSAGES];
+      for(int i = 0; i < NUMBER_OF_MESSAGES; i++)
+      {
+         messages[i] = MessageFactory.createCoreMessage(i, false, "payload" + i);
+
+         // transacted send, non-reliable message, multiple messages
+         // for a transactional send, handle() return value is unspecified
+         messageQueue.handle(observer, messages[i], tx);
+      }
+
+      // no messages in the channel
+      assertEquals(0, messageQueue.browse().size());
+
+      // no message at the receiver
+      assertTrue(r.getMessages().isEmpty());
+
+      tx.commit();
+
+      assertEqualSets(messages, messageQueue.browse());
+      assertEqualSets(messages, r.getMessages());
+
+      for(Iterator i = r.getMessages().iterator(); i.hasNext();)
+      {
+         Message ackm = (Message)i.next();
+         // non-transacted acknowledgment
+         r.acknowledge(ackm, null);
+      }
+
+      assertTrue(messageQueue.browse().isEmpty());
+   }
+
+   ////////
+   //////// Reliable message
+   ////////
+
+   //////////
+   ////////// One message
+   //////////
+
+   public void testRecoverableChannel_31() throws Throwable
+   {
+      if (!messageQueue.isRecoverable())
+      {
+         // we test only recoverable channels now
+         return;
+      }
+
+
+      // add an NACKING receiver to the channel
+      SimpleReceiver r = new SimpleReceiver("NackingReceiver", SimpleReceiver.NACKING);
+      assertTrue(messageQueue.add(r));
+
+
+      Message m = MessageFactory.createCoreMessage(0, true, "payload");
+      SimpleDeliveryObserver observer = new SimpleDeliveryObserver();
+
+      Transaction tx = tr.createTransaction();
+
+      // transacted send, reliable message, one message
+      // for a transactional send, handle() return value is unspecified
+      messageQueue.handle(observer, m, tx);
+
+      // no messages in the channel yet
+      assertEquals(0, messageQueue.browse().size());
+
+      // no message at the receiver
+      assertTrue(r.getMessages().isEmpty());
+
+      tx.commit();
+
+      List delivering = messageQueue.browse();
+      assertEquals(1, delivering.size());
+      assertEquals(0, ((Message)delivering.get(0)).getMessageID());
+
+      List acknowledging = r.getMessages();
+      assertEquals(1, acknowledging.size());
+      Message ackm = (Message)acknowledging.get(0);
+      assertEquals(0, ackm.getMessageID());
+
+      // non-transacted acknowledgment
+      r.acknowledge(ackm, null);
+
+      assertTrue(messageQueue.browse().isEmpty());
+   }
+
+   //////////
+   ////////// Multiple message
+   //////////
+
+   public void testRecoverableChannel_32() throws Throwable
+   {
+      if (!messageQueue.isRecoverable())
+      {
+         // we test only recoverable channels now
+         return;
+      }
+
+      // add an NACKING receiver to the channel
+      SimpleReceiver r = new SimpleReceiver("NackingReceiver", SimpleReceiver.NACKING);
+      assertTrue(messageQueue.add(r));
+
+      SimpleDeliveryObserver observer = new SimpleDeliveryObserver();
+
+      Transaction tx = tr.createTransaction();
+
+      Message[] messages = new Message[NUMBER_OF_MESSAGES];
+      for(int i = 0; i < NUMBER_OF_MESSAGES; i++)
+      {
+         messages[i] = MessageFactory.createCoreMessage(i, true, "payload" + i);
+
+         // transacted send, reliable message, multiple messages
+         // for a transactional send, handle() return value is unspecified
+         messageQueue.handle(observer, messages[i], tx);
+      }
+
+      // no messages in the channel yet
+      assertEquals(0, messageQueue.browse().size());
+
+      // no message at the receiver
+      assertTrue(r.getMessages().isEmpty());
+
+      tx.commit();
+
+      assertEqualSets(messages, messageQueue.browse());
+      assertEqualSets(messages, r.getMessages());
+
+      for(Iterator i = r.getMessages().iterator(); i.hasNext();)
+      {
+         Message ackm = (Message)i.next();
+         // non-transacted acknowledgment
+         r.acknowledge(ackm, null);
+      }
+
+      assertTrue(messageQueue.browse().isEmpty());
+   }
+
+   /**
+    * This is a variation where I send a mixture of reliable and non-reliable messages,
+    */
+   public void testRecoverableChannel_32_mixed() throws Throwable
+   {
+      if (!messageQueue.isRecoverable())
+      {
+         // we test only recoverable channels now
+         return;
+      }
+
+
+      // add an NACKING receiver to the channel
+      SimpleReceiver r = new SimpleReceiver("NackingReceiver", SimpleReceiver.NACKING);
+      assertTrue(messageQueue.add(r));
+
+
+      SimpleDeliveryObserver observer = new SimpleDeliveryObserver();
+
+      Transaction tx = tr.createTransaction();
+
+      Message[] messages = new Message[NUMBER_OF_MESSAGES];
+      for(int i = 0; i < NUMBER_OF_MESSAGES; i++)
+      {
+         // send a mixture of reliable and non-reliable messages
+         messages[i] = MessageFactory.createCoreMessage(i, (i % 2 == 1), "payload" + i);
+
+         // transacted send, reliable/non-reliable messages, multiple messages
+         // for a transactional send, handle() return value is unspecified
+         messageQueue.handle(observer, messages[i], tx);
+      }
+
+      // no messages in the channel
+      assertEquals(0, messageQueue.browse().size());
+
+      // no message at the receiver
+      assertTrue(r.getMessages().isEmpty());
+
+      tx.commit();
+
+      assertEqualSets(messages, messageQueue.browse());
+      assertEqualSets(messages, r.getMessages());
+
+      for(Iterator i = r.getMessages().iterator(); i.hasNext();)
+      {
+         Message ackm = (Message)i.next();
+         // non-transacted acknowledgment
+         r.acknowledge(ackm, null);
+      }
+
+      assertTrue(messageQueue.browse().isEmpty());
+   }
+
+
+   //////
+   ////// Transacted send and rollback
+   //////
+
+   ////////
+   //////// Non-reliable message
+   ////////
+
+   //////////
+   ////////// One message
+   //////////
+
+   public void testRecoverableChannel_33() throws Exception
+   {
+      if (!messageQueue.isRecoverable())
+      {
+         // we test only recoverable channels now
+         return;
+      }
+
+      // add an NACKING receiver to the channel
+      SimpleReceiver r = new SimpleReceiver("NackingReceiver", SimpleReceiver.NACKING);
+      assertTrue(messageQueue.add(r));
+
+
+      Message m = MessageFactory.createCoreMessage(0, false, "payload");
+      SimpleDeliveryObserver observer = new SimpleDeliveryObserver();
+
+      Transaction tx = tr.createTransaction();
+
+      // transacted send, non-reliable message, one message
+      // for a transactional send, handle() return value is unspecified
+      messageQueue.handle(observer, m, tx);
+
+      // no messages in the channel
+      assertEquals(0, messageQueue.browse().size());
+
+      // no message at the receiver
+      assertTrue(r.getMessages().isEmpty());
+
+
+      tx.rollback();
+
+      // no messages in the channel
+      assertEquals(0, messageQueue.browse().size());
+
+      // no message at the receiver
+      assertTrue(r.getMessages().isEmpty());
+
+   }
+
+   //////////
+   ////////// Multiple message
+   //////////
+
+   public void testRecoverableChannel_34() throws Exception
+   {
+      if (!messageQueue.isRecoverable())
+      {
+         // we test only recoverable channels now
+         return;
+      }
+
+      // add an NACKING receiver to the channel
+      SimpleReceiver r = new SimpleReceiver("NackingReceiver", SimpleReceiver.NACKING);
+      assertTrue(messageQueue.add(r));
+
+      SimpleDeliveryObserver observer = new SimpleDeliveryObserver();
+
+      Transaction tx = tr.createTransaction();
+
+      Message[] messages = new Message[NUMBER_OF_MESSAGES];
+      for(int i = 0; i < NUMBER_OF_MESSAGES; i++)
+      {
+         messages[i] = MessageFactory.createCoreMessage(i, false, "payload" + i);
+
+         // transacted send, non-reliable message, multiple messages
+         // for a transactional send, handle() return value is unspecified
+         messageQueue.handle(observer, messages[i], tx);
+      }
+
+      // no messages in the channel
+      assertEquals(0, messageQueue.browse().size());
+
+      // no message at the receiver
+      assertTrue(r.getMessages().isEmpty());
+
+      tx.rollback();
+
+      // no messages in the channel
+      assertEquals(0, messageQueue.browse().size());
+
+      // no message at the receiver
+      assertTrue(r.getMessages().isEmpty());
+   }
+
+   ////////
+   //////// Reliable message
+   ////////
+
+   //////////
+   ////////// One message
+   //////////
+
+   public void testRecoverableChannel_35() throws Exception
+   {
+      if (!messageQueue.isRecoverable())
+      {
+         // we test only recoverable channels now
+         return;
+      }
+
+      // add an NACKING receiver to the channel
+      SimpleReceiver r = new SimpleReceiver("NackingReceiver", SimpleReceiver.NACKING);
+      assertTrue(messageQueue.add(r));
+
+
+      Message m = MessageFactory.createCoreMessage(0, true, "payload");
+      SimpleDeliveryObserver observer = new SimpleDeliveryObserver();
+
+      Transaction tx = tr.createTransaction();
+
+      // transacted send, reliable message, one message
+      // for a transactional send, handle() return value is unspecified
+      messageQueue.handle(observer, m, tx);
+
+      // no messages in the channel
+      assertEquals(0, messageQueue.browse().size());
+
+      // no message at the receiver
+      assertTrue(r.getMessages().isEmpty());
+
+      tx.rollback();
+
+      // no messages in the channel
+      assertEquals(0, messageQueue.browse().size());
+
+      // no message at the receiver
+      assertTrue(r.getMessages().isEmpty());
+   }
+
+   //////////
+   ////////// Multiple message
+   //////////
+
+   public void testRecoverableChannel_36() throws Exception
+   {
+      if (!messageQueue.isRecoverable())
+      {
+         // we test only recoverable channels now
+         return;
+      }
+
+      // add an NACKING receiver to the channel
+      SimpleReceiver r = new SimpleReceiver("NackingReceiver", SimpleReceiver.NACKING);
+      assertTrue(messageQueue.add(r));
+
+
+      SimpleDeliveryObserver observer = new SimpleDeliveryObserver();
+
+      Transaction tx = tr.createTransaction();
+
+      Message[] messages = new Message[NUMBER_OF_MESSAGES];
+      for(int i = 0; i < NUMBER_OF_MESSAGES; i++)
+      {
+         messages[i] = MessageFactory.createCoreMessage(i, true, "payload" + i);
+
+         // transacted send, reliable message, multiple messages
+         // for a transactional send, handle() return value is unspecified
+         messageQueue.handle(observer, messages[i], tx);
+      }
+
+      // no messages in the channel
+      assertEquals(0, messageQueue.browse().size());
+
+      // no message at the receiver
+      assertTrue(r.getMessages().isEmpty());
+
+      tx.rollback();
+
+      // no messages in the channel
+      assertEquals(0, messageQueue.browse().size());
+
+      // no message at the receiver
+      assertTrue(r.getMessages().isEmpty());
+   }
+
+   /**
+    * This is a variation where I send a mixture of reliable and non-reliable messages,
+    */
+   public void testRecoverableChannel_36_mixed() throws Exception
+   {
+      if (!messageQueue.isRecoverable())
+      {
+         // we test only recoverable channels now
+         return;
+      }
+
+      // add an NACKING receiver to the channel
+      SimpleReceiver r = new SimpleReceiver("NackingReceiver", SimpleReceiver.NACKING);
+      assertTrue(messageQueue.add(r));
+
+
+      SimpleDeliveryObserver observer = new SimpleDeliveryObserver();
+
+      Transaction tx = tr.createTransaction();
+
+      Message[] messages = new Message[NUMBER_OF_MESSAGES];
+      for(int i = 0; i < NUMBER_OF_MESSAGES; i++)
+      {
+         // send a mixture of reliable and non-reliable messages
+         messages[i] = MessageFactory.createCoreMessage(i, (i % 2 == 1), "payload" + i);
+
+         // transacted send, reliable/non-reliable messages, multiple messages
+         // for a transactional send, handle() return value is unspecified
+         messageQueue.handle(observer, messages[i], tx);
+      }
+
+      // no messages in the channel
+      assertEquals(0, messageQueue.browse().size());
+
+      // no message at the receiver
+      assertTrue(r.getMessages().isEmpty());
+
+      tx.rollback();
+
+      // no messages in the channel
+      assertEquals(0, messageQueue.browse().size());
+
+      // no message at the receiver
+      assertTrue(r.getMessages().isEmpty());
+   }
+
+   ///////////////////////////////
+   /////////////////////////////// Add receiver tests
+   ///////////////////////////////
+   ///////////////////////////////
+   ///////////////////////////////
+
+   //
+   // Non-recoverable channel
+   //
+
+   ////
+   //// Non-reliable message
+   ////
+
+   //////
+   ////// Broken receiver
+   //////
+
+   public void testAddReceiver_1() throws Exception
+   {
+      if (messageQueue.isRecoverable())
+      {
+         // we test only non-recoverable channels now
+         return;
+      }
+
+      // the channel has no receivers
+      assertFalse(messageQueue.iterator().hasNext());
+
+      Message m = MessageFactory.createCoreMessage(0, false, "payload");
+      SimpleDeliveryObserver observer = new SimpleDeliveryObserver();
+
+      // non-recoverable channel, non-reliable message
+      Delivery delivery = messageQueue.handle(observer, m, null);
+      assertTrue(delivery.isDone());
+
+      List stored = messageQueue.browse();
+      assertEquals(1, stored.size());
+
+
+      SimpleReceiver receiver = new SimpleReceiver("BrokenReceiver", SimpleReceiver.BROKEN);
+      assertTrue(messageQueue.add(receiver));
+
+      stored = messageQueue.browse();
+      assertEquals(1, stored.size());
+      Message sm = (Message)stored.iterator().next();
+      assertFalse(sm.isReliable());
+      assertEquals(0, sm.getMessageID());
+
+      assertTrue(receiver.getMessages().isEmpty());
+   }
+
+   //////
+   ////// ACKING receiver
+   //////
+
+   public void testAddReceiver_2() throws Exception
+   {
+      if (messageQueue.isRecoverable())
+      {
+         // we test only non-recoverable channels now
+         return;
+      }
+
+      // the channel has no receivers
+      assertFalse(messageQueue.iterator().hasNext());
+
+      Message m = MessageFactory.createCoreMessage(0, false, "payload");
+      SimpleDeliveryObserver observer = new SimpleDeliveryObserver();
+
+      // non-recoverable channel, non-reliable message
+      Delivery delivery = messageQueue.handle(observer, m, null);
+      assertTrue(delivery.isDone());
+
+      List stored = messageQueue.browse();
+      assertEquals(1, stored.size());
+
+      SimpleReceiver receiver =
+            new SimpleReceiver("ACKINGReceiver", SimpleReceiver.ACKING, messageQueue);
+      assertTrue(messageQueue.add(receiver));
+
+      assertEquals(1, messageQueue.browse().size());
+
+      // receiver explicitely asks for message
+      receiver.requestMessages();
+
+      assertTrue(messageQueue.browse().isEmpty());
+
+      List messages = receiver.getMessages();
+      assertEquals(1, messages.size());
+      Message sm = (Message)messages.iterator().next();
+      assertFalse(sm.isReliable());
+      assertEquals(0, sm.getMessageID());
+   }
+
+   //////
+   ////// NACKING receiver
+   //////
+
+   public void testAddReceiver_3() throws Throwable
+   {
+      if (messageQueue.isRecoverable())
+      {
+         // we test only non-recoverable channels now
+         return;
+      }
+
+      // the channel has no receivers
+      assertFalse(messageQueue.iterator().hasNext());
+
+      Message m = MessageFactory.createCoreMessage(0, false, "payload");
+      SimpleDeliveryObserver observer = new SimpleDeliveryObserver();
+
+      // non-recoverable channel, non-reliable message
+      Delivery delivery = messageQueue.handle(observer, m, null);
+      assertTrue(delivery.isDone());
+
+      List stored = messageQueue.browse();
+      assertEquals(1, stored.size());
+
+      SimpleReceiver receiver =
+            new SimpleReceiver("NACKINGReceiver", SimpleReceiver.NACKING, messageQueue);
+      assertTrue(messageQueue.add(receiver));
+
+      assertEquals(1, messageQueue.browse().size());
+
+      // receiver explicitely asks for message
+      receiver.requestMessages();
+
+      assertEquals(1, messageQueue.browse().size());
+
+      List messages = receiver.getMessages();
+      assertEquals(1, messages.size());
+      Message sm = (Message)messages.iterator().next();
+      assertFalse(sm.isReliable());
+      assertEquals(0, sm.getMessageID());
+
+      receiver.acknowledge(sm, null);
+
+      assertTrue(messageQueue.browse().isEmpty());
+
+      messages = receiver.getMessages();
+      assertEquals(1, messages.size());
+      sm = (Message)messages.iterator().next();
+      assertFalse(sm.isReliable());
+      assertEquals(0, sm.getMessageID());
+   }
+
+   //
+   // Recoverable channel
+   //
+
+   ////
+   //// Reliable message
+   ////
+
+   public void testAddReceiver_4() throws Exception
+   {
+      if (!messageQueue.isRecoverable())
+      {
+         // we test only recoverable channels now
+         return;
+      }
+
+      // the channel has no receivers
+      assertFalse(messageQueue.iterator().hasNext());
+
+      Message m = MessageFactory.createCoreMessage(0, true, "payload");
+      SimpleDeliveryObserver observer = new SimpleDeliveryObserver();
+
+      // non-recoverable channel, non-reliable message
+      Delivery delivery = messageQueue.handle(observer, m, null);
+      assertTrue(delivery.isDone());
+
+      List stored = messageQueue.browse();
+      assertEquals(1, stored.size());
+
+
+      SimpleReceiver receiver = new SimpleReceiver("BrokenReceiver", SimpleReceiver.BROKEN);
+      assertTrue(messageQueue.add(receiver));
+
+      stored = messageQueue.browse();
+      assertEquals(1, stored.size());
+      Message sm = (Message)stored.iterator().next();
+      assertTrue(sm.isReliable());
+      assertEquals(0, sm.getMessageID());
+
+      assertTrue(receiver.getMessages().isEmpty());
+   }
+
+   //////
+   ////// ACKING receiver
+   //////
+
+   public void testAddReceiver_5() throws Exception
+   {
+      if (!messageQueue.isRecoverable())
+      {
+         // we test only recoverable channels now
+         return;
+      }
+
+      // the channel has no receivers
+      assertFalse(messageQueue.iterator().hasNext());
+
+      Message m = MessageFactory.createCoreMessage(0, true, "payload");
+      SimpleDeliveryObserver observer = new SimpleDeliveryObserver();
+
+      // non-recoverable channel, non-reliable message
+      Delivery delivery = messageQueue.handle(observer, m, null);
+      assertTrue(delivery.isDone());
+
+      List stored = messageQueue.browse();
+      assertEquals(1, stored.size());
+
+      SimpleReceiver receiver =
+            new SimpleReceiver("ACKINGReceiver", SimpleReceiver.ACKING, messageQueue);
+      assertTrue(messageQueue.add(receiver));
+
+      // receiver explicitely asks for message
+      receiver.requestMessages();
+
+      assertTrue(messageQueue.browse().isEmpty());
+
+      List messages = receiver.getMessages();
+      assertEquals(1, messages.size());
+      Message sm = (Message)messages.iterator().next();
+      assertTrue(sm.isReliable());
+      assertEquals(0, sm.getMessageID());
+   }
+
+   //////
+   ////// NACKING receiver
+   //////
+
+   public void testAddReceiver_6() throws Throwable
+   {
+      if (!messageQueue.isRecoverable())
+      {
+         // we test only recoverable channels now
+         return;
+      }
+
+      // the channel has no receivers
+      assertFalse(messageQueue.iterator().hasNext());
+
+      Message m = MessageFactory.createCoreMessage(0, true, "payload");
+      SimpleDeliveryObserver observer = new SimpleDeliveryObserver();
+
+      // non-recoverable channel, non-reliable message
+      Delivery delivery = messageQueue.handle(observer, m, null);
+      assertTrue(delivery.isDone());
+
+      List stored = messageQueue.browse();
+      assertEquals(1, stored.size());
+
+      SimpleReceiver receiver =
+            new SimpleReceiver("NACKINGReceiver", SimpleReceiver.NACKING, messageQueue);
+      assertTrue(messageQueue.add(receiver));
+
+      assertEquals(1, messageQueue.browse().size());
+
+      // receiver explicitely asks for message
+      receiver.requestMessages();
+
+      assertEquals(1, messageQueue.browse().size());
+
+      List messages = receiver.getMessages();
+      assertEquals(1, messages.size());
+      Message sm = (Message)messages.iterator().next();
+      assertTrue(sm.isReliable());
+      assertEquals(0, sm.getMessageID());
+
+      receiver.acknowledge(sm, null);
+
+      assertTrue(messageQueue.browse().isEmpty());
+
+      messages = receiver.getMessages();
+      assertEquals(1, messages.size());
+      sm = (Message)messages.iterator().next();
+      assertTrue(sm.isReliable());
+      assertEquals(0, sm.getMessageID());
+   }
+
+
+
+
+   ///////////////////////////////
+   /////////////////////////////// Channel crash tests
+   ///////////////////////////////
+
+//   public void testReliableChannelFailure() throws Throwable
+//   {
+//      if (!channel.isRecoverable())
+//      {
+//         return;
+//      }
+//
+//      SimpleDeliveryObserver observer = new SimpleDeliveryObserver();
+//      SimpleReceiver r = new SimpleReceiver("ONE", SimpleReceiver.NACKING);
+//      channel.add(r);
+//
+//      Routable m = Factory.createMessage("m0", true, "payload");
+//      Delivery d = channel.handle(observer, m, null);
+//      assertTrue(d.isDone());
+//
+//      List l = r.getMessages();
+//      assertEquals(1, l.size());
+//      Message rm  = (Message)l.get(0);
+//      assertEquals(rm.getMessageID(), m.getMessageID());
+//
+//      crashChannel();
+//
+//      recoverChannel();
+//
+//      // make sure the recovered channel still holds the message
+//
+//      l = channel.browse();
+//      assertEquals(1, l.size());
+//      MessageReference ref = (MessageReference)l.get(0);
+//      rm  = ref.getMessage();
+//      assertEquals(rm.getMessageID(), m.getMessageID());
+//
+//
+//      // TODO review this
+//      try
+//      {
+//         r.acknowledge(m, null);
+//         fail("should throw exception");
+//      }
+//      catch(IllegalStateException e)
+//      {
+//         // OK
+//      }
+//   }
+
+
+   // Distributor tests ---------------------------------------------
+
+   public void testAddOneReceiver()
+   {
+      Receiver r = new SimpleReceiver("ONE");
+
+      assertTrue(messageQueue.add(r));
+      assertFalse(messageQueue.add(r));
+
+      assertTrue(messageQueue.contains(r));
+
+      Iterator i = messageQueue.iterator();
+      assertEquals(r, i.next());
+      assertFalse(i.hasNext());
+
+      messageQueue.clear();
+      assertFalse(messageQueue.iterator().hasNext());
+   }
+
+   public void testRemoveInexistentReceiver()
+   {
+      assertFalse(messageQueue.remove(new SimpleReceiver("INEXISTENT")));
+   }
+
+
+   // Package protected ---------------------------------------------
+   
+   // Protected -----------------------------------------------------
+
+   protected abstract void crashChannel() throws Exception;
+
+   protected abstract void recoverChannel() throws Exception;
+
+   // Private -------------------------------------------------------
+   
+   // Inner classes -------------------------------------------------
+
+}

Deleted: trunk/tests/src/org/jboss/test/messaging/core/base/NoTestsChannelTestBase.java
===================================================================
--- trunk/tests/src/org/jboss/test/messaging/core/base/NoTestsChannelTestBase.java	2006-08-30 09:26:13 UTC (rev 1236)
+++ trunk/tests/src/org/jboss/test/messaging/core/base/NoTestsChannelTestBase.java	2006-08-30 18:36:36 UTC (rev 1237)
@@ -1,83 +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.core.base;
-
-import org.jboss.messaging.core.Channel;
-import org.jboss.test.messaging.MessagingTestCase;
-import org.jboss.test.messaging.tools.jmx.ServiceContainer;
-
-/**
- * Useful when want to run only tests of a specific subclass.
- *
- * @author <a href="mailto:ovidiu at jboss.org">Ovidiu Feodorov</a>
- * @version <tt>$Revision$</tt>
-
- * $Id$
- */
-public abstract class NoTestsChannelTestBase extends MessagingTestCase
-{
-   // Constants -----------------------------------------------------
-
-   // Static --------------------------------------------------------
-
-   // Attributes ----------------------------------------------------
-
-   protected ServiceContainer sc;
-
-   protected Channel channel;
-
-   // Constructors --------------------------------------------------
-
-   public NoTestsChannelTestBase(String name)
-   {
-      super(name);
-   }
-
-   // Public --------------------------------------------------------
-
-   public void setUp() throws Exception
-   {
-      super.setUp();
-
-      sc = new ServiceContainer("all,-remoting,-security");
-      sc.start();
-   }
-
-   public void tearDown() throws Exception
-   {
-      sc.stop();
-      sc = null;
-
-      super.tearDown();
-   }
-
-   // NO TESTS
-
-   // Package protected ---------------------------------------------
-
-   // Protected -----------------------------------------------------
-
-   // Private -------------------------------------------------------
-
-   // Inner classes -------------------------------------------------
-
-}

Deleted: trunk/tests/src/org/jboss/test/messaging/core/base/SingleReceiverDeliveryTestBase.java
===================================================================
--- trunk/tests/src/org/jboss/test/messaging/core/base/SingleReceiverDeliveryTestBase.java	2006-08-30 09:26:13 UTC (rev 1236)
+++ trunk/tests/src/org/jboss/test/messaging/core/base/SingleReceiverDeliveryTestBase.java	2006-08-30 18:36:36 UTC (rev 1237)
@@ -1,63 +0,0 @@
-/**
- * JBoss, Home of Professional Open Source
- *
- * Distributable under LGPL license.
- * See terms of license at gnu.org.
- */
-
-
-package org.jboss.test.messaging.core.base;
-
-import org.jboss.messaging.core.SingleReceiverDelivery;
-
-
-/**
- * @author <a href="mailto:ovidiu at jboss.org">Ovidiu Feodorov</a>
- * @version <tt>$Revision$</tt>
- *
- * $Id$
- */
-public abstract class SingleReceiverDeliveryTestBase extends DeliveryTestBase
-{
-   // Constants -----------------------------------------------------
-
-   // Static --------------------------------------------------------
-   
-   // Attributes ----------------------------------------------------
-
-   // Constructors --------------------------------------------------
-
-   public SingleReceiverDeliveryTestBase(String name)
-   {
-      super(name);
-   }
-
-   // Public --------------------------------------------------------
-
-   public void setUp() throws Exception
-   {
-      super.setUp();
-   }
-
-   public void tearDown() throws Exception
-   {
-      super.tearDown();
-   }
-
-   public void testAcknowledgment() throws Throwable
-   {
-      assertFalse(delivery.isDone());
-
-      ((SingleReceiverDelivery)delivery).acknowledge(null);
-
-      assertTrue(delivery.isDone());
-   }
-
-   // Package protected ---------------------------------------------
-   
-   // Protected -----------------------------------------------------
-
-   // Private -------------------------------------------------------
-   
-   // Inner classes -------------------------------------------------
-}

Copied: trunk/tests/src/org/jboss/test/messaging/core/local/MessageQueueWithFilterTest.java (from rev 1223, trunk/tests/src/org/jboss/test/messaging/core/local/SubscriptionWithFilterTest.java)
===================================================================
--- trunk/tests/src/org/jboss/test/messaging/core/local/SubscriptionWithFilterTest.java	2006-08-10 19:04:47 UTC (rev 1223)
+++ trunk/tests/src/org/jboss/test/messaging/core/local/MessageQueueWithFilterTest.java	2006-08-30 18:36:36 UTC (rev 1237)
@@ -0,0 +1,152 @@
+/*
+  * 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.core.local;
+
+import org.jboss.messaging.core.Filter;
+import org.jboss.messaging.core.Message;
+import org.jboss.messaging.core.Routable;
+import org.jboss.messaging.core.local.MessageQueue;
+import org.jboss.messaging.core.message.CoreMessage;
+import org.jboss.messaging.core.plugin.JDBCPersistenceManager;
+import org.jboss.messaging.core.plugin.SimpleMessageStore;
+import org.jboss.messaging.core.plugin.contract.MessageStore;
+import org.jboss.messaging.core.plugin.contract.PersistenceManager;
+import org.jboss.test.messaging.MessagingTestCase;
+import org.jboss.test.messaging.tools.jmx.ServiceContainer;
+
+import EDU.oswego.cs.dl.util.concurrent.QueuedExecutor;
+
+/**
+ * 
+ * A MessageQueueWithFilterTest.
+ * 
+ * @author <a href="tim.fox at jboss.com">Tim Fox</a>
+ * @version $Revision$
+ *
+ * $Id$
+ */
+public class MessageQueueWithFilterTest extends MessagingTestCase
+{
+   public MessageQueueWithFilterTest(String name)
+   {
+      super(name);
+   }
+
+   protected PersistenceManager pm;
+   
+   protected MessageStore ms;
+   
+   protected ServiceContainer sc;
+    
+   // ChannelTestBase overrides  ------------------------------------
+
+   public void setUp() throws Exception
+   {
+      super.setUp();
+      
+      sc = new ServiceContainer("all,-remoting,-security");
+      sc.start();
+      
+      pm = new JDBCPersistenceManager(sc.getDataSource(), sc.getTransactionManager());
+      pm.start();
+      
+      ms = new SimpleMessageStore();
+            
+      log.debug("setup done");
+   }
+
+   public void tearDown() throws Exception
+   {
+      pm.stop();
+      
+      sc.stop();
+
+      super.tearDown();
+   }
+   
+
+   public void testWithFilter()
+   {
+      Filter f = new SimpleFilter(3);
+      
+      MessageQueue messageQueue = new MessageQueue(1, ms, pm, true, true, 100, 20, 10, new QueuedExecutor(),
+                                                   f);
+       
+      Message m1 = new CoreMessage(1, false, 0, 0, (byte)0, null, null, 0);
+      Message m2 = new CoreMessage(2, false, 0, 0, (byte)0, null, null, 0);
+      Message m3 = new CoreMessage(3, false, 0, 0, (byte)0, null, null, 0);
+      Message m4 = new CoreMessage(4, false, 0, 0, (byte)0, null, null, 0);
+      Message m5 = new CoreMessage(5, false, 0, 0, (byte)0, null, null, 0);
+      
+      assertNull(messageQueue.handle(null, m1, null));
+      assertNull(messageQueue.handle(null, m2, null));
+      assertNotNull(messageQueue.handle(null, m3, null));
+      assertNull(messageQueue.handle(null, m4, null));
+      assertNull(messageQueue.handle(null, m5, null));
+      
+   }
+   
+   public void testWithoutFilter()
+   {
+      MessageQueue messageQueue = new MessageQueue(1, ms, pm, true, true, 100, 20, 10, new QueuedExecutor(),
+                                                   null);     
+      
+      Message m1 = new CoreMessage(1, false, 0, 0, (byte)0, null, null, 0);
+      Message m2 = new CoreMessage(2, false, 0, 0, (byte)0, null, null, 0);
+      Message m3 = new CoreMessage(3, false, 0, 0, (byte)0, null, null, 0);
+      Message m4 = new CoreMessage(4, false, 0, 0, (byte)0, null, null, 0);
+      Message m5 = new CoreMessage(5, false, 0, 0, (byte)0, null, null, 0);
+      
+      assertNotNull(messageQueue.handle(null, m1, null));
+      assertNotNull(messageQueue.handle(null, m2, null));
+      assertNotNull(messageQueue.handle(null, m3, null));
+      assertNotNull(messageQueue.handle(null, m4, null));
+      assertNotNull(messageQueue.handle(null, m5, null));
+      
+   }
+   
+   public void crashChannel() throws Exception
+   {
+   }
+
+   public void recoverChannel() throws Exception
+   {
+   }
+   
+   class SimpleFilter implements Filter
+   {
+      private long value;
+      SimpleFilter(long value)
+      {
+         this.value = value;
+      }
+      public boolean accept(Routable routable)
+      {
+         CoreMessage msg = (CoreMessage)routable;
+         return msg.getMessageID() == value;
+      }
+      public String getFilterString()
+      {
+         return null;
+      }
+   }
+}

Copied: trunk/tests/src/org/jboss/test/messaging/core/local/NonRecoverableMessageQueueTest.java (from rev 1223, trunk/tests/src/org/jboss/test/messaging/core/local/NonRecoverableQueueTest.java)
===================================================================
--- trunk/tests/src/org/jboss/test/messaging/core/local/NonRecoverableQueueTest.java	2006-08-10 19:04:47 UTC (rev 1223)
+++ trunk/tests/src/org/jboss/test/messaging/core/local/NonRecoverableMessageQueueTest.java	2006-08-30 18:36:36 UTC (rev 1237)
@@ -0,0 +1,89 @@
+/*
+* 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.core.local;
+
+import org.jboss.messaging.core.local.MessageQueue;
+import org.jboss.test.messaging.core.base.MessageQueueTestBase;
+
+import EDU.oswego.cs.dl.util.concurrent.QueuedExecutor;
+
+/**
+ * @author <a href="mailto:ovidiu at jboss.org">Ovidiu Feodorov</a>
+ * @author <a href="mailto:tim.fox at jboss.com">Tim Fox</a>
+ * @version <tt>$Revision$</tt>
+ *
+ * $Id$
+ */
+public class NonRecoverableMessageQueueTest extends MessageQueueTestBase
+{
+   // Constants -----------------------------------------------------
+
+   // Static --------------------------------------------------------
+   
+   // Attributes ----------------------------------------------------
+
+  
+   // Constructors --------------------------------------------------
+
+   public NonRecoverableMessageQueueTest(String name)
+   {
+      super(name);
+   }
+
+   // ChannelTestBase overrides  ------------------------------------
+
+   public void setUp() throws Exception
+   {
+      super.setUp();
+      
+      messageQueue = new MessageQueue(1, ms, pm, true, false, 100, 20, 10, new QueuedExecutor(),
+                                      null);
+   }
+
+   public void tearDown() throws Exception
+   {
+      messageQueue.close();
+      super.tearDown();
+   }
+
+   public void crashChannel() throws Exception
+   {
+      messageQueue.close();
+   }
+
+   public void recoverChannel() throws Exception
+   {
+      messageQueue = new MessageQueue(1, ms, pm, true, false, 100, 20, 10, new QueuedExecutor(),
+                                      null);
+   }
+
+   // Public --------------------------------------------------------
+
+   // Package protected ---------------------------------------------
+   
+   // Protected -----------------------------------------------------
+   
+   // Private -------------------------------------------------------
+   
+   // Inner classes -------------------------------------------------   
+}
+

Deleted: trunk/tests/src/org/jboss/test/messaging/core/local/NonRecoverableQueueTest.java
===================================================================
--- trunk/tests/src/org/jboss/test/messaging/core/local/NonRecoverableQueueTest.java	2006-08-30 09:26:13 UTC (rev 1236)
+++ trunk/tests/src/org/jboss/test/messaging/core/local/NonRecoverableQueueTest.java	2006-08-30 18:36:36 UTC (rev 1237)
@@ -1,89 +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.core.local;
-
-import org.jboss.test.messaging.core.local.base.QueueTestBase;
-import org.jboss.messaging.core.local.Queue;
-
-import EDU.oswego.cs.dl.util.concurrent.QueuedExecutor;
-
-/**
- * Tests a non-recoverable queue that doesn't accept reliable messages.
- *
- * @author <a href="mailto:ovidiu at jboss.org">Ovidiu Feodorov</a>
- * @author <a href="mailto:tim.fox at jboss.com">Tim Fox</a>
- * @version <tt>$Revision$</tt>
- * 
- * $Id$
- */
-public class NonRecoverableQueueTest extends QueueTestBase
-{
-   // Constants -----------------------------------------------------
-
-   // Static --------------------------------------------------------
-   
-   // Attributes ----------------------------------------------------
-
-   // Constructors --------------------------------------------------
-
-   public NonRecoverableQueueTest(String name)
-   {
-      super(name);
-   }
-
-   // ChannelTestBase overrides  ------------------------------------
-
-   public void setUp() throws Exception
-   {
-      super.setUp();
-
-      channel = new Queue(1, ms, pm, null, false, 100, 20, 10, new QueuedExecutor());
-   }
-
-   public void tearDown() throws Exception
-   {
-      channel.close();
-      channel = null;
-
-      super.tearDown();
-   }
-
-   public void crashChannel() throws Exception
-   {
-      // doesn't matter
-   }
-
-   public void recoverChannel() throws Exception
-   {
-      // doesn't matter
-   }
-
-   // Public --------------------------------------------------------
-
-   // Package protected ---------------------------------------------
-   
-   // Protected -----------------------------------------------------
-   
-   // Private -------------------------------------------------------
-   
-   // Inner classes -------------------------------------------------   
-}

Deleted: trunk/tests/src/org/jboss/test/messaging/core/local/NonRecoverableSubscriptionTest.java
===================================================================
--- trunk/tests/src/org/jboss/test/messaging/core/local/NonRecoverableSubscriptionTest.java	2006-08-30 09:26:13 UTC (rev 1236)
+++ trunk/tests/src/org/jboss/test/messaging/core/local/NonRecoverableSubscriptionTest.java	2006-08-30 18:36:36 UTC (rev 1237)
@@ -1,89 +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.core.local;
-
-import org.jboss.messaging.core.local.CoreSubscription;
-import org.jboss.test.messaging.core.local.base.QueueTestBase;
-
-import EDU.oswego.cs.dl.util.concurrent.QueuedExecutor;
-
-/**
- * @author <a href="mailto:ovidiu at jboss.org">Ovidiu Feodorov</a>
- * @author <a href="mailto:tim.fox at jboss.com">Tim Fox</a>
- * @version <tt>$Revision$</tt>
- * 
- * $Id$
- */
-public class NonRecoverableSubscriptionTest extends QueueTestBase
-{
-   // Constants -----------------------------------------------------
-
-   // Static --------------------------------------------------------
-   
-   // Attributes ----------------------------------------------------
-
-   // Constructors --------------------------------------------------
-
-   public NonRecoverableSubscriptionTest(String name)
-   {
-      super(name);
-   }
-
-   // ChannelTestBase overrides  ------------------------------------
-
-   public void setUp() throws Exception
-   {
-      super.setUp();
-      
-      channel = new CoreSubscription(123, null, ms, pm, null, false, 100, 20, 10, new QueuedExecutor(), null);
-      
-      log.debug("setup done");
-   }
-
-   public void tearDown() throws Exception
-   {
-      channel.close();
-      channel = null;
-
-      super.tearDown();
-   }
-
-   public void crashChannel() throws Exception
-   {
-      // doesn't matter
-   }
-
-   public void recoverChannel() throws Exception
-   {
-      // doesn't matter
-   }
-
-   // Public --------------------------------------------------------
-
-   // Package protected ---------------------------------------------
-   
-   // Protected -----------------------------------------------------
-   
-   // Private -------------------------------------------------------
-   
-   // Inner classes -------------------------------------------------   
-}

Added: trunk/tests/src/org/jboss/test/messaging/core/local/RecoverableMessageQueueTest.java
===================================================================
--- trunk/tests/src/org/jboss/test/messaging/core/local/RecoverableMessageQueueTest.java	2006-08-30 09:26:13 UTC (rev 1236)
+++ trunk/tests/src/org/jboss/test/messaging/core/local/RecoverableMessageQueueTest.java	2006-08-30 18:36:36 UTC (rev 1237)
@@ -0,0 +1,88 @@
+/*
+* 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.core.local;
+
+import org.jboss.messaging.core.local.MessageQueue;
+import org.jboss.test.messaging.core.base.MessageQueueTestBase;
+
+import EDU.oswego.cs.dl.util.concurrent.QueuedExecutor;
+
+/**
+ * @author <a href="mailto:ovidiu at jboss.org">Ovidiu Feodorov</a>
+ * @author <a href="mailto:tim.fox at jboss.com">Tim Fox</a>
+ * @version <tt>$Revision: 1019 $</tt>
+ *
+ * $Id: RecoverableQueueTest.java 1019 2006-07-17 17:15:04Z timfox $
+ */
+public class RecoverableMessageQueueTest extends MessageQueueTestBase
+{
+   // Constants -----------------------------------------------------
+
+   // Static --------------------------------------------------------
+   
+   // Attributes ----------------------------------------------------
+
+  
+   // Constructors --------------------------------------------------
+
+   public RecoverableMessageQueueTest(String name)
+   {
+      super(name);
+   }
+
+   // ChannelTestBase overrides  ------------------------------------
+
+   public void setUp() throws Exception
+   {
+      super.setUp();
+      
+      messageQueue = new MessageQueue(1, ms, pm, true, true, 100, 20, 10, new QueuedExecutor(),
+                                      null);
+   }
+
+   public void tearDown() throws Exception
+   {
+      messageQueue.close();
+      super.tearDown();
+   }
+
+   public void crashChannel() throws Exception
+   {
+      messageQueue.close();
+   }
+
+   public void recoverChannel() throws Exception
+   {
+      messageQueue = new MessageQueue(1, ms, pm, true, true, 100, 20, 10, new QueuedExecutor(),
+                                      null);
+   }
+
+   // Public --------------------------------------------------------
+
+   // Package protected ---------------------------------------------
+   
+   // Protected -----------------------------------------------------
+   
+   // Private -------------------------------------------------------
+   
+   // Inner classes -------------------------------------------------   
+}

Deleted: trunk/tests/src/org/jboss/test/messaging/core/local/RecoverableQueueTest.java
===================================================================
--- trunk/tests/src/org/jboss/test/messaging/core/local/RecoverableQueueTest.java	2006-08-30 09:26:13 UTC (rev 1236)
+++ trunk/tests/src/org/jboss/test/messaging/core/local/RecoverableQueueTest.java	2006-08-30 18:36:36 UTC (rev 1237)
@@ -1,99 +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.core.local;
-
-import org.jboss.messaging.core.local.Queue;
-import org.jboss.messaging.core.plugin.SimpleMessageStore;
-import org.jboss.test.messaging.core.local.base.QueueTestBase;
-
-import EDU.oswego.cs.dl.util.concurrent.QueuedExecutor;
-
-/**
- * @author <a href="mailto:ovidiu at jboss.org">Ovidiu Feodorov</a>
- * @author <a href="mailto:tim.fox at jboss.com">Tim Fox</a>
- * @version <tt>$Revision$</tt>
- *
- * $Id$
- */
-public class RecoverableQueueTest extends QueueTestBase
-{
-   // Constants -----------------------------------------------------
-
-   // Static --------------------------------------------------------
-   
-   // Attributes ----------------------------------------------------
-
-  
-   // Constructors --------------------------------------------------
-
-   public RecoverableQueueTest(String name)
-   {
-      super(name);
-   }
-
-   // ChannelTestBase overrides  ------------------------------------
-
-   public void setUp() throws Exception
-   {
-      super.setUp();
-      
-      ms = new SimpleMessageStore("s14");
-
-      channel = new Queue(1, ms, pm, null, true, 100, 20, 10, new QueuedExecutor());
-
-      
-      tr.start(pm);
-   }
-
-   public void tearDown() throws Exception
-   {
-      channel.close();
-      channel = null;
-
-      pm.stop();
-      ms = null;
-
-      super.tearDown();
-   }
-
-   public void crashChannel() throws Exception
-   {
-      channel.close();
-      channel = null;
-
-   }
-
-   public void recoverChannel() throws Exception
-   {
-      channel = new Queue(1, ms, pm, null, true, 100, 20, 10, new QueuedExecutor());
-   }
-
-   // Public --------------------------------------------------------
-
-   // Package protected ---------------------------------------------
-   
-   // Protected -----------------------------------------------------
-   
-   // Private -------------------------------------------------------
-   
-   // Inner classes -------------------------------------------------   
-}

Deleted: trunk/tests/src/org/jboss/test/messaging/core/local/RecoverableSubscriptionTest.java
===================================================================
--- trunk/tests/src/org/jboss/test/messaging/core/local/RecoverableSubscriptionTest.java	2006-08-30 09:26:13 UTC (rev 1236)
+++ trunk/tests/src/org/jboss/test/messaging/core/local/RecoverableSubscriptionTest.java	2006-08-30 18:36:36 UTC (rev 1237)
@@ -1,108 +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.core.local;
-
-import org.jboss.messaging.core.local.CoreSubscription;
-import org.jboss.messaging.core.plugin.JDBCPersistenceManager;
-import org.jboss.messaging.core.plugin.SimpleMessageStore;
-import org.jboss.test.messaging.core.base.ChannelTestBase;
-
-import EDU.oswego.cs.dl.util.concurrent.QueuedExecutor;
-
-/**
- * @author <a href="mailto:ovidiu at jboss.org">Ovidiu Feodorov</a>
- * @author <a href="mailto:tim.fox at jboss.com">Tim Fox</a>
- * @version <tt>$Revision$</tt>
- *
- * $Id$
- */
-public class RecoverableSubscriptionTest extends ChannelTestBase
-{
-   // Constants -----------------------------------------------------
-
-   // Static --------------------------------------------------------
-   
-   // Attributes ----------------------------------------------------
-
-   private JDBCPersistenceManager tl;
-
-   // Constructors --------------------------------------------------                                        /
-
-   public RecoverableSubscriptionTest(String name)
-   {
-      super(name);
-   }
-
-   // ChannelTestBase overrides  ------------------------------------
-
-   public void setUp() throws Exception
-   {
-      super.setUp();
-
-      tl = new JDBCPersistenceManager(sc.getDataSource(), sc.getTransactionManager());
-      tl.start();
-
-      ms = new SimpleMessageStore("s20");
-
-      tr.start(tl);
-   
-      channel = new CoreSubscription(123, null, ms, tl, null, true, 100, 20, 10, new QueuedExecutor(), null);
-      
-
-      log.debug("setup done");
-   }
-
-   public void tearDown() throws Exception
-   {
-      log.debug("tearing down");
-
-      channel.close();
-      channel = null;
-
-      tl.stop();
-      ms = null;
-
-      super.tearDown();
-   }
-
-   public void crashChannel() throws Exception
-   {
-      channel.close();
-      channel = null;
-
-   }
-
-   public void recoverChannel() throws Exception
-   {
-      //channel = new Queue(1, ms, tl, true, 100, 20);
-   }
-
-   // Public --------------------------------------------------------
-
-   // Package protected ---------------------------------------------
-   
-   // Protected -----------------------------------------------------
-   
-   // Private -------------------------------------------------------
-   
-   // Inner classes -------------------------------------------------   
-}

Modified: trunk/tests/src/org/jboss/test/messaging/core/local/RoundRobinPointToPointRouterTest.java
===================================================================
--- trunk/tests/src/org/jboss/test/messaging/core/local/RoundRobinPointToPointRouterTest.java	2006-08-30 09:26:13 UTC (rev 1236)
+++ trunk/tests/src/org/jboss/test/messaging/core/local/RoundRobinPointToPointRouterTest.java	2006-08-30 18:36:36 UTC (rev 1237)
@@ -21,8 +21,6 @@
 */
 package org.jboss.test.messaging.core.local;
 
-import java.util.Set;
-
 import org.jboss.messaging.core.Delivery;
 import org.jboss.messaging.core.DeliveryObserver;
 import org.jboss.messaging.core.MessageReference;
@@ -87,81 +85,68 @@
       
       MessageReference ref = new SimpleMessageReference();
       
-      Set dels = router.handle(null, ref, null);
-      assertNotNull(dels);
-      assertEquals(1, dels.size());
+      Delivery del = router.handle(null, ref, null);
+      assertNotNull(del);
       checkReceiverGotRef(receivers, 0);
       resetReceivers(receivers);
       
-      dels = router.handle(null, ref, null);
-      assertNotNull(dels);
-      assertEquals(1, dels.size());
+      del = router.handle(null, ref, null);
+      assertNotNull(del);
       checkReceiverGotRef(receivers, 1);
       resetReceivers(receivers);
       
-      dels = router.handle(null, ref, null);
-      assertNotNull(dels);
-      assertEquals(1, dels.size());
+      del = router.handle(null, ref, null);
+      assertNotNull(del);
       checkReceiverGotRef(receivers, 2);
       resetReceivers(receivers);
       
-      dels = router.handle(null, ref, null);
-      assertNotNull(dels);
-      assertEquals(1, dels.size());
+      del = router.handle(null, ref, null);
+      assertNotNull(del);
       checkReceiverGotRef(receivers, 3);
       resetReceivers(receivers);
       
-      dels = router.handle(null, ref, null);
-      assertNotNull(dels);
-      assertEquals(1, dels.size());
+      del = router.handle(null, ref, null);
+      assertNotNull(del);
       checkReceiverGotRef(receivers, 4);
       resetReceivers(receivers);
       
-      dels = router.handle(null, ref, null);
-      assertNotNull(dels);
-      assertEquals(1, dels.size());
+      del = router.handle(null, ref, null);
+      assertNotNull(del);
       checkReceiverGotRef(receivers, 5);
       resetReceivers(receivers);
       
-      dels = router.handle(null, ref, null);
-      assertNotNull(dels);
-      assertEquals(1, dels.size());
+      del = router.handle(null, ref, null);
+      assertNotNull(del);
       checkReceiverGotRef(receivers, 6);
       resetReceivers(receivers);
       
-      dels = router.handle(null, ref, null);
-      assertNotNull(dels);
-      assertEquals(1, dels.size());
+      del = router.handle(null, ref, null);
+      assertNotNull(del);
       checkReceiverGotRef(receivers, 7);
       resetReceivers(receivers);
       
-      dels = router.handle(null, ref, null);
-      assertNotNull(dels);
-      assertEquals(1, dels.size());
+      del = router.handle(null, ref, null);
+      assertNotNull(del);
       checkReceiverGotRef(receivers, 8);
       resetReceivers(receivers);
       
-      dels = router.handle(null, ref, null);
-      assertNotNull(dels);
-      assertEquals(1, dels.size());
+      del = router.handle(null, ref, null);
+      assertNotNull(del);
       checkReceiverGotRef(receivers, 9);
       resetReceivers(receivers);
       
-      dels = router.handle(null, ref, null);
-      assertNotNull(dels);
-      assertEquals(1, dels.size());
+      del = router.handle(null, ref, null);
+      assertNotNull(del);
       checkReceiverGotRef(receivers, 0);
       resetReceivers(receivers);
       
-      dels = router.handle(null, ref, null);
-      assertNotNull(dels);
-      assertEquals(1, dels.size());
+      del = router.handle(null, ref, null);
+      assertNotNull(del);
       checkReceiverGotRef(receivers, 1);
       resetReceivers(receivers);
       
-      dels = router.handle(null, ref, null);
-      assertNotNull(dels);
-      assertEquals(1, dels.size());
+      del = router.handle(null, ref, null);
+      assertNotNull(del);
       checkReceiverGotRef(receivers, 2);
       resetReceivers(receivers);
       
@@ -191,63 +176,53 @@
       
       MessageReference ref = new SimpleMessageReference();
       
-      Set dels = router.handle(null, ref, null);
-      assertNotNull(dels);
-      assertEquals(1, dels.size());
+      Delivery del = router.handle(null, ref, null);
+      assertNotNull(del);
       checkReceiverGotRef(receivers, 0);
       resetReceivers(receivers);
       
-      dels = router.handle(null, ref, null);
-      assertNotNull(dels);
-      assertEquals(1, dels.size());
+      del = router.handle(null, ref, null);
+      assertNotNull(del);
       checkReceiverGotRef(receivers, 1);
       resetReceivers(receivers);
       
-      dels = router.handle(null, ref, null);
-      assertNotNull(dels);
-      assertEquals(1, dels.size());
+      del = router.handle(null, ref, null);
+      assertNotNull(del);
       checkReceiverGotRef(receivers, 3);
       resetReceivers(receivers);
       
-      dels = router.handle(null, ref, null);
-      assertNotNull(dels);
-      assertEquals(1, dels.size());
+      del = router.handle(null, ref, null);
+      assertNotNull(del);
       checkReceiverGotRef(receivers, 4);
       resetReceivers(receivers);
       
-      dels = router.handle(null, ref, null);
-      assertNotNull(dels);
-      assertEquals(1, dels.size());
+      del = router.handle(null, ref, null);
+      assertNotNull(del);
       checkReceiverGotRef(receivers, 7);
       resetReceivers(receivers);
       
-      dels = router.handle(null, ref, null);
-      assertNotNull(dels);
-      assertEquals(1, dels.size());
+      del = router.handle(null, ref, null);
+      assertNotNull(del);
       checkReceiverGotRef(receivers, 8);
       resetReceivers(receivers);
       
-      dels = router.handle(null, ref, null);
-      assertNotNull(dels);
-      assertEquals(1, dels.size());
+      del = router.handle(null, ref, null);
+      assertNotNull(del);
       checkReceiverGotRef(receivers, 0);
       resetReceivers(receivers);
       
-      dels = router.handle(null, ref, null);
-      assertNotNull(dels);
-      assertEquals(1, dels.size());
+      del = router.handle(null, ref, null);
+      assertNotNull(del);
       checkReceiverGotRef(receivers, 1);
       resetReceivers(receivers);
       
-      dels = router.handle(null, ref, null);
-      assertNotNull(dels);
-      assertEquals(1, dels.size());
+      del = router.handle(null, ref, null);
+      assertNotNull(del);
       checkReceiverGotRef(receivers, 3);
       resetReceivers(receivers);
       
-      dels = router.handle(null, ref, null);
-      assertNotNull(dels);
-      assertEquals(1, dels.size());
+      del = router.handle(null, ref, null);
+      assertNotNull(del);
       checkReceiverGotRef(receivers, 4);
       resetReceivers(receivers);
       
@@ -274,19 +249,17 @@
       
       MessageReference ref = new SimpleMessageReference();
       
-      Set dels = router.handle(null, ref, null);
-      assertNotNull(dels);
-      assertEquals(0, dels.size());
+      Delivery del = router.handle(null, ref, null);
+      assertNull(del);
+
+      del = router.handle(null, ref, null);
+      assertNull(del);
       
-      dels = router.handle(null, ref, null);
-      assertNotNull(dels);
-      assertEquals(0, dels.size());
+      del = router.handle(null, ref, null);
+      assertNull(del);
+
       
-      dels = router.handle(null, ref, null);
-      assertNotNull(dels);
-      assertEquals(0, dels.size());
       
-      
    }
    
    public void testSomeNoSelectorMatch()
@@ -313,63 +286,53 @@
       
       MessageReference ref = new SimpleMessageReference();
       
-      Set dels = router.handle(null, ref, null);
-      assertNotNull(dels);
-      assertEquals(1, dels.size());
+      Delivery del = router.handle(null, ref, null);
+      assertNotNull(del);
       checkReceiverGotRef(receivers, 0);
       resetReceivers(receivers);
       
-      dels = router.handle(null, ref, null);
-      assertNotNull(dels);
-      assertEquals(1, dels.size());
+      del = router.handle(null, ref, null);
+      assertNotNull(del);
       checkReceiverGotRef(receivers, 1);
       resetReceivers(receivers);
       
-      dels = router.handle(null, ref, null);
-      assertNotNull(dels);
-      assertEquals(1, dels.size());
+      del = router.handle(null, ref, null);
+      assertNotNull(del);
       checkReceiverGotRef(receivers, 3);
       resetReceivers(receivers);
       
-      dels = router.handle(null, ref, null);
-      assertNotNull(dels);
-      assertEquals(1, dels.size());
+      del = router.handle(null, ref, null);
+      assertNotNull(del);
       checkReceiverGotRef(receivers, 4);
       resetReceivers(receivers);
       
-      dels = router.handle(null, ref, null);
-      assertNotNull(dels);
-      assertEquals(1, dels.size());
+      del = router.handle(null, ref, null);
+      assertNotNull(del);
       checkReceiverGotRef(receivers, 7);
       resetReceivers(receivers);
       
-      dels = router.handle(null, ref, null);
-      assertNotNull(dels);
-      assertEquals(1, dels.size());
+      del = router.handle(null, ref, null);
+      assertNotNull(del);
       checkReceiverGotRef(receivers, 8);
       resetReceivers(receivers);
       
-      dels = router.handle(null, ref, null);
-      assertNotNull(dels);
-      assertEquals(1, dels.size());
+      del = router.handle(null, ref, null);
+      assertNotNull(del);
       checkReceiverGotRef(receivers, 0);
       resetReceivers(receivers);
       
-      dels = router.handle(null, ref, null);
-      assertNotNull(dels);
-      assertEquals(1, dels.size());
+      del = router.handle(null, ref, null);
+      assertNotNull(del);
       checkReceiverGotRef(receivers, 1);
       resetReceivers(receivers);
       
-      dels = router.handle(null, ref, null);
-      assertNotNull(dels);
-      assertEquals(1, dels.size());
+      del = router.handle(null, ref, null);
+      assertNotNull(del);
       checkReceiverGotRef(receivers, 3);
       resetReceivers(receivers);
       
-      dels = router.handle(null, ref, null);
-      assertNotNull(dels);
-      assertEquals(1, dels.size());
+      del = router.handle(null, ref, null);
+      assertNotNull(del);
       checkReceiverGotRef(receivers, 4);
       resetReceivers(receivers);
       
@@ -395,18 +358,17 @@
       
       MessageReference ref = new SimpleMessageReference();
       
-      Set dels = router.handle(null, ref, null);
-      assertNotNull(dels);
-      assertEquals(1, dels.size());
-      assertFalse(((SimpleDelivery)dels.iterator().next()).isSelectorAccepted());
+      Delivery del = router.handle(null, ref, null);
+      assertNotNull(del);
+      assertFalse(del.isSelectorAccepted());
       
-      dels = router.handle(null, ref, null);
-      assertNotNull(dels);
-      assertFalse(((SimpleDelivery)dels.iterator().next()).isSelectorAccepted());
+      del = router.handle(null, ref, null);
+      assertNotNull(del);
+      assertFalse(del.isSelectorAccepted());
       
-      dels = router.handle(null, ref, null);
-      assertNotNull(dels);
-      assertFalse(((SimpleDelivery)dels.iterator().next()).isSelectorAccepted());
+      del = router.handle(null, ref, null);
+      assertNotNull(del);
+      assertFalse(del.isSelectorAccepted());
            
    }
    
@@ -416,17 +378,14 @@
 
       MessageReference ref = new SimpleMessageReference();
       
-      Set dels = router.handle(null, ref, null);
-      assertNotNull(dels);
-      assertEquals(0, dels.size());
+      Delivery del = router.handle(null, ref, null);
+      assertNotNull(del);
       
-      dels = router.handle(null, ref, null);
-      assertNotNull(dels);
-      assertEquals(0, dels.size());
+      del = router.handle(null, ref, null);
+      assertNotNull(del);
       
-      dels = router.handle(null, ref, null);
-      assertNotNull(dels);
-      assertEquals(0, dels.size());     
+      del = router.handle(null, ref, null);
+      assertNotNull(del);    
    }
 
 

Deleted: trunk/tests/src/org/jboss/test/messaging/core/local/SubscriptionWithFilterTest.java
===================================================================
--- trunk/tests/src/org/jboss/test/messaging/core/local/SubscriptionWithFilterTest.java	2006-08-30 09:26:13 UTC (rev 1236)
+++ trunk/tests/src/org/jboss/test/messaging/core/local/SubscriptionWithFilterTest.java	2006-08-30 18:36:36 UTC (rev 1237)
@@ -1,147 +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.core.local;
-
-import org.jboss.messaging.core.Filter;
-import org.jboss.messaging.core.Message;
-import org.jboss.messaging.core.Routable;
-import org.jboss.messaging.core.local.CoreSubscription;
-import org.jboss.messaging.core.message.CoreMessage;
-import org.jboss.messaging.core.plugin.JDBCPersistenceManager;
-import org.jboss.messaging.core.plugin.SimpleMessageStore;
-import org.jboss.messaging.core.plugin.contract.MessageStore;
-import org.jboss.messaging.core.plugin.contract.PersistenceManager;
-import org.jboss.test.messaging.MessagingTestCase;
-import org.jboss.test.messaging.tools.jmx.ServiceContainer;
-
-import EDU.oswego.cs.dl.util.concurrent.QueuedExecutor;
-
-/**
- * 
- * A SubscriptionWithFilterTest.
- * 
- * @author <a href="tim.fox at jboss.com">Tim Fox</a>
- * @version $Revision$
- *
- * $Id$
- */
-public class SubscriptionWithFilterTest extends MessagingTestCase
-{
-   public SubscriptionWithFilterTest(String name)
-   {
-      super(name);
-   }
-
-   protected PersistenceManager pm;
-   
-   protected MessageStore ms;
-   
-   protected ServiceContainer sc;
-    
-   // ChannelTestBase overrides  ------------------------------------
-
-   public void setUp() throws Exception
-   {
-      super.setUp();
-      
-      sc = new ServiceContainer("all,-remoting,-security");
-      sc.start();
-      
-      pm = new JDBCPersistenceManager(sc.getDataSource(), sc.getTransactionManager());
-      pm.start();
-      
-      ms = new SimpleMessageStore("123");
-      
-      
-      log.debug("setup done");
-   }
-
-   public void tearDown() throws Exception
-   {
-      pm.stop();
-      
-      sc.stop();
-
-      super.tearDown();
-   }
-   
-
-   public void testWithFilter()
-   {
-      Filter f = new SimpleFilter(3);
-      
-      CoreSubscription sub = new CoreSubscription(123, null, ms, pm, null, false, 100, 20, 10, new QueuedExecutor(), f);
-            
-      Message m1 = new CoreMessage(1, false, 0, 0, (byte)0, null, null, 0);
-      Message m2 = new CoreMessage(2, false, 0, 0, (byte)0, null, null, 0);
-      Message m3 = new CoreMessage(3, false, 0, 0, (byte)0, null, null, 0);
-      Message m4 = new CoreMessage(4, false, 0, 0, (byte)0, null, null, 0);
-      Message m5 = new CoreMessage(5, false, 0, 0, (byte)0, null, null, 0);
-      
-      assertNull(sub.handle(null, m1, null));
-      assertNull(sub.handle(null, m2, null));
-      assertNotNull(sub.handle(null, m3, null));
-      assertNull(sub.handle(null, m4, null));
-      assertNull(sub.handle(null, m5, null));
-      
-   }
-   
-   public void testWithoutFilter()
-   {
-      CoreSubscription sub = new CoreSubscription(123, null, ms, pm, null, false, 100, 20, 10, new QueuedExecutor(), null);
-            
-      Message m1 = new CoreMessage(1, false, 0, 0, (byte)0, null, null, 0);
-      Message m2 = new CoreMessage(2, false, 0, 0, (byte)0, null, null, 0);
-      Message m3 = new CoreMessage(3, false, 0, 0, (byte)0, null, null, 0);
-      Message m4 = new CoreMessage(4, false, 0, 0, (byte)0, null, null, 0);
-      Message m5 = new CoreMessage(5, false, 0, 0, (byte)0, null, null, 0);
-      
-      assertNotNull(sub.handle(null, m1, null));
-      assertNotNull(sub.handle(null, m2, null));
-      assertNotNull(sub.handle(null, m3, null));
-      assertNotNull(sub.handle(null, m4, null));
-      assertNotNull(sub.handle(null, m5, null));
-      
-   }
-   
-   public void crashChannel() throws Exception
-   {
-   }
-
-   public void recoverChannel() throws Exception
-   {
-   }
-   
-   class SimpleFilter implements Filter
-   {
-      private long value;
-      SimpleFilter(long value)
-      {
-         this.value = value;
-      }
-      public boolean accept(Routable routable)
-      {
-         CoreMessage msg = (CoreMessage)routable;
-         return msg.getMessageID() == value;
-      }
-   }
-}

Deleted: trunk/tests/src/org/jboss/test/messaging/core/local/TopicTest.java
===================================================================
--- trunk/tests/src/org/jboss/test/messaging/core/local/TopicTest.java	2006-08-30 09:26:13 UTC (rev 1236)
+++ trunk/tests/src/org/jboss/test/messaging/core/local/TopicTest.java	2006-08-30 18:36:36 UTC (rev 1237)
@@ -1,72 +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.core.local;
-
-import org.jboss.test.messaging.core.local.base.TopicTestBase;
-import org.jboss.messaging.core.local.Topic;
-
-/**
- * @author <a href="mailto:ovidiu at jboss.org">Ovidiu Feodorov</a>
- * @version <tt>$Revision$</tt>
- * 
- * $Id$
- */
-public class TopicTest extends TopicTestBase
-{
-   // Constants -----------------------------------------------------
-
-   // Static --------------------------------------------------------
-   
-   // Attributes ----------------------------------------------------
-
-   // Constructors --------------------------------------------------
-
-   public TopicTest(String name)
-   {
-      super(name);
-   }
-
-   // ChannelTestBase overrides  ------------------------------------
-
-   public void setUp() throws Exception
-   {
-      super.setUp();
-
-      topic = new Topic(1, 100, 20, 10);
-   }
-
-   public void tearDown() throws Exception
-   {
-      topic = null;
-      super.tearDown();
-   }
-
-   // Public --------------------------------------------------------
-
-   // Package protected ---------------------------------------------
-   
-   // Protected -----------------------------------------------------
-   
-   // Private -------------------------------------------------------
-   
-   // Inner classes -------------------------------------------------   
-}

Deleted: trunk/tests/src/org/jboss/test/messaging/core/local/base/QueueTestBase.java
===================================================================
--- trunk/tests/src/org/jboss/test/messaging/core/local/base/QueueTestBase.java	2006-08-30 09:26:13 UTC (rev 1236)
+++ trunk/tests/src/org/jboss/test/messaging/core/local/base/QueueTestBase.java	2006-08-30 18:36:36 UTC (rev 1237)
@@ -1,148 +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.core.local.base;
-
-import org.jboss.test.messaging.core.base.ChannelTestBase;
-import org.jboss.test.messaging.core.SimpleDeliveryObserver;
-import org.jboss.test.messaging.core.SimpleReceiver;
-import org.jboss.messaging.core.message.MessageFactory;
-import org.jboss.messaging.core.Delivery;
-import org.jboss.messaging.core.Message;
-import org.jboss.messaging.core.plugin.JDBCPersistenceManager;
-
-import java.util.List;
-
-/**
- * @author <a href="mailto:ovidiu at jboss.org">Ovidiu Feodorov</a>
- * @version <tt>$Revision$</tt>
- * 
- * $Id$
- */
-public abstract class QueueTestBase extends ChannelTestBase
-{
-   // Constants -----------------------------------------------------
-
-   // Static --------------------------------------------------------
-   
-   // Attributes ----------------------------------------------------
-   
-   protected JDBCPersistenceManager pm;
-
-   // Constructors --------------------------------------------------
-   
-   public QueueTestBase(String name)
-   {
-      super(name);
-   }
-   
-   // Public --------------------------------------------------------
-
-   public void setUp() throws Exception
-   {
-      super.setUp();
-      
-      pm = new JDBCPersistenceManager(sc.getDataSource(), sc.getTransactionManager());
-      pm.start();
-   }
-
-   public void tearDown() throws Exception
-   {
-      super.tearDown();
-   }
-
-   public void testUnreliableSynchronousDeliveryTwoReceivers() throws Exception
-   {
-      if (channel.isRecoverable())
-      {
-         // we test only non-recoverable channels now
-         return;
-      }
-
-      SimpleDeliveryObserver observer = new SimpleDeliveryObserver();
-      SimpleReceiver r1 = new SimpleReceiver("ONE", SimpleReceiver.ACKING);
-      SimpleReceiver r2 = new SimpleReceiver("TWO", SimpleReceiver.ACKING);
-      channel.add(r1);
-      channel.add(r2);
-
-      Delivery d = channel.handle(observer, MessageFactory.createCoreMessage(0, false, "payload"), null);
-
-      assertTrue(d.isDone());
-      List l1 = r1.getMessages();
-      List l2 = r2.getMessages();
-      if (l2.isEmpty())
-      {
-         assertEquals(1, l1.size());
-         Message m = (Message)l1.get(0);
-         assertEquals("payload", m.getPayload());
-      }
-      else
-      {
-         assertTrue(l1.isEmpty());
-         assertEquals(1, l2.size());
-         Message m = (Message)l2.get(0);
-         assertEquals("payload", m.getPayload());
-      }
-   }
-
-
-   public void testReliableSynchronousDeliveryTwoReceivers() throws Exception
-   {
-      if (!channel.isRecoverable())
-      {
-         // we test only recoverable channels now
-         return;
-      }
-
-      SimpleDeliveryObserver observer = new SimpleDeliveryObserver();
-      SimpleReceiver r1 = new SimpleReceiver("ONE", SimpleReceiver.ACKING);
-      SimpleReceiver r2 = new SimpleReceiver("TWO", SimpleReceiver.ACKING);
-      assertTrue(channel.add(r1));
-      assertTrue(channel.add(r2));
-
-      Delivery d = channel.handle(observer, MessageFactory.createCoreMessage(0, true, "payload"), null);
-
-      assertTrue(d.isDone());
-      List l1 = r1.getMessages();
-      List l2 = r2.getMessages();
-      if (l2.isEmpty())
-      {
-         assertEquals(1, l1.size());
-         Message m = (Message)l1.get(0);
-         assertEquals("payload", m.getPayload());
-      }
-      else
-      {
-         assertTrue(l1.isEmpty());
-         assertEquals(1, l2.size());
-         Message m = (Message)l2.get(0);
-         assertEquals("payload", m.getPayload());
-      }
-   }
-   
-   // Package protected ---------------------------------------------
-   
-   // Protected -----------------------------------------------------
-   
-   // Private -------------------------------------------------------
-   
-   // Inner classes -------------------------------------------------   
-}

Deleted: trunk/tests/src/org/jboss/test/messaging/core/local/base/TopicTestBase.java
===================================================================
--- trunk/tests/src/org/jboss/test/messaging/core/local/base/TopicTestBase.java	2006-08-30 09:26:13 UTC (rev 1236)
+++ trunk/tests/src/org/jboss/test/messaging/core/local/base/TopicTestBase.java	2006-08-30 18:36:36 UTC (rev 1237)
@@ -1,249 +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.core.local.base;
-
-import java.util.Iterator;
-
-import org.jboss.messaging.core.Delivery;
-import org.jboss.messaging.core.Message;
-import org.jboss.messaging.core.MessageReference;
-import org.jboss.messaging.core.local.CoreDestination;
-import org.jboss.messaging.core.message.MessageFactory;
-import org.jboss.messaging.core.plugin.JDBCPersistenceManager;
-import org.jboss.messaging.core.plugin.SimpleMessageStore;
-import org.jboss.messaging.core.plugin.contract.MessageStore;
-import org.jboss.messaging.core.plugin.contract.PersistenceManager;
-import org.jboss.test.messaging.MessagingTestCase;
-import org.jboss.test.messaging.core.SimpleDeliveryObserver;
-import org.jboss.test.messaging.core.SimpleReceiver;
-import org.jboss.test.messaging.tools.jmx.ServiceContainer;
-
-/**
- * @author <a href="mailto:ovidiu at jboss.org">Ovidiu Feodorov</a>
- * @author <a href="mailto:tim.fox at jboss.com">Tim Fox</a>
- * @version <tt>$Revision$</tt>
- * $Id$
- */
-public abstract class TopicTestBase extends MessagingTestCase
-{
-   // Constants -----------------------------------------------------
-
-   // Static --------------------------------------------------------
-   
-   // Attributes ----------------------------------------------------
-
-   protected ServiceContainer sc;
-
-   protected CoreDestination topic;
-
-   protected PersistenceManager tl;
-   protected MessageStore ms;
-
-   // Constructors --------------------------------------------------
-   
-   public TopicTestBase(String name)
-   {
-      super(name);
-   }
-   
-   // Public --------------------------------------------------------
-
-   public void setUp() throws Exception
-   {
-      super.setUp();
-
-      sc = new ServiceContainer("all,-remoting,-security");
-      sc.start();
-
-      tl = new JDBCPersistenceManager(sc.getDataSource(), sc.getTransactionManager());
-      ((JDBCPersistenceManager)tl).start();
-      
-      ms = new SimpleMessageStore("s33");
-
-   }
-
-   public void tearDown() throws Exception
-   {
-      tl = null;
-      ms = null;
-      sc.stop();
-      sc = null;
-      super.tearDown();
-   }
-
-   /**
-    * Rejecting receivers are ignored.
-    */
-   public void testRejectingReceiver() throws Exception
-   {
-      SimpleReceiver rec = new SimpleReceiver("REJECTING", SimpleReceiver.REJECTING);
-      topic.add(rec);
-
-      Message m = MessageFactory.createCoreMessage(0, false, "payload");
-      MessageReference ref = ms.reference(m);
-
-      Delivery d = topic.handle(null, ref, null);
-      assertTrue(d.isDone());
-   }
-
-   /**
-    * Broken receivers are ignored.
-    */
-   public void testBrokenReceiver() throws Exception
-   {
-      SimpleReceiver rec = new SimpleReceiver("BROKEN", SimpleReceiver.BROKEN);
-      topic.add(rec);
-
-      Message m = MessageFactory.createCoreMessage(0, false, "payload");
-      MessageReference ref = ms.reference(m);
-
-      Delivery d = topic.handle(null, ref, null);
-      assertTrue(d.isDone());
-   }
-
-   /**
-    * No NACKING receiver must be allowed by a topic. If this situation occurs, the topic must
-    * throw IllegalStateException.
-    */
-   public void testNACKINGReceiver() throws Exception
-   {
-      SimpleReceiver rec = new SimpleReceiver("NACKING", SimpleReceiver.NACKING);
-      topic.add(rec);
-
-      Message m = MessageFactory.createCoreMessage(0, false, "payload");
-      MessageReference ref = ms.reference(m);
-
-      try
-      {
-         topic.handle(null, ref, null);
-         fail("this should throw exception");
-      }
-      catch(IllegalStateException e)
-      {
-         // OK
-      }
-   }
-
-
-
-   //
-   // Zero receivers
-   //
-
-   ////
-   //// Unreliable message
-   ////
-
-   public void testTopic_1() throws Exception
-   {
-      SimpleDeliveryObserver observer = new SimpleDeliveryObserver();
-      assertFalse(topic.iterator().hasNext());
-
-      Message m = MessageFactory.createCoreMessage(0, false, "payload");
-      Delivery d = topic.handle(observer, ms.reference(m), null);
-
-      assertTrue(d.isDone());
-   }
-
-   ////
-   //// Reliable message
-   ////
-
-   // a reliable message is not handled differently
-
-   //
-   // One receiver
-   //
-
-   ////
-   //// Unreliable message
-   ////
-
-   public void testTopic_2() throws Exception
-   {
-      SimpleDeliveryObserver observer = new SimpleDeliveryObserver();
-
-      SimpleReceiver r = new SimpleReceiver("ACKING", SimpleReceiver.ACKING);
-      assertTrue(topic.add(r));
-
-      Iterator i = topic.iterator();
-      assertEquals(r, i.next());
-      assertFalse(i.hasNext());
-
-      Message m = MessageFactory.createCoreMessage(0, false, "payload0");
-      Delivery d = topic.handle(observer, ms.reference(m), null);
-
-      assertTrue(d.isDone());
-
-      assertEquals(1, r.getMessages().size());
-      assertEquals(0, ((Message)r.getMessages().get(0)).getMessageID());
-      assertEquals("payload0", ((Message)r.getMessages().get(0)).getPayload());
-   }
-
-   ////
-   //// Reliable message
-   ////
-
-   // a reliable message is not handled differently
-
-   //
-   // Two receivers
-   //
-   
-   public void testTopic_3() throws Exception
-   {
-      SimpleDeliveryObserver observer = new SimpleDeliveryObserver();
-
-      SimpleReceiver r = new SimpleReceiver("ACKING", SimpleReceiver.ACKING);
-      SimpleReceiver r2 = new SimpleReceiver("ACKING2", SimpleReceiver.ACKING);
-
-      assertTrue(topic.add(r));
-      assertTrue(topic.add(r2));
-
-      Message m = MessageFactory.createCoreMessage(0, false, "payload0");
-      Delivery d = topic.handle(observer, ms.reference(m), null);
-
-      assertTrue(d.isDone());
-
-      assertEquals(1, r.getMessages().size());
-      assertEquals(0, ((Message)r.getMessages().get(0)).getMessageID());
-      assertEquals("payload0", ((Message)r.getMessages().get(0)).getPayload());
-
-      assertEquals(1, r2.getMessages().size());
-      assertEquals(0, ((Message)r2.getMessages().get(0)).getMessageID());
-      assertEquals("payload0", ((Message)r2.getMessages().get(0)).getPayload());
-   }
-
-   ////
-   //// Reliable message
-   ////
-
-   // a reliable message is not handled differently
-
-   // Package protected ---------------------------------------------
-   
-   // Protected -----------------------------------------------------
-   
-   // Private -------------------------------------------------------
-   
-   // Inner classes -------------------------------------------------   
-}

Modified: trunk/tests/src/org/jboss/test/messaging/core/message/JBossMessageTest.java
===================================================================
--- trunk/tests/src/org/jboss/test/messaging/core/message/JBossMessageTest.java	2006-08-30 09:26:13 UTC (rev 1236)
+++ trunk/tests/src/org/jboss/test/messaging/core/message/JBossMessageTest.java	2006-08-30 18:36:36 UTC (rev 1237)
@@ -57,8 +57,8 @@
    protected void setUp() throws Exception
    {
       rs = (MessageSupport)MessageFactory.createJBossMessage(0, false, 0, 0, (byte)4, null,
-                                                        null, 0, JBossMessage.TYPE,
-                                                        null, null, null, null, null, null);
+                                                             null, 0, JBossMessage.TYPE,
+                                                             null, null, null, null, null, null);
       super.setUp();
       log.debug("setup done");
    }

Modified: trunk/tests/src/org/jboss/test/messaging/core/message/SimpleMessageReferenceTest.java
===================================================================
--- trunk/tests/src/org/jboss/test/messaging/core/message/SimpleMessageReferenceTest.java	2006-08-30 09:26:13 UTC (rev 1236)
+++ trunk/tests/src/org/jboss/test/messaging/core/message/SimpleMessageReferenceTest.java	2006-08-30 18:36:36 UTC (rev 1237)
@@ -71,7 +71,7 @@
       Message m = MessageFactory.createCoreMessage(0);
       m.putHeader("headerName01", "headerValue01");
 
-      MessageStore ms = new SimpleMessageStore("0");
+      MessageStore ms = new SimpleMessageStore();
 
       rs = (RoutableSupport)ms.reference(m);
 

Modified: trunk/tests/src/org/jboss/test/messaging/core/message/base/MessageSupportTestBase.java
===================================================================
--- trunk/tests/src/org/jboss/test/messaging/core/message/base/MessageSupportTestBase.java	2006-08-30 09:26:13 UTC (rev 1236)
+++ trunk/tests/src/org/jboss/test/messaging/core/message/base/MessageSupportTestBase.java	2006-08-30 18:36:36 UTC (rev 1237)
@@ -21,8 +21,6 @@
 */
 package org.jboss.test.messaging.core.message.base;
 
-
-
 /**
  * @author <a href="mailto:ovidiu at jboss.org">Ovidiu Feodorov</a>
  * @version <tt>$Revision$</tt>

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-08-30 09:26:13 UTC (rev 1236)
+++ trunk/tests/src/org/jboss/test/messaging/core/paging/ChannelShare_NP_2PCTest.java	2006-08-30 18:36:36 UTC (rev 1237)
@@ -23,10 +23,9 @@
 
 import java.util.List;
 
-import org.jboss.messaging.core.ChannelSupport;
 import org.jboss.messaging.core.Message;
 import org.jboss.messaging.core.MessageReference;
-import org.jboss.messaging.core.local.Queue;
+import org.jboss.messaging.core.local.MessageQueue;
 import org.jboss.messaging.core.message.MessageFactory;
 import org.jboss.messaging.core.plugin.LockMap;
 import org.jboss.messaging.core.tx.Transaction;
@@ -65,9 +64,9 @@
    
    public void testChannelShareNP_2PC() throws Throwable
    {
-      ChannelSupport queue1 = new Queue(1, ms, pm, null, true, 100, 20, 10, new QueuedExecutor());
+      MessageQueue queue1 = new MessageQueue(1, ms, pm, true, true, 100, 20, 10, new QueuedExecutor(), null);
       
-      ChannelSupport queue2 = new Queue(2, ms, pm, null, true, 50, 10, 5, new QueuedExecutor());
+      MessageQueue queue2 = new MessageQueue(2, ms, pm, true, true, 50, 10, 5, new QueuedExecutor(), null);
                       
       Message[] msgs = new Message[150];
       

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-08-30 09:26:13 UTC (rev 1236)
+++ trunk/tests/src/org/jboss/test/messaging/core/paging/ChannelShare_NP_NTTest.java	2006-08-30 18:36:36 UTC (rev 1237)
@@ -23,10 +23,9 @@
 
 import java.util.List;
 
-import org.jboss.messaging.core.ChannelSupport;
 import org.jboss.messaging.core.Message;
 import org.jboss.messaging.core.MessageReference;
-import org.jboss.messaging.core.local.Queue;
+import org.jboss.messaging.core.local.MessageQueue;
 import org.jboss.messaging.core.message.MessageFactory;
 import org.jboss.messaging.core.plugin.LockMap;
 
@@ -64,9 +63,9 @@
    
    public void test1() throws Throwable
    {
-      ChannelSupport queue1 = new Queue(1, ms, pm, null, true, 100, 20, 10, new QueuedExecutor());
+      MessageQueue queue1 = new MessageQueue(1, ms, pm, true, true, 100, 20, 10, new QueuedExecutor(), null);
       
-      ChannelSupport queue2 = new Queue(2, ms, pm, null, true, 50, 10, 5, new QueuedExecutor());
+      MessageQueue queue2 = new MessageQueue(2, ms, pm, true, true, 50, 10, 5, new QueuedExecutor(), null);
                   
       Message[] msgs = new Message[150];
       

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-08-30 09:26:13 UTC (rev 1236)
+++ trunk/tests/src/org/jboss/test/messaging/core/paging/ChannelShare_NP_TTest.java	2006-08-30 18:36:36 UTC (rev 1237)
@@ -23,10 +23,9 @@
 
 import java.util.List;
 
-import org.jboss.messaging.core.ChannelSupport;
 import org.jboss.messaging.core.Message;
 import org.jboss.messaging.core.MessageReference;
-import org.jboss.messaging.core.local.Queue;
+import org.jboss.messaging.core.local.MessageQueue;
 import org.jboss.messaging.core.message.MessageFactory;
 import org.jboss.messaging.core.plugin.LockMap;
 import org.jboss.messaging.core.tx.Transaction;
@@ -65,10 +64,10 @@
    
    public void testChannelShareNP_Transactional() throws Throwable
    {
-      ChannelSupport queue1 = new Queue(1, ms, pm, null, true, 100, 20, 10, new QueuedExecutor());
+      MessageQueue queue1 = new MessageQueue(1, ms, pm, true, true, 100, 20, 10, new QueuedExecutor(), null);
       
-      ChannelSupport queue2 = new Queue(2, ms, pm, null, true, 50, 10, 5, new QueuedExecutor());
-                     
+      MessageQueue queue2 = new MessageQueue(2, ms, pm, true, true, 50, 10, 5, new QueuedExecutor(), null);
+                               
       Message[] msgs = new Message[150];
       
       MessageReference[] refs1 = new MessageReference[150];

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-08-30 09:26:13 UTC (rev 1236)
+++ trunk/tests/src/org/jboss/test/messaging/core/paging/ChannelShare_P_2PCTest.java	2006-08-30 18:36:36 UTC (rev 1237)
@@ -23,10 +23,9 @@
 
 import java.util.List;
 
-import org.jboss.messaging.core.ChannelSupport;
 import org.jboss.messaging.core.Message;
 import org.jboss.messaging.core.MessageReference;
-import org.jboss.messaging.core.local.Queue;
+import org.jboss.messaging.core.local.MessageQueue;
 import org.jboss.messaging.core.message.MessageFactory;
 import org.jboss.messaging.core.plugin.LockMap;
 import org.jboss.messaging.core.tx.Transaction;
@@ -34,6 +33,16 @@
 import EDU.oswego.cs.dl.util.concurrent.QueuedExecutor;
 
 
+/**
+ * 
+ * A ChannelShare_P_2PCTest
+
+ * @author <a href="mailto:tim.fox at jboss.com">Tim Fox</a>
+ * @version <tt>$Revision: 1.1 $</tt>
+ *
+ * $Id$
+ *
+ */
 public class ChannelShare_P_2PCTest extends PagingStateTestBase
 {
    public ChannelShare_P_2PCTest(String name)
@@ -50,10 +59,10 @@
    
    public void test1() throws Throwable
    {
-      ChannelSupport queue1 = new Queue(1, ms, pm, null, true, 100, 20, 10, new QueuedExecutor());
+      MessageQueue queue1 = new MessageQueue(1, ms, pm, true, true, 100, 20, 10, new QueuedExecutor(), null);
       
-      ChannelSupport queue2 = new Queue(2, ms, pm, null, true, 50, 10, 5, new QueuedExecutor());
-                       
+      MessageQueue queue2 = new MessageQueue(2, ms, pm, true, true, 50, 10, 5, new QueuedExecutor(), null);
+                            
       Message[] msgs = new Message[150];
       
       MessageReference[] refs1 = new MessageReference[150];

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-08-30 09:26:13 UTC (rev 1236)
+++ trunk/tests/src/org/jboss/test/messaging/core/paging/ChannelShare_P_NTTest.java	2006-08-30 18:36:36 UTC (rev 1237)
@@ -23,16 +23,14 @@
 
 import java.util.List;
 
-import org.jboss.messaging.core.ChannelSupport;
 import org.jboss.messaging.core.Message;
 import org.jboss.messaging.core.MessageReference;
-import org.jboss.messaging.core.local.Queue;
+import org.jboss.messaging.core.local.MessageQueue;
 import org.jboss.messaging.core.message.MessageFactory;
 import org.jboss.messaging.core.plugin.LockMap;
 
 import EDU.oswego.cs.dl.util.concurrent.QueuedExecutor;
 
-
 /**
  * 
  * A ChannelShare_P_NT_Recoverable.
@@ -65,10 +63,10 @@
    
    public void test1() throws Throwable
    {
-      ChannelSupport queue1 = new Queue(1, ms, pm, null, true, 100, 20, 10, new QueuedExecutor());
+      MessageQueue queue1 = new MessageQueue(1, ms, pm, true, true, 100, 20, 10, new QueuedExecutor(), null);
       
-      ChannelSupport queue2 = new Queue(2, ms, pm, null, true, 50, 10, 5, new QueuedExecutor());
-                     
+      MessageQueue queue2 = new MessageQueue(2, ms, pm, true, true, 50, 10, 5, new QueuedExecutor(), null);
+                                
       Message[] msgs = new Message[150];
       
       MessageReference[] refs1 = new MessageReference[150];

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-08-30 09:26:13 UTC (rev 1236)
+++ trunk/tests/src/org/jboss/test/messaging/core/paging/ChannelShare_P_TTest.java	2006-08-30 18:36:36 UTC (rev 1237)
@@ -23,17 +23,15 @@
 
 import java.util.List;
 
-import org.jboss.messaging.core.ChannelSupport;
 import org.jboss.messaging.core.Message;
 import org.jboss.messaging.core.MessageReference;
-import org.jboss.messaging.core.local.Queue;
+import org.jboss.messaging.core.local.MessageQueue;
 import org.jboss.messaging.core.message.MessageFactory;
 import org.jboss.messaging.core.plugin.LockMap;
 import org.jboss.messaging.core.tx.Transaction;
 
 import EDU.oswego.cs.dl.util.concurrent.QueuedExecutor;
 
-
 /**
  * 
  * A ChannelShare_P_T_Recoverable.
@@ -65,10 +63,10 @@
    
    public void test1() throws Throwable
    {
-      ChannelSupport queue1 = new Queue(1, ms, pm, null, true, 100, 20, 10, new QueuedExecutor());
+      MessageQueue queue1 = new MessageQueue(1, ms, pm, true, true, 100, 20, 10, new QueuedExecutor(), null);
       
-      ChannelSupport queue2 = new Queue(2, ms, pm, null, true, 50, 10, 5, new QueuedExecutor());
-                       
+      MessageQueue queue2 = new MessageQueue(2, ms, pm, true, true, 50, 10, 5, new QueuedExecutor(), null);
+                            
       Message[] msgs = new Message[150];
       
       MessageReference[] refs1 = new MessageReference[150];

Modified: trunk/tests/src/org/jboss/test/messaging/core/paging/PagingStateTestBase.java
===================================================================
--- trunk/tests/src/org/jboss/test/messaging/core/paging/PagingStateTestBase.java	2006-08-30 09:26:13 UTC (rev 1236)
+++ trunk/tests/src/org/jboss/test/messaging/core/paging/PagingStateTestBase.java	2006-08-30 18:36:36 UTC (rev 1237)
@@ -32,7 +32,6 @@
 import javax.sql.DataSource;
 import javax.transaction.TransactionManager;
 
-import org.jboss.jms.server.plugin.JDBCChannelMapper;
 import org.jboss.messaging.core.Channel;
 import org.jboss.messaging.core.Delivery;
 import org.jboss.messaging.core.DeliveryObserver;
@@ -40,6 +39,7 @@
 import org.jboss.messaging.core.Receiver;
 import org.jboss.messaging.core.Routable;
 import org.jboss.messaging.core.SimpleDelivery;
+import org.jboss.messaging.core.plugin.IdManager;
 import org.jboss.messaging.core.plugin.JDBCPersistenceManager;
 import org.jboss.messaging.core.plugin.SimpleMessageStore;
 import org.jboss.messaging.core.plugin.contract.PersistenceManager;
@@ -96,19 +96,15 @@
       sc = new ServiceContainer("all,-remoting,-security");
       sc.start();
 
-      JDBCChannelMapper cm = new JDBCChannelMapper(sc.getDataSource(), sc.getTransactionManager());
-      pm = new JDBCPersistenceManager(sc.getDataSource(), sc.getTransactionManager(), cm);
-      
-      cm.start();
-      
+      pm = new JDBCPersistenceManager(sc.getDataSource(), sc.getTransactionManager());            
+        
       ((JDBCPersistenceManager)pm).start();
 
-      ms = new SimpleMessageStore("store1");
+      ms = new SimpleMessageStore();
       
-      tr = new TransactionRepository();
+      tr = new TransactionRepository();      
       
-      tr.start(pm);
-      
+      tr.injectAttributes(pm, new IdManager("TRANSACTION_ID", 10, pm));
    }
    
    
@@ -250,9 +246,7 @@
             {
                theTx.commit();
             }
-         }
-         
-         
+         }    
       }
    }
    

Modified: trunk/tests/src/org/jboss/test/messaging/core/paging/PagingTest.java
===================================================================
--- trunk/tests/src/org/jboss/test/messaging/core/paging/PagingTest.java	2006-08-30 09:26:13 UTC (rev 1236)
+++ trunk/tests/src/org/jboss/test/messaging/core/paging/PagingTest.java	2006-08-30 18:36:36 UTC (rev 1237)
@@ -29,7 +29,7 @@
 import org.jboss.messaging.core.plugin.SimpleMessageStore;
 import org.jboss.messaging.core.message.CoreMessage;
 import org.jboss.messaging.core.message.MessageFactory;
-import org.jboss.messaging.core.local.Pipe;
+import org.jboss.messaging.core.local.MessageQueue;
 
 import EDU.oswego.cs.dl.util.concurrent.QueuedExecutor;
 
@@ -63,8 +63,8 @@
 
    public void testPaging() throws Exception
    {
+      MessageQueue p = new MessageQueue(0, ms, pm, true, true, 100, 20, 10, new QueuedExecutor(), null);
 
-      Pipe p = new Pipe(0, ms, pm, null, true, true, 100, 20, 10, new QueuedExecutor());
       CoreMessage m = null;
 
       m = MessageFactory.createCoreMessage(0);
@@ -87,7 +87,7 @@
 
       pm = new JDBCPersistenceManager(sc.getDataSource(), sc.getTransactionManager());
       pm.start();
-      ms = new SimpleMessageStore("store0");
+      ms = new SimpleMessageStore();
    }
 
    public void tearDown() throws Exception

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-08-30 09:26:13 UTC (rev 1236)
+++ trunk/tests/src/org/jboss/test/messaging/core/paging/SingleChannel_NP_2PCTest.java	2006-08-30 18:36:36 UTC (rev 1237)
@@ -23,11 +23,10 @@
 
 import java.util.List;
 
-import org.jboss.messaging.core.ChannelSupport;
 import org.jboss.messaging.core.Message;
 import org.jboss.messaging.core.MessageReference;
 import org.jboss.messaging.core.SimpleDelivery;
-import org.jboss.messaging.core.local.Queue;
+import org.jboss.messaging.core.local.MessageQueue;
 import org.jboss.messaging.core.message.MessageFactory;
 import org.jboss.messaging.core.plugin.LockMap;
 import org.jboss.messaging.core.tx.Transaction;
@@ -67,8 +66,8 @@
    
    public void test1() throws Throwable
    {
-      ChannelSupport queue = new Queue(1, ms, pm, null, true, 100, 20, 10, new QueuedExecutor());
-                     
+      MessageQueue queue = new MessageQueue(1, ms, pm, true, true, 100, 20, 10, new QueuedExecutor(), null);
+               
       Message[] msgs = new Message[241];
       
       MessageReference[] refs = new MessageReference[241];

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-08-30 09:26:13 UTC (rev 1236)
+++ trunk/tests/src/org/jboss/test/messaging/core/paging/SingleChannel_NP_NTTest.java	2006-08-30 18:36:36 UTC (rev 1237)
@@ -23,11 +23,10 @@
 
 import java.util.List;
 
-import org.jboss.messaging.core.ChannelSupport;
 import org.jboss.messaging.core.Message;
 import org.jboss.messaging.core.MessageReference;
 import org.jboss.messaging.core.SimpleDelivery;
-import org.jboss.messaging.core.local.Queue;
+import org.jboss.messaging.core.local.MessageQueue;
 import org.jboss.messaging.core.message.MessageFactory;
 import org.jboss.messaging.core.plugin.LockMap;
 
@@ -66,8 +65,8 @@
    
    public void test1() throws Throwable
    {
-      ChannelSupport queue = new Queue(1, ms, pm, null, true, 100, 20, 10, new QueuedExecutor());
-                     
+      MessageQueue queue = new MessageQueue(1, ms, pm, true, true, 100, 20, 10, new QueuedExecutor(), null);
+                           
       Message[] msgs = new Message[241];
       
       MessageReference[] refs = new MessageReference[241];

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-08-30 09:26:13 UTC (rev 1236)
+++ trunk/tests/src/org/jboss/test/messaging/core/paging/SingleChannel_NP_TTest.java	2006-08-30 18:36:36 UTC (rev 1237)
@@ -23,11 +23,10 @@
 
 import java.util.List;
 
-import org.jboss.messaging.core.ChannelSupport;
 import org.jboss.messaging.core.Message;
 import org.jboss.messaging.core.MessageReference;
 import org.jboss.messaging.core.SimpleDelivery;
-import org.jboss.messaging.core.local.Queue;
+import org.jboss.messaging.core.local.MessageQueue;
 import org.jboss.messaging.core.message.MessageFactory;
 import org.jboss.messaging.core.plugin.LockMap;
 import org.jboss.messaging.core.tx.Transaction;
@@ -67,8 +66,8 @@
  
    public void test1() throws Throwable
    {
-      ChannelSupport queue = new Queue(1, ms, pm, null, true, 100, 20, 10, new QueuedExecutor());
-                     
+      MessageQueue queue = new MessageQueue(1, ms, pm, true, true, 100, 20, 10, new QueuedExecutor(), null);
+                    
       Message[] msgs = new Message[241];
       
       MessageReference[] refs = new MessageReference[241];

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-08-30 09:26:13 UTC (rev 1236)
+++ trunk/tests/src/org/jboss/test/messaging/core/paging/SingleChannel_P_2PCTest.java	2006-08-30 18:36:36 UTC (rev 1237)
@@ -23,11 +23,10 @@
 
 import java.util.List;
 
-import org.jboss.messaging.core.ChannelSupport;
 import org.jboss.messaging.core.Message;
 import org.jboss.messaging.core.MessageReference;
 import org.jboss.messaging.core.SimpleDelivery;
-import org.jboss.messaging.core.local.Queue;
+import org.jboss.messaging.core.local.MessageQueue;
 import org.jboss.messaging.core.message.MessageFactory;
 import org.jboss.messaging.core.plugin.LockMap;
 import org.jboss.messaging.core.tx.Transaction;
@@ -67,8 +66,8 @@
    
    public void test1() throws Throwable
    {
-      ChannelSupport queue = new Queue(1, ms, pm, null, true, 100, 20, 10, new QueuedExecutor());
-                          
+      MessageQueue queue = new MessageQueue(1, ms, pm, true, true, 100, 20, 10, new QueuedExecutor(), null);
+                    
       Message[] msgs = new Message[241];
       
       MessageReference[] refs = new MessageReference[241];

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-08-30 09:26:13 UTC (rev 1236)
+++ trunk/tests/src/org/jboss/test/messaging/core/paging/SingleChannel_P_NTTest.java	2006-08-30 18:36:36 UTC (rev 1237)
@@ -23,11 +23,10 @@
 
 import java.util.List;
 
-import org.jboss.messaging.core.ChannelSupport;
 import org.jboss.messaging.core.Message;
 import org.jboss.messaging.core.MessageReference;
 import org.jboss.messaging.core.SimpleDelivery;
-import org.jboss.messaging.core.local.Queue;
+import org.jboss.messaging.core.local.MessageQueue;
 import org.jboss.messaging.core.message.MessageFactory;
 import org.jboss.messaging.core.plugin.LockMap;
 
@@ -66,7 +65,7 @@
    
    public void test1() throws Throwable
    {
-      ChannelSupport queue = new Queue(1, ms, pm, null, true, 100, 20, 10, new QueuedExecutor());
+      MessageQueue queue = new MessageQueue(1, ms, pm, true, true, 100, 20, 10, new QueuedExecutor(), null);
                         
       Message[] msgs = new Message[241];
       

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-08-30 09:26:13 UTC (rev 1236)
+++ trunk/tests/src/org/jboss/test/messaging/core/paging/SingleChannel_P_TTest.java	2006-08-30 18:36:36 UTC (rev 1237)
@@ -23,11 +23,10 @@
 
 import java.util.List;
 
-import org.jboss.messaging.core.ChannelSupport;
 import org.jboss.messaging.core.Message;
 import org.jboss.messaging.core.MessageReference;
 import org.jboss.messaging.core.SimpleDelivery;
-import org.jboss.messaging.core.local.Queue;
+import org.jboss.messaging.core.local.MessageQueue;
 import org.jboss.messaging.core.message.MessageFactory;
 import org.jboss.messaging.core.plugin.LockMap;
 import org.jboss.messaging.core.tx.Transaction;
@@ -67,8 +66,8 @@
    
    public void test1() throws Throwable
    {
-      ChannelSupport queue = new Queue(1, ms, pm, null, true, 100, 20, 10, new QueuedExecutor());
-                    
+      MessageQueue queue = new MessageQueue(1, ms, pm, true, true, 100, 20, 10, new QueuedExecutor(), null);
+                  
       Message[] msgs = new Message[241];
       
       MessageReference[] refs = new MessageReference[241];

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-08-30 09:26:13 UTC (rev 1236)
+++ trunk/tests/src/org/jboss/test/messaging/core/paging/SingleChannel_ReloadTest.java	2006-08-30 18:36:36 UTC (rev 1237)
@@ -23,10 +23,9 @@
 
 import java.util.List;
 
-import org.jboss.messaging.core.ChannelSupport;
 import org.jboss.messaging.core.Message;
 import org.jboss.messaging.core.MessageReference;
-import org.jboss.messaging.core.local.Queue;
+import org.jboss.messaging.core.local.MessageQueue;
 import org.jboss.messaging.core.message.MessageFactory;
 import org.jboss.messaging.core.plugin.JDBCPersistenceManager;
 import org.jboss.messaging.core.plugin.LockMap;
@@ -66,7 +65,7 @@
    
    public void testRecoverableQueueCrash() throws Throwable
    {
-      ChannelSupport queue = new Queue(1, ms, pm, null, true, 100, 20, 10, new QueuedExecutor());
+      MessageQueue queue = new MessageQueue(1, ms, pm, true, true, 100, 20, 10, new QueuedExecutor(), null);
       
       Message[] msgs = new Message[200];
       
@@ -111,8 +110,6 @@
       //Only the persistent messages should survive
       //This is what would happen if the server crashed
        
-      tr.stop();
-      ms.stop();
       pm.stop();
       
       pm =
@@ -120,14 +117,12 @@
 
       ((JDBCPersistenceManager)pm).start();
 
-      ms = new SimpleMessageStore("store1");
+      ms = new SimpleMessageStore();
       
       tr = new TransactionRepository();
+       
+      MessageQueue queue2 = new MessageQueue(1, ms, pm, true, true, 100, 20, 10, new QueuedExecutor(), null);
       
-      tr.start(pm);
-         
-      ChannelSupport queue2 = new Queue(1, ms, pm, null, true, 100, 20, 10, new QueuedExecutor());
-      
       queue2.load();
       
       refIds = getReferenceIds(queue.getChannelID());
@@ -155,8 +150,8 @@
    {
       //Non recoverable queue - eg temporary queue
       
-      ChannelSupport queue = new Queue(1, ms, pm, null, false, 100, 20, 10, new QueuedExecutor());
-      
+      MessageQueue queue = new MessageQueue(1, ms, pm, true, false, 100, 20, 10, new QueuedExecutor(), null);
+
       Message[] msgs = new Message[200];
       
       MessageReference[] refs = new MessageReference[200];
@@ -199,9 +194,7 @@
       //Stop and restart the persistence manager
       //No messages should survive
       //This is what would happen if the server crashed
-       
-      tr.stop();
-      ms.stop();
+
       pm.stop();
       
       pm =
@@ -209,13 +202,11 @@
 
       ((JDBCPersistenceManager)pm).start();
 
-      ms = new SimpleMessageStore("store1");
+      ms = new SimpleMessageStore();
       
       tr = new TransactionRepository();
       
-      tr.start(pm);
-         
-      ChannelSupport queue2 = new Queue(1, ms, pm, null, false, 100, 20, 10, new QueuedExecutor());
+      MessageQueue queue2 = new MessageQueue(1, ms, pm, true, false, 100, 20, 10, new QueuedExecutor(), null);
       
       queue2.load();
       
@@ -242,7 +233,7 @@
    {
       //Non recoverable queue - eg temporary queue
       
-      ChannelSupport queue = new Queue(1, ms, pm, null, false, 100, 20, 10, new QueuedExecutor());
+      MessageQueue queue = new MessageQueue(1, ms, pm, true, false, 100, 20, 10, new QueuedExecutor(), null);
       
       Message[] msgs = new Message[200];
       
@@ -304,4 +295,180 @@
       assertEquals(0, LockMap.instance.getSize());
    }
    
+   public void testQueueReloadWithSmallerFullSize() throws Throwable
+   {
+      MessageQueue queue = new MessageQueue(1, ms, pm, true, true, 100, 20, 10, new QueuedExecutor(), null);
+
+      Message[] msgs = new Message[150];
+      
+      MessageReference[] refs = new MessageReference[150];
+       
+      //Send 150 p messages
+      for (int i = 0; i < 150; i++)
+      {
+         msgs[i] = MessageFactory.createCoreMessage(i, true, null);
+         
+         refs[i] = ms.reference(msgs[i]);
+                
+         queue.handle(null, refs[i], null); 
+         
+         refs[i].releaseMemoryReference();
+      }
+
+      List refIds = getReferenceIds(queue.getChannelID());
+      assertEquals(150, refIds.size());
+                                                
+      assertEquals(100, queue.memoryRefCount());
+      
+      assertEquals(0, queue.downCacheCount());
+      
+      assertTrue(queue.isPaging());      
+      
+      assertEquals(0, queue.memoryDeliveryCount());
+      
+      //Stop and restart the persistence manager
+
+      pm.stop();
+      
+      pm =
+         new JDBCPersistenceManager(sc.getDataSource(), sc.getTransactionManager());
+
+      ((JDBCPersistenceManager)pm).start();
+
+      ms = new SimpleMessageStore();
+      
+      tr = new TransactionRepository();
+      
+      //Reload the queue with a smaller fullSize
+      
+      MessageQueue queue2 = new MessageQueue(1, ms, pm, true, false, 50, 20, 10, new QueuedExecutor(), null);
+      
+      queue2.load();
+      
+      refIds = getReferenceIds(queue.getChannelID());
+      assertEquals(150, refIds.size());
+      
+      List msgIds = getMessageIds();
+      assertEquals(150, msgIds.size());
+                                                                  
+      assertEquals(50, queue2.memoryRefCount());
+      
+      assertEquals(0, queue2.downCacheCount());
+      
+      assertTrue(queue2.isPaging());      
+      
+      assertEquals(0, queue2.memoryDeliveryCount());
+      
+      assertEquals(50, queue2.messageCount());
+      
+      //Consume all the messages
+      this.consume(queue2, 0, refs, 150);
+      
+      refIds = getReferenceIds(queue.getChannelID());
+      assertEquals(0, refIds.size());
+      
+      msgIds = getMessageIds();
+      assertEquals(0, msgIds.size());
+                                                                  
+      assertEquals(0, queue2.memoryRefCount());
+      
+      assertEquals(0, queue2.downCacheCount());
+      
+      assertFalse(queue2.isPaging());      
+      
+      assertEquals(0, queue2.memoryDeliveryCount());
+      
+      assertEquals(0, queue2.messageCount());
+      
+      assertEquals(0, LockMap.instance.getSize());            
+   }
+   
+   public void testReloadWithLargerFullSize() throws Throwable
+   {
+      MessageQueue queue = new MessageQueue(1, ms, pm, true, true, 100, 20, 10, new QueuedExecutor(), null);
+
+      Message[] msgs = new Message[150];
+      
+      MessageReference[] refs = new MessageReference[150];
+       
+      //Send 150 p messages
+      for (int i = 0; i < 150; i++)
+      {
+         msgs[i] = MessageFactory.createCoreMessage(i, true, null);
+         
+         refs[i] = ms.reference(msgs[i]);
+                
+         queue.handle(null, refs[i], null); 
+         
+         refs[i].releaseMemoryReference();
+      }
+
+      List refIds = getReferenceIds(queue.getChannelID());
+      assertEquals(150, refIds.size());
+                                                
+      assertEquals(100, queue.memoryRefCount());
+      
+      assertEquals(0, queue.downCacheCount());
+      
+      assertTrue(queue.isPaging());      
+      
+      assertEquals(0, queue.memoryDeliveryCount());
+      
+      //Stop and restart the persistence manager
+
+      pm.stop();
+      
+      pm =
+         new JDBCPersistenceManager(sc.getDataSource(), sc.getTransactionManager());
+
+      ((JDBCPersistenceManager)pm).start();
+
+      ms = new SimpleMessageStore();
+      
+      tr = new TransactionRepository();
+      
+      //Reload the queue with a smaller fullSize
+      
+      MessageQueue queue2 = new MessageQueue(1, ms, pm, true, false, 130, 20, 10, new QueuedExecutor(), null);
+      
+      queue2.load();
+      
+      refIds = getReferenceIds(queue.getChannelID());
+      assertEquals(150, refIds.size());
+      
+      List msgIds = getMessageIds();
+      assertEquals(150, msgIds.size());
+                                                                  
+      assertEquals(130, queue2.memoryRefCount());
+      
+      assertEquals(0, queue2.downCacheCount());
+      
+      assertTrue(queue2.isPaging());      
+      
+      assertEquals(0, queue2.memoryDeliveryCount());
+      
+      assertEquals(130, queue2.messageCount());
+      
+      //Consume all the messages
+      this.consume(queue2, 0, refs, 150);
+      
+      refIds = getReferenceIds(queue.getChannelID());
+      assertEquals(0, refIds.size());
+      
+      msgIds = getMessageIds();
+      assertEquals(0, msgIds.size());
+                                                                  
+      assertEquals(0, queue2.memoryRefCount());
+      
+      assertEquals(0, queue2.downCacheCount());
+      
+      assertFalse(queue2.isPaging());      
+      
+      assertEquals(0, queue2.memoryDeliveryCount());
+      
+      assertEquals(0, queue2.messageCount());
+      
+      assertEquals(0, LockMap.instance.getSize());            
+   }
+   
 }

Modified: trunk/tests/src/org/jboss/test/messaging/core/persistence/JDBCUtilTest.java
===================================================================
--- trunk/tests/src/org/jboss/test/messaging/core/persistence/JDBCUtilTest.java	2006-08-30 09:26:13 UTC (rev 1236)
+++ trunk/tests/src/org/jboss/test/messaging/core/persistence/JDBCUtilTest.java	2006-08-30 18:36:36 UTC (rev 1237)
@@ -22,7 +22,7 @@
 package org.jboss.test.messaging.core.persistence;
 
 import org.jboss.test.messaging.MessagingTestCase;
-import org.jboss.messaging.core.persistence.JDBCUtil;
+import org.jboss.messaging.util.JDBCUtil;
 
 
 /**

Added: trunk/tests/src/org/jboss/test/messaging/core/plugin/ClusteredTopicExchangeTest.java
===================================================================
--- trunk/tests/src/org/jboss/test/messaging/core/plugin/ClusteredTopicExchangeTest.java	2006-08-30 09:26:13 UTC (rev 1236)
+++ trunk/tests/src/org/jboss/test/messaging/core/plugin/ClusteredTopicExchangeTest.java	2006-08-30 18:36:36 UTC (rev 1237)
@@ -0,0 +1,175 @@
+/*
+  * 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.core.plugin;
+
+import java.util.List;
+
+import org.jboss.messaging.core.Message;
+import org.jboss.messaging.core.MessageReference;
+import org.jboss.messaging.core.local.MessageQueue;
+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.jgroups.Channel;
+import org.jgroups.JChannel;
+
+/**
+ * 
+ * A ClusteredTopicExchangeTest
+
+ * @author <a href="mailto:tim.fox at jboss.com">Tim Fox</a>
+ * @version <tt>$Revision: 1.1 $</tt>
+ *
+ * $Id$
+ *
+ */
+public class ClusteredTopicExchangeTest extends TopicExchangeTest
+{
+   // Constants -----------------------------------------------------
+
+   // Static --------------------------------------------------------
+   
+   // Attributes ----------------------------------------------------
+   
+   // Constructors --------------------------------------------------
+
+   public ClusteredTopicExchangeTest(String name)
+   {
+      super(name);
+   }
+
+   // Public --------------------------------------------------------
+
+   public void setUp() throws Exception
+   {
+      super.setUp();     
+            
+   }
+
+   public void tearDown() throws Exception
+   {           
+      super.tearDown();
+   }
+   
+   public void testClusteredTopic() throws Exception
+   {
+      Exchange exchange1 = null;
+      
+      Exchange exchange2 = null;
+      
+      try
+      {         
+         exchange1 = createExchange("node1", "testgroup");
+         
+         Binding binding1 = exchange1.bindQueue("sub1", "topic1", null, false, true, ms, pm, 20000, 100, 100);
+         
+         exchange2 = createExchange("node2", "testgroup");
+         
+         Binding binding2 = exchange1.bindQueue("sub2", "topic1", null, false, true, ms, pm, 20000, 100, 100);
+         
+         Binding binding3 = exchange2.bindQueue("sub3", "topic1", null, false, true, ms, pm, 20000, 100, 100);
+         
+         Message msg1 = MessageFactory.createCoreMessage(1);      
+         MessageReference ref1 = ms.reference(msg1);
+         
+         boolean routed = exchange1.route(ref1, "topic1", null); 
+         
+         //For non reliable messages may take little while for messages to arrive
+         //Since they are just put on the bus and the caller continues - so we sleep
+         Thread.sleep(500);
+         
+         checkQueueContainsRef(binding1, ref1);
+         checkQueueContainsRef(binding2, ref1);
+         checkQueueContainsRef(binding3, ref1);
+         
+         log.info("Done test");
+      }
+      finally
+      {
+         if (exchange1 != null)
+         {
+            exchange1.stop();
+         }
+         
+         if (exchange2 != null)
+         {
+            exchange2.stop();
+         }
+      }
+   }
+   
+   private void checkQueueContainsRef(Binding binding, MessageReference ref)
+   {
+      MessageQueue queue = binding.getQueue();
+      
+      List refs = queue.browse();
+      
+      assertNotNull(refs);
+      
+      assertEquals(1, refs.size());
+      
+      Message msg = (Message)refs.get(0);
+      
+      assertEquals(ref.getMessageID(), msg.getMessageID());
+   }
+
+   // Package protected ---------------------------------------------
+
+   // Protected -----------------------------------------------------
+   
+   protected Exchange createExchange() throws Exception
+   {
+      ClusteredTopicExchange exchange = new ClusteredTopicExchange(sc.getDataSource(), sc.getTransactionManager());
+      
+      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();
+      
+      return exchange;
+   }
+   
+   protected Exchange createExchange(String nodeId, String groupName) throws Exception
+   {
+      ClusteredTopicExchange exchange = new ClusteredTopicExchange(sc.getDataSource(), sc.getTransactionManager());
+      
+      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();
+      
+      return exchange;
+   }
+
+   // Private -------------------------------------------------------
+
+   // Inner classes -------------------------------------------------
+
+}
+
+
+

Added: trunk/tests/src/org/jboss/test/messaging/core/plugin/DirectExchangeTest.java
===================================================================
--- trunk/tests/src/org/jboss/test/messaging/core/plugin/DirectExchangeTest.java	2006-08-30 09:26:13 UTC (rev 1236)
+++ trunk/tests/src/org/jboss/test/messaging/core/plugin/DirectExchangeTest.java	2006-08-30 18:36:36 UTC (rev 1237)
@@ -0,0 +1,275 @@
+/*
+  * 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.core.plugin;
+
+import java.util.List;
+
+import org.jboss.messaging.core.Message;
+import org.jboss.messaging.core.MessageReference;
+import org.jboss.messaging.core.local.MessageQueue;
+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.DirectExchange;
+import org.jboss.messaging.core.tx.Transaction;
+import org.jboss.test.messaging.core.plugin.base.ExchangeTestBase;
+
+/**
+ * 
+ * A DirectExchangeTest
+
+ * @author <a href="mailto:tim.fox at jboss.com">Tim Fox</a>
+ * @version <tt>$Revision: 1.1 $</tt>
+ *
+ * $Id$
+ *
+ */
+public class DirectExchangeTest extends ExchangeTestBase
+{
+   // Constants -----------------------------------------------------
+
+   // Static --------------------------------------------------------
+   
+   // Attributes ----------------------------------------------------
+
+   // Constructors --------------------------------------------------
+
+   public DirectExchangeTest(String name)
+   {
+      super(name);
+   }
+
+   // Public --------------------------------------------------------
+
+   public void setUp() throws Exception
+   {
+      super.setUp();            
+   }
+
+   public void tearDown() throws Exception
+   {      
+     
+      super.tearDown();
+   }
+   
+   public void testRoute() throws Throwable
+   {
+      Exchange exchange = createExchange();
+      
+      Binding binding1 =
+         exchange.bindQueue("queue1", "queue1", null, false, true, ms, pm, 1000, 20, 20);      
+      Binding binding2 =
+         exchange.bindQueue("queue2", "queue2", null, false, true, ms, pm, 1000, 20, 20);
+      
+      MessageQueue queue1 = binding1.getQueue();      
+      MessageQueue queue2 = binding2.getQueue();
+      
+      assertTrue(binding1.isActive());      
+      assertTrue(binding2.isActive());
+      
+      Message msg1 = MessageFactory.createCoreMessage(1);      
+      MessageReference ref1 = ms.reference(msg1);
+      
+      boolean routed = exchange.route(ref1, "queue1", null);      
+      assertTrue(routed);
+      
+      List msgs = queue1.browse();
+      assertNotNull(msgs);
+      assertEquals(1, msgs.size());
+      Message msgRec = (Message)msgs.get(0);
+      assertEquals(msgRec.getMessageID(), msg1.getMessageID());
+      queue1.removeAllReferences();
+      
+      msgs = queue2.browse();
+      assertNotNull(msgs);
+      assertEquals(0, msgs.size());
+      
+      Message msg2 = MessageFactory.createCoreMessage(2);      
+      MessageReference ref2 = ms.reference(msg2);
+      
+      routed = exchange.route(ref2, "queue2", null);      
+      assertTrue(routed);
+      
+      msgs = queue2.browse();
+      assertNotNull(msgs);
+      assertEquals(1, msgs.size());
+      msgRec = (Message)msgs.get(0);
+      assertEquals(msgRec.getMessageID(), msg2.getMessageID());
+      queue2.removeAllReferences();
+      
+      msgs = queue1.browse();
+      assertNotNull(msgs);
+      assertEquals(0, msgs.size());
+   }
+   
+   public void testRouteInactive() throws Throwable
+   {
+      Exchange exchange = createExchange();
+      
+      Binding binding1 =
+         exchange.bindQueue("queue1", "queue1", null, false, true, ms, pm, 1000, 20, 20);      
+      Binding binding2 =
+         exchange.bindQueue("queue2", "queue2", null, false, true, ms, pm, 1000, 20, 20);
+      
+      MessageQueue queue1 = binding1.getQueue();
+      MessageQueue queue2 = binding2.getQueue();
+      
+      //Now make bindings inactive
+      binding1.deactivate();
+      binding2.deactivate();
+      
+      assertFalse(binding1.isActive());
+      assertFalse(binding2.isActive());
+      
+      Message msg1 = MessageFactory.createCoreMessage(1);      
+      MessageReference ref1 = ms.reference(msg1);
+      
+      boolean routed = exchange.route(ref1, "queue1", null);      
+      assertFalse(routed);
+      
+      Message msg2 = MessageFactory.createCoreMessage(2);      
+      MessageReference ref2 = ms.reference(msg2);
+      
+      routed = exchange.route(ref1, "queue2", null);      
+      assertFalse(routed);
+      
+      List msgs = queue1.browse();
+      assertNotNull(msgs);
+      assertEquals(0, msgs.size());     
+      
+      msgs = queue2.browse();
+      assertNotNull(msgs);
+      assertEquals(0, msgs.size());     
+   
+   }
+   
+   public void testRouteNoBinding() throws Throwable
+   {
+      Exchange exchange = createExchange();
+      
+      Binding binding1 =
+         exchange.bindQueue("queue1", "queue1", null, false, true, ms, pm, 1000, 20, 20);      
+
+      MessageQueue queue1 = binding1.getQueue();
+
+      assertTrue(binding1.isActive());
+
+      Message msg1 = MessageFactory.createCoreMessage(1);      
+      MessageReference ref1 = ms.reference(msg1);
+      
+      boolean routed = exchange.route(ref1, "this won't match anything", null);      
+      
+      //A direct exchange should return false if there is no binding
+      assertFalse(routed);
+            
+      List msgs = queue1.browse();
+      assertNotNull(msgs);
+      assertEquals(0, msgs.size());             
+   }
+   
+   public void testRouteTransactional() throws Throwable
+   {
+      Exchange exchange = createExchange();
+      
+      Binding binding1 =
+         exchange.bindQueue("queue1", "queue1", null, false, true, ms, pm, 1000, 20, 20);      
+
+      MessageQueue queue1 = binding1.getQueue();
+
+      assertTrue(binding1.isActive());
+
+      Message msg1 = MessageFactory.createCoreMessage(1);      
+      MessageReference ref1 = ms.reference(msg1);
+      
+      Message msg2 = MessageFactory.createCoreMessage(2);      
+      MessageReference ref2 = ms.reference(msg2);
+      
+      Transaction tx = tr.createTransaction();
+      
+      boolean routed = exchange.route(ref1, "queue1", tx);            
+      assertTrue(routed);
+      routed = exchange.route(ref2, "queue1", tx);            
+      assertTrue(routed);
+            
+      List msgs = queue1.browse();
+      assertNotNull(msgs);
+      assertEquals(0, msgs.size()); 
+      
+      tx.commit();
+      
+      msgs = queue1.browse();
+      assertNotNull(msgs);
+      assertEquals(2, msgs.size());
+      Message msgRec1 = (Message)msgs.get(0);
+      Message msgRec2 = (Message)msgs.get(0);
+      assertEquals(msg1.getMessageID(), msgRec1.getMessageID());
+      assertEquals(msg2.getMessageID(), msgRec2.getMessageID());
+      
+      queue1.removeAllReferences();
+      
+      Message msg3 = MessageFactory.createCoreMessage(3);      
+      MessageReference ref3 = ms.reference(msg3);
+      
+      Message msg4 = MessageFactory.createCoreMessage(4);      
+      MessageReference ref4 = ms.reference(msg4);
+      
+      Transaction tx2 = tr.createTransaction();
+      
+      routed = exchange.route(ref3, "queue1", tx2);            
+      assertTrue(routed);
+      routed = exchange.route(ref4, "queue1", tx2);            
+      assertTrue(routed);
+            
+      msgs = queue1.browse();
+      assertNotNull(msgs);
+      assertEquals(0, msgs.size()); 
+      
+      tx.rollback();
+      
+      msgs = queue1.browse();
+      assertNotNull(msgs);
+      assertEquals(0, msgs.size());
+   }
+   
+
+   // Package protected ---------------------------------------------
+   
+   protected Exchange createExchange() throws Exception
+   {
+      DirectExchange exchange = new DirectExchange(sc.getDataSource(), sc.getTransactionManager());
+      
+      ((DirectExchange)exchange).injectAttributes("Direct", "node1", ms, im, pool);
+      
+      exchange.start();      
+      
+      return exchange;
+   }
+
+   // Protected -----------------------------------------------------
+
+   // Private -------------------------------------------------------
+
+   // Inner classes -------------------------------------------------
+
+}
+
+

Modified: trunk/tests/src/org/jboss/test/messaging/core/plugin/JDBCPersistenceManagerTest.java
===================================================================
--- trunk/tests/src/org/jboss/test/messaging/core/plugin/JDBCPersistenceManagerTest.java	2006-08-30 09:26:13 UTC (rev 1236)
+++ trunk/tests/src/org/jboss/test/messaging/core/plugin/JDBCPersistenceManagerTest.java	2006-08-30 18:36:36 UTC (rev 1237)
@@ -40,6 +40,7 @@
 import org.jboss.messaging.core.Message;
 import org.jboss.messaging.core.MessageReference;
 import org.jboss.messaging.core.message.MessageFactory;
+import org.jboss.messaging.core.plugin.IdManager;
 import org.jboss.messaging.core.plugin.JDBCPersistenceManager;
 import org.jboss.messaging.core.plugin.SimpleMessageStore;
 import org.jboss.messaging.core.plugin.contract.MessageStore;
@@ -96,7 +97,7 @@
    {
       pm = createPM();      
       pm.setUsingBatchUpdates(batch);      
-      ms = new SimpleMessageStore("s0");      
+      ms = new SimpleMessageStore();      
    }
    
    protected JDBCPersistenceManager createPM() throws Throwable
@@ -117,37 +118,210 @@
       super.tearDown();
    }
    
-   public void testGetMinOrdering() throws Throwable
+   
+   public void testAddRemoveGetReferences_Batch() throws Throwable
    {
+      addRemoveGetReferences(true);
+   }
+   
+   public void testAddRemoveGetReferences_NoBatch() throws Throwable
+   {
+      addRemoveGetReferences(false);
+   }
+   
+   
+   
+         
+   public void testAddRemoveReference() throws Throwable
+   {
       doSetup(false);
       
-      Channel channel = new SimpleChannel(0, ms);
+      Channel channel1 = new SimpleChannel(0, ms);
+      Channel channel2 = new SimpleChannel(1, ms);
+
+      Message[] messages = createMessages(10);     
       
-      Message[] m = createMessages(10);
+      for (int i = 0; i < 5; i++)
+      {
+         Message m1 = messages[i * 2];
+         Message m2 = messages[i * 2 + 1];
+         
+         MessageReference ref1_1 = ms.reference(m1);
+         MessageReference ref1_2 = ms.reference(m1);
+                
+         MessageReference ref2_1 = ms.reference(m2);
+         MessageReference ref2_2 = ms.reference(m2);
+                  
+         pm.addReference(channel1.getChannelID(), ref1_1, null);
+         pm.addReference(channel1.getChannelID(), ref2_1, null);         
+         
+         pm.addReference(channel2.getChannelID(), ref1_2, null);
+         pm.addReference(channel2.getChannelID(), ref2_2, null);
       
-      List refs = new ArrayList();
+         List refs = getReferenceIds(channel1.getChannelID());
+         
+         assertNotNull(refs);
+         assertEquals(2, refs.size());
+         assertTrue(refs.contains(new Long(m1.getMessageID())));
+         assertTrue(refs.contains(new Long(m2.getMessageID())));
+         
+         refs = getReferenceIds(channel2.getChannelID());
+         
+         assertNotNull(refs);
+         assertEquals(2, refs.size());
+         assertTrue(refs.contains(new Long(m1.getMessageID())));
+         assertTrue(refs.contains(new Long(m2.getMessageID())));
+         
+         List msgs = getMessageIds();
+         assertNotNull(msgs);
+         assertEquals(2, msgs.size());
+         assertTrue(msgs.contains(new Long(m1.getMessageID())));
+         assertTrue(msgs.contains(new Long(m2.getMessageID())));
+                  
+         pm.removeReference(channel1.getChannelID(), ref1_1, null);
+                  
+         refs = getReferenceIds(channel1.getChannelID());
+         assertNotNull(refs);
+         assertEquals(1, refs.size());
+         assertTrue(refs.contains(new Long(m2.getMessageID())));
+         
+         refs = getReferenceIds(channel2.getChannelID());
+         assertNotNull(refs);
+         assertEquals(2, refs.size());
+         assertTrue(refs.contains(new Long(m1.getMessageID())));
+         assertTrue(refs.contains(new Long(m2.getMessageID())));
+         
+         msgs = getMessageIds();
+         assertNotNull(msgs);
+         assertEquals(2, msgs.size());
+         assertTrue(msgs.contains(new Long(m1.getMessageID())));
+         assertTrue(msgs.contains(new Long(m2.getMessageID())));
+         
+         pm.removeReference(channel2.getChannelID(), ref1_2, null);
+         
+         refs = getReferenceIds(channel1.getChannelID());
+         assertNotNull(refs);
+         assertEquals(1, refs.size());
+         assertTrue(refs.contains(new Long(m2.getMessageID())));
+         
+         refs = getReferenceIds(channel2.getChannelID());
+         assertNotNull(refs);
+         assertEquals(1, refs.size());         
+         assertTrue(refs.contains(new Long(m2.getMessageID())));
+         
+         msgs = getMessageIds();
+         assertNotNull(msgs);
+         assertEquals(1, msgs.size());
+         assertTrue(msgs.contains(new Long(m2.getMessageID())));
+         
+         pm.removeReference(channel1.getChannelID(), ref2_1, null);
+         
+         refs = getReferenceIds(channel1.getChannelID());
+         assertNotNull(refs);
+         assertTrue(refs.isEmpty());
+         
+         refs = getReferenceIds(channel2.getChannelID());
+         assertNotNull(refs);
+         assertEquals(1, refs.size());         
+         assertTrue(refs.contains(new Long(m2.getMessageID())));
+         
+         msgs = getMessageIds();
+         assertNotNull(msgs);
+         assertEquals(1, msgs.size());
+         assertTrue(msgs.contains(new Long(m2.getMessageID())));
+         
+         pm.removeReference(channel2.getChannelID(), ref2_2, null);
+         
+         refs = getReferenceIds(channel1.getChannelID());
+         assertNotNull(refs);
+         assertTrue(refs.isEmpty());
+         
+         refs = getReferenceIds(channel2.getChannelID());
+         assertNotNull(refs);
+         assertTrue(refs.isEmpty());
+         
+         msgs = getMessageIds();
+         assertNotNull(msgs);
+         assertTrue(msgs.isEmpty());
+            
+      }
+   }
+       
+   
+   
+   //non batch
+   
+   public void testCommit_NotXA_Long_NB() throws Throwable
+   {
+      doTransactionCommit(false, false);
+   }
+   
+   public void testCommit_XA_Long_NB() throws Throwable
+   {
+      doTransactionCommit(true, false);
+   }
+
+   public void testRollback_NotXA_Long_NB() throws Throwable
+   {
+      doTransactionRollback(false, false);
+   }
+       
+   public void testRollback_XA_Long_NB() throws Throwable
+   {
+      doTransactionRollback(true, false);
+   }
+   
+
+   //batch
+   
+   public void testCommit_NotXA_Long_B() throws Throwable
+   {
+      doTransactionCommit(false, true);
+   }
+     
+   public void testCommit_XA_Long_B() throws Throwable
+   {
+      doTransactionCommit(true, true);
+   }
+
+   public void testRollback_NotXA_Long_B() throws Throwable
+   {
+      doTransactionRollback(false, true);
+   }
+        
+   public void testRollback_XA_Long_B() throws Throwable
+   {
+      doTransactionRollback(true, true);
+   }
+   
+   protected void addRemoveGetReferences(boolean batch) throws Throwable
+   {
+      doSetup(false);
       
+      Channel channel1 = new SimpleChannel(0, ms);
+      
+      Channel channel2 = new SimpleChannel(1, ms);
+      
+      Message[] m = createMessages(10);
+      
       MessageReference ref1 = ms.reference(m[0]);
-      ref1.setOrdering(11);
       MessageReference ref2 = ms.reference(m[1]);
-      ref2.setOrdering(23);
       MessageReference ref3 = ms.reference(m[2]);
-      ref3.setOrdering(27);
       MessageReference ref4 = ms.reference(m[3]);
-      ref4.setOrdering(30);
       MessageReference ref5 = ms.reference(m[4]);
-      ref5.setOrdering(89);
       MessageReference ref6 = ms.reference(m[5]);
-      ref6.setOrdering(101);
       MessageReference ref7 = ms.reference(m[6]);
-      ref7.setOrdering(123);
       MessageReference ref8 = ms.reference(m[7]);
-      ref8.setOrdering(345);
       MessageReference ref9 = ms.reference(m[8]);
-      ref9.setOrdering(678);
       MessageReference ref10 = ms.reference(m[9]);
-      ref10.setOrdering(890);
       
+      MessageReference ref11 = ms.reference(m[0]);
+      MessageReference ref12 = ms.reference(m[1]);
+      MessageReference ref13 = ms.reference(m[2]);
+      MessageReference ref14 = ms.reference(m[3]);
+      MessageReference ref15 = ms.reference(m[4]);
+      
+      List refs = new ArrayList();
       refs.add(ref1);
       refs.add(ref2);
       refs.add(ref3);
@@ -159,9 +333,18 @@
       refs.add(ref9);
       refs.add(ref10);
       
-      pm.addReferences(channel.getChannelID(), refs, false);
-         
-      List refIds = getReferenceIds(channel.getChannelID());
+      pm.addReferences(channel1.getChannelID(), refs);
+      
+      refs = new ArrayList();
+      refs.add(ref11);
+      refs.add(ref12);
+      refs.add(ref13);
+      refs.add(ref14);
+      refs.add(ref15);
+    
+      pm.addReferences(channel2.getChannelID(), refs);
+                  
+      List refIds = getReferenceIds(channel1.getChannelID());
       assertNotNull(refIds);
       assertEquals(10, refIds.size());
       assertTrue(refIds.contains(new Long(ref1.getMessageID())));
@@ -175,6 +358,16 @@
       assertTrue(refIds.contains(new Long(ref9.getMessageID())));
       assertTrue(refIds.contains(new Long(ref10.getMessageID())));
       
+      refIds = getReferenceIds(channel2.getChannelID());
+      assertNotNull(refIds);
+      assertEquals(5, refIds.size());
+      assertTrue(refIds.contains(new Long(ref11.getMessageID())));
+      assertTrue(refIds.contains(new Long(ref12.getMessageID())));
+      assertTrue(refIds.contains(new Long(ref13.getMessageID())));
+      assertTrue(refIds.contains(new Long(ref14.getMessageID())));
+      assertTrue(refIds.contains(new Long(ref15.getMessageID())));
+     
+      
       List msgs = getMessageIds();
       assertNotNull(msgs);
       assertEquals(10, msgs.size());
@@ -189,31 +382,39 @@
       assertTrue(msgs.contains(new Long(ref9.getMessageID())));
       assertTrue(msgs.contains(new Long(ref10.getMessageID())));
       
-      long minOrdering = pm.getMinOrdering(channel.getChannelID());
+      List msgIds = new ArrayList();
+      msgIds.add(new Long(ref3.getMessageID()));
+      msgIds.add(new Long(ref4.getMessageID()));
+      msgIds.add(new Long(ref7.getMessageID()));
+      msgIds.add(new Long(ref9.getMessageID()));
+      msgIds.add(new Long(ref1.getMessageID()));
       
-      assertEquals(11, minOrdering);
-           
-      pm.removeReferences(channel.getChannelID(), refs);
- 
-      pm.addReferences(channel.getChannelID(), refs, true);
+      List ms = pm.getMessages(msgIds);
+      assertNotNull(ms);
+      assertEquals(5, ms.size());
+      assertTrue(containsMessage(ms, ref3.getMessageID()));
+      assertTrue(containsMessage(ms, ref4.getMessageID()));
+      assertTrue(containsMessage(ms, ref7.getMessageID()));
+      assertTrue(containsMessage(ms, ref9.getMessageID()));
+      assertTrue(containsMessage(ms, ref1.getMessageID()));
       
-      refIds = getReferenceIds(channel.getChannelID());
+      refs = new ArrayList();
+      refs.add(ref12);
+      refs.add(ref13);
+      refs.add(ref14);
+      refs.add(ref15);
+      pm.removeReferences(channel2.getChannelID(), refs);
+      
+      refIds = getReferenceIds(channel2.getChannelID());
       assertNotNull(refIds);
-      assertEquals(10, refIds.size());
-      assertTrue(refIds.contains(new Long(ref1.getMessageID())));
-      assertTrue(refIds.contains(new Long(ref2.getMessageID())));
-      assertTrue(refIds.contains(new Long(ref3.getMessageID())));
-      assertTrue(refIds.contains(new Long(ref4.getMessageID())));
-      assertTrue(refIds.contains(new Long(ref5.getMessageID())));
-      assertTrue(refIds.contains(new Long(ref6.getMessageID())));
-      assertTrue(refIds.contains(new Long(ref7.getMessageID())));
-      assertTrue(refIds.contains(new Long(ref8.getMessageID())));
-      assertTrue(refIds.contains(new Long(ref9.getMessageID())));
-      assertTrue(refIds.contains(new Long(ref10.getMessageID())));
+      assertEquals(1, refIds.size());
+      assertTrue(refIds.contains(new Long(ref11.getMessageID())));
       
-      msgs = getMessageIds();
-      assertNotNull(msgs);
-      assertEquals(10, msgs.size());
+      ms = getMessageIds();
+
+      assertNotNull(ms);
+      assertEquals(10, ms.size());
+      
       assertTrue(msgs.contains(new Long(ref1.getMessageID())));
       assertTrue(msgs.contains(new Long(ref2.getMessageID())));
       assertTrue(msgs.contains(new Long(ref3.getMessageID())));
@@ -224,91 +425,17 @@
       assertTrue(msgs.contains(new Long(ref8.getMessageID())));
       assertTrue(msgs.contains(new Long(ref9.getMessageID())));
       assertTrue(msgs.contains(new Long(ref10.getMessageID())));
+     
       
-      minOrdering = pm.getMinOrdering(channel.getChannelID());
+      refs = new ArrayList();
+      refs.add(ref1);
+      refs.add(ref2);
+      refs.add(ref3);
+      pm.removeReferences(channel1.getChannelID(), refs);
       
-      assertEquals(0, minOrdering);
-        
-   }
-   
-   public void testGetNumberOfReferences() throws Throwable
-   {
-      doSetup(false);
-      
-      Channel channel = new SimpleChannel(0, ms);
-      
-      Message m0 = this.createMessage((byte)0, false);
-      Message m1 = this.createMessage((byte)1, false);
-      Message m2 = this.createMessage((byte)2, false);
-      Message m3 = this.createMessage((byte)3, false);
-      Message m4 = this.createMessage((byte)4, false);
-      Message m5 = this.createMessage((byte)5, false);
-      Message m6 = this.createMessage((byte)6, false);
-      Message m7 = this.createMessage((byte)7, false);
-      Message m8 = this.createMessage((byte)8, false);
-      Message m9 = this.createMessage((byte)9, false);
-      
-      Message m10 = this.createMessage((byte)10, true);
-      Message m11 = this.createMessage((byte)11, true);
-      Message m12 = this.createMessage((byte)12, true);
-      Message m13 = this.createMessage((byte)13, true);
-      Message m14 = this.createMessage((byte)14, true);
-      
-      MessageReference ref1 = ms.reference(m0);      
-      ref1.setOrdering(0);
-      MessageReference ref2 = ms.reference(m1);
-      ref2.setOrdering(1);
-      MessageReference ref3 = ms.reference(m2);
-      ref3.setOrdering(2);
-      MessageReference ref4 = ms.reference(m3);
-      ref4.setOrdering(3);
-      MessageReference ref5 = ms.reference(m4);
-      ref5.setOrdering(4);
-      MessageReference ref6 = ms.reference(m5);
-      ref6.setOrdering(5);
-      MessageReference ref7 = ms.reference(m6);
-      ref7.setOrdering(6);
-      MessageReference ref8 = ms.reference(m7);
-      ref8.setOrdering(7);
-      MessageReference ref9 = ms.reference(m8);
-      ref9.setOrdering(8);
-      MessageReference ref10 = ms.reference(m9);
-      ref10.setOrdering(9);
-      
-      MessageReference ref11 = ms.reference(m10);
-      ref11.setOrdering(10);
-      MessageReference ref12 = ms.reference(m11);
-      ref12.setOrdering(11);
-      MessageReference ref13 = ms.reference(m12);
-      ref13.setOrdering(12);
-      MessageReference ref14 = ms.reference(m13);
-      ref14.setOrdering(13);
-      MessageReference ref15 = ms.reference(m14);
-      ref15.setOrdering(14);
-      
-      
-      pm.addReference(channel.getChannelID(), ref1, null);
-      pm.addReference(channel.getChannelID(), ref2, null);
-      pm.addReference(channel.getChannelID(), ref3, null);
-      pm.addReference(channel.getChannelID(), ref4, null);
-      pm.addReference(channel.getChannelID(), ref5, null);
-      pm.addReference(channel.getChannelID(), ref6, null);
-      pm.addReference(channel.getChannelID(), ref7, null);
-      pm.addReference(channel.getChannelID(), ref8, null);
-      pm.addReference(channel.getChannelID(), ref9, null);
-      pm.addReference(channel.getChannelID(), ref10, null);
-      pm.addReference(channel.getChannelID(), ref11, null);
-      pm.addReference(channel.getChannelID(), ref12, null);
-      pm.addReference(channel.getChannelID(), ref13, null);
-      pm.addReference(channel.getChannelID(), ref14, null);
-      pm.addReference(channel.getChannelID(), ref15, null);
-      
-      List refIds = getReferenceIds(channel.getChannelID());
+      refIds = getReferenceIds(channel1.getChannelID());
       assertNotNull(refIds);
-      assertEquals(15, refIds.size());
-      assertTrue(refIds.contains(new Long(ref1.getMessageID())));
-      assertTrue(refIds.contains(new Long(ref2.getMessageID())));
-      assertTrue(refIds.contains(new Long(ref3.getMessageID())));
+      assertEquals(7, refIds.size());
       assertTrue(refIds.contains(new Long(ref4.getMessageID())));
       assertTrue(refIds.contains(new Long(ref5.getMessageID())));
       assertTrue(refIds.contains(new Long(ref6.getMessageID())));
@@ -316,18 +443,14 @@
       assertTrue(refIds.contains(new Long(ref8.getMessageID())));
       assertTrue(refIds.contains(new Long(ref9.getMessageID())));
       assertTrue(refIds.contains(new Long(ref10.getMessageID())));
-      assertTrue(refIds.contains(new Long(ref11.getMessageID())));
-      assertTrue(refIds.contains(new Long(ref12.getMessageID())));
-      assertTrue(refIds.contains(new Long(ref13.getMessageID())));
-      assertTrue(refIds.contains(new Long(ref14.getMessageID())));
-      assertTrue(refIds.contains(new Long(ref15.getMessageID())));
+     
       
-      List msgs = getMessageIds();
-      assertNotNull(msgs);
-      assertEquals(15, msgs.size());
+      ms = getMessageIds();
+        
+      assertNotNull(ms);
+      assertEquals(8, ms.size());
+      
       assertTrue(msgs.contains(new Long(ref1.getMessageID())));
-      assertTrue(msgs.contains(new Long(ref2.getMessageID())));
-      assertTrue(msgs.contains(new Long(ref3.getMessageID())));
       assertTrue(msgs.contains(new Long(ref4.getMessageID())));
       assertTrue(msgs.contains(new Long(ref5.getMessageID())));
       assertTrue(msgs.contains(new Long(ref6.getMessageID())));
@@ -335,40 +458,27 @@
       assertTrue(msgs.contains(new Long(ref8.getMessageID())));
       assertTrue(msgs.contains(new Long(ref9.getMessageID())));
       assertTrue(msgs.contains(new Long(ref10.getMessageID())));
-      assertTrue(msgs.contains(new Long(ref11.getMessageID())));
-      assertTrue(msgs.contains(new Long(ref12.getMessageID())));
-      assertTrue(msgs.contains(new Long(ref13.getMessageID())));
-      assertTrue(msgs.contains(new Long(ref14.getMessageID())));
-      assertTrue(msgs.contains(new Long(ref15.getMessageID())));
       
-      int numberOfReferences = pm.getNumberOfUnloadedReferences(channel.getChannelID());
+      refs = new ArrayList();
+      refs.add(ref11);
+      pm.removeReferences(channel2.getChannelID(), refs);
       
-      //getNumberOfReferences only returns refs with loaded = 'N' - these will be 'Y'
-      assertEquals(0, numberOfReferences);
-      
-      List refs = new ArrayList();
-      
+      refs = new ArrayList();
+      refs.add(ref4);
+      refs.add(ref5);
+      refs.add(ref6);
+      refs.add(ref7);
       refs.add(ref8);
       refs.add(ref9);
       refs.add(ref10);
-      refs.add(ref11);
-      refs.add(ref12);
-      refs.add(ref13);
+      pm.removeReferences(channel1.getChannelID(), refs);
       
-      pm.updateReferencesNotLoaded(channel.getChannelID(), refs);
-      
-      numberOfReferences = pm.getNumberOfUnloadedReferences(channel.getChannelID());
-      
-      assertEquals(6, numberOfReferences);
-      
-      pm.updateReliableReferencesLoadedInRange(channel.getChannelID(), 8, 11);
-      
-      numberOfReferences = pm.getNumberOfUnloadedReferences(channel.getChannelID());
-      
-      assertEquals(4, numberOfReferences);    
+      ms = getMessageIds();
+      assertNotNull(ms);
+      assertEquals(0, ms.size());
    }
    
-   public void testGetReferenceInfos() throws Throwable
+   public void testPageOrders() throws Throwable
    {
       doSetup(false);
       
@@ -376,29 +486,19 @@
       
       Message[] m = createMessages(10);
       
+      List refs = new ArrayList();
+      
       MessageReference ref1 = ms.reference(m[0]);
-      ref1.setOrdering(0);
       MessageReference ref2 = ms.reference(m[1]);
-      ref2.setOrdering(1);
       MessageReference ref3 = ms.reference(m[2]);
-      ref3.setOrdering(2);
       MessageReference ref4 = ms.reference(m[3]);
-      ref4.setOrdering(11);
       MessageReference ref5 = ms.reference(m[4]);
-      ref5.setOrdering(22);
       MessageReference ref6 = ms.reference(m[5]);
-      ref6.setOrdering(100);
       MessageReference ref7 = ms.reference(m[6]);
-      ref7.setOrdering(303);
       MessageReference ref8 = ms.reference(m[7]);
-      ref8.setOrdering(1000);
       MessageReference ref9 = ms.reference(m[8]);
-      ref9.setOrdering(1001);
       MessageReference ref10 = ms.reference(m[9]);
-      ref10.setOrdering(1002);
       
-      List refs = new ArrayList();
-      
       refs.add(ref1);
       refs.add(ref2);
       refs.add(ref3);
@@ -410,52 +510,27 @@
       refs.add(ref9);
       refs.add(ref10);
       
-      pm.addReferences(channel.getChannelID(), refs, false);
+      pm.addReferences(channel.getChannelID(), refs); 
       
-      List refIds = getReferenceIds(channel.getChannelID());
-      assertNotNull(refIds);
-      assertEquals(10, refIds.size());
-           
-      assertTrue(refIds.contains(new Long(ref1.getMessageID())));
-      assertTrue(refIds.contains(new Long(ref2.getMessageID())));
-      assertTrue(refIds.contains(new Long(ref3.getMessageID())));
-      assertTrue(refIds.contains(new Long(ref4.getMessageID())));
-      assertTrue(refIds.contains(new Long(ref5.getMessageID())));
-      assertTrue(refIds.contains(new Long(ref6.getMessageID())));
-      assertTrue(refIds.contains(new Long(ref7.getMessageID())));
-      assertTrue(refIds.contains(new Long(ref8.getMessageID())));
-      assertTrue(refIds.contains(new Long(ref9.getMessageID())));
-      assertTrue(refIds.contains(new Long(ref10.getMessageID())));
+      ref1.setPagingOrder(0);
+      ref2.setPagingOrder(1);
+      ref3.setPagingOrder(2);
+      ref4.setPagingOrder(3);
+      ref5.setPagingOrder(4);
+      ref6.setPagingOrder(5);
+      ref7.setPagingOrder(6);
+      ref8.setPagingOrder(7);
+      ref9.setPagingOrder(8);
+      ref10.setPagingOrder(9);
       
-      List msgs = getMessageIds();
-      assertNotNull(msgs);
-      assertEquals(10, msgs.size());
-      assertTrue(msgs.contains(new Long(ref1.getMessageID())));
-      assertTrue(msgs.contains(new Long(ref2.getMessageID())));
-      assertTrue(msgs.contains(new Long(ref3.getMessageID())));
-      assertTrue(msgs.contains(new Long(ref4.getMessageID())));
-      assertTrue(msgs.contains(new Long(ref5.getMessageID())));
-      assertTrue(msgs.contains(new Long(ref6.getMessageID())));
-      assertTrue(msgs.contains(new Long(ref7.getMessageID())));
-      assertTrue(msgs.contains(new Long(ref8.getMessageID())));
-      assertTrue(msgs.contains(new Long(ref9.getMessageID())));
-      assertTrue(msgs.contains(new Long(ref10.getMessageID())));
+      pm.updatePageOrder(channel.getChannelID(), refs);
       
-      List refInfos = pm.getReferenceInfos(channel.getChannelID(), 0, 0);
+      List refInfos = pm.getPagedReferenceInfos(channel.getChannelID(), 0, 10);
       
       assertNotNull(refInfos);
-      assertEquals(0, refInfos.size());
       
-      refInfos = pm.getReferenceInfos(channel.getChannelID(), 0, 3);
-      assertNotNull(refInfos);
-      assertEquals(3, refInfos.size());
-      assertEquals(ref1.getMessageID(), ((PersistenceManager.ReferenceInfo)refInfos.get(0)).getMessageId());
-      assertEquals(ref2.getMessageID(), ((PersistenceManager.ReferenceInfo)refInfos.get(1)).getMessageId());
-      assertEquals(ref3.getMessageID(), ((PersistenceManager.ReferenceInfo)refInfos.get(2)).getMessageId());
-      
-      refInfos = pm.getReferenceInfos(channel.getChannelID(), 0, 10);
-      assertNotNull(refInfos);
       assertEquals(10, refInfos.size());
+      
       assertEquals(ref1.getMessageID(), ((PersistenceManager.ReferenceInfo)refInfos.get(0)).getMessageId());
       assertEquals(ref2.getMessageID(), ((PersistenceManager.ReferenceInfo)refInfos.get(1)).getMessageId());
       assertEquals(ref3.getMessageID(), ((PersistenceManager.ReferenceInfo)refInfos.get(2)).getMessageId());
@@ -466,29 +541,34 @@
       assertEquals(ref8.getMessageID(), ((PersistenceManager.ReferenceInfo)refInfos.get(7)).getMessageId());
       assertEquals(ref9.getMessageID(), ((PersistenceManager.ReferenceInfo)refInfos.get(8)).getMessageId());
       assertEquals(ref10.getMessageID(), ((PersistenceManager.ReferenceInfo)refInfos.get(9)).getMessageId());
-
-      refInfos = pm.getReferenceInfos(channel.getChannelID(), 2, 6);
+      
+      refInfos = pm.getPagedReferenceInfos(channel.getChannelID(), 3, 5);
+      
       assertNotNull(refInfos);
-      assertEquals(6, refInfos.size());     
-      assertEquals(ref3.getMessageID(), ((PersistenceManager.ReferenceInfo)refInfos.get(0)).getMessageId());
-      assertEquals(ref4.getMessageID(), ((PersistenceManager.ReferenceInfo)refInfos.get(1)).getMessageId());
-      assertEquals(ref5.getMessageID(), ((PersistenceManager.ReferenceInfo)refInfos.get(2)).getMessageId());
-      assertEquals(ref6.getMessageID(), ((PersistenceManager.ReferenceInfo)refInfos.get(3)).getMessageId());
-      assertEquals(ref7.getMessageID(), ((PersistenceManager.ReferenceInfo)refInfos.get(4)).getMessageId());
-      assertEquals(ref8.getMessageID(), ((PersistenceManager.ReferenceInfo)refInfos.get(5)).getMessageId());
-
-      try
-      {
-         refInfos = pm.getReferenceInfos(channel.getChannelID(), 0, 19);
-         fail();
-      }
-      catch (IllegalStateException e)
-      {
-         //ok - there are not this many refs
-      }
+      
+      assertEquals(5, refInfos.size());
+      
+      assertEquals(ref4.getMessageID(), ((PersistenceManager.ReferenceInfo)refInfos.get(0)).getMessageId());
+      assertEquals(ref5.getMessageID(), ((PersistenceManager.ReferenceInfo)refInfos.get(1)).getMessageId());
+      assertEquals(ref6.getMessageID(), ((PersistenceManager.ReferenceInfo)refInfos.get(2)).getMessageId());
+      assertEquals(ref7.getMessageID(), ((PersistenceManager.ReferenceInfo)refInfos.get(3)).getMessageId());
+      assertEquals(ref8.getMessageID(), ((PersistenceManager.ReferenceInfo)refInfos.get(4)).getMessageId());
+    
+      pm.updateReliableReferencesNotPagedInRange(channel.getChannelID(), 0, 4);
+      
+      refInfos = pm.getPagedReferenceInfos(channel.getChannelID(), 5, 5);
+      
+      assertNotNull(refInfos);
+      
+      assertEquals(5, refInfos.size());
+          
+      assertEquals(ref6.getMessageID(), ((PersistenceManager.ReferenceInfo)refInfos.get(0)).getMessageId());
+      assertEquals(ref7.getMessageID(), ((PersistenceManager.ReferenceInfo)refInfos.get(1)).getMessageId());
+      assertEquals(ref8.getMessageID(), ((PersistenceManager.ReferenceInfo)refInfos.get(2)).getMessageId());
+      assertEquals(ref9.getMessageID(), ((PersistenceManager.ReferenceInfo)refInfos.get(3)).getMessageId());
+      assertEquals(ref10.getMessageID(), ((PersistenceManager.ReferenceInfo)refInfos.get(4)).getMessageId());                
    }
-   
-   
+     
    public void testGetMessages() throws Throwable
    {
       doSetup(false);
@@ -566,6 +646,191 @@
         
    }
    
+   public void testGetInitialRefInfos() throws Throwable
+   {
+      doSetup(false);
+      
+      Channel channel = new SimpleChannel(0, ms);
+      
+      Message[] m = createMessages(10);
+      
+      List refs = new ArrayList();
+      
+      MessageReference ref1 = ms.reference(m[0]);
+      MessageReference ref2 = ms.reference(m[1]);
+      MessageReference ref3 = ms.reference(m[2]);
+      MessageReference ref4 = ms.reference(m[3]);
+      MessageReference ref5 = ms.reference(m[4]);
+      MessageReference ref6 = ms.reference(m[5]);
+      MessageReference ref7 = ms.reference(m[6]);
+      MessageReference ref8 = ms.reference(m[7]);
+      MessageReference ref9 = ms.reference(m[8]);
+      MessageReference ref10 = ms.reference(m[9]);
+      
+      refs.add(ref1);
+      refs.add(ref2);
+      refs.add(ref3);
+      refs.add(ref4);
+      refs.add(ref5);
+      refs.add(ref6);
+      refs.add(ref7);
+      refs.add(ref8);
+      refs.add(ref9);
+      refs.add(ref10);
+      
+      pm.addReferences(channel.getChannelID(), refs); 
+      
+      //First load exactly 10
+      PersistenceManager.InitialLoadInfo info = pm.getInitialReferenceInfos(channel.getChannelID(), 10);
+      
+      assertEquals(-1, info.getMinPageOrdering());
+      assertEquals(-1, info.getMaxPageOrdering());
+      
+      List refInfos = info.getRefInfos();
+      
+      assertNotNull(refInfos);
+      assertEquals(10, refInfos.size());
+      
+      assertEquals(ref1.getMessageID(), ((PersistenceManager.ReferenceInfo)refInfos.get(0)).getMessageId());
+      assertEquals(ref2.getMessageID(), ((PersistenceManager.ReferenceInfo)refInfos.get(1)).getMessageId());
+      assertEquals(ref3.getMessageID(), ((PersistenceManager.ReferenceInfo)refInfos.get(2)).getMessageId());
+      assertEquals(ref4.getMessageID(), ((PersistenceManager.ReferenceInfo)refInfos.get(3)).getMessageId());
+      assertEquals(ref5.getMessageID(), ((PersistenceManager.ReferenceInfo)refInfos.get(4)).getMessageId());
+      assertEquals(ref6.getMessageID(), ((PersistenceManager.ReferenceInfo)refInfos.get(5)).getMessageId());
+      assertEquals(ref7.getMessageID(), ((PersistenceManager.ReferenceInfo)refInfos.get(6)).getMessageId());
+      assertEquals(ref8.getMessageID(), ((PersistenceManager.ReferenceInfo)refInfos.get(7)).getMessageId());
+      assertEquals(ref9.getMessageID(), ((PersistenceManager.ReferenceInfo)refInfos.get(8)).getMessageId());
+      assertEquals(ref10.getMessageID(), ((PersistenceManager.ReferenceInfo)refInfos.get(9)).getMessageId());
+      
+      //fullSize has increased to 15 - only 10 should be loadeed still
+      info = pm.getInitialReferenceInfos(channel.getChannelID(), 15);
+      
+      assertEquals(-1, info.getMinPageOrdering());
+      assertEquals(-1, info.getMaxPageOrdering());
+      
+      refInfos = info.getRefInfos();
+      assertNotNull(refInfos);
+      assertEquals(10, refInfos.size());
+      
+      assertEquals(ref1.getMessageID(), ((PersistenceManager.ReferenceInfo)refInfos.get(0)).getMessageId());
+      assertEquals(ref2.getMessageID(), ((PersistenceManager.ReferenceInfo)refInfos.get(1)).getMessageId());
+      assertEquals(ref3.getMessageID(), ((PersistenceManager.ReferenceInfo)refInfos.get(2)).getMessageId());
+      assertEquals(ref4.getMessageID(), ((PersistenceManager.ReferenceInfo)refInfos.get(3)).getMessageId());
+      assertEquals(ref5.getMessageID(), ((PersistenceManager.ReferenceInfo)refInfos.get(4)).getMessageId());
+      assertEquals(ref6.getMessageID(), ((PersistenceManager.ReferenceInfo)refInfos.get(5)).getMessageId());
+      assertEquals(ref7.getMessageID(), ((PersistenceManager.ReferenceInfo)refInfos.get(6)).getMessageId());
+      assertEquals(ref8.getMessageID(), ((PersistenceManager.ReferenceInfo)refInfos.get(7)).getMessageId());
+      assertEquals(ref9.getMessageID(), ((PersistenceManager.ReferenceInfo)refInfos.get(8)).getMessageId());
+      assertEquals(ref10.getMessageID(), ((PersistenceManager.ReferenceInfo)refInfos.get(9)).getMessageId());
+      
+      //fullSize has gone down to 7 - 7 should be loaded and the other 3 marked as paged
+      info = pm.getInitialReferenceInfos(channel.getChannelID(), 7);
+      
+      assertEquals(0, info.getMinPageOrdering());
+      assertEquals(2, info.getMaxPageOrdering());
+      
+      refInfos = info.getRefInfos();
+      assertNotNull(refInfos);
+      assertEquals(7, refInfos.size());
+      
+      assertEquals(ref1.getMessageID(), ((PersistenceManager.ReferenceInfo)refInfos.get(0)).getMessageId());
+      assertEquals(ref2.getMessageID(), ((PersistenceManager.ReferenceInfo)refInfos.get(1)).getMessageId());
+      assertEquals(ref3.getMessageID(), ((PersistenceManager.ReferenceInfo)refInfos.get(2)).getMessageId());
+      assertEquals(ref4.getMessageID(), ((PersistenceManager.ReferenceInfo)refInfos.get(3)).getMessageId());
+      assertEquals(ref5.getMessageID(), ((PersistenceManager.ReferenceInfo)refInfos.get(4)).getMessageId());
+      assertEquals(ref6.getMessageID(), ((PersistenceManager.ReferenceInfo)refInfos.get(5)).getMessageId());
+      assertEquals(ref7.getMessageID(), ((PersistenceManager.ReferenceInfo)refInfos.get(6)).getMessageId());
+      
+      List pagedInfos = pm.getPagedReferenceInfos(channel.getChannelID(), 0, 3);
+      assertNotNull(pagedInfos);
+      assertEquals(3, pagedInfos.size());
+      assertEquals(ref8.getMessageID(), ((PersistenceManager.ReferenceInfo)pagedInfos.get(0)).getMessageId());
+      assertEquals(ref9.getMessageID(), ((PersistenceManager.ReferenceInfo)pagedInfos.get(1)).getMessageId());
+      assertEquals(ref10.getMessageID(), ((PersistenceManager.ReferenceInfo)pagedInfos.get(2)).getMessageId());
+            
+      //fullSize gone down even further to 4 - 4 should be loaded and othe others re-ordered from zero
+      
+      info = pm.getInitialReferenceInfos(channel.getChannelID(), 4);
+      
+      assertEquals(0, info.getMinPageOrdering());
+      assertEquals(5, info.getMaxPageOrdering());
+      
+      refInfos = info.getRefInfos();
+      assertNotNull(refInfos);
+      assertEquals(4, refInfos.size());
+      
+      assertEquals(ref1.getMessageID(), ((PersistenceManager.ReferenceInfo)refInfos.get(0)).getMessageId());
+      assertEquals(ref2.getMessageID(), ((PersistenceManager.ReferenceInfo)refInfos.get(1)).getMessageId());
+      assertEquals(ref3.getMessageID(), ((PersistenceManager.ReferenceInfo)refInfos.get(2)).getMessageId());
+      assertEquals(ref4.getMessageID(), ((PersistenceManager.ReferenceInfo)refInfos.get(3)).getMessageId());
+         
+      pagedInfos = pm.getPagedReferenceInfos(channel.getChannelID(), 0, 6);
+      assertNotNull(pagedInfos);
+      assertEquals(6, pagedInfos.size());
+      assertEquals(ref5.getMessageID(), ((PersistenceManager.ReferenceInfo)pagedInfos.get(0)).getMessageId());
+      assertEquals(ref6.getMessageID(), ((PersistenceManager.ReferenceInfo)pagedInfos.get(1)).getMessageId());
+      assertEquals(ref7.getMessageID(), ((PersistenceManager.ReferenceInfo)pagedInfos.get(2)).getMessageId());
+      assertEquals(ref8.getMessageID(), ((PersistenceManager.ReferenceInfo)pagedInfos.get(3)).getMessageId());
+      assertEquals(ref9.getMessageID(), ((PersistenceManager.ReferenceInfo)pagedInfos.get(4)).getMessageId());
+      assertEquals(ref10.getMessageID(), ((PersistenceManager.ReferenceInfo)pagedInfos.get(5)).getMessageId());
+      
+      //fullSize back up to 6 - 6 should be loaded and the others shifted
+      
+      info = pm.getInitialReferenceInfos(channel.getChannelID(), 6);
+      
+      assertEquals(2, info.getMinPageOrdering());
+      assertEquals(5, info.getMaxPageOrdering());
+      
+      refInfos = info.getRefInfos();
+      assertNotNull(refInfos);
+      assertEquals(6, refInfos.size());
+      
+      log.info("msg id: " + ((PersistenceManager.ReferenceInfo)refInfos.get(0)).getMessageId());
+      log.info("msg id: " + ((PersistenceManager.ReferenceInfo)refInfos.get(1)).getMessageId());
+      log.info("msg id: " + ((PersistenceManager.ReferenceInfo)refInfos.get(2)).getMessageId());
+      log.info("msg id: " + ((PersistenceManager.ReferenceInfo)refInfos.get(3)).getMessageId());
+      log.info("msg id: " + ((PersistenceManager.ReferenceInfo)refInfos.get(4)).getMessageId());
+      log.info("msg id: " + ((PersistenceManager.ReferenceInfo)refInfos.get(5)).getMessageId());
+      
+      assertEquals(ref1.getMessageID(), ((PersistenceManager.ReferenceInfo)refInfos.get(0)).getMessageId());
+      assertEquals(ref2.getMessageID(), ((PersistenceManager.ReferenceInfo)refInfos.get(1)).getMessageId());
+      assertEquals(ref3.getMessageID(), ((PersistenceManager.ReferenceInfo)refInfos.get(2)).getMessageId());
+      assertEquals(ref4.getMessageID(), ((PersistenceManager.ReferenceInfo)refInfos.get(3)).getMessageId());
+      assertEquals(ref5.getMessageID(), ((PersistenceManager.ReferenceInfo)refInfos.get(4)).getMessageId());
+      assertEquals(ref6.getMessageID(), ((PersistenceManager.ReferenceInfo)refInfos.get(5)).getMessageId());
+              
+      pagedInfos = pm.getPagedReferenceInfos(channel.getChannelID(), 2, 4);
+      assertNotNull(pagedInfos);
+      assertEquals(4, pagedInfos.size());
+      assertEquals(ref7.getMessageID(), ((PersistenceManager.ReferenceInfo)pagedInfos.get(0)).getMessageId());
+      assertEquals(ref8.getMessageID(), ((PersistenceManager.ReferenceInfo)pagedInfos.get(1)).getMessageId());
+      assertEquals(ref9.getMessageID(), ((PersistenceManager.ReferenceInfo)pagedInfos.get(2)).getMessageId());
+      assertEquals(ref10.getMessageID(), ((PersistenceManager.ReferenceInfo)pagedInfos.get(3)).getMessageId());
+              
+      //fullSize up to 12
+      
+      info = pm.getInitialReferenceInfos(channel.getChannelID(), 12);
+      
+      assertEquals(-1, info.getMinPageOrdering());
+      assertEquals(-1, info.getMaxPageOrdering());
+      
+      refInfos = info.getRefInfos();
+      assertNotNull(refInfos);
+      assertEquals(10, refInfos.size());
+      
+      assertEquals(ref1.getMessageID(), ((PersistenceManager.ReferenceInfo)refInfos.get(0)).getMessageId());
+      assertEquals(ref2.getMessageID(), ((PersistenceManager.ReferenceInfo)refInfos.get(1)).getMessageId());
+      assertEquals(ref3.getMessageID(), ((PersistenceManager.ReferenceInfo)refInfos.get(2)).getMessageId());
+      assertEquals(ref4.getMessageID(), ((PersistenceManager.ReferenceInfo)refInfos.get(3)).getMessageId());
+      assertEquals(ref5.getMessageID(), ((PersistenceManager.ReferenceInfo)refInfos.get(4)).getMessageId());
+      assertEquals(ref6.getMessageID(), ((PersistenceManager.ReferenceInfo)refInfos.get(5)).getMessageId());
+      assertEquals(ref7.getMessageID(), ((PersistenceManager.ReferenceInfo)refInfos.get(6)).getMessageId());
+      assertEquals(ref8.getMessageID(), ((PersistenceManager.ReferenceInfo)refInfos.get(7)).getMessageId());
+      assertEquals(ref9.getMessageID(), ((PersistenceManager.ReferenceInfo)refInfos.get(8)).getMessageId());
+      assertEquals(ref10.getMessageID(), ((PersistenceManager.ReferenceInfo)refInfos.get(9)).getMessageId());                              
+   }
+      
+   
    protected boolean containsMessage(List msgs, long msgId)
    {
       Iterator iter = msgs.iterator();
@@ -657,366 +922,7 @@
       assertTrue(containsMessage(ms, ref1.getMessageID()));   
    }
    
-   public void testaddRemoveGetReferences_Batch() throws Throwable
-   {
-      addRemoveGetReferences(true);
-   }
-   
-   public void testaddRemoveGetReferences_NoBatch() throws Throwable
-   {
-      addRemoveGetReferences(false);
-   }
-   
-   protected void addRemoveGetReferences(boolean batch) throws Throwable
-   {
-      doSetup(false);
-      
-      Channel channel1 = new SimpleChannel(0, ms);
-      
-      Channel channel2 = new SimpleChannel(1, ms);
-      
-      Message[] m = createMessages(10);
-      
-      MessageReference ref1 = ms.reference(m[0]);
-      MessageReference ref2 = ms.reference(m[1]);
-      MessageReference ref3 = ms.reference(m[2]);
-      MessageReference ref4 = ms.reference(m[3]);
-      MessageReference ref5 = ms.reference(m[4]);
-      MessageReference ref6 = ms.reference(m[5]);
-      MessageReference ref7 = ms.reference(m[6]);
-      MessageReference ref8 = ms.reference(m[7]);
-      MessageReference ref9 = ms.reference(m[8]);
-      MessageReference ref10 = ms.reference(m[9]);
-      
-      MessageReference ref11 = ms.reference(m[0]);
-      MessageReference ref12 = ms.reference(m[1]);
-      MessageReference ref13 = ms.reference(m[2]);
-      MessageReference ref14 = ms.reference(m[3]);
-      MessageReference ref15 = ms.reference(m[4]);
-      
-      List refs = new ArrayList();
-      refs.add(ref1);
-      refs.add(ref2);
-      refs.add(ref3);
-      refs.add(ref4);
-      refs.add(ref5);
-      refs.add(ref6);
-      refs.add(ref7);
-      refs.add(ref8);
-      refs.add(ref9);
-      refs.add(ref10);
-      
-      pm.addReferences(channel1.getChannelID(), refs, true);
-      
-      refs = new ArrayList();
-      refs.add(ref11);
-      refs.add(ref12);
-      refs.add(ref13);
-      refs.add(ref14);
-      refs.add(ref15);
-    
-      pm.addReferences(channel2.getChannelID(), refs, true);
-                  
-      List refIds = getReferenceIds(channel1.getChannelID());
-      assertNotNull(refIds);
-      assertEquals(10, refIds.size());
-      assertTrue(refIds.contains(new Long(ref1.getMessageID())));
-      assertTrue(refIds.contains(new Long(ref2.getMessageID())));
-      assertTrue(refIds.contains(new Long(ref3.getMessageID())));
-      assertTrue(refIds.contains(new Long(ref4.getMessageID())));
-      assertTrue(refIds.contains(new Long(ref5.getMessageID())));
-      assertTrue(refIds.contains(new Long(ref6.getMessageID())));
-      assertTrue(refIds.contains(new Long(ref7.getMessageID())));
-      assertTrue(refIds.contains(new Long(ref8.getMessageID())));
-      assertTrue(refIds.contains(new Long(ref9.getMessageID())));
-      assertTrue(refIds.contains(new Long(ref10.getMessageID())));
-      
-      refIds = getReferenceIds(channel2.getChannelID());
-      assertNotNull(refIds);
-      assertEquals(5, refIds.size());
-      assertTrue(refIds.contains(new Long(ref11.getMessageID())));
-      assertTrue(refIds.contains(new Long(ref12.getMessageID())));
-      assertTrue(refIds.contains(new Long(ref13.getMessageID())));
-      assertTrue(refIds.contains(new Long(ref14.getMessageID())));
-      assertTrue(refIds.contains(new Long(ref15.getMessageID())));
-     
-      
-      List msgs = getMessageIds();
-      assertNotNull(msgs);
-      assertEquals(10, msgs.size());
-      assertTrue(msgs.contains(new Long(ref1.getMessageID())));
-      assertTrue(msgs.contains(new Long(ref2.getMessageID())));
-      assertTrue(msgs.contains(new Long(ref3.getMessageID())));
-      assertTrue(msgs.contains(new Long(ref4.getMessageID())));
-      assertTrue(msgs.contains(new Long(ref5.getMessageID())));
-      assertTrue(msgs.contains(new Long(ref6.getMessageID())));
-      assertTrue(msgs.contains(new Long(ref7.getMessageID())));
-      assertTrue(msgs.contains(new Long(ref8.getMessageID())));
-      assertTrue(msgs.contains(new Long(ref9.getMessageID())));
-      assertTrue(msgs.contains(new Long(ref10.getMessageID())));
-      
-      List msgIds = new ArrayList();
-      msgIds.add(new Long(ref3.getMessageID()));
-      msgIds.add(new Long(ref4.getMessageID()));
-      msgIds.add(new Long(ref7.getMessageID()));
-      msgIds.add(new Long(ref9.getMessageID()));
-      msgIds.add(new Long(ref1.getMessageID()));
-      
-      List ms = pm.getMessages(msgIds);
-      assertNotNull(ms);
-      assertEquals(5, ms.size());
-      assertTrue(containsMessage(ms, ref3.getMessageID()));
-      assertTrue(containsMessage(ms, ref4.getMessageID()));
-      assertTrue(containsMessage(ms, ref7.getMessageID()));
-      assertTrue(containsMessage(ms, ref9.getMessageID()));
-      assertTrue(containsMessage(ms, ref1.getMessageID()));
-      
-      refs = new ArrayList();
-      refs.add(ref12);
-      refs.add(ref13);
-      refs.add(ref14);
-      refs.add(ref15);
-      pm.removeReferences(channel2.getChannelID(), refs);
-      
-      refIds = getReferenceIds(channel2.getChannelID());
-      assertNotNull(refIds);
-      assertEquals(1, refIds.size());
-      assertTrue(refIds.contains(new Long(ref11.getMessageID())));
-      
-      ms = getMessageIds();
 
-      assertNotNull(ms);
-      assertEquals(10, ms.size());
-      
-      assertTrue(msgs.contains(new Long(ref1.getMessageID())));
-      assertTrue(msgs.contains(new Long(ref2.getMessageID())));
-      assertTrue(msgs.contains(new Long(ref3.getMessageID())));
-      assertTrue(msgs.contains(new Long(ref4.getMessageID())));
-      assertTrue(msgs.contains(new Long(ref5.getMessageID())));
-      assertTrue(msgs.contains(new Long(ref6.getMessageID())));
-      assertTrue(msgs.contains(new Long(ref7.getMessageID())));
-      assertTrue(msgs.contains(new Long(ref8.getMessageID())));
-      assertTrue(msgs.contains(new Long(ref9.getMessageID())));
-      assertTrue(msgs.contains(new Long(ref10.getMessageID())));
-     
-      
-      refs = new ArrayList();
-      refs.add(ref1);
-      refs.add(ref2);
-      refs.add(ref3);
-      pm.removeReferences(channel1.getChannelID(), refs);
-      
-      refIds = getReferenceIds(channel1.getChannelID());
-      assertNotNull(refIds);
-      assertEquals(7, refIds.size());
-      assertTrue(refIds.contains(new Long(ref4.getMessageID())));
-      assertTrue(refIds.contains(new Long(ref5.getMessageID())));
-      assertTrue(refIds.contains(new Long(ref6.getMessageID())));
-      assertTrue(refIds.contains(new Long(ref7.getMessageID())));
-      assertTrue(refIds.contains(new Long(ref8.getMessageID())));
-      assertTrue(refIds.contains(new Long(ref9.getMessageID())));
-      assertTrue(refIds.contains(new Long(ref10.getMessageID())));
-     
-      
-      ms = getMessageIds();
-        
-      assertNotNull(ms);
-      assertEquals(8, ms.size());
-      
-      assertTrue(msgs.contains(new Long(ref1.getMessageID())));
-      assertTrue(msgs.contains(new Long(ref4.getMessageID())));
-      assertTrue(msgs.contains(new Long(ref5.getMessageID())));
-      assertTrue(msgs.contains(new Long(ref6.getMessageID())));
-      assertTrue(msgs.contains(new Long(ref7.getMessageID())));
-      assertTrue(msgs.contains(new Long(ref8.getMessageID())));
-      assertTrue(msgs.contains(new Long(ref9.getMessageID())));
-      assertTrue(msgs.contains(new Long(ref10.getMessageID())));
-      
-      refs = new ArrayList();
-      refs.add(ref11);
-      pm.removeReferences(channel2.getChannelID(), refs);
-      
-      refs = new ArrayList();
-      refs.add(ref4);
-      refs.add(ref5);
-      refs.add(ref6);
-      refs.add(ref7);
-      refs.add(ref8);
-      refs.add(ref9);
-      refs.add(ref10);
-      pm.removeReferences(channel1.getChannelID(), refs);
-      
-      ms = getMessageIds();
-      assertNotNull(ms);
-      assertEquals(0, ms.size());
-   }
-   
-   
-   
-   
-   public void testAddRemoveReference() throws Throwable
-   {
-      doSetup(false);
-      
-      Channel channel1 = new SimpleChannel(0, ms);
-      Channel channel2 = new SimpleChannel(1, ms);
-
-      Message[] messages = createMessages(10);     
-      
-      for (int i = 0; i < 5; i++)
-      {
-         Message m1 = messages[i * 2];
-         Message m2 = messages[i * 2 + 1];
-         
-         MessageReference ref1_1 = ms.reference(m1);
-         MessageReference ref1_2 = ms.reference(m1);
-                
-         MessageReference ref2_1 = ms.reference(m2);
-         MessageReference ref2_2 = ms.reference(m2);
-                  
-         pm.addReference(channel1.getChannelID(), ref1_1, null);
-         pm.addReference(channel1.getChannelID(), ref2_1, null);         
-         
-         pm.addReference(channel2.getChannelID(), ref1_2, null);
-         pm.addReference(channel2.getChannelID(), ref2_2, null);
-      
-         List refs = getReferenceIds(channel1.getChannelID());
-         
-         assertNotNull(refs);
-         assertEquals(2, refs.size());
-         assertTrue(refs.contains(new Long(m1.getMessageID())));
-         assertTrue(refs.contains(new Long(m2.getMessageID())));
-         
-         refs = getReferenceIds(channel2.getChannelID());
-         
-         assertNotNull(refs);
-         assertEquals(2, refs.size());
-         assertTrue(refs.contains(new Long(m1.getMessageID())));
-         assertTrue(refs.contains(new Long(m2.getMessageID())));
-         
-         List msgs = getMessageIds();
-         assertNotNull(msgs);
-         assertEquals(2, msgs.size());
-         assertTrue(msgs.contains(new Long(m1.getMessageID())));
-         assertTrue(msgs.contains(new Long(m2.getMessageID())));
-                  
-         pm.removeReference(channel1.getChannelID(), ref1_1, null);
-                  
-         refs = getReferenceIds(channel1.getChannelID());
-         assertNotNull(refs);
-         assertEquals(1, refs.size());
-         assertTrue(refs.contains(new Long(m2.getMessageID())));
-         
-         refs = getReferenceIds(channel2.getChannelID());
-         assertNotNull(refs);
-         assertEquals(2, refs.size());
-         assertTrue(refs.contains(new Long(m1.getMessageID())));
-         assertTrue(refs.contains(new Long(m2.getMessageID())));
-         
-         msgs = getMessageIds();
-         assertNotNull(msgs);
-         assertEquals(2, msgs.size());
-         assertTrue(msgs.contains(new Long(m1.getMessageID())));
-         assertTrue(msgs.contains(new Long(m2.getMessageID())));
-         
-         pm.removeReference(channel2.getChannelID(), ref1_2, null);
-         
-         refs = getReferenceIds(channel1.getChannelID());
-         assertNotNull(refs);
-         assertEquals(1, refs.size());
-         assertTrue(refs.contains(new Long(m2.getMessageID())));
-         
-         refs = getReferenceIds(channel2.getChannelID());
-         assertNotNull(refs);
-         assertEquals(1, refs.size());         
-         assertTrue(refs.contains(new Long(m2.getMessageID())));
-         
-         msgs = getMessageIds();
-         assertNotNull(msgs);
-         assertEquals(1, msgs.size());
-         assertTrue(msgs.contains(new Long(m2.getMessageID())));
-         
-         pm.removeReference(channel1.getChannelID(), ref2_1, null);
-         
-         refs = getReferenceIds(channel1.getChannelID());
-         assertNotNull(refs);
-         assertTrue(refs.isEmpty());
-         
-         refs = getReferenceIds(channel2.getChannelID());
-         assertNotNull(refs);
-         assertEquals(1, refs.size());         
-         assertTrue(refs.contains(new Long(m2.getMessageID())));
-         
-         msgs = getMessageIds();
-         assertNotNull(msgs);
-         assertEquals(1, msgs.size());
-         assertTrue(msgs.contains(new Long(m2.getMessageID())));
-         
-         pm.removeReference(channel2.getChannelID(), ref2_2, null);
-         
-         refs = getReferenceIds(channel1.getChannelID());
-         assertNotNull(refs);
-         assertTrue(refs.isEmpty());
-         
-         refs = getReferenceIds(channel2.getChannelID());
-         assertNotNull(refs);
-         assertTrue(refs.isEmpty());
-         
-         msgs = getMessageIds();
-         assertNotNull(msgs);
-         assertTrue(msgs.isEmpty());
-            
-      }
-   }
-       
-   
-   
-   //non batch
-   
-   public void testCommit_NotXA_Long_NB() throws Throwable
-   {
-      doTransactionCommit(false, false);
-   }
-   
-   public void testCommit_XA_Long_NB() throws Throwable
-   {
-      doTransactionCommit(true, false);
-   }
-
-   public void testRollback_NotXA_Long_NB() throws Throwable
-   {
-      doTransactionRollback(false, false);
-   }
-       
-   public void testRollback_XA_Long_NB() throws Throwable
-   {
-      doTransactionRollback(true, false);
-   }
-   
-
-   //batch
-   
-   public void testCommit_NotXA_Long_B() throws Throwable
-   {
-      doTransactionCommit(false, true);
-   }
-     
-   public void testCommit_XA_Long_B() throws Throwable
-   {
-      doTransactionCommit(true, true);
-   }
-
-   public void testRollback_NotXA_Long_B() throws Throwable
-   {
-      doTransactionRollback(false, true);
-   }
-        
-   public void testRollback_XA_Long_B() throws Throwable
-   {
-      doTransactionRollback(true, true);
-   }
-   
-
    public void testRetrievePreparedTransactions() throws Throwable
    {
       doSetup(false);
@@ -1024,7 +930,8 @@
       Channel channel = new SimpleChannel(0, ms);
       
       TransactionRepository txRep = new TransactionRepository();
-      txRep.start(pm);
+      IdManager idMgr = new IdManager("TRANSCTION_ID", 10, pm);
+      txRep.injectAttributes(pm, idMgr);
 
       Message[] messages = createMessages(10);
       
@@ -1378,7 +1285,8 @@
 
       Channel channel = new SimpleChannel(0, ms);
       TransactionRepository txRep = new TransactionRepository();
-      txRep.start(pm);
+      IdManager idMgr = new IdManager("TRANSCTION_ID", 10, pm);
+      txRep.injectAttributes(pm, idMgr);
 
       log.debug("transaction log started");
 
@@ -1474,7 +1382,8 @@
 
       Channel channel = new SimpleChannel(0, ms);
       TransactionRepository txRep = new TransactionRepository();
-      txRep.start(pm);
+      IdManager idMgr = new IdManager("TRANSCTION_ID", 10, pm);
+      txRep.injectAttributes(pm, idMgr);
  
       Message[] messages = createMessages(10);     
       
@@ -1558,6 +1467,7 @@
       assertTrue(msgs.contains(new Long(ref2.getMessageID())));          
    }
    
+   
    protected List getReferenceIds(long channelId) throws Throwable
    {
       InitialContext ctx = new InitialContext();

Copied: trunk/tests/src/org/jboss/test/messaging/core/plugin/JGroupsUtil.java (from rev 1226, trunk/tests/src/org/jboss/test/messaging/core/distributed/JGroupsUtil.java)
===================================================================
--- trunk/tests/src/org/jboss/test/messaging/core/distributed/JGroupsUtil.java	2006-08-16 20:25:23 UTC (rev 1226)
+++ trunk/tests/src/org/jboss/test/messaging/core/plugin/JGroupsUtil.java	2006-08-30 18:36:36 UTC (rev 1237)
@@ -0,0 +1,100 @@
+/**
+ * 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.core.plugin;
+
+/**
+ * @author <a href="mailto:ovidiu at jboss.org">Ovidiu Feodorov</a>
+ * @author <a href="mailto:tim.fox at jboss.com">Tim Fox</a>
+ * @version <tt>$Revision$</tt>
+ *
+ * $Id$
+ */
+public class JGroupsUtil
+{
+   // Constants -----------------------------------------------------
+
+   // Static --------------------------------------------------------
+
+   
+   public static String getDataStackProperties(int PING_timeout,
+                                                       int PING_num_initial_members)
+   {
+      String host = System.getProperty("test.bind.address");
+      if (host == null)
+      {
+         host = "localhost";
+      }
+
+      return
+         "UDP(mcast_addr=228.8.8.8;mcast_port=45566;ip_ttl=32;bind_addr=" + host + "):" +
+         "PING(timeout=" + PING_timeout + ";num_initial_members=" + PING_num_initial_members + "):"+
+         "FD(timeout=3000):"+
+         "VERIFY_SUSPECT(timeout=1500):"+
+         "pbcast.NAKACK(gc_lag=10;retransmit_timeout=600,1200,2400,4800):"+
+         "pbcast.STABLE(desired_avg_gossip=10000):"+
+         "FRAG:"+
+         "pbcast.GMS(join_timeout=5000;join_retry_timeout=2000;shun=true;print_local_addr=true)"; 
+   }
+   
+
+   
+   /*
+    * The control stack is used for sending control messages and maintaining state
+    * It must be reliable and have the state protocol enabled
+    */
+   public static String getControlStackProperties(int PING_timeout,
+                                                  int PING_num_initial_members)
+   {
+      String host = System.getProperty("test.bind.address");
+      if (host == null)
+      {
+         host = "localhost";
+      }
+
+      return
+         "UDP(mcast_addr=228.8.8.8;mcast_port=45568;ip_ttl=32;bind_addr=" + host + "):" +
+         "PING(timeout=" + PING_timeout + ";num_initial_members=" + PING_num_initial_members + "):"+
+         "FD(timeout=3000):"+
+         "VERIFY_SUSPECT(timeout=1500):"+
+         "pbcast.NAKACK(gc_lag=10;retransmit_timeout=600,1200,2400,4800):"+
+         "pbcast.STABLE(desired_avg_gossip=10000):"+
+         "FRAG:"+
+         "pbcast.GMS(join_timeout=5000;join_retry_timeout=2000;shun=true;print_local_addr=true):" +
+         "pbcast.STATE_TRANSFER";     
+   }
+
+   // Attributes ----------------------------------------------------
+   
+   // Constructors --------------------------------------------------
+   
+   // Public --------------------------------------------------------
+
+   // Package protected ---------------------------------------------
+   
+   // Protected -----------------------------------------------------
+   
+   // Private -------------------------------------------------------
+   
+   // Inner classes -------------------------------------------------   
+}

Deleted: trunk/tests/src/org/jboss/test/messaging/core/plugin/MessageStoreWithPersistenceManagerTest.java
===================================================================
--- trunk/tests/src/org/jboss/test/messaging/core/plugin/MessageStoreWithPersistenceManagerTest.java	2006-08-30 09:26:13 UTC (rev 1236)
+++ trunk/tests/src/org/jboss/test/messaging/core/plugin/MessageStoreWithPersistenceManagerTest.java	2006-08-30 18:36:36 UTC (rev 1237)
@@ -1,152 +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.core.plugin;
-
-import org.jboss.logging.Logger;
-import org.jboss.messaging.core.plugin.JDBCPersistenceManager;
-import org.jboss.messaging.core.plugin.SimpleMessageStore;
-import org.jboss.messaging.core.plugin.contract.MessageStore;
-import org.jboss.messaging.core.plugin.contract.PersistenceManager;
-import org.jboss.test.messaging.core.plugin.base.MessageStoreTestBase;
-
-/**
- * @author <a href="mailto:ovidiu at jboss.org">Ovidiu Feodorov</a>
- * @version <tt>$Revision$</tt>
- *
- * $Id$
- */
-public class MessageStoreWithPersistenceManagerTest extends MessageStoreTestBase
-{
-   // Constants -----------------------------------------------------
-
-   protected Logger log = Logger.getLogger(MessageStoreWithPersistenceManagerTest.class);
-
-   // Static --------------------------------------------------------
-
-   // Attributes ----------------------------------------------------
-
-   protected MessageStore ms2;
-   
-   protected PersistenceManager pm;
-
-   // Constructors --------------------------------------------------
-
-   public MessageStoreWithPersistenceManagerTest(String name)
-   {
-      super(name);
-   }
-
-   // Public --------------------------------------------------------
-
-   public void setUp() throws Exception
-   {
-      super.setUp();
-
-      pm = new JDBCPersistenceManager(sc.getDataSource(), sc.getTransactionManager());
-      pm.start();
-      
-      ms = new SimpleMessageStore("s9");
-
-      ms2 = new SimpleMessageStore("s10");
-
-      log.debug("setup done");
-   }
-
-   public void tearDown() throws Exception
-   {
-      ms = null;
-      ms2 = null;
-      super.tearDown();
-   }
-
-   /**
-    * In a distributed configuration, multiple persistent store may access the same database.
-    */
-   
-   //Note - this test is commented out since it no longer makes sense because we no longer record message store id
-   //in the message reference table
-   //It is testing behaviour that no longer exists
-   
-  
-   
-//   public void testTwoStoresSameDatabase() throws Exception
-//   {
-//      Message m =
-//         MessageFactory.createMessage("message0", true, 777l, 888l, (byte)9, headers, "payload");
-//
-//      assertEquals(0, pm.getMessageReferenceCount(m.getMessageID()));
-//
-//      MessageReference ref = ms.reference(m);
-//      ref.incrementChannelCount();
-//      pm.addReference("channel1", ref, null);
-//      log.debug("referenced " + m + " using " + ms);
-//      assertCorrectReference(ref, ms.getStoreID(), m);
-//      assertEquals(1, pm.getMessageReferenceCount(m.getMessageID()));
-//
-//      // add the same message to the second store
-//      MessageReference ref2 = ms2.reference(m);
-//      ref2.incrementChannelCount();
-//      pm.addReference("channel1", ref2, null);
-//      log.debug("referenced " + m + " using " + ms2);
-//      assertCorrectReference(ref2, ms2.getStoreID(), m);
-//      assertEquals(2, pm.getMessageReferenceCount(m.getMessageID()));
-//
-//      assertFalse(ref == ref2);      
-//                  
-//      pm.removeReference("channel1", ref, null);
-//      
-//      ref.decrementChannelCount();
-//
-//      assertEquals(1, pm.getMessageReferenceCount(m.getMessageID()));
-//
-//      // ... but because the message is still in the database, trying to get a new reference
-//      // is successful.
-//
-//      ref = ms.reference((String)m.getMessageID());
-//      ref.incrementChannelCount();
-//      assertCorrectReference(ref, ms.getStoreID(), m);
-//      
-//      assertEquals(2, pm.getMessageReferenceCount(m.getMessageID()));
-//
-//      
-//      log.info("ref cc:" + ref.getChannelCount());
-//      pm.removeReference("channel1", ref, null);
-//      ref.decrementChannelCount();
-//      
-//      
-//      pm.removeReference("channel1", ref2, null);
-//      ref2.decrementChannelCount();
-//
-//      assertNull(ms.reference((String)m.getMessageID()));
-//      assertNull(ms2.reference((String)m.getMessageID()));
-//      assertEquals(0, pm.getMessageReferenceCount(m.getMessageID()));
-//   }
-
-
-   // Package protected ---------------------------------------------
-
-   // Protected -----------------------------------------------------
-
-   // Private -------------------------------------------------------
-
-   // Inner classes -------------------------------------------------
-}
\ No newline at end of file

Deleted: trunk/tests/src/org/jboss/test/messaging/core/plugin/MessageStoreWithoutPersistenceManagerTest.java
===================================================================
--- trunk/tests/src/org/jboss/test/messaging/core/plugin/MessageStoreWithoutPersistenceManagerTest.java	2006-08-30 09:26:13 UTC (rev 1236)
+++ trunk/tests/src/org/jboss/test/messaging/core/plugin/MessageStoreWithoutPersistenceManagerTest.java	2006-08-30 18:36:36 UTC (rev 1237)
@@ -1,78 +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.core.plugin;
-
-import org.jboss.test.messaging.core.plugin.base.MessageStoreTestBase;
-import org.jboss.logging.Logger;
-import org.jboss.messaging.core.plugin.SimpleMessageStore;
-
-/**
- * @author <a href="mailto:ovidiu at jboss.org">Ovidiu Feodorov</a>
- * @version <tt>$Revision$</tt>
- *
- * $Id$
- */
-public class MessageStoreWithoutPersistenceManagerTest extends MessageStoreTestBase
-{
-   // Constants -----------------------------------------------------
-
-   protected Logger log = Logger.getLogger(MessageStoreWithoutPersistenceManagerTest.class);
-
-   // Static --------------------------------------------------------
-
-   // Attributes ----------------------------------------------------
-
-   // Constructors --------------------------------------------------
-
-   public MessageStoreWithoutPersistenceManagerTest(String name)
-   {
-      super(name);
-   }
-
-   // Public --------------------------------------------------------
-
-   public void setUp() throws Exception
-   {
-      super.setUp();
-
-      ms = new SimpleMessageStore("test-memory-store");
-
-      log.debug("setup done");
-   }
-
-   public void tearDown() throws Exception
-   {
-      ms = null;
-
-      super.tearDown();
-   }
-
-   // Package protected ---------------------------------------------
-
-   // Protected -----------------------------------------------------
-
-   // Private -------------------------------------------------------
-
-   // Inner classes -------------------------------------------------
-
-
-}
\ No newline at end of file

Added: trunk/tests/src/org/jboss/test/messaging/core/plugin/SimpleMessageStoreTest.java
===================================================================
--- trunk/tests/src/org/jboss/test/messaging/core/plugin/SimpleMessageStoreTest.java	2006-08-30 09:26:13 UTC (rev 1236)
+++ trunk/tests/src/org/jboss/test/messaging/core/plugin/SimpleMessageStoreTest.java	2006-08-30 18:36:36 UTC (rev 1237)
@@ -0,0 +1,79 @@
+/*
+* 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.core.plugin;
+
+import org.jboss.test.messaging.core.plugin.base.MessageStoreTestBase;
+import org.jboss.logging.Logger;
+import org.jboss.messaging.core.plugin.SimpleMessageStore;
+
+/**
+ * @author <a href="mailto:ovidiu at jboss.org">Ovidiu Feodorov</a>
+ * @author <a href="mailto:tim.fox at jboss.com">Tim Fox</a>
+ * @version <tt>$Revision: 731 $</tt>
+ *
+ * $Id: MessageStoreWithoutPersistenceManagerTest.java 731 2006-03-13 05:26:40Z ovidiu $
+ */
+public class SimpleMessageStoreTest extends MessageStoreTestBase
+{
+   // Constants -----------------------------------------------------
+
+   protected Logger log = Logger.getLogger(SimpleMessageStoreTest.class);
+
+   // Static --------------------------------------------------------
+
+   // Attributes ----------------------------------------------------
+
+   // Constructors --------------------------------------------------
+
+   public SimpleMessageStoreTest(String name)
+   {
+      super(name);
+   }
+
+   // Public --------------------------------------------------------
+
+   public void setUp() throws Exception
+   {
+      super.setUp();
+
+      ms = new SimpleMessageStore();
+
+      log.debug("setup done");
+   }
+
+   public void tearDown() throws Exception
+   {
+      ms = null;
+
+      super.tearDown();
+   }
+
+   // Package protected ---------------------------------------------
+
+   // Protected -----------------------------------------------------
+
+   // Private -------------------------------------------------------
+
+   // Inner classes -------------------------------------------------
+
+
+}
\ No newline at end of file

Added: trunk/tests/src/org/jboss/test/messaging/core/plugin/TopicExchangeTest.java
===================================================================
--- trunk/tests/src/org/jboss/test/messaging/core/plugin/TopicExchangeTest.java	2006-08-30 09:26:13 UTC (rev 1236)
+++ trunk/tests/src/org/jboss/test/messaging/core/plugin/TopicExchangeTest.java	2006-08-30 18:36:36 UTC (rev 1237)
@@ -0,0 +1,399 @@
+/*
+  * 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.core.plugin;
+
+import java.util.List;
+
+import org.jboss.messaging.core.Message;
+import org.jboss.messaging.core.MessageReference;
+import org.jboss.messaging.core.local.MessageQueue;
+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.TopicExchange;
+import org.jboss.messaging.core.tx.Transaction;
+import org.jboss.test.messaging.core.plugin.base.ExchangeTestBase;
+
+/**
+ * 
+ * A TopicExchangeTest
+
+ * @author <a href="mailto:tim.fox at jboss.com">Tim Fox</a>
+ * @version <tt>$Revision: 1.1 $</tt>
+ *
+ * $Id$
+ *
+ */
+public class TopicExchangeTest extends ExchangeTestBase
+{
+   // Constants -----------------------------------------------------
+
+   // Static --------------------------------------------------------
+   
+   // Attributes ----------------------------------------------------
+
+   // Constructors --------------------------------------------------
+
+   public TopicExchangeTest(String name)
+   {
+      super(name);
+   }
+
+   // Public --------------------------------------------------------
+
+   public void setUp() throws Exception
+   {
+      super.setUp();            
+   }
+
+   public void tearDown() throws Exception
+   {      
+     
+      super.tearDown();
+   }
+   
+   public void testRoute() throws Throwable
+   {
+      Exchange exchange = createExchange();
+      
+      Binding binding1 =
+         exchange.bindQueue("sub1", "topic1", null, false, true, ms, pm, 1000, 20, 20);      
+      Binding binding2 =
+         exchange.bindQueue("sub2", "topic1", null, false, true, ms, pm, 1000, 20, 20);
+      Binding binding3 =
+         exchange.bindQueue("sub3", "topic1", null, false, true, ms, pm, 1000, 20, 20);      
+      Binding binding4 =
+         exchange.bindQueue("sub4", "topic2", null, false, true, ms, pm, 1000, 20, 20);
+      Binding binding5 =
+         exchange.bindQueue("sub5", "topic2", null, false, true, ms, pm, 1000, 20, 20);      
+      Binding binding6 =
+         exchange.bindQueue("sub6", "topic2", null, false, true, ms, pm, 1000, 20, 20);
+      
+      MessageQueue queue1 = binding1.getQueue();      
+      MessageQueue queue2 = binding2.getQueue();
+      MessageQueue queue3 = binding3.getQueue();      
+      MessageQueue queue4 = binding4.getQueue();
+      MessageQueue queue5 = binding5.getQueue();      
+      MessageQueue queue6 = binding6.getQueue();
+      
+      assertTrue(binding1.isActive());      
+      assertTrue(binding2.isActive());
+      assertTrue(binding3.isActive());      
+      assertTrue(binding4.isActive());
+      assertTrue(binding5.isActive());      
+      assertTrue(binding6.isActive());
+      
+      Message msg1 = MessageFactory.createCoreMessage(1);      
+      MessageReference ref1 = ms.reference(msg1);
+      
+      boolean routed = exchange.route(ref1, "topic1", null);      
+      assertTrue(routed);
+      
+      List msgs = queue1.browse();
+      assertNotNull(msgs);
+      assertEquals(1, msgs.size());
+      Message msgRec = (Message)msgs.get(0);
+      assertEquals(msgRec.getMessageID(), msg1.getMessageID());
+      
+      msgs = queue2.browse();
+      assertNotNull(msgs);
+      assertEquals(1, msgs.size());
+      msgRec = (Message)msgs.get(0);
+      assertEquals(msgRec.getMessageID(), msg1.getMessageID());
+      
+      msgs = queue3.browse();
+      assertNotNull(msgs);
+      assertEquals(1, msgs.size());
+      msgRec = (Message)msgs.get(0);
+      assertEquals(msgRec.getMessageID(), msg1.getMessageID());
+      
+      msgs = queue4.browse();
+      assertNotNull(msgs);
+      assertEquals(0, msgs.size());
+      
+      msgs = queue5.browse();
+      assertNotNull(msgs);
+      assertEquals(0, msgs.size());
+      
+      msgs = queue6.browse();
+      assertNotNull(msgs);
+      assertEquals(0, msgs.size());
+      
+      queue1.removeAllReferences();
+      queue2.removeAllReferences();
+      queue3.removeAllReferences();
+      
+      
+      Message msg2 = MessageFactory.createCoreMessage(2);      
+      MessageReference ref2 = ms.reference(msg2);
+      
+      routed = exchange.route(ref2, "topic2", null);      
+      assertTrue(routed);
+      
+      msgs = queue4.browse();
+      assertNotNull(msgs);
+      assertEquals(1, msgs.size());
+      msgRec = (Message)msgs.get(0);
+      assertEquals(msgRec.getMessageID(), msg2.getMessageID());
+      
+      msgs = queue5.browse();
+      assertNotNull(msgs);
+      assertEquals(1, msgs.size());
+      msgRec = (Message)msgs.get(0);
+      assertEquals(msgRec.getMessageID(), msg2.getMessageID());
+      
+      msgs = queue6.browse();
+      assertNotNull(msgs);
+      assertEquals(1, msgs.size());
+      msgRec = (Message)msgs.get(0);
+      assertEquals(msgRec.getMessageID(), msg2.getMessageID());
+      
+      msgs = queue1.browse();
+      assertNotNull(msgs);
+      assertEquals(0, msgs.size());
+      
+      msgs = queue2.browse();
+      assertNotNull(msgs);
+      assertEquals(0, msgs.size());
+      
+      msgs = queue3.browse();
+      assertNotNull(msgs);
+      assertEquals(0, msgs.size());
+      
+      
+   }
+   
+   public void testRouteInactive() throws Throwable
+   {
+      Exchange exchange = createExchange();
+      
+      Binding binding1 =
+         exchange.bindQueue("sub1", "topic1", null, false, true, ms, pm, 1000, 20, 20);      
+      Binding binding2 =
+         exchange.bindQueue("sub2", "topic1", null, false, true, ms, pm, 1000, 20, 20);
+      Binding binding3 =
+         exchange.bindQueue("sub3", "topic1", null, false, true, ms, pm, 1000, 20, 20);      
+      Binding binding4 =
+         exchange.bindQueue("sub4", "topic2", null, false, true, ms, pm, 1000, 20, 20);
+      Binding binding5 =
+         exchange.bindQueue("sub5", "topic2", null, false, true, ms, pm, 1000, 20, 20);      
+      Binding binding6 =
+         exchange.bindQueue("sub6", "topic2", null, false, true, ms, pm, 1000, 20, 20);
+      
+      MessageQueue queue1 = binding1.getQueue();      
+      MessageQueue queue2 = binding2.getQueue();
+      MessageQueue queue3 = binding3.getQueue();      
+      MessageQueue queue4 = binding4.getQueue();
+      MessageQueue queue5 = binding5.getQueue();      
+      MessageQueue queue6 = binding6.getQueue();
+      
+      binding1.deactivate();
+      binding2.deactivate();
+      binding3.deactivate();
+      
+      assertFalse(binding1.isActive());      
+      assertFalse(binding2.isActive());
+      assertFalse(binding3.isActive());      
+      assertTrue(binding4.isActive());
+      assertTrue(binding5.isActive());      
+      assertTrue(binding6.isActive());
+      
+      Message msg1 = MessageFactory.createCoreMessage(1);      
+      MessageReference ref1 = ms.reference(msg1);
+      
+      boolean routed = exchange.route(ref1, "topic1", null);      
+      assertTrue(routed);
+      
+      List msgs = queue1.browse();
+      assertNotNull(msgs);
+      assertEquals(0, msgs.size());
+      
+      msgs = queue2.browse();
+      assertNotNull(msgs);
+      assertEquals(0, msgs.size());
+      
+      msgs = queue3.browse();
+      assertNotNull(msgs);
+      assertEquals(0, msgs.size());
+
+      msgs = queue4.browse();
+      assertNotNull(msgs);
+      assertEquals(0, msgs.size());
+      
+      msgs = queue5.browse();
+      assertNotNull(msgs);
+      assertEquals(0, msgs.size());
+      
+      msgs = queue6.browse();
+      assertNotNull(msgs);
+      assertEquals(0, msgs.size());
+      
+      Message msg2 = MessageFactory.createCoreMessage(2);      
+      MessageReference ref2 = ms.reference(msg2);
+      
+      routed = exchange.route(ref2, "topic2", null);      
+      assertTrue(routed);
+      
+      msgs = queue4.browse();
+      assertNotNull(msgs);
+      assertEquals(1, msgs.size());
+      Message msgRec = (Message)msgs.get(0);
+      assertEquals(msgRec.getMessageID(), msg2.getMessageID());
+      
+      msgs = queue5.browse();
+      assertNotNull(msgs);
+      assertEquals(1, msgs.size());
+      msgRec = (Message)msgs.get(0);
+      assertEquals(msgRec.getMessageID(), msg2.getMessageID());
+      
+      msgs = queue6.browse();
+      assertNotNull(msgs);
+      assertEquals(1, msgs.size());
+      msgRec = (Message)msgs.get(0);
+      assertEquals(msgRec.getMessageID(), msg2.getMessageID());
+      
+      msgs = queue1.browse();
+      assertNotNull(msgs);
+      assertEquals(0, msgs.size());
+      
+      msgs = queue2.browse();
+      assertNotNull(msgs);
+      assertEquals(0, msgs.size());
+      
+      msgs = queue3.browse();
+      assertNotNull(msgs);
+      assertEquals(0, msgs.size());
+   
+   }
+
+   public void testRouteNoBinding() throws Throwable
+   {
+      Exchange exchange = createExchange();
+      
+      Binding binding1 =
+         exchange.bindQueue("sub1", "topic1", null, false, true, ms, pm, 1000, 20, 20);      
+
+      MessageQueue queue1 = binding1.getQueue();
+
+      assertTrue(binding1.isActive());
+
+      Message msg1 = MessageFactory.createCoreMessage(1);      
+      MessageReference ref1 = ms.reference(msg1);
+      
+      boolean routed = exchange.route(ref1, "this won't match anything", null);      
+      
+      //A topic exchange always returns true even if there is no binding
+      assertTrue(routed);
+            
+      List msgs = queue1.browse();
+      assertNotNull(msgs);
+      assertEquals(0, msgs.size());             
+   }
+   
+   public void testRouteTransactional() throws Throwable
+   {
+      Exchange exchange = createExchange();
+      
+      Binding binding1 =
+         exchange.bindQueue("sub1", "topic1", null, false, true, ms, pm, 1000, 20, 20);      
+
+      MessageQueue queue1 = binding1.getQueue();
+
+      assertTrue(binding1.isActive());
+
+      Message msg1 = MessageFactory.createCoreMessage(1);      
+      MessageReference ref1 = ms.reference(msg1);
+      
+      Message msg2 = MessageFactory.createCoreMessage(2);      
+      MessageReference ref2 = ms.reference(msg2);
+      
+      Transaction tx = tr.createTransaction();
+      
+      boolean routed = exchange.route(ref1, "topic1", tx);            
+      assertTrue(routed);
+      routed = exchange.route(ref2, "topic1", tx);            
+      assertTrue(routed);
+            
+      List msgs = queue1.browse();
+      assertNotNull(msgs);
+      assertEquals(0, msgs.size()); 
+      
+      tx.commit();
+      
+      msgs = queue1.browse();
+      assertNotNull(msgs);
+      assertEquals(2, msgs.size());
+      Message msgRec1 = (Message)msgs.get(0);
+      Message msgRec2 = (Message)msgs.get(0);
+      assertEquals(msg1.getMessageID(), msgRec1.getMessageID());
+      assertEquals(msg2.getMessageID(), msgRec2.getMessageID());
+      
+      queue1.removeAllReferences();
+      
+      Message msg3 = MessageFactory.createCoreMessage(3);      
+      MessageReference ref3 = ms.reference(msg3);
+      
+      Message msg4 = MessageFactory.createCoreMessage(4);      
+      MessageReference ref4 = ms.reference(msg4);
+      
+      Transaction tx2 = tr.createTransaction();
+      
+      routed = exchange.route(ref3, "topic1", tx2);            
+      assertTrue(routed);
+      routed = exchange.route(ref4, "topic1", tx2);            
+      assertTrue(routed);
+            
+      msgs = queue1.browse();
+      assertNotNull(msgs);
+      assertEquals(0, msgs.size()); 
+      
+      tx.rollback();
+      
+      msgs = queue1.browse();
+      assertNotNull(msgs);
+      assertEquals(0, msgs.size());
+   }
+   
+   // Package protected ---------------------------------------------
+
+   // Protected -----------------------------------------------------
+   
+   protected Exchange createExchange() throws Exception
+   {
+      TopicExchange exchange = new TopicExchange(sc.getDataSource(), sc.getTransactionManager());      
+      
+      ((TopicExchange)exchange).injectAttributes("Topic", "node1", ms, im, pool, tr);
+      
+      exchange.start();
+      
+      return exchange;
+   }
+
+   // Private -------------------------------------------------------
+
+   // Inner classes -------------------------------------------------
+
+}
+
+
+

Added: trunk/tests/src/org/jboss/test/messaging/core/plugin/base/ExchangeTestBase.java
===================================================================
--- trunk/tests/src/org/jboss/test/messaging/core/plugin/base/ExchangeTestBase.java	2006-08-30 09:26:13 UTC (rev 1236)
+++ trunk/tests/src/org/jboss/test/messaging/core/plugin/base/ExchangeTestBase.java	2006-08-30 18:36:36 UTC (rev 1237)
@@ -0,0 +1,417 @@
+/*
+  * 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.core.plugin.base;
+
+import java.util.List;
+
+import org.jboss.jms.selector.Selector;
+import org.jboss.jms.server.QueuedExecutorPool;
+import org.jboss.messaging.core.Filter;
+import org.jboss.messaging.core.Message;
+import org.jboss.messaging.core.MessageReference;
+import org.jboss.messaging.core.local.MessageQueue;
+import org.jboss.messaging.core.memory.MemoryManager;
+import org.jboss.messaging.core.memory.SimpleMemoryManager;
+import org.jboss.messaging.core.message.MessageFactory;
+import org.jboss.messaging.core.plugin.IdManager;
+import org.jboss.messaging.core.plugin.JDBCPersistenceManager;
+import org.jboss.messaging.core.plugin.SimpleMessageStore;
+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.Binding;
+import org.jboss.messaging.core.tx.TransactionRepository;
+import org.jboss.test.messaging.MessagingTestCase;
+import org.jboss.test.messaging.tools.ServerManagement;
+import org.jboss.test.messaging.tools.jmx.ServiceContainer;
+
+/**
+ * 
+ * A ExchangeTestBase
+
+ * @author <a href="mailto:tim.fox at jboss.com">Tim Fox</a>
+ * @version <tt>$Revision: 1.1 $</tt>
+ *
+ * $Id$
+ *
+ */
+public abstract class ExchangeTestBase extends MessagingTestCase
+{
+   // Constants -----------------------------------------------------
+
+   // Static --------------------------------------------------------
+   
+   // Attributes ----------------------------------------------------
+
+   protected ServiceContainer sc;
+
+   protected PersistenceManager pm;
+      
+   protected MessageStore ms;
+   
+   protected IdManager im;
+   
+   protected TransactionRepository tr;
+   
+   protected QueuedExecutorPool pool;
+   
+   // Constructors --------------------------------------------------
+
+   public ExchangeTestBase(String name)
+   {
+      super(name);
+   }
+
+   // Public --------------------------------------------------------
+
+   public void setUp() throws Exception
+   {
+      super.setUp();
+
+      sc = new ServiceContainer("all");
+      
+      sc.start();                
+      
+      pm = new JDBCPersistenceManager(sc.getDataSource(), sc.getTransactionManager());
+      
+      pm.start();
+      
+      ms = new SimpleMessageStore();
+      
+      im = new IdManager("CHANNEL_ID", 10, pm);
+      
+      tr = new TransactionRepository();
+      
+      tr.injectAttributes(pm, new IdManager("TRANSACTION_ID", 10, pm));
+      
+      pool = new QueuedExecutorPool(10);
+            
+      log.debug("setup done");
+   }
+
+   public void tearDown() throws Exception
+   {      
+      if (!ServerManagement.isRemote())
+      {
+         sc.stop();
+         sc = null;
+      }
+      pm.stop();
+      
+      super.tearDown();
+   }
+   
+   // Public --------------------------------------------------------
+   
+   public void testBind() throws Throwable
+   {
+      Exchange exchange1 = createExchange();
+      
+      //Bind one durable
+      
+      Filter filter1 = new Selector("x = 'cheese'");
+      Filter filter2 = new Selector("y = 'bread'");
+      
+      Binding binding1 =
+         exchange1.bindQueue("durableQueue", "condition1", filter1, true, true, ms, pm, 2000, 100, 100);
+      
+      //Binding twice with the same name should fail      
+      try
+      {
+         Binding bindFail = exchange1.bindQueue("durableQueue", "condition1", filter1, true, true, ms, pm, 2000, 100, 100);
+         fail();
+      }
+      catch (Exception e)
+      {
+         //Ok
+      }
+            
+      //Bind one non durable
+      Binding binding2 =
+         exchange1.bindQueue("nonDurableQueue", "condition2", filter2, true, false, ms, pm, 2000, 100, 100);
+      
+      //Check they're there
+      
+      Binding binding3 = exchange1.getBindingForName("durableQueue");
+      assertNotNull(binding3);
+      assertTrue(binding1 == binding3);
+      assertEquals("durableQueue", binding3.getQueueName());
+      assertEquals("condition1", binding3.getCondition());
+      assertEquals(filter1.getFilterString(), binding3.getSelector());
+      assertEquals(true, binding3.isNoLocal());
+      assertEquals(true, binding3.isDurable());
+      assertNotNull(binding3.getQueue());
+      assertEquals(true, binding3.getQueue().isRecoverable());
+      
+      
+      Binding binding4 = exchange1.getBindingForName("nonDurableQueue");
+      assertNotNull(binding4);
+      assertTrue(binding2 == binding4);
+      assertEquals("nonDurableQueue", binding4.getQueueName());
+      assertEquals("condition2", binding4.getCondition());
+      assertEquals(filter2.getFilterString(), binding4.getSelector());
+      assertEquals(true, binding4.isNoLocal());
+      assertEquals(false, binding4.isDurable());
+      assertNotNull(binding4.getQueue());
+      assertEquals(false, binding4.getQueue().isRecoverable());
+      
+      //Throw away the exchange and create another
+      Exchange exchange2 = createExchange();
+      
+      //Only one binding should be there
+      Binding binding5 = exchange2.getBindingForName("durableQueue");
+      assertNotNull(binding5);
+      assertEquals("durableQueue", binding5.getQueueName());
+      assertEquals("condition1", binding5.getCondition());
+      assertEquals(filter1.getFilterString(), binding5.getSelector());
+      assertEquals(true, binding5.isNoLocal());
+      assertEquals(true, binding5.isDurable());
+      //Should be unloaded
+      assertNull(binding5.getQueue());
+      
+      Binding binding6 = exchange2.getBindingForName("nonDurableQueue");
+      assertNull(binding6);
+      
+      //ReLoad the durable queue - or we won't be able to unbind it
+      exchange2.reloadQueues("condition1", ms, pm, 2000, 100, 100);
+      
+      //Unbind the binding
+      Binding binding7 = exchange2.unbindQueue("durableQueue");
+      assertNotNull(binding7);
+      assertEquals("durableQueue", binding7.getQueueName());
+      assertEquals("condition1", binding7.getCondition());
+      assertEquals(filter1.getFilterString(), binding7.getSelector());
+      assertEquals(true, binding7.isNoLocal());
+      assertEquals(true, binding7.isDurable());
+      
+      //Make sure no longer there
+      Binding binding8 = exchange2.getBindingForName("durableQueue");
+      assertNull(binding8);
+      
+      //Throw away exchange and start another
+      Exchange exchange3 = createExchange();
+      
+      //Make sure not there
+      Binding binding9 = exchange3.getBindingForName("durableQueue");
+      assertNull(binding9);
+            
+   }
+   
+   public void testListBindings() throws Throwable
+   {
+      Exchange exchange = createExchange();
+      
+      Binding binding1 =
+         exchange.bindQueue("queue1", "condition1", null, true, false, ms, pm, 2000, 100, 100);
+      Binding binding2 =
+         exchange.bindQueue("queue2", "condition1", null, true, false, ms, pm, 2000, 100, 100);
+      Binding binding3 =
+         exchange.bindQueue("queue3", "condition1", null, true, false, ms, pm, 2000, 100, 100);
+      Binding binding4 =
+         exchange.bindQueue("queue4", "condition1", null, true, false, ms, pm, 2000, 100, 100);
+      Binding binding5 =
+         exchange.bindQueue("queue5", "condition2", null, true, false, ms, pm, 2000, 100, 100);
+      Binding binding6 =
+         exchange.bindQueue("queue6", "condition2", null, true, false, ms, pm, 2000, 100, 100);
+      Binding binding7 =
+         exchange.bindQueue("queue7", "condition2", null, true, false, ms, pm, 2000, 100, 100);
+      Binding binding8 =
+         exchange.bindQueue("queue8", "condition2", null, true, false, ms, pm, 2000, 100, 100);
+      
+      List bindings = exchange.listBindingsForWildcard("dummy");
+      assertNotNull(bindings);
+      assertTrue(bindings.isEmpty());
+      
+      //We don't match on substrings
+      bindings = exchange.listBindingsForWildcard("condition123");
+      assertNotNull(bindings);
+      assertTrue(bindings.isEmpty());
+      
+      //We don't currently support hierarchies
+      bindings = exchange.listBindingsForWildcard("condition1.subcondition");
+      assertNotNull(bindings);
+      assertTrue(bindings.isEmpty());
+      
+      //We currently just do an exact match
+      bindings = exchange.listBindingsForWildcard("condition1");
+      assertNotNull(bindings);
+      assertEquals(4, bindings.size());
+      
+      assertEquivalent((Binding)bindings.get(0), binding1);
+      assertEquivalent((Binding)bindings.get(1), binding2);
+      assertEquivalent((Binding)bindings.get(2), binding3);
+      assertEquivalent((Binding)bindings.get(3), binding4);
+      
+      bindings = exchange.listBindingsForWildcard("condition2");
+      assertNotNull(bindings);
+      assertEquals(4, bindings.size());
+      
+      assertEquivalent((Binding)bindings.get(0), binding5);
+      assertEquivalent((Binding)bindings.get(1), binding6);
+      assertEquivalent((Binding)bindings.get(2), binding7);
+      assertEquivalent((Binding)bindings.get(3), binding8);
+         
+   }
+   
+   public void testUnloadReload() throws Exception
+   {
+      Exchange exchange = createExchange();
+      
+      Binding binding1 =
+         exchange.bindQueue("reloadqueue1", "condition3", null, true, true, ms, pm, 2000, 100, 100);
+      Binding binding2 =
+         exchange.bindQueue("reloadqueue2", "condition3", null, true, true, ms, pm, 2000, 100, 100);
+      Binding binding3 =
+         exchange.bindQueue("reloadqueue3", "condition3", null, true, true, ms, pm, 2000, 100, 100);
+      Binding binding4 =
+         exchange.bindQueue("reloadqueue4", "condition3", null, true, true, ms, pm, 2000, 100, 100);
+      Binding binding5 =
+         exchange.bindQueue("reloadqueue5", "condition4", null, true, true, ms, pm, 2000, 100, 100);
+      Binding binding6 =
+         exchange.bindQueue("reloadqueue6", "condition4", null, true, true, ms, pm, 2000, 100, 100);
+      Binding binding7 =
+         exchange.bindQueue("reloadqueue7", "condition4", null, true, true, ms, pm, 2000, 100, 100);
+      Binding binding8 =
+         exchange.bindQueue("reloadqueue8", "condition4", null, true, true, ms, pm, 2000, 100, 100);
+      
+      assertNotNull(binding1.getQueue());
+      assertTrue(binding1.isActive());      
+      assertNotNull(binding2.getQueue());
+      assertTrue(binding2.isActive());
+      assertNotNull(binding3.getQueue());
+      assertTrue(binding3.isActive());
+      assertNotNull(binding4.getQueue());
+      assertTrue(binding4.isActive());
+      
+      assertNotNull(binding5.getQueue());
+      assertTrue(binding5.isActive());
+      assertNotNull(binding6.getQueue());
+      assertTrue(binding6.isActive());
+      assertNotNull(binding7.getQueue());
+      assertTrue(binding7.isActive());
+      assertNotNull(binding8.getQueue());
+      assertTrue(binding8.isActive());
+      
+      exchange.unloadQueues("condition3");
+      assertNull(binding1.getQueue());
+      assertFalse(binding1.isActive());      
+      assertNull(binding2.getQueue());
+      assertFalse(binding2.isActive());
+      assertNull(binding3.getQueue());
+      assertFalse(binding3.isActive());
+      assertNull(binding4.getQueue());
+      assertFalse(binding4.isActive());
+      
+      assertNotNull(binding5.getQueue());
+      assertTrue(binding5.isActive());
+      assertNotNull(binding6.getQueue());
+      assertTrue(binding6.isActive());
+      assertNotNull(binding7.getQueue());
+      assertTrue(binding7.isActive());
+      assertNotNull(binding8.getQueue());
+      assertTrue(binding8.isActive());
+      
+      exchange.unloadQueues("condition4");
+      assertNull(binding1.getQueue());
+      assertFalse(binding1.isActive());      
+      assertNull(binding2.getQueue());
+      assertFalse(binding2.isActive());
+      assertNull(binding3.getQueue());
+      assertFalse(binding3.isActive());
+      assertNull(binding4.getQueue());
+      assertFalse(binding4.isActive());
+      
+      assertNull(binding5.getQueue());
+      assertFalse(binding5.isActive());
+      assertNull(binding6.getQueue());
+      assertFalse(binding6.isActive());
+      assertNull(binding7.getQueue());
+      assertFalse(binding7.isActive());
+      assertNull(binding8.getQueue());
+      assertFalse(binding8.isActive());
+      
+      exchange.reloadQueues("condition3", ms, pm, 2000, 100, 100);
+      assertNotNull(binding1.getQueue());
+      assertTrue(binding1.isActive());      
+      assertNotNull(binding2.getQueue());
+      assertTrue(binding2.isActive());
+      assertNotNull(binding3.getQueue());
+      assertTrue(binding3.isActive());
+      assertNotNull(binding4.getQueue());
+      assertTrue(binding4.isActive());
+      
+      assertNull(binding5.getQueue());
+      assertFalse(binding5.isActive());
+      assertNull(binding6.getQueue());
+      assertFalse(binding6.isActive());
+      assertNull(binding7.getQueue());
+      assertFalse(binding7.isActive());
+      assertNull(binding8.getQueue());
+      assertFalse(binding8.isActive());
+      
+      exchange.reloadQueues("condition4", ms, pm, 2000, 100, 100);
+      
+      assertNotNull(binding1.getQueue());
+      assertTrue(binding1.isActive());      
+      assertNotNull(binding2.getQueue());
+      assertTrue(binding2.isActive());
+      assertNotNull(binding3.getQueue());
+      assertTrue(binding3.isActive());
+      assertNotNull(binding4.getQueue());
+      assertTrue(binding4.isActive());
+      
+      assertNotNull(binding5.getQueue());
+      assertTrue(binding5.isActive());
+      assertNotNull(binding6.getQueue());
+      assertTrue(binding6.isActive());
+      assertNotNull(binding7.getQueue());
+      assertTrue(binding7.isActive());
+      assertNotNull(binding8.getQueue());
+      assertTrue(binding8.isActive());
+   }
+   
+   
+
+
+   
+   
+   // Package protected ---------------------------------------------
+
+   // Protected -----------------------------------------------------
+   
+   protected abstract Exchange createExchange() throws Exception;
+   
+   protected void assertEquivalent(Binding binding1, Binding binding2)
+   {
+      assertEquals(binding1.getQueueName(), binding2.getQueueName());
+      assertEquals(binding1.getCondition(), binding2.getCondition());
+      assertEquals(binding1.getSelector(), binding2.getSelector());
+      assertEquals(binding1.isNoLocal(), binding2.isNoLocal());
+      assertEquals(binding1.isDurable(), binding2.isDurable());
+   }
+
+   // Private -------------------------------------------------------
+
+   // Inner classes -------------------------------------------------
+   
+}
+

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-08-30 09:26:13 UTC (rev 1236)
+++ trunk/tests/src/org/jboss/test/messaging/core/plugin/base/MessageStoreTestBase.java	2006-08-30 18:36:36 UTC (rev 1237)
@@ -36,16 +36,19 @@
 /**
  * The test strategy is to try as many combination as it makes sense of the following
  * variables:
+ * 
+ * Note: This test is more or less defunct now since the message store doesn't do much
+ * but we'll keep it here anyway
+ * 
+ * TODO - we should refactor this at some point
+ * 
+ * 1. The message can be non-reliable or reliable.
+ * 2. One or multiple messages can be stored.
+ * 3. One or more strong references may be maintain for the same MessageReference.
+ * 4. A recoverable message store may be forcibly crashed and tested if it recovers.
  *
- * 1. The message store can be can be non-recoverable (does not have access to a
- *    PersistenceManager) or recoverable. A non-recoverable message store can accept reliable
- *    messages or not.
- * 2. The message can be non-reliable or reliable.
- * 3. One or multiple messages can be stored.
- * 4. One or more strong references may be maintain for the same MessageReference.
- * 5. A recoverable message store may be forcibly crashed and tested if it recovers.
- *
  * @author <a href="mailto:ovidiu at jboss.org">Ovidiu Feodorov</a>
+ * @author <a href="mailto:tim.fox at jboss.com">Tim Fox</a>
  * @version <tt>$Revision$</tt>
  *
  * $Id$
@@ -61,9 +64,8 @@
    /**
     * Makes sure the given reference refers the given message.
     */
-   public static void assertCorrectReference(MessageReference ref, Object storeID, Message m)
+   public static void assertCorrectReference(MessageReference ref, Message m)
    {
-      assertEquals(storeID, ref.getStoreID());
       assertTrue(ref.isReference());
       assertEquals(m.getMessageID(), ref.getMessageID());
       assertEquals(m.isReliable(), ref.isReliable());
@@ -140,20 +142,14 @@
 
    public void testNonRecoverableMessageStore_1() throws Exception
    {
-      if (ms.isRecoverable())
-      {
-         // we only test non-recoverable message stores
-         return;
-      }
-
       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, ms.getStoreID(), m);
+      assertCorrectReference(ref, m);
 
-      assertCorrectReference(ref, ms.getStoreID(), m);
+      assertCorrectReference(ref, m);
   
       ref.releaseMemoryReference();
 
@@ -169,22 +165,16 @@
 
    public void testNonRecoverableMessageStore_1_1() throws Exception
    {
-      if (ms.isRecoverable())
-      {
-         // we only test non-recoverable message stores
-         return;
-      }
-
       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, ms.getStoreID(), m);
+      assertCorrectReference(ref, m);
 
       MessageReference ref2 = ms.reference(m);
 
-      assertCorrectReference(ref2, ms.getStoreID(), m);
+      assertCorrectReference(ref2, m);
    }
 
    //////
@@ -193,12 +183,6 @@
 
    public void testNonRecoverableMessageStore_2() throws Exception
    {
-      if (ms.isRecoverable())
-      {
-         // we only test non-recoverable message stores
-         return;
-      }
-
       Message[] m = new Message[NUMBER_OF_MESSAGES];
       MessageReference[] refs = new MessageReference[NUMBER_OF_MESSAGES];
       for(int i = 0; i < NUMBER_OF_MESSAGES; i++ )
@@ -208,12 +192,12 @@
 
          // non-recoverable store, non-reliable message, one message
          refs[i] = ms.reference(m[i]);
-         assertCorrectReference(refs[i], ms.getStoreID(), m[i]);
+         assertCorrectReference(refs[i], m[i]);
       }
 
       for (int i = 0; i < NUMBER_OF_MESSAGES; i++)
       {         
-         assertCorrectReference(refs[i], ms.getStoreID(), m[i]);
+         assertCorrectReference(refs[i], m[i]);
          refs[i].releaseMemoryReference();
       }
 
@@ -240,18 +224,6 @@
 
    public void testNonRecoverableMessageStore_3() throws Exception
    {
-      if (ms.isRecoverable())
-      {
-         // we only test non-recoverable message stores
-         return;
-      }
-
-      if (ms.acceptReliableMessages())
-      {
-         // we only test message stores that do not accept reliable message
-         return;
-      }
-
       Message m = MessageFactory.
       createCoreMessage(0, true, 777l, 888l, (byte)9, headers, "payload");
 
@@ -277,24 +249,12 @@
 
    public void testNonRecoverableMessageStore_4() throws Exception
    {
-      if (ms.isRecoverable())
-      {
-         // we only test non-recoverable message stores
-         return;
-      }
-
-      if (!ms.acceptReliableMessages())
-      {
-         // we only test message stores that accept reliable message
-         return;
-      }
-
       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, ms.getStoreID(), m);
+      assertCorrectReference(ref, m);
       
       ref.releaseMemoryReference();
 
@@ -311,18 +271,6 @@
 
    public void testNonRecoverableMessageStore_5() throws Exception
    {
-      if (ms.isRecoverable())
-      {
-         // we only test non-recoverable message stores
-         return;
-      }
-
-      if (!ms.acceptReliableMessages())
-      {
-         // we only test message stores that accept reliable message
-         return;
-      }
-
       Message[] m = new Message[NUMBER_OF_MESSAGES];
       MessageReference[] refs = new MessageReference[NUMBER_OF_MESSAGES];
       for(int i = 0; i < NUMBER_OF_MESSAGES; i++ )
@@ -332,14 +280,14 @@
 
          // non-recoverable store, non-reliable message, one message
          refs[i] = ms.reference(m[i]);
-         assertCorrectReference(refs[i], ms.getStoreID(), m[i]);
+         assertCorrectReference(refs[i], m[i]);
       }
 
       // get reachable reference
 
       for (int i = 0; i < NUMBER_OF_MESSAGES; i++)
       {         
-         assertCorrectReference(refs[i], ms.getStoreID(), m[i]);
+         assertCorrectReference(refs[i], m[i]);
          refs[i].releaseMemoryReference();
       }
 
@@ -354,24 +302,12 @@
    
    public void testNonRecoverableMessageStore_6() throws Exception
    {
-      if (ms.isRecoverable())
-      {
-         // we only test non-recoverable message stores
-         return;
-      }
-
-      if (!ms.acceptReliableMessages())
-      {
-         // we only test message stores that accept reliable message
-         return;
-      }
-
       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, ms.getStoreID(), m);
+      assertCorrectReference(ref, m);
       
       //Create another reference from that reference
       MessageReference ref2 = ms.reference(m.getMessageID());
@@ -381,7 +317,7 @@
       MessageReference ref3 = ms.reference(m.getMessageID());
       assertNotNull(ref3);
       
-      assertCorrectReference(ref3, ms.getStoreID(), m);
+      assertCorrectReference(ref3, m);
       
       ref2.releaseMemoryReference();
       
@@ -396,32 +332,20 @@
    
    public void testNonRecoverableMessageStore_7() throws Exception
    {
-      if (ms.isRecoverable())
-      {
-         // we only test non-recoverable message stores
-         return;
-      }
-
-      if (!ms.acceptReliableMessages())
-      {
-         // we only test message stores that accept reliable message
-         return;
-      }
-
       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, ms.getStoreID(), m);
+      assertCorrectReference(ref, m);
       
       MessageReference ref2 = ms.reference(ref.getMessageID());
       assertNotNull(ref2);      
-      assertCorrectReference(ref2, ms.getStoreID(), m);
+      assertCorrectReference(ref2, m);
         
       MessageReference ref3 = ms.reference(ref.getMessageID());
       assertNotNull(ref3);      
-      assertCorrectReference(ref3, ms.getStoreID(), m);
+      assertCorrectReference(ref3, m);
       
       ref.releaseMemoryReference();
       ref2.releaseMemoryReference();
@@ -451,18 +375,12 @@
 
    public void testRecoverableMessageStore_1() throws Exception
    {
-      if (!ms.isRecoverable())
-      {
-         // we only test recoverable message stores
-         return;
-      }
-
       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, ms.getStoreID(), m);
+      assertCorrectReference(ref, m);
       ref.releaseMemoryReference();
 
       ref = ms.reference(m.getMessageID());
@@ -475,22 +393,17 @@
 
    public void testRecoverableMessageStore_1_1() throws Exception
    {
-      if (!ms.isRecoverable())
-      {
-         // we only test recoverable message stores
-         return;
-      }
 
       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, ms.getStoreID(), m);
+      assertCorrectReference(ref, m);
 
       MessageReference ref2 = ms.reference(m);
 
-      assertCorrectReference(ref2, ms.getStoreID(), m);
+      assertCorrectReference(ref2, m);
    }
 
    //////
@@ -499,12 +412,6 @@
 
    public void testRecoverableMessageStore_2() throws Exception
    {
-      if (!ms.isRecoverable())
-      {
-         // we only test recoverable message stores
-         return;
-      }
-
       Message[] m = new Message[NUMBER_OF_MESSAGES];
       MessageReference[] refs = new MessageReference[NUMBER_OF_MESSAGES];
       for(int i = 0; i < NUMBER_OF_MESSAGES; i++ )
@@ -514,14 +421,14 @@
 
          // recoverable store, non-reliable message, one message
          refs[i] = ms.reference(m[i]);
-         assertCorrectReference(refs[i], ms.getStoreID(), m[i]);
+         assertCorrectReference(refs[i], m[i]);
       }
 
       // get reachable reference
 
       for (int i = 0; i < NUMBER_OF_MESSAGES; i++)
       {         
-         assertCorrectReference(refs[i], ms.getStoreID(), m[i]);
+         assertCorrectReference(refs[i], m[i]);
          refs[i].releaseMemoryReference();
       }
 
@@ -545,18 +452,12 @@
 
    public void testRecoverableMessageStore_3() throws Exception
    {
-      if (!ms.isRecoverable())
-      {
-         // we only test recoverable message stores
-         return;
-      }
-
       Message m = MessageFactory.
       createCoreMessage(0, true, 777l, 888l, (byte)9, headers, "payload");
 
       // recoverable store, non-reliable message, one message
       MessageReference ref = ms.reference(m);
-      assertCorrectReference(ref, ms.getStoreID(), m);
+      assertCorrectReference(ref, m);
 
       ref.releaseMemoryReference();
 
@@ -573,22 +474,16 @@
 
    public void testRecoverableMessageStore_3_1() throws Exception
    {
-      if (!ms.isRecoverable())
-      {
-         // we only test recoverable message stores
-         return;
-      }
-
       Message m = MessageFactory.
       createCoreMessage(0, true, 777l, 888l, (byte)9, headers, "payload");
 
       // recoverable store, non-reliable message, one message
       MessageReference ref = ms.reference(m);
-      assertCorrectReference(ref, ms.getStoreID(), m);
+      assertCorrectReference(ref, m);
 
       MessageReference ref2 = ms.reference(m);
 
-      assertCorrectReference(ref2, ms.getStoreID(), m);
+      assertCorrectReference(ref2, m);
    }
 
    //////
@@ -597,12 +492,6 @@
 
    public void testRecoverableMessageStore_4() throws Exception
    {
-      if (!ms.isRecoverable())
-      {
-         // we only test recoverable message stores
-         return;
-      }
-
       Message[] m = new Message[NUMBER_OF_MESSAGES];
       MessageReference[] refs = new MessageReference[NUMBER_OF_MESSAGES];
       for(int i = 0; i < NUMBER_OF_MESSAGES; i++ )
@@ -612,7 +501,7 @@
 
          // recoverable store, non-reliable message, one message
          refs[i] = ms.reference(m[i]);
-         assertCorrectReference(refs[i], ms.getStoreID(), m[i]);
+         assertCorrectReference(refs[i], m[i]);
       }
 
       // get reachable reference
@@ -633,18 +522,13 @@
    
    public void testRecoverableMessageStore_6() throws Exception
    {
-      if (!ms.isRecoverable())
-      {
-         // we only test recoverable message stores
-         return;
-      }
 
       Message m = MessageFactory.
       createCoreMessage(0, true, 777l, 888l, (byte)9, headers, "payload");
 
       // non-recoverable store, non-reliable message, one message
       MessageReference ref = ms.reference(m);
-      assertCorrectReference(ref, ms.getStoreID(), m);
+      assertCorrectReference(ref, m);
       
       //Create another reference from that reference
       MessageReference ref2 = ms.reference(m);
@@ -655,7 +539,7 @@
       assertNotNull(ref3);
       ref3.releaseMemoryReference();
       
-      assertCorrectReference(ref3, ms.getStoreID(), m);
+      assertCorrectReference(ref3, m);
       
       ref2.releaseMemoryReference();
 
@@ -668,26 +552,20 @@
    
    public void testRecoverableMessageStore_7() throws Exception
    {
-      if (!ms.isRecoverable())
-      {
-         // we only test recoverable message stores
-         return;
-      }
-
       Message m = MessageFactory.
       createCoreMessage(0, true, 777l, 888l, (byte)9, headers, "payload");
 
       // non-recoverable store, non-reliable message, one message
       MessageReference ref = ms.reference(m);
-      assertCorrectReference(ref, ms.getStoreID(), m);
+      assertCorrectReference(ref, m);
       
       MessageReference ref2 = ms.reference(ref.getMessageID());
       assertNotNull(ref2);      
-      assertCorrectReference(ref2, ms.getStoreID(), m);
+      assertCorrectReference(ref2, m);
       
       MessageReference ref3 = ms.reference(ref.getMessageID());
       assertNotNull(ref3);      
-      assertCorrectReference(ref3, ms.getStoreID(), m);
+      assertCorrectReference(ref3, m);
       
       ref.releaseMemoryReference();
       ref2.releaseMemoryReference();

Modified: trunk/tests/src/org/jboss/test/messaging/jms/AcknowledgmentTest.java
===================================================================
--- trunk/tests/src/org/jboss/test/messaging/jms/AcknowledgmentTest.java	2006-08-30 09:26:13 UTC (rev 1236)
+++ trunk/tests/src/org/jboss/test/messaging/jms/AcknowledgmentTest.java	2006-08-30 18:36:36 UTC (rev 1237)
@@ -103,160 +103,160 @@
 
 
    // 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();
+//         }
+//      }
+//   }
    
-   
-   /* 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
    {
 
@@ -423,439 +423,439 @@
    }
 
 	
-	
-	/**
-	 * 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();
-
-   }
+//	
+//	/**
+//	 * 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);
+//   }
+//   
    
-   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 -----------------------------------------------------
@@ -1193,7 +1193,7 @@
    private boolean assertRemainingMessages(int expected) throws Exception
    {
       //Need to pause since delivery may still be in progress
-      Thread.sleep(1000);
+      Thread.sleep(500);
       ObjectName destObjectName = 
          new ObjectName("jboss.messaging.destination:service=Queue,name=Queue");
       Integer messageCount = (Integer)ServerManagement.getAttribute(destObjectName, "MessageCount");      

Modified: trunk/tests/src/org/jboss/test/messaging/jms/CTSMiscellaneousTest.java
===================================================================
--- trunk/tests/src/org/jboss/test/messaging/jms/CTSMiscellaneousTest.java	2006-08-30 09:26:13 UTC (rev 1236)
+++ trunk/tests/src/org/jboss/test/messaging/jms/CTSMiscellaneousTest.java	2006-08-30 18:36:36 UTC (rev 1237)
@@ -21,34 +21,32 @@
   */
 package org.jboss.test.messaging.jms;
 
-import org.jboss.test.messaging.MessagingTestCase;
-import org.jboss.test.messaging.jms.message.SimpleJMSBytesMessage;
-import org.jboss.test.messaging.jms.message.SimpleJMSMessage;
-import org.jboss.test.messaging.tools.ServerManagement;
-import org.jboss.jms.client.JBossConnectionFactory;
-
-import javax.jms.Queue;
-import javax.jms.ConnectionFactory;
-import javax.jms.Connection;
-import javax.jms.Session;
-import javax.jms.MessageProducer;
-import javax.jms.MessageConsumer;
 import javax.jms.BytesMessage;
+import javax.jms.Connection;
+import javax.jms.ConnectionFactory;
+import javax.jms.InvalidSelectorException;
 import javax.jms.Message;
-import javax.jms.TextMessage;
-import javax.jms.QueueReceiver;
+import javax.jms.MessageConsumer;
+import javax.jms.MessageProducer;
+import javax.jms.Queue;
 import javax.jms.QueueConnection;
-import javax.jms.QueueSession;
 import javax.jms.QueueConnectionFactory;
+import javax.jms.QueueReceiver;
 import javax.jms.QueueSender;
+import javax.jms.QueueSession;
+import javax.jms.Session;
+import javax.jms.TextMessage;
 import javax.jms.Topic;
-import javax.jms.InvalidSelectorException;
-import javax.jms.TopicSession;
 import javax.jms.TopicConnection;
 import javax.jms.TopicConnectionFactory;
+import javax.jms.TopicSession;
 import javax.naming.InitialContext;
 
-import EDU.oswego.cs.dl.util.concurrent.Slot;
+import org.jboss.jms.client.JBossConnectionFactory;
+import org.jboss.test.messaging.MessagingTestCase;
+import org.jboss.test.messaging.jms.message.SimpleJMSBytesMessage;
+import org.jboss.test.messaging.jms.message.SimpleJMSMessage;
+import org.jboss.test.messaging.tools.ServerManagement;
 
 /**
  * Safeguards for previously detected TCK failures.

Modified: trunk/tests/src/org/jboss/test/messaging/jms/ConnectionFactoryTest.java
===================================================================
--- trunk/tests/src/org/jboss/test/messaging/jms/ConnectionFactoryTest.java	2006-08-30 09:26:13 UTC (rev 1236)
+++ trunk/tests/src/org/jboss/test/messaging/jms/ConnectionFactoryTest.java	2006-08-30 18:36:36 UTC (rev 1237)
@@ -37,6 +37,7 @@
 
 /**
  * @author <a href="mailto:ovidiu at jboss.org">Ovidiu Feodorov</a>
+ * @author <a href="mailto:tim.fox at jboss.com">Tim Fox</a>
  * @version <tt>$Revision$</tt>
  *
  * $Id$

Modified: trunk/tests/src/org/jboss/test/messaging/jms/DurableSubscriberTest.java
===================================================================
--- trunk/tests/src/org/jboss/test/messaging/jms/DurableSubscriberTest.java	2006-08-30 09:26:13 UTC (rev 1236)
+++ trunk/tests/src/org/jboss/test/messaging/jms/DurableSubscriberTest.java	2006-08-30 18:36:36 UTC (rev 1237)
@@ -21,31 +21,31 @@
   */
 package org.jboss.test.messaging.jms;
 
-import org.jboss.test.messaging.MessagingTestCase;
-import org.jboss.test.messaging.tools.ServerManagement;
-
-import javax.naming.InitialContext;
-import javax.naming.NamingException;
-import javax.jms.ConnectionFactory;
 import javax.jms.Connection;
-import javax.jms.Session;
-import javax.jms.MessageProducer;
-import javax.jms.Topic;
+import javax.jms.ConnectionFactory;
 import javax.jms.DeliveryMode;
-import javax.jms.MessageConsumer;
-import javax.jms.TextMessage;
-import javax.jms.Message;
 import javax.jms.InvalidDestinationException;
-import javax.jms.JMSException;
 import javax.jms.InvalidSelectorException;
-import java.util.Set;
+import javax.jms.JMSException;
+import javax.jms.Message;
+import javax.jms.MessageConsumer;
+import javax.jms.MessageProducer;
+import javax.jms.Session;
+import javax.jms.TextMessage;
+import javax.jms.Topic;
+import javax.management.ObjectName;
+import javax.naming.InitialContext;
+import javax.naming.NamingException;
 
+import org.jboss.test.messaging.MessagingTestCase;
+import org.jboss.test.messaging.tools.ServerManagement;
 
 /**
  * Tests focused on durable subscription behavior. More durable subscription tests can be found in
  * MessageConsumerTest.
  *
  * @author <a href="mailto:ovidiu at jboss.org">Ovidiu Feodorov</a>
+ * @author <a href="mailto:tim.fox at jboss.com">Tim Fox</a>
  *
  * $Id$
  */
@@ -106,30 +106,21 @@
       prod.setDeliveryMode(DeliveryMode.PERSISTENT);
 
       s.createDurableSubscriber(topic, "monicabelucci");
+      
+      ObjectName destObjectName = 
+         new ObjectName("jboss.messaging.destination:service=Topic,name=Topic");
+      String text = (String)ServerManagement.invoke(destObjectName, "listSubscriptionsAsText", null, null);
+     
+      assertTrue(text.indexOf("monicabelucci") != -1);
 
-
-      Set subs = (Set)ServerManagement.
-         invoke(ServerManagement.getChannelMapperObjectName(),
-                "getSubscriptions",
-                new Object[] { "brookeburke" },
-                new String[] { "java.lang.String" });
-
-      assertEquals(1, subs.size());
-      assertEquals("monicabelucci", subs.iterator().next());
-
       prod.send(s.createTextMessage("k"));
 
       conn.close();
 
-      subs = (Set)ServerManagement.
-         invoke(ServerManagement.getChannelMapperObjectName(),
-                "getSubscriptions",
-                new Object[] { "brookeburke" },
-                new String[] { "java.lang.String" });
+      text = (String)ServerManagement.invoke(destObjectName, "listSubscriptionsAsText", null, null);
+      
+      assertTrue(text.indexOf("monicabelucci") != -1);
 
-      assertEquals(1, subs.size());
-      assertEquals("monicabelucci", subs.iterator().next());
-
       conn = cf.createConnection();
       conn.setClientID("brookeburke");
 
@@ -372,9 +363,11 @@
       MessageConsumer ds = s.createDurableSubscriber(topic, "monicabelucci");
       conn.start();
 
+      log.info("&&&&&&&&&&&& sending messages");
       prod.send(s.createTextMessage("one"));
       prod.send(s.createTextMessage("two"));
-
+      log.info("&&&&&&&&&&&& sent messages");
+      
       ServerManagement.undeployTopic("TopicToBeRedeployed");
       log.debug("topic undeployed");
 
@@ -416,7 +409,7 @@
       ds =  s.createDurableSubscriber(topic, "monicabelucci");
       conn.start();
 
-      tm = (TextMessage)ds.receive();
+      tm = (TextMessage)ds.receive(1000);
       assertEquals("two", tm.getText());
 
       conn.close();

Modified: trunk/tests/src/org/jboss/test/messaging/jms/MessageConsumerTest.java
===================================================================
--- trunk/tests/src/org/jboss/test/messaging/jms/MessageConsumerTest.java	2006-08-30 09:26:13 UTC (rev 1236)
+++ trunk/tests/src/org/jboss/test/messaging/jms/MessageConsumerTest.java	2006-08-30 18:36:36 UTC (rev 1237)
@@ -53,7 +53,6 @@
 
 import EDU.oswego.cs.dl.util.concurrent.Latch;
 
-
 /**
  * @author <a href="mailto:ovidiu at jboss.org">Ovidiu Feodorov</a>
  * @author <a href="mailto:tim.fox at jboss.com">Tim Fox</a>
@@ -2095,6 +2094,7 @@
                try
                {
                   m = consumer.receive(1500);
+                  log.info(consumer + " received: " + m);
                }
                catch (Exception e)
                {

Modified: trunk/tests/src/org/jboss/test/messaging/jms/MessageProxyTest.java
===================================================================
--- trunk/tests/src/org/jboss/test/messaging/jms/MessageProxyTest.java	2006-08-30 09:26:13 UTC (rev 1236)
+++ trunk/tests/src/org/jboss/test/messaging/jms/MessageProxyTest.java	2006-08-30 18:36:36 UTC (rev 1237)
@@ -40,8 +40,14 @@
 import org.jboss.test.messaging.tools.ServerManagement;
 
 /**
+ * 
+ * A MessageProxyTest
+
  * @author <a href="mailto:tim.fox at jboss.com">Tim Fox</a>
+ * @version <tt>$Revision: 1.1 $</tt>
  *
+ * $Id$
+ *
  */
 public class MessageProxyTest extends MessagingTestCase
 {

Modified: trunk/tests/src/org/jboss/test/messaging/jms/MultipleServerInvocationHandlersTest.java
===================================================================
--- trunk/tests/src/org/jboss/test/messaging/jms/MultipleServerInvocationHandlersTest.java	2006-08-30 09:26:13 UTC (rev 1236)
+++ trunk/tests/src/org/jboss/test/messaging/jms/MultipleServerInvocationHandlersTest.java	2006-08-30 18:36:36 UTC (rev 1237)
@@ -119,8 +119,6 @@
 
       ServerManagement.start("all");
       
-      
-
       ic = new InitialContext(ServerManagement.getJNDIEnvironment());
 
       // stop the Messaging server and re-start it after I register an extra remoting invocation

Modified: trunk/tests/src/org/jboss/test/messaging/jms/PersistenceTest.java
===================================================================
--- trunk/tests/src/org/jboss/test/messaging/jms/PersistenceTest.java	2006-08-30 09:26:13 UTC (rev 1236)
+++ trunk/tests/src/org/jboss/test/messaging/jms/PersistenceTest.java	2006-08-30 18:36:36 UTC (rev 1237)
@@ -37,9 +37,14 @@
 import org.jboss.test.messaging.tools.ServerManagement;
 
 /**
+ * 
+ * A PersistenceTest
+
  * @author <a href="mailto:tim.fox at jboss.com">Tim Fox</a>
+ * @version <tt>$Revision$</tt>
  *
  * $Id$
+ *
  */
 public class PersistenceTest extends MessagingTestCase
 {
@@ -121,7 +126,11 @@
       
       ServerManagement.stopServerPeer();
       
+      
+      log.info("******************** restartiong");
       ServerManagement.startServerPeer();
+      
+      
 
       // Messaging server restart implies new ConnectionFactory lookup
       cf = (ConnectionFactory)initialContext.lookup("/ConnectionFactory");
@@ -427,6 +436,7 @@
       ds = s.createDurableSubscriber(thisTopic, "sub", null, false);
 
       TextMessage rm = (TextMessage)ds.receive(3000);
+      assertNotNull(rm);
       assertEquals("thebody", rm.getText());
 
 

Modified: trunk/tests/src/org/jboss/test/messaging/jms/QueueRequestorTest.java
===================================================================
--- trunk/tests/src/org/jboss/test/messaging/jms/QueueRequestorTest.java	2006-08-30 09:26:13 UTC (rev 1236)
+++ trunk/tests/src/org/jboss/test/messaging/jms/QueueRequestorTest.java	2006-08-30 18:36:36 UTC (rev 1237)
@@ -71,8 +71,7 @@
    {
       super.setUp();
       ServerManagement.start("all");
-      
-      
+            
       initialContext = new InitialContext(ServerManagement.getJNDIEnvironment());
       cf = (QueueConnectionFactory)initialContext.lookup("/ConnectionFactory");
       ServerManagement.undeployQueue("Queue");

Modified: trunk/tests/src/org/jboss/test/messaging/jms/String64KLimitTest.java
===================================================================
--- trunk/tests/src/org/jboss/test/messaging/jms/String64KLimitTest.java	2006-08-30 09:26:13 UTC (rev 1236)
+++ trunk/tests/src/org/jboss/test/messaging/jms/String64KLimitTest.java	2006-08-30 18:36:36 UTC (rev 1237)
@@ -36,7 +36,7 @@
 import javax.naming.InitialContext;
 
 import org.jboss.jms.client.JBossConnectionFactory;
-import org.jboss.jms.util.SafeUTF;
+import org.jboss.messaging.util.SafeUTF;
 import org.jboss.test.messaging.MessagingTestCase;
 import org.jboss.test.messaging.tools.ServerManagement;
 

Modified: trunk/tests/src/org/jboss/test/messaging/jms/XARecoveryTest.java
===================================================================
--- trunk/tests/src/org/jboss/test/messaging/jms/XARecoveryTest.java	2006-08-30 09:26:13 UTC (rev 1236)
+++ trunk/tests/src/org/jboss/test/messaging/jms/XARecoveryTest.java	2006-08-30 18:36:36 UTC (rev 1237)
@@ -29,8 +29,14 @@
 import org.jboss.test.messaging.tools.ServerManagement;
 
 /**
+ * 
+ * A XARecoveryTest
+
  * @author <a href="mailto:tim.fox at jboss.com">Tim Fox</a>
+ * @version <tt>$Revision: 1.1 $</tt>
  *
+ * $Id$
+ *
  */
 public class XARecoveryTest extends MessagingTestCase
 {

Modified: trunk/tests/src/org/jboss/test/messaging/jms/XATest.java
===================================================================
--- trunk/tests/src/org/jboss/test/messaging/jms/XATest.java	2006-08-30 09:26:13 UTC (rev 1236)
+++ trunk/tests/src/org/jboss/test/messaging/jms/XATest.java	2006-08-30 18:36:36 UTC (rev 1237)
@@ -45,9 +45,14 @@
 import org.jboss.tm.TransactionManagerLocator;
 
 /**
+ * 
+ * A XATest
+
  * @author <a href="mailto:tim.fox at jboss.com">Tim Fox</a>
+ * @version <tt>$Revision: 1.1 $</tt>
  *
  * $Id$
+ *
  */
 public class XATest extends MessagingTestCase
 {

Modified: trunk/tests/src/org/jboss/test/messaging/jms/message/JMSReplyToHeaderTest.java
===================================================================
--- trunk/tests/src/org/jboss/test/messaging/jms/message/JMSReplyToHeaderTest.java	2006-08-30 09:26:13 UTC (rev 1236)
+++ trunk/tests/src/org/jboss/test/messaging/jms/message/JMSReplyToHeaderTest.java	2006-08-30 18:36:36 UTC (rev 1237)
@@ -25,8 +25,14 @@
 import javax.jms.TemporaryQueue;
 
 /**
+ * 
+ * A JMSReplyToHeaderTest
+
  * @author <a href="mailto:tim.fox at jboss.com">Tim Fox</a>
  * @version <tt>$Revision$</tt>
+ *
+ * $Id$
+ *
  */
 public class JMSReplyToHeaderTest extends MessageTest
 {

Modified: trunk/tests/src/org/jboss/test/messaging/jms/message/JMSXDeliveryCountTest.java
===================================================================
--- trunk/tests/src/org/jboss/test/messaging/jms/message/JMSXDeliveryCountTest.java	2006-08-30 09:26:13 UTC (rev 1236)
+++ trunk/tests/src/org/jboss/test/messaging/jms/message/JMSXDeliveryCountTest.java	2006-08-30 18:36:36 UTC (rev 1237)
@@ -37,10 +37,14 @@
 import org.jboss.test.messaging.tools.ServerManagement;
 
 /**
+ * 
+ * A JMSXDeliveryCountTest
+
  * @author <a href="mailto:tim.fox at jboss.com">Tim Fox</a>
  * @version <tt>$Revision$</tt>
  *
  * $Id$
+ *
  */
 public class JMSXDeliveryCountTest extends MessagingTestCase
 {

Modified: trunk/tests/src/org/jboss/test/messaging/jms/message/MessageBodyTest.java
===================================================================
--- trunk/tests/src/org/jboss/test/messaging/jms/message/MessageBodyTest.java	2006-08-30 09:26:13 UTC (rev 1236)
+++ trunk/tests/src/org/jboss/test/messaging/jms/message/MessageBodyTest.java	2006-08-30 18:36:36 UTC (rev 1237)
@@ -47,10 +47,14 @@
 import org.jboss.test.messaging.tools.ServerManagement;
 
 /**
- * Tests for different types of message
+ * 
+ * A MessageBodyTest
+
+ * @author <a href="mailto:tim.fox at jboss.com">Tim Fox</a>
+ * @version <tt>$Revision$</tt>
  *
- * @author <a href="mailto:tim.fox at jboss.com">Tim Fox</a>
  * $Id$
+ *
  */
 public class MessageBodyTest extends MessagingTestCase
 {

Modified: trunk/tests/src/org/jboss/test/messaging/jms/message/ObjectMessageDeliveryTest.java
===================================================================
--- trunk/tests/src/org/jboss/test/messaging/jms/message/ObjectMessageDeliveryTest.java	2006-08-30 09:26:13 UTC (rev 1236)
+++ trunk/tests/src/org/jboss/test/messaging/jms/message/ObjectMessageDeliveryTest.java	2006-08-30 18:36:36 UTC (rev 1237)
@@ -37,7 +37,16 @@
 import org.jboss.test.messaging.MessagingTestCase;
 import org.jboss.test.messaging.tools.ServerManagement;
 
+/**
+ * 
+ * A ObjectMessageDeliveryTest
 
+ * @author <a href="mailto:tim.fox at jboss.com">Tim Fox</a>
+ * @version <tt>$Revision$</tt>
+ *
+ * $Id$
+ *
+ */
 public class ObjectMessageDeliveryTest extends MessagingTestCase
 {
    // Constants -----------------------------------------------------

Modified: trunk/tests/src/org/jboss/test/messaging/jms/persistence/MessagePersistenceManagerTest.java
===================================================================
--- trunk/tests/src/org/jboss/test/messaging/jms/persistence/MessagePersistenceManagerTest.java	2006-08-30 09:26:13 UTC (rev 1236)
+++ trunk/tests/src/org/jboss/test/messaging/jms/persistence/MessagePersistenceManagerTest.java	2006-08-30 18:36:36 UTC (rev 1237)
@@ -25,9 +25,6 @@
 
 import org.jboss.jms.destination.JBossQueue;
 import org.jboss.jms.message.JBossMessage;
-import org.jboss.jms.server.QueuedExecutorPool;
-import org.jboss.jms.server.plugin.JDBCChannelMapper;
-import org.jboss.jms.server.plugin.contract.ChannelMapper;
 import org.jboss.messaging.core.Message;
 import org.jboss.messaging.core.plugin.JDBCPersistenceManager;
 import org.jboss.test.messaging.core.plugin.JDBCPersistenceManagerTest;
@@ -44,9 +41,7 @@
 public class MessagePersistenceManagerTest extends JDBCPersistenceManagerTest
 {
    // Attributes ----------------------------------------------------
-   
-   protected ChannelMapper cm;
-      
+     
    // Constructors --------------------------------------------------
 
    public MessagePersistenceManagerTest(String name)
@@ -67,44 +62,20 @@
    protected void doSetup(boolean batch) throws Throwable
    {
       super.doSetup(batch);
-      
-      cm.deployCoreDestination(true, "testDestination", ms, pm, null, 100, 20, 10);
-      cm.deployCoreDestination(true, "testReplyTo", ms, pm, null, 100, 20, 10);
    }
 
    public void tearDown() throws Exception
    {
       super.tearDown();
-      
-      cm.undeployCoreDestination(true, "testDestination");
-      cm.undeployCoreDestination(true, "testReplyTo");
-      
-      cm.stop();
    }
    
    protected JDBCPersistenceManager createPM() throws Exception
-   {
-      try
-      {
-         cm = new JDBCChannelMapper(sc.getDataSource(), sc.getTransactionManager());
-                  
-         JDBCPersistenceManager pm = new JDBCPersistenceManager(sc.getDataSource(), sc.getTransactionManager(), cm);
-         
-         pm.start();
-         
-         cm.setPersistenceManager(pm);
-         
-         cm.setQueuedExecutorPool(new QueuedExecutorPool(100));
-         
-         cm.start();
-                      
-         return pm;
-      }
-      catch (Exception e)
-      {
-         e.printStackTrace();
-         return null;
-      }
+   {           
+      JDBCPersistenceManager pm = new JDBCPersistenceManager(sc.getDataSource(), sc.getTransactionManager());
+      
+      pm.start();                 
+                   
+      return pm;     
    }
   
    protected void checkEquivalent(Message m1, Message m2) throws Throwable

Modified: trunk/tests/src/org/jboss/test/messaging/jms/server/connectionfactory/ConnectionFactoryTest.java
===================================================================
--- trunk/tests/src/org/jboss/test/messaging/jms/server/connectionfactory/ConnectionFactoryTest.java	2006-08-30 09:26:13 UTC (rev 1236)
+++ trunk/tests/src/org/jboss/test/messaging/jms/server/connectionfactory/ConnectionFactoryTest.java	2006-08-30 18:36:36 UTC (rev 1237)
@@ -69,8 +69,6 @@
       super.setUp();
       ServerManagement.start("all");
       
-      
-
       initialContext = new InitialContext(ServerManagement.getJNDIEnvironment());
 
       log.debug("setup done");

Modified: trunk/tests/src/org/jboss/test/messaging/jms/server/connectormanager/SimpleConnectorManagerTest.java
===================================================================
--- trunk/tests/src/org/jboss/test/messaging/jms/server/connectormanager/SimpleConnectorManagerTest.java	2006-08-30 09:26:13 UTC (rev 1236)
+++ trunk/tests/src/org/jboss/test/messaging/jms/server/connectormanager/SimpleConnectorManagerTest.java	2006-08-30 18:36:36 UTC (rev 1237)
@@ -27,7 +27,16 @@
 import org.jboss.test.messaging.MessagingTestCase;
 import org.jboss.test.messaging.tools.ServerManagement;
 
+/**
+ * 
+ * A SimpleConnectorManagerTest
 
+ * @author <a href="mailto:tim.fox at jboss.com">Tim Fox</a>
+ * @version <tt>$Revision: 1.1 $</tt>
+ *
+ * $Id$
+ *
+ */
 public class SimpleConnectorManagerTest extends MessagingTestCase
 {
    // Constants -----------------------------------------------------

Modified: trunk/tests/src/org/jboss/test/messaging/jms/server/destination/base/DestinationManagementTestBase.java
===================================================================
--- trunk/tests/src/org/jboss/test/messaging/jms/server/destination/base/DestinationManagementTestBase.java	2006-08-30 09:26:13 UTC (rev 1236)
+++ trunk/tests/src/org/jboss/test/messaging/jms/server/destination/base/DestinationManagementTestBase.java	2006-08-30 18:36:36 UTC (rev 1237)
@@ -21,25 +21,23 @@
   */
 package org.jboss.test.messaging.jms.server.destination.base;
 
+import java.util.Set;
+
+import javax.jms.Destination;
+import javax.jms.Queue;
+import javax.jms.Topic;
 import javax.management.ObjectName;
 import javax.naming.InitialContext;
 import javax.naming.NamingException;
-import javax.jms.Destination;
-import javax.jms.Queue;
-import javax.jms.Topic;
 
-import org.jboss.test.messaging.MessagingTestCase;
-import org.jboss.test.messaging.tools.ServerManagement;
 import org.jboss.jms.destination.JBossDestination;
 import org.jboss.jms.destination.JBossQueue;
 import org.jboss.jms.destination.JBossTopic;
-import org.jboss.jms.server.plugin.contract.ChannelMapper;
 import org.jboss.jms.util.XMLUtil;
-import org.jboss.messaging.core.local.CoreDestination;
+import org.jboss.test.messaging.MessagingTestCase;
+import org.jboss.test.messaging.tools.ServerManagement;
 import org.w3c.dom.Element;
 
-import java.util.Set;
-
 /**
  * Exercises a destinatio's management interface after deployment.
  *
@@ -495,15 +493,23 @@
       assertEquals(new Integer(pageSize), ServerManagement.getAttribute(destObjectName, "PageSize"));
       assertEquals(new Integer(downCacheSize), ServerManagement.getAttribute(destObjectName, "DownCacheSize"));
 
-      ChannelMapper cm = ServerManagement.getChannelMapper();
-      JBossDestination jbd = isQueue() ? (JBossDestination)new JBossQueue("PageableAttributes") : 
-         (JBossDestination)new JBossTopic("PageableAttributes");
-      CoreDestination cd = cm.getCoreDestination(jbd);
+      JBossDestination jbd2;
       
-      assertEquals(fullSize, cd.getFullSize());
-      assertEquals(pageSize, cd.getPageSize());
-      assertEquals(downCacheSize, cd.getDownCacheSize());
+      if (isQueue())
+      {
+         jbd2 = new JBossQueue("PageableAttributes");
+      }
+      else
+      {
+         jbd2 = new JBossTopic("PageableAttributes");
+      }
       
+      jbd2 = ServerManagement.getDestinationManager().getDestination(jbd2);
+       
+      assertEquals(fullSize, jbd2.getFullSize());
+      assertEquals(pageSize, jbd2.getPageSize());
+      assertEquals(downCacheSize, jbd2.getDownCacheSize());
+      
       // Try to change the values when destination lives, no effect
       ServerManagement.setAttribute(destObjectName, "FullSize", "1111");
       assertEquals(new Integer(fullSize), ServerManagement.getAttribute(destObjectName, "FullSize"));
@@ -524,11 +530,12 @@
       // Start the service again and test the value from core destination
       ServerManagement.invoke(destObjectName, "start", null, null);
       
-      // Must get the new core destination!
-      cd = cm.getCoreDestination(jbd);
-      assertEquals(751119, cd.getFullSize());
-      assertEquals(20019, cd.getPageSize());
-      assertEquals(9999, cd.getDownCacheSize());
+      jbd2 = ServerManagement.getDestinationManager().getDestination(jbd2);
+      
+      // Must get the new core destination!      
+      assertEquals(751119, jbd2.getFullSize());
+      assertEquals(20019, jbd2.getPageSize());
+      assertEquals(9999, jbd2.getDownCacheSize());
 
       undeployDestination("PageableAttributes");
    }

Deleted: trunk/tests/src/org/jboss/test/messaging/jms/server/plugin/JDBCChannelMapperTest.java
===================================================================
--- trunk/tests/src/org/jboss/test/messaging/jms/server/plugin/JDBCChannelMapperTest.java	2006-08-30 09:26:13 UTC (rev 1236)
+++ trunk/tests/src/org/jboss/test/messaging/jms/server/plugin/JDBCChannelMapperTest.java	2006-08-30 18:36:36 UTC (rev 1237)
@@ -1,357 +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.server.plugin;
-
-import java.sql.Connection;
-import java.sql.PreparedStatement;
-
-import javax.naming.InitialContext;
-import javax.sql.DataSource;
-import javax.transaction.Transaction;
-import javax.transaction.TransactionManager;
-
-import org.jboss.jms.destination.JBossDestination;
-import org.jboss.jms.destination.JBossQueue;
-import org.jboss.jms.destination.JBossTopic;
-import org.jboss.jms.server.DestinationManager;
-import org.jboss.jms.server.plugin.contract.ChannelMapper;
-import org.jboss.jms.server.subscription.DurableSubscription;
-import org.jboss.messaging.core.local.CoreDestination;
-import org.jboss.messaging.core.local.Queue;
-import org.jboss.messaging.core.local.Topic;
-import org.jboss.messaging.core.persistence.JDBCUtil;
-import org.jboss.messaging.core.plugin.contract.MessageStore;
-import org.jboss.messaging.core.plugin.contract.PersistenceManager;
-import org.jboss.test.messaging.MessagingTestCase;
-import org.jboss.test.messaging.tools.ServerManagement;
-import org.jboss.tm.TransactionManagerService;
-import org.jboss.util.id.GUID;
-
-/**
- * These tests must not be run in remote mode!
- *
- * @author <a href="mailto:tim.fox at jboss.com">Tim Fox</a>
- * @version <tt>1.1</tt>
- *
- * JDBCChannelMapperTest.java,v 1.1 2006/02/28 16:48:15 timfox Exp
- */
-public class JDBCChannelMapperTest extends MessagingTestCase
-{
-   // Attributes ----------------------------------------------------
-
-   protected PersistenceManager pm;
-   protected DestinationManager dm;
-   protected MessageStore ms;
-   protected ChannelMapper channelMapper;
-
-   // Constructors --------------------------------------------------
-
-   public JDBCChannelMapperTest(String name)
-   {
-      super(name);
-   }
-
-   // Public --------------------------------------------------------
-
-   public void setUp() throws Exception
-   {
-      if (ServerManagement.isRemote())
-      {
-         fail("This test must not be ran in remote mode!");
-      }
-
-      super.setUp();
-
-      ServerManagement.start("all");
-
-      dm = ServerManagement.getDestinationManager();
-      ms = ServerManagement.getMessageStore();
-      pm = ServerManagement.getPersistenceManager();
-      channelMapper = ServerManagement.getChannelMapper();
-      
-
-      log.debug("setup done");
-   }
-
-   public void tearDown() throws Exception
-   {
-      log.debug("starting tear down");
-      
-      super.tearDown();
-   }
-
-   public void testCreateGetRemoveDurableSubscription() throws Exception
-   {
-      String topicName = new GUID().toString();
-      String clientID = new GUID().toString();
-      String subscriptionName = new GUID().toString();
-      String selector = "color = 'red'";
-
-      ServerManagement.deployTopic(topicName);
-
-      DurableSubscription sub = channelMapper.createDurableSubscription(topicName,
-                                                               clientID,
-                                                               subscriptionName,
-                                                               selector,
-                                                               false,
-                                                               ms, pm, null);
-
-      assertEquals(sub.getSelector(), selector);
-
-      DurableSubscription sub_r = channelMapper.getDurableSubscription(clientID,
-                                                              subscriptionName,
-                                                              ms, pm, null);
-
-      assertEquals(sub_r.getSelector(), selector);
-
-      boolean removed = channelMapper.removeDurableSubscription(clientID, subscriptionName);
-      assertTrue(removed);
-
-      sub_r = channelMapper.getDurableSubscription(clientID, subscriptionName, ms, pm, null);
-
-      assertNull(sub_r);
-
-      removed = channelMapper.removeDurableSubscription(clientID, subscriptionName);
-      assertFalse(removed);
-
-   }
-
-   public void testCreateGetRemoveDurableSubscriptionNullSelector() throws Exception
-   {
-      String topicName = new GUID().toString();
-      String clientID = new GUID().toString();
-      String subscriptionName = new GUID().toString();
-
-      ServerManagement.deployTopic(topicName);
-
-      DurableSubscription sub = channelMapper.createDurableSubscription(topicName,
-                                                               clientID,
-                                                               subscriptionName,
-                                                               null,
-                                                               false,
-                                                               ms, pm, null);
-
-      assertNull(sub.getSelector());
-
-      DurableSubscription sub_r = channelMapper.getDurableSubscription(clientID,
-                                                              subscriptionName,
-                                                              ms, pm, null);
-
-      assertNull(sub_r.getSelector());
-
-      boolean removed = channelMapper.removeDurableSubscription(clientID, subscriptionName);
-      assertTrue(removed);
-
-      sub_r = channelMapper.getDurableSubscription(clientID, subscriptionName, ms, pm, null);
-
-      assertNull(sub_r);
-
-      removed = channelMapper.removeDurableSubscription(clientID, subscriptionName);
-      assertFalse(removed);
-
-   }
-
-   public void testGetPreConfClientId_1() throws Exception
-   {
-      String clientID = channelMapper.getPreConfiguredClientID("blahblah");
-      assertNull(clientID);
-   }
-
-   public void testGetPreConfClientId_2() throws Exception
-   {
-      InitialContext ctx = new InitialContext();
-
-      TransactionManager mgr = (TransactionManager)ctx.lookup(TransactionManagerService.JNDI_NAME);
-      DataSource ds = (DataSource)ctx.lookup("java:/DefaultDS");
-      String username = "user123";
-      String clientID = "clientid-4354";
-      String password = "my_password";
-
-      Transaction txOld = mgr.suspend();
-      mgr.begin();
-
-      Connection conn = ds.getConnection();
-      String sql = "INSERT INTO JMS_USER (USERID, CLIENTID, PASSWD) VALUES (?,?,?)";
-      PreparedStatement ps = conn.prepareStatement(sql);
-      ps.setString(1, username);
-      ps.setString(2, clientID);
-      ps.setString(3, password);
-      int rows = ps.executeUpdate();
-
-      log.debug(JDBCUtil.statementToString(sql, username, clientID, password) + " completed successfully");
-
-      assertEquals(1, rows);
-
-      mgr.commit();
-
-      if (txOld != null)
-      {
-         mgr.resume(txOld);
-      }
-
-      conn.close();
-
-      String theClientID = channelMapper.getPreConfiguredClientID(username);
-
-      assertNotNull(theClientID);
-      assertEquals(clientID, theClientID);
-           
-   }
-   
-   public void testGetDeployCoreDestinationTest() throws Exception
-   {
-      //Lookup a non existent core destination -  verify returns null
-      
-      JBossQueue queue = new JBossQueue("queue1");
-      
-      JBossTopic topic = new JBossTopic("topic1");
-      
-      CoreDestination cd = channelMapper.getCoreDestination(queue);
-      
-      assertNull(cd);
-      
-      cd = channelMapper.getCoreDestination(topic);
-      
-      assertNull(cd);
-      
-      //Lookup a non existent jboss destination - verify returns null
-      
-      JBossDestination jbd = channelMapper.getJBossDestination(123);
-      
-      assertNull(jbd);
-      
-      //Deploy core destinations
-      
-      channelMapper.deployCoreDestination(true, "queue1", ms, pm, null, 100, 20, 10);
-      
-      channelMapper.deployCoreDestination(false, "topic1", ms, pm, null, 100, 20, 10);
-      
-      //Lookup core dest
-      
-      CoreDestination cd1 = channelMapper.getCoreDestination(queue);
-      
-      assertNotNull(cd1);
-      
-      assertTrue(cd1 instanceof Queue);
-      
-      Queue q = (Queue)cd1;
-      
-      CoreDestination cd2 = channelMapper.getCoreDestination(topic);
-      
-      assertNotNull(cd2);
-      
-      assertTrue(cd2 instanceof Topic);
-      
-      Topic t = (Topic)cd2;
-                  
-      //Lookup jboss dest
-      
-      JBossDestination jb1 = channelMapper.getJBossDestination(q.getChannelID());
-      
-      assertNotNull(jb1);
-      
-      assertEquals("queue1", jb1.getName());
-      
-      JBossDestination jb2 = channelMapper.getJBossDestination(t.getId());
-      
-      assertNotNull(jb2);
-      
-      assertEquals("topic1", jb2.getName());
-      
-      //undeploy core dest
-      
-      CoreDestination cd3 = channelMapper.undeployCoreDestination(true, "queue1");
-      
-      assertNotNull(cd3);
-      
-      assertEquals(q.getChannelID(), cd3.getId());
-      
-      CoreDestination cd4 = channelMapper.undeployCoreDestination(false, "topic1");
-      
-      assertNotNull(cd3);
-      
-      assertEquals(t.getId(), cd4.getId());
-      
-      cd3 = channelMapper.undeployCoreDestination(true, "queue1");
-      
-      assertNull(cd3);
-      
-      cd4 = channelMapper.undeployCoreDestination(false, "topic1");
-      
-      assertNull(cd4);
-      
-      //Lookup core dest - null
-      
-      cd3 = channelMapper.getCoreDestination(queue);
-      
-      assertNull(cd3);
-      
-      cd4 = channelMapper.getCoreDestination(topic);
-      
-      assertNull(cd4);
-      
-      //lookup jboss dest - null
-      
-      jb1 = channelMapper.getJBossDestination(q.getChannelID());
-      
-      assertNull(jb1);
-      
-      jb2 = channelMapper.getJBossDestination(t.getId());
-      
-      assertNull(jb2);
-      
-      //Deploy a core dest
-      
-      channelMapper.deployCoreDestination(true, "queue1", ms, pm, null, 100, 20, 10);
-      
-      channelMapper.deployCoreDestination(false, "topic1", ms, pm, null, 100, 20, 10);
-            
-      //lookup core dest - verify has same id
-      
-      cd3 = channelMapper.getCoreDestination(queue);
-      
-      assertNotNull(cd3);
-      
-      assertEquals(cd3.getId(), cd1.getId());
-      
-      cd4 = channelMapper.getCoreDestination(topic);
-      
-      assertNotNull(cd4);
-      
-      assertEquals(cd4.getId(), cd2.getId());
-   }
-   
-   
-
-   // Package protected ---------------------------------------------
-
-   // Protected -----------------------------------------------------
-
-   // Private -------------------------------------------------------
-
-   // Inner classes -------------------------------------------------
-
-}
-
-
-
-

Added: trunk/tests/src/org/jboss/test/messaging/jms/util/MessageQueueNameHelperTest.java
===================================================================
--- trunk/tests/src/org/jboss/test/messaging/jms/util/MessageQueueNameHelperTest.java	2006-08-30 09:26:13 UTC (rev 1236)
+++ trunk/tests/src/org/jboss/test/messaging/jms/util/MessageQueueNameHelperTest.java	2006-08-30 18:36:36 UTC (rev 1237)
@@ -0,0 +1,72 @@
+/*
+  * 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.util;
+
+import junit.framework.TestCase;
+
+import org.jboss.jms.util.MessageQueueNameHelper;
+
+
+public class MessageQueueNameHelperTest extends TestCase
+{   
+   // Constants -----------------------------------------------------
+   
+   // Static --------------------------------------------------------
+   
+   // Attributes ----------------------------------------------------
+   
+   // Constructors --------------------------------------------------
+   
+   public MessageQueueNameHelperTest(String name)
+   {
+      super(name);
+   }
+   
+   // Public --------------------------------------------------------
+
+   public void testQueueName()
+   {
+      String name = "clientid123.mysub";
+      
+      MessageQueueNameHelper helper = MessageQueueNameHelper.createHelper(name);
+      
+      assertEquals("clientid123", helper.getClientId());
+      assertEquals("mysub", helper.getSubName());
+   }
+   
+   public void testCreate()
+   {
+      String name = MessageQueueNameHelper.createSubscriptionName("clientid456", "mysub2");
+      
+      assertEquals("clientid456.mysub2", name);
+   }
+
+   // Package protected ---------------------------------------------
+   
+   // Protected -----------------------------------------------------
+   
+   // Private -------------------------------------------------------
+   
+   // Inner classes -------------------------------------------------
+}
+
+

Modified: trunk/tests/src/org/jboss/test/messaging/tools/ServerManagement.java
===================================================================
--- trunk/tests/src/org/jboss/test/messaging/tools/ServerManagement.java	2006-08-30 09:26:13 UTC (rev 1236)
+++ trunk/tests/src/org/jboss/test/messaging/tools/ServerManagement.java	2006-08-30 18:36:36 UTC (rev 1237)
@@ -34,16 +34,15 @@
 
 import org.jboss.jms.message.MessageIdGeneratorFactory;
 import org.jboss.jms.server.DestinationManager;
-import org.jboss.jms.server.plugin.contract.ChannelMapper;
 import org.jboss.logging.Logger;
 import org.jboss.messaging.core.plugin.contract.MessageStore;
 import org.jboss.messaging.core.plugin.contract.PersistenceManager;
+import org.jboss.remoting.ServerInvocationHandler;
 import org.jboss.test.messaging.tools.jmx.rmi.LocalTestServer;
 import org.jboss.test.messaging.tools.jmx.rmi.RMITestServer;
 import org.jboss.test.messaging.tools.jmx.rmi.Server;
 import org.jboss.test.messaging.tools.jndi.InVMInitialContextFactory;
 import org.jboss.test.messaging.tools.jndi.RemoteInitialContextFactory;
-import org.jboss.remoting.ServerInvocationHandler;
 
 /**
  * Collection of static methods to use to start/stop and interact with the in-memory JMS server. It
@@ -298,12 +297,6 @@
       return server.getServerPeerObjectName();
    }
 
-   public static ObjectName getChannelMapperObjectName() throws Exception
-   {
-      insureStarted();
-      return server.getChannelMapperObjectName();
-   }
-
    /**
     * @return a Set<String> with the subsystems currently registered with the Connector.
     *         This method is supposed to work locally as well as remotely.
@@ -356,13 +349,6 @@
       return server.getPersistenceManager();
    }
 
-   public static ChannelMapper getChannelMapper()
-      throws Exception
-   {
-      insureStarted();
-      return server.getChannelMapper();
-   }
-
    public static void configureSecurityForDestination(String destName, String config)
       throws Exception
    {

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-08-30 09:26:13 UTC (rev 1236)
+++ trunk/tests/src/org/jboss/test/messaging/tools/jmx/rmi/LocalTestServer.java	2006-08-30 18:36:36 UTC (rev 1237)
@@ -35,18 +35,18 @@
 
 import org.jboss.jms.server.DestinationManager;
 import org.jboss.jms.server.ServerPeer;
-import org.jboss.jms.server.plugin.contract.ChannelMapper;
 import org.jboss.jms.util.XMLUtil;
 import org.jboss.logging.Logger;
+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.remoting.ServerInvocationHandler;
 import org.jboss.test.messaging.tools.ServerManagement;
 import org.jboss.test.messaging.tools.jboss.MBeanConfigurationElement;
 import org.jboss.test.messaging.tools.jboss.ServiceDeploymentDescriptor;
 import org.jboss.test.messaging.tools.jmx.MockJBossSecurityManager;
 import org.jboss.test.messaging.tools.jmx.RemotingJMXWrapper;
 import org.jboss.test.messaging.tools.jmx.ServiceContainer;
-import org.jboss.remoting.ServerInvocationHandler;
 import org.w3c.dom.Element;
 
 /**
@@ -70,8 +70,9 @@
 
    // service dependencies   
    private ObjectName persistenceManagerObjectName;
-   private ObjectName messageStoreObjectName;
-   private ObjectName channelMapperObjectName;
+   private ObjectName directExchangeObjectName;
+   private ObjectName topicExchangeObjectName;
+   private ObjectName jmsUserManagerObjectName;
 
    // the server MBean itself
    private ObjectName serverPeerObjectName;
@@ -246,24 +247,30 @@
       ServiceDeploymentDescriptor pdd = new ServiceDeploymentDescriptor(persistenceConfigFileURL);
       ServiceDeploymentDescriptor cfdd = new ServiceDeploymentDescriptor(connFactoryConfigFileURL);
 
-      MBeanConfigurationElement channelMapperConfig =
-         (MBeanConfigurationElement)pdd.query("service", "ChannelMapper").iterator().next();
-      channelMapperObjectName = sc.registerAndConfigureService(channelMapperConfig);
-      sc.invoke(channelMapperObjectName, "create", new Object[0], new String[0]);
-      sc.invoke(channelMapperObjectName, "start", new Object[0], new String[0]);
-
       MBeanConfigurationElement persistenceManagerConfig =
          (MBeanConfigurationElement)pdd.query("service", "PersistenceManager").iterator().next();
       persistenceManagerObjectName = sc.registerAndConfigureService(persistenceManagerConfig);
       sc.invoke(persistenceManagerObjectName, "create", new Object[0], new String[0]);
-      sc.invoke(persistenceManagerObjectName, "start", new Object[0], new String[0]);     
+      sc.invoke(persistenceManagerObjectName, "start", new Object[0], new String[0]);    
+      
+      MBeanConfigurationElement directExchangeConfig =
+         (MBeanConfigurationElement)pdd.query("service", "DirectExchange").iterator().next();
+      directExchangeObjectName = sc.registerAndConfigureService(directExchangeConfig);
+      sc.invoke(directExchangeObjectName, "create", new Object[0], new String[0]);
+      sc.invoke(directExchangeObjectName, "start", new Object[0], new String[0]);
+      
+      MBeanConfigurationElement topicExchangeConfig =
+         (MBeanConfigurationElement)pdd.query("service", "TopicExchange").iterator().next();
+      topicExchangeObjectName = sc.registerAndConfigureService(topicExchangeConfig);
+      sc.invoke(topicExchangeObjectName, "create", new Object[0], new String[0]);
+      sc.invoke(topicExchangeObjectName, "start", new Object[0], new String[0]);
+      
+      MBeanConfigurationElement jmsUserManagerConfig =
+         (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]);      
 
-      MBeanConfigurationElement messageStoreConfig =
-         (MBeanConfigurationElement)mdd.query("service", "MessageStore").iterator().next();
-      messageStoreObjectName = sc.registerAndConfigureService(messageStoreConfig);
-      sc.invoke(messageStoreObjectName, "create", new Object[0], new String[0]);
-      sc.invoke(messageStoreObjectName, "start", new Object[0], new String[0]);
-
       // register server peer as a service, dependencies are injected automatically
       MBeanConfigurationElement serverPeerConfig =
          (MBeanConfigurationElement)mdd.query("service", "ServerPeer").iterator().next();
@@ -368,15 +375,19 @@
       sc.unregisterService(serverPeerObjectName);
 
       log.debug("stopping ServerPeer's plug-in dependencies");
+      
+      sc.invoke(jmsUserManagerObjectName, "stop", new Object[0], new String[0]);
+      sc.invoke(jmsUserManagerObjectName, "destroy", new Object[0], new String[0]);
+      sc.unregisterService(jmsUserManagerObjectName);
 
-      sc.invoke(channelMapperObjectName, "stop", new Object[0], new String[0]);
-      sc.invoke(channelMapperObjectName, "destroy", new Object[0], new String[0]);
-      sc.unregisterService(channelMapperObjectName);
+      sc.invoke(directExchangeObjectName, "stop", new Object[0], new String[0]);
+      sc.invoke(directExchangeObjectName, "destroy", new Object[0], new String[0]);
+      sc.unregisterService(directExchangeObjectName);
+      
+      sc.invoke(topicExchangeObjectName, "stop", new Object[0], new String[0]);
+      sc.invoke(topicExchangeObjectName, "destroy", new Object[0], new String[0]);
+      sc.unregisterService(topicExchangeObjectName);
 
-      sc.invoke(messageStoreObjectName, "stop", new Object[0], new String[0]);
-      sc.invoke(messageStoreObjectName, "destroy", new Object[0], new String[0]);
-      sc.unregisterService(messageStoreObjectName);
-
       sc.invoke(persistenceManagerObjectName, "stop", new Object[0], new String[0]);
       sc.invoke(persistenceManagerObjectName, "destroy", new Object[0], new String[0]);
       sc.unregisterService(persistenceManagerObjectName);
@@ -400,10 +411,15 @@
       return serverPeerObjectName;
    }
 
-   public ObjectName getChannelMapperObjectName()
+   public ObjectName getDirectExchangeObjectName()
    {
-      return channelMapperObjectName;
+      return directExchangeObjectName;
    }
+   
+   public ObjectName getTopicExchangeObjectName()
+   {
+      return topicExchangeObjectName;
+   }
 
    public Set getConnectorSubsystems() throws Exception
    {
@@ -435,12 +451,10 @@
     */
    public MessageStore getMessageStore() throws Exception
    {
-      return (MessageStore)sc.getAttribute(messageStoreObjectName, "Instance");
+      ServerPeer serverPeer = (ServerPeer)sc.getAttribute(serverPeerObjectName, "Instance");
+      return serverPeer.getMessageStore();
    }
 
-   /**
-    * Only for in-VM use!
-    */
    public DestinationManager getDestinationManager() throws Exception
    {
       ServerPeer serverPeer = (ServerPeer)sc.getAttribute(serverPeerObjectName, "Instance");
@@ -452,16 +466,20 @@
       ServerPeer serverPeer = (ServerPeer)sc.getAttribute(serverPeerObjectName, "Instance");
       return serverPeer.getPersistenceManagerDelegate();
    }
-
-   /**
-    * Only for in-VM use!
-    */
-   public ChannelMapper getChannelMapper() throws Exception
+   
+   public Exchange getDirectExchange() throws Exception
    {
-      return (ChannelMapper)sc.
-         getAttribute(channelMapperObjectName, "Instance");
+      return (Exchange)sc.
+         getAttribute(directExchangeObjectName, "Instance");
    }
    
+   public Exchange getTopicExchange() throws Exception
+   {
+      return (Exchange)sc.
+         getAttribute(topicExchangeObjectName, "Instance");
+   }
+
+   
    /**
     * Only for in-VM use!
     */

Modified: trunk/tests/src/org/jboss/test/messaging/tools/jmx/rmi/RMITestServer.java
===================================================================
--- trunk/tests/src/org/jboss/test/messaging/tools/jmx/rmi/RMITestServer.java	2006-08-30 09:26:13 UTC (rev 1236)
+++ trunk/tests/src/org/jboss/test/messaging/tools/jmx/rmi/RMITestServer.java	2006-08-30 18:36:36 UTC (rev 1237)
@@ -31,8 +31,8 @@
 
 import org.jboss.jms.server.DestinationManager;
 import org.jboss.jms.server.ServerPeer;
-import org.jboss.jms.server.plugin.contract.ChannelMapper;
 import org.jboss.logging.Logger;
+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.remoting.ServerInvocationHandler;
@@ -217,24 +217,24 @@
       return server.getDestinationManager();
    }
 
-   public ChannelMapper getChannelMapper() throws Exception
+   public MessageStore getMessageStore() throws Exception
    {
-      return server.getChannelMapper();
+      return server.getMessageStore();
    }
 
-   public ObjectName getChannelMapperObjectName() throws Exception
+   public PersistenceManager getPersistenceManager() throws Exception
    {
-      return server.getChannelMapperObjectName();
+      return server.getPersistenceManager();
    }
-
-   public MessageStore getMessageStore() throws Exception
+   
+   public Exchange getDirectExchange() throws Exception
    {
-      return server.getMessageStore();
+      return server.getDirectExchange();
    }
-
-   public PersistenceManager getPersistenceManager() throws Exception
+   
+   public Exchange getTopicExchange() throws Exception
    {
-      return null;
+      return server.getTopicExchange();
    }
 
    public ObjectName getServerPeerObjectName() throws Exception

Modified: trunk/tests/src/org/jboss/test/messaging/tools/jmx/rmi/RemoteTestServer.java
===================================================================
--- trunk/tests/src/org/jboss/test/messaging/tools/jmx/rmi/RemoteTestServer.java	2006-08-30 09:26:13 UTC (rev 1236)
+++ trunk/tests/src/org/jboss/test/messaging/tools/jmx/rmi/RemoteTestServer.java	2006-08-30 18:36:36 UTC (rev 1237)
@@ -22,8 +22,9 @@
 package org.jboss.test.messaging.tools.jmx.rmi;
 
 import org.jboss.jms.server.DestinationManager;
-import org.jboss.jms.server.plugin.contract.ChannelMapper;
+import org.jboss.messaging.core.plugin.contract.Exchange;
 import org.jboss.messaging.core.plugin.contract.MessageStore;
+import org.jboss.messaging.core.plugin.contract.PersistenceManager;
 
 /**
  *
@@ -65,10 +66,26 @@
    /**
     * Only for in-VM use!
     */
-   public ChannelMapper getChannelMapper() throws Exception
+   public PersistenceManager getPersistenceManager() throws Exception
    {
       throw new UnsupportedOperationException("This method shouldn't be invoked on a remote server");      
    }
+   
+   /**
+    * Only for in-VM use!
+    */
+   public Exchange getDirectExchange() throws Exception
+   {
+      throw new UnsupportedOperationException("This method shouldn't be invoked on a remote server");      
+   }
+   
+   /**
+    * Only for in-VM use!
+    */
+   public Exchange getTopicExchange() throws Exception
+   {
+      throw new UnsupportedOperationException("This method shouldn't be invoked on a remote server");      
+   }
 
    // Public --------------------------------------------------------
     

Modified: trunk/tests/src/org/jboss/test/messaging/tools/jmx/rmi/Server.java
===================================================================
--- trunk/tests/src/org/jboss/test/messaging/tools/jmx/rmi/Server.java	2006-08-30 09:26:13 UTC (rev 1236)
+++ trunk/tests/src/org/jboss/test/messaging/tools/jmx/rmi/Server.java	2006-08-30 18:36:36 UTC (rev 1237)
@@ -29,7 +29,7 @@
 
 import org.jboss.jms.server.DestinationManager;
 import org.jboss.jms.server.ServerPeer;
-import org.jboss.jms.server.plugin.contract.ChannelMapper;
+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.remoting.ServerInvocationHandler;
@@ -84,7 +84,6 @@
    boolean isServerPeerStarted() throws Exception;
 
    ObjectName getServerPeerObjectName() throws Exception;
-   ObjectName getChannelMapperObjectName() throws Exception;
 
    boolean isStarted() throws Exception;
 
@@ -122,7 +121,9 @@
    /**
     * Only for in-VM use!
     */
-   ChannelMapper getChannelMapper() throws Exception;
+   Exchange getDirectExchange() throws Exception;
+   
+   Exchange getTopicExchange() throws Exception;
 
    /**
     * Only for in-VM use




More information about the jboss-cvs-commits mailing list